7. Examples

This chapter contains example VdmTools programs. The source code for all examples resides in devtools/src/vdm/exam.

7.1. Example 1, List Datasets on a Library Device

This example illustrates opening an SDRC Universal file and listing all of the datasets. Initially a SDRCLib library device object and an associated DataFun object are created. The DataFun object is loaded with function pointers by the SDRCLib object. At this point all further data access of the library device is handled through the data function object.

The library device is opened and attached to a Universal file residing on file bumper.unv. The library name, “Bumper”, is completely arbitrary. Opening a library device is often the most time consuming operation performed on a library. In general the library file must be completely scanned to determine the number and type of datasets, number of nodes and elements, etc. At this point the library device may be queried for dataset information. First the number of nodes and elements are queried and printed. Next, in order to begin to query for dataset parameters, the generic Library object used by the library device must be retrieved. A loop is entered over the total number of datasets on the library. The Dataset object is retrieved for each dataset on the library and queried for the dataset parameters. These parameters are listed for each dataset. Finally the library device is closed and the DataFun and SDRCLib objects are destroyed.

#include "base/base.h"
#include "vdm/vdm.h"

/*----------------------------------------------------------------------
                      List all Datasets
----------------------------------------------------------------------*/
int
main()
{
   vdm_SDRCLib  *sdrclib;
   vdm_DataFun  *datafun;
   vdm_Library  *library;
   vdm_Dataset  *dataset;
   Vint filetype;
   Vint numnp, numel;
   Vint numdatasets, numattributes;
   Vchar dsname[DATASET_MAXNAME];
   Vlong lrec;
   Vint nrow, ncol, ntyp;

   int i;

                   /* create data function object */
   datafun = vdm_DataFunBegin ();

                   /* create SDRC Universal File library device */
   filetype = VDM_SDRC_UNIVERSAL;
   sdrclib = vdm_SDRCLibBegin ();
   vdm_SDRCLibDataFun (sdrclib,datafun);

                   /* open library device */
   vdm_DataFunOpen (datafun,0,"bumper.unv",filetype);

                   /* get number of nodes and elements */ 
   vdm_DataFunGetNumEntities (datafun,SYS_NODE,&numnp);
   vdm_DataFunGetNumEntities (datafun,SYS_ELEM,&numel);
   printf("Number of nodes    = %10d\n",numnp);
   printf("Number of elements = %10d\n",numel);

                   /* get library object */ 
   vdm_DataFunGetLibrary (datafun,&library);

                   /* get number of datasets on library */ 
   vdm_LibraryGetNumDatasets (library,&numdatasets);

                   /* print heading */ 
   printf("Number of datasets = %10d\n",numdatasets);
   printf("  Seq     LRec  NRow     NCol  NTyp  NAtt  Name\n");

                   /* loop through datasets */ 
   for(i = 0; i < numdatasets; i++) {
      vdm_LibraryGetDataset (library,i,&dataset);
      vdm_DatasetInq (dataset,dsname,&lrec,&nrow,&ncol,&ntyp);
      vdm_DatasetGetNumAttributes (dataset,&numattributes);
      printf("%5d %8lld %5d %8d %5d %5d  %s\n",
             i,lrec,nrow,ncol,ntyp,numattributes,dsname);
   }
                   /* close library device */ 
   vdm_DataFunClose (datafun);

                   /* free objects */ 
   vdm_DataFunEnd (datafun);
   vdm_SDRCLibEnd (sdrclib);
   return 0;
}

7.2. Example 2, Read and Print Model Data

This example illustrates loading a Model object with typically a finite element model residing on an external file and then traversing and printing the node coordinates and element connectivity contained in the Connect object registered in the Model object. The finite element model may reside on any external file in a format supported by VdmTools. The external file name is entered as the first argument to the example executable. If no file name is entered then the file “bumper.unv”, a simple IDEAS universal file, is assumed. The model object is created and then loaded using the function vdm_LManLoadModel(). During this process many objects are created and registered in the Model object by the function. These objects represent the various components of the finite element model.

The Connect object is retrieved from the Model object and information about the nodes and elements is accessed and printed.

#include <stdlib.h>
#include "base/base.h"
#include "vis/visdata.h"
#include "vdm/vdm.h"

static void
printNodes(vis_Connect *connect);
static void
printElements(vis_Connect *connect);

/*----------------------------------------------------------------------
                      Read and Print Model Data
----------------------------------------------------------------------*/
int
main(int argc, char **argv)
{
   char inputfile[256];
   vdm_ABAFil  *abafil;
   vdm_ABALib  *abalib;
   vdm_ANSFil  *ansfil;
   vdm_ANSLib  *anslib;
   vdm_NASFil  *nasfil;
   vdm_NASLib  *naslib;
   vdm_SDRCLib *sdrclib;
   vdm_FLUENTLib *fluentlib;
   vdm_DataFun *datafun;
   vdm_LMan    *lman;
   Vint filetype;
   vis_Model *model;
   vis_Connect *connect;

   if(argc < 2) {
      fprintf(stderr,"Usage: %s inputfile\n",argv[0]);
      fprintf(stderr," inputfile is blank, 'bumper.unv' is assumed\n");
      strcpy(inputfile,"bumper.unv");
   } else {
      strcpy(inputfile,argv[1]);
   }

                   /* create data function object */
   datafun = vdm_DataFunBegin ();

                   /* determine file type from file extension */
   if(strstr(inputfile,".bdf") != NULL  ||
      strstr(inputfile,".dat") != NULL) {
      filetype = VDM_NASTRAN_BULKDATA;
      nasfil = vdm_NASFilBegin ();
      vdm_NASFilDataFun (nasfil,datafun);
      printf("Nastran Bulk Data File: %s\n",inputfile);
   } else if(strstr(inputfile,".op2") != NULL) {
      filetype = VDM_NASTRAN_OUTPUT2;
      naslib = vdm_NASLibBegin ();
      vdm_NASLibDataFun (naslib,datafun);
      printf("Nastran Output2 File: %s\n",inputfile);
   } else if(strstr(inputfile,".inp") != NULL) {
      filetype = VDM_ABAQUS_INPUT;
      abafil = vdm_ABAFilBegin ();
      vdm_ABAFilDataFun (abafil,datafun);
      printf("Abaqus Input File: %s\n",inputfile);
   } else if(strstr(inputfile,".fil") != NULL) {
      filetype = VDM_ABAQUS_FIL;
      abalib = vdm_ABALibBegin ();
      vdm_ABALibDataFun (abalib,datafun);
      printf("Abaqus Binary (.fil) File: %s\n",inputfile);
   } else if(strstr(inputfile,".cdb") != NULL) {
      filetype = VDM_ANSYS_INPUT;
      ansfil = vdm_ANSFilBegin ();
      vdm_ANSFilDataFun (ansfil,datafun);
      printf("Ansys Input File: %s\n",inputfile);
   } else if(strstr(inputfile,".rst") != NULL) {
      filetype = VDM_ANSYS_RESULT;
      anslib = vdm_ANSLibBegin ();
      vdm_ANSLibDataFun (anslib,datafun);
      printf("Ansys Result (.rst) File: %s\n",inputfile);
   } else if(strstr(inputfile,".unv") != NULL) {
      filetype = VDM_SDRC_UNIVERSAL;
      sdrclib = vdm_SDRCLibBegin ();
      vdm_SDRCLibDataFun (sdrclib,datafun);
      printf("SDRC Universal File: %s\n",inputfile);
   } else if(strstr(inputfile,".cas") != NULL  ||
             strstr(inputfile,".msh") != NULL) {
      filetype = VDM_FLUENT_MESH;
      fluentlib = vdm_FLUENTLibBegin();
      vdm_FLUENTLibDataFun (fluentlib,datafun);
      printf("Fluent Mesh File: %s\n",inputfile);
   } else {
      fprintf(stderr,"Error: Bad input file %s\n",inputfile);
      exit(1);
   }
                   /* open library device */
   vdm_DataFunOpen (datafun,0,inputfile,filetype);
                   /* instance model object for finite element model */
   model = vis_ModelBegin();
                   /* use Library Manager object to load model */
   lman = vdm_LManBegin ();
   vdm_LManSetObject (lman,VDM_DATAFUN,datafun);
   vdm_LManLoadModel (lman,model);
   if(vdm_LManError(lman)) {
      fprintf(stderr,"Error: Unable to load model information\n");
      exit(1);
   }
                   /* traverse Model object */ 
                   /* get Connect object and print nodes and elements */ 
   vis_ModelGetObject (model,VIS_CONNECT,(Vobject**)&connect);
   if(connect != NULL) {
      printNodes (connect);
      printElements (connect);
   }
                   /* delete objects registered in Model */
   vis_ModelDelete (model);
                   /* destroy Model object itself */
   vis_ModelEnd (model);
                   /* close library device and delete interface */
   vdm_DataFunClose (datafun);
   vdm_DataFunEnd (datafun);
   if(filetype == VDM_NASTRAN_BULKDATA) {
      vdm_NASFilEnd (nasfil);
   } else if(filetype == VDM_NASTRAN_OUTPUT2) {
      vdm_NASLibEnd (naslib);
   } else if(filetype == VDM_ABAQUS_INPUT) {
      vdm_ABAFilEnd (abafil);
   } else if(filetype == VDM_ABAQUS_FIL) {
      vdm_ABALibEnd (abalib);
   } else if(filetype == VDM_ANSYS_INPUT) {
      vdm_ANSFilEnd (ansfil);
   } else if(filetype == VDM_ANSYS_RESULT) {
      vdm_ANSLibEnd (anslib);
   } else if(filetype == VDM_SDRC_UNIVERSAL) {
      vdm_SDRCLibEnd (sdrclib);
   } else if(filetype == VDM_FLUENT_MESH) {
      vdm_FLUENTLibEnd (fluentlib);
   }
   vdm_LManEnd (lman);
   return 0;
}

/*----------------------------------------------------------------------
                      print nodes
----------------------------------------------------------------------*/
static void
printNodes(vis_Connect *connect)
{
   Vint i;
   Vint numnp;
   Vint nid, cid;
   Vint featype;
   Vdouble x[3];

   vis_ConnectNumber (connect,SYS_NODE,&numnp);
   printf("Number of nodes=    %d\n",numnp);
                   /* nodes: coordinates, user id and
                      displacement coordinate system id */
   printf("\nNodes\n");
   for(i = 1; i <= numnp; i++) {
      vis_ConnectCoordsdv (connect,1,&i,(Vdouble(*)[3])x);
      vis_ConnectNodeAssoc (connect,VIS_USERID,1,&i,&nid);
      vis_ConnectNodeAssoc (connect,VIS_CSYSID,1,&i,&cid);
      printf("id= %d, cid= %d, x= %e %e %e\n",nid,cid,x[0],x[1],x[2]);
                   /* check for scalar node */ 
      vis_ConnectNodeAssoc (connect,VIS_FEATYPE,1,&i,&featype);
      if(featype == SYS_NODE_SCALAR) {
         printf("featype= Scalar node\n");
      }
   }
}

/*----------------------------------------------------------------------
                      print elements
----------------------------------------------------------------------*/
static void
printElements(vis_Connect *connect)
{
   Vint i, j;
   Vint numel;
   Vint cid;
   Vint eid, pid, mid, partid;
   Vint featype;
   Vint maxelemnode;
   Vint nix, *ix, *ux;
   Vint shape, maxi, maxj, maxk;

   vis_ConnectNumber (connect,SYS_ELEM,&numel);
   printf("Number of elements= %d\n",numel);
                   /* elements: connectivity, user id, material and 
                      property id, etc. */
   printf("\nElements\n");
   vis_ConnectMaxElemNode (connect,&maxelemnode);
                   /* allocate vectors for internal node ids and user ids */
   ix = (Vint*)malloc(maxelemnode*sizeof(Vint));
   ux = (Vint*)malloc(maxelemnode*sizeof(Vint));
   for(i = 1; i <= numel; i++) {
      vis_ConnectTopology (connect,i,&shape,&maxi,&maxj,&maxk);
      vis_ConnectElemNode (connect,i,&nix,ix);
      vis_ConnectElemAssoc (connect,VIS_USERID,1,&i,&eid);
      vis_ConnectElemAssoc (connect,VIS_PARTID,1,&i,&partid);
      vis_ConnectElemAssoc (connect,VIS_PROPID,1,&i,&pid);
      vis_ConnectElemAssoc (connect,VIS_MATLID,1,&i,&mid);
      vis_ConnectElemAssoc (connect,VIS_CSYSID,1,&i,&cid);
      vis_ConnectElemAssoc (connect,VIS_FEATYPE,1,&i,&featype);
      printf("id= %d, partid= %d, pid= %d, mid= %d, cid= %d, nodes= %d\n",
              eid,partid,pid,mid,cid,nix);
                   /* interpret shape */ 
      if(shape == SYS_SHAPEPOINT) {
         printf(" shape= Point(s):");
      } else if(shape == SYS_SHAPELINE) {
         printf(" shape= Line:");
      } else if(shape == SYS_SHAPETRI) {
         printf(" shape= Triangle:");
      } else if(shape == SYS_SHAPEQUAD) {
         printf(" shape= Quadrilateral:");
      } else if(shape == SYS_SHAPETET) {
         printf(" shape= Tetrahedron:");
      } else if(shape == SYS_SHAPEPYR) {
         printf(" shape= Pyramid:");
      } else if(shape == SYS_SHAPEWED) {
         printf(" shape= Pentahedron:");
      } else if(shape == SYS_SHAPEHEX) {
         printf(" shape= Hexahedron:");
      } else if(shape == SYS_SHAPEPOLYGON) {
         printf(" shape= Polygon:");
      } else if(shape == SYS_SHAPEPOLYHED) {
         printf(" shape= Polyhedron:");
      }
      printf("  maxi= %d, maxj= %d, maxk= %d\n",maxi,maxj,maxk);
                   /* convert internal index to user id */ 
      vis_ConnectNodeAssoc (connect,VIS_USERID,nix,ix,ux);
                   /* print element connectivity */ 
      printf(" connectivity=");
      for(j = 0; j < nix; j++) {
         printf(" %d",ux[j]);
      }
      printf("\n");
   }
                   /* free vectors */ 
   free(ix);
   free(ux);
}

7.3. Example 3, Read and Print Results State Data

This example is an extension of Example 3a and illustrates using VisTools global modules to store the model and results data read from a library device. The basic finite element model information is read into a VisTools Model object with the help of the LMan module function, vdm_LManLoadModel(). The Model object consists of single instances as well as lists and hashtables of other VisTools global modules which store information describing the finite element model. The Connect object, which stores the basic finite element connectivity and node coordinates values is retrieved from the Model object using vis_ModelGetObject(). The user defined node and element identifiers are queried from the Connect object and loaded into separate IdTran objects.

Results datasets are accessed in two basic ways. The first is illustrated by looking specifically for node displacement and element stress results. The second is illustrated by examining all datasets and attempting to identify and process any dataset which contains a result quantity of any kind. Results are read into State objects using vdm_LManLoadState(). The result property object, RProp is used in this case to pass the dataset name to vdm_LManLoadState(). The vdm_LManLoadState() function will populate the RProp and State objects with result properties such as title, subtitle, contents, numeric identifiers, etc. Any State object which is configured to hold element node data or is involved in a coordinate system transformation must have knowledge of the element connectivity and node coordinates. This is done by instancing a GridFun object, loading it with function pointers as an abstract interface to the Connect object and setting it as an attribute object into the State object using vis_StateSetObject().

The function vdm_LManLoadState() loads results data into State objects in the local coordinate system in which they appear on the library device. The vis_StateTransform() function may be used to transform the results to the global coordinate system. In order to perform this transformation, the State object must have the appropriate model information extracted from the Model object. This consists of the entity coordinate system identifiers stored in an IdTran object, the HashTable of CoordSys objects, and in the case of element results, the HashTable of ElemDat objects which is required to provide element property information.

Note the use of the Dataset module functions vdm_DatasetResult(), vdm_DatasetInq(), vdm_DatasetDecode(), vdm_DatasetDataType() and vdm_DatasetContents() to help in the result identification process.

#include <stdlib.h>
#include "base/base.h"
#include "vis/visdata.h"
#include "vdm/vdm.h"
#include "datafile.h"

static void
print_displacement(vdm_LMan *lman, vdm_Library *library, vis_Model *model);

static void
print_temp_gradient(vdm_LMan *lman, vdm_Library *library, vis_Model *model);
static void
print_stress(vdm_LMan *lman, vdm_Library *library, vis_Model *model);
static void
print_result(vdm_LMan *lman, vdm_Library *library, vis_Model *model);
static void
print_section(Vint lpos, Vint isec);
static void
print_attributes(vdm_Dataset *dataset);

/*----------------------------------------------------------------------
                     Read and Print Results State Data
----------------------------------------------------------------------*/
int
main(int argc, char **argv)
{
   Vint i;
   char inputfile[256];
   vdm_DataFun   *datafun;
   vdm_Library   *library;
   vdm_LMan      *lman;
   Vint filetype, filetype1;
   Vint numnp, numel;
   vis_Model *model;
   vis_Connect *connect;
   Vint ierr;

                   /* check input arguments */ 
   if(argc < 2) {
      fprintf(stderr,"Usage: %s inputfile [appendfile]\n",argv[0]);
      fprintf(stderr," inputfile is blank, 'cantilever.unv' is assumed\n");
      strcpy(inputfile,"cantilever.unv");
   } else {
      strcpy(inputfile,argv[1]);
   }
                   /* create data function object */
   datafun = vdm_DataFunBegin ();

   datafiletype(inputfile,&filetype);
   if(filetype == 0) {
      fprintf(stderr,"Error: Bad input file %s\n",inputfile);
      exit(1);
   }
   datafileinit(filetype,datafun);
                   /* set convention to support sparse datasets */
   vdm_DataFunSetConvention (datafun,VDM_CONVENTION_SPARSE);
                   /* open library device */
   vdm_DataFunOpen (datafun,0,inputfile,filetype);
                   /* check for error */
   ierr = vdm_DataFunError(datafun);
   if(ierr) {
      fprintf(stderr,"Error: opening file %s\n",inputfile);
      vdm_DataFunClose (datafun);
      datafileterm(filetype,datafun);
      vdm_DataFunEnd (datafun);
      exit(0);
   }
                   /* look for appended file */ 
   for(i = 2; i < argc; i++) {
      if(strstr(argv[i],".op2") != NULL) {
         filetype1 = VDM_NASTRAN_OUTPUT2;
      } else if(strstr(argv[i],".unv") != NULL  ||
                strstr(argv[i],".bun") != NULL) {
         filetype1 = VDM_SDRC_UNIVERSAL;
      } else if(strstr(argv[i],".vdm") != NULL) {
         filetype1 = VDM_NATIVE;
      } else if(strstr(argv[i],".dis") != NULL) {
         filetype1 = VDM_PATRAN_RESULT;
      } else if(strstr(argv[i],".q") != NULL) {
         filetype1 = VDM_PLOT3D_SOLUTION;
      } else if(strstr(argv[i],".dat") != NULL) {
         filetype1 = VDM_FLUENT_MESH;
      } else if(strstr(argv[i],".cgns") != NULL) {
         filetype1 = VDM_CGNS;
      } else {
         fprintf(stderr,"Error: Bad appended file %s\n",argv[i]);
         exit(0);
      }
      vdm_DataFunAppend (datafun,argv[i],filetype1);
                   /* check for error */
      ierr = vdm_DataFunError(datafun);
      if(ierr) {
         fprintf(stderr,"Error: appending file %s to file %s\n",
                 argv[i],argv[1]);
         exit(0);
      }
   }
                   /* instance Model object for finite element model */ 
   model = vis_ModelBegin();

                   /* use Library Manager object to load model */ 
   lman = vdm_LManBegin ();
   vdm_LManSetObject (lman,VDM_DATAFUN,datafun);
   vdm_LManLoadModel (lman,model);

                   /* get Connect object created in Model */ 
   vis_ModelGetObject (model,VIS_CONNECT,(Vobject**)&connect);
   vis_ConnectNumber (connect,SYS_NODE,&numnp);
   vis_ConnectNumber (connect,SYS_ELEM,&numel);
   printf("number of nodes= %d\n",numnp);
   printf("number of elems= %d\n",numel);

                   /* get library object */ 
   vdm_DataFunGetLibrary (datafun,&library);

                   /* access and print displacments */ 
   print_displacement (lman,library,model);
                   /* access and print temperature gradients */ 
   print_temp_gradient (lman,library,model);

                   /* access and print stresses */ 
   print_stress (lman,library,model);
                   /* access and print all results */ 
   print_result (lman,library,model);

                   /* close library device */ 
   vdm_DataFunClose (datafun);

                   /* delete objects in Model created by LManLoadModel */ 
   vis_ModelDelete (model);

   datafileterm(filetype,datafun);
                   /* free objects */ 
   vdm_DataFunEnd (datafun);

   vdm_LManEnd (lman);
   vis_ModelEnd (model);
   return 0;
}

/*----------------------------------------------------------------------
                      print displacments
----------------------------------------------------------------------*/
static void
print_displacement(vdm_LMan *lman, vdm_Library *library, vis_Model *model)
{
   vdm_Dataset *dataset;
   Vchar dsname[DATASET_MAXNAME];
   Vlong lrec;
   Vint nrow, ncol, ntyp;
   Vint numdatasets;
   Vint ndst_d;
   Vint *idst_d;
   Vint numids, ids[3];
   Vint numnp, nodenumber;
   Vint cid;
   Vint i, n;
   vis_Connect *connect;
   vsy_HashTable *hashcsys;
   vis_IdTran *idtrannsys;
   vis_GridFun *gridfun;
   vis_State *state;
   vis_RProp *rprop;
   Vfloat dvec[6], dmag, rmag;
   Vint nument, enttype, subtype, datatype;
   Vint system;
   Vint thermalflag;

                   /* determine maximum number of datasets */ 
   vdm_LibraryGetNumDatasets (library,&numdatasets);

                   /* allocate array for dataset indices */ 
   idst_d = (Vint*)malloc(numdatasets*sizeof(Vint));

                   /* search for displacement results datasets */
   thermalflag = 0;
   vdm_LibrarySearchDataset (library,"D.*N:*",numdatasets,idst_d,&ndst_d);
                   /* if no displacement, search for temperature */
   if(ndst_d == 0) {
      thermalflag = 1;
      vdm_LibrarySearchDataset(library,"TEMP.*N:*",numdatasets,idst_d,&ndst_d);
   }

   if(ndst_d == 0) {
      free(idst_d);
      return;
   }
                   /* get Connect object created in Model */ 
   vis_ModelGetObject (model,VIS_CONNECT,(Vobject**)&connect);
   vis_ConnectNumber (connect,SYS_NODE,&numnp);

                   /* create a grid function object */
   gridfun = vis_GridFunBegin ();
   vis_ConnectGridFun (connect,gridfun);

                   /* get HashTable of CoordSys objects */
   vis_ModelGetHashTable (model,VIS_COORDSYS,&hashcsys);

                   /* install coordinate system ids into IdTran object */
   idtrannsys = vis_IdTranBegin ();
   vis_IdTranDef (idtrannsys,numnp);
   for(i = 1; i <= numnp; i++) {
      vis_ConnectNodeAssoc (connect,VIS_CSYSID,1,&i,&cid);
      vis_IdTranSetId (idtrannsys,i,cid);
   }
                   /* create state */ 
   state = vis_StateBegin ();

                   /* initialize result property object */ 
   rprop = vis_RPropBegin ();
   vis_RPropDef (rprop,SYS_NODE,SYS_NONE);

                   /* print first, middle and last node */
   numids = 3;
   ids[0] = 1;  ids[1] = numnp/2;  ids[2] = numnp;

                   /* loop over displacement datasets */
   for(i = 0; i < ndst_d; i++) {
      vdm_LibraryGetDataset (library,idst_d[i],&dataset);
      vdm_DatasetInq (dataset,dsname,&lrec,&nrow,&ncol,&ntyp);

                   /* print header */
      printf("\n\nDataset: %s\n",dsname);
      if(thermalflag == 0) {
         printf("\nDisplacements\n");
      } else {
         printf("\nTemperatures\n");
      }

                   /* load state */ 
      vis_RPropSetDatasetIndex (rprop,idst_d[i]);
      vdm_LManLoadState (lman,state,rprop);
      vis_StateInq (state,&nument,&enttype,&subtype,&datatype);

                   /* loop over requested nodes */
      for(n = 0; n < numids; n++) {
         if(ids[n] == 0)  continue;
         vis_ConnectNodeAssoc (connect,VIS_USERID,1,&ids[n],&nodenumber);
         printf("%8d",nodenumber);
         vis_StateSetDerive (state,datatype);

         if(datatype == VIS_SCALAR) {
            vis_StateData (state,1,&ids[n],dvec);
            printf("%14e\n",dvec[0]);
                   /* vector type */ 
         } else if(datatype == VIS_VECTOR) {
                   /* print components */ 
            vis_StateData (state,1,&ids[n],dvec);
            printf("%14e %14e %14e",dvec[0],dvec[1],dvec[2]);
                   /* print magnitude */ 
            vis_StateSetDerive (state,VIS_VECTOR_MAG);
            vis_StateData (state,1,&ids[n],&dmag);
            printf("  magnitude= %14e\n",dmag);
                   /* six dof vector type */ 
         } else if(datatype == VIS_SIXDOF) {
                   /* print components */ 
            vis_StateData (state,1,&ids[n],dvec);
            printf("%14e %14e %14e  %14e %14e %14e",
                    dvec[0],dvec[1],dvec[2],dvec[3],dvec[4],dvec[5]);
                   /* print magnitudes */ 
            vis_StateSetDerive (state,VIS_SIXDOF_TMAG);
            vis_StateData (state,1,&ids[n],&dmag);
            vis_StateSetDerive (state,VIS_SIXDOF_RMAG);
            vis_StateData (state,1,&ids[n],&rmag);
            printf("  magnitudes= %14e %14e\n",dmag,rmag);
         }
      }
      printf("\n");

                   /* print global components if originally local components */ 

                   /* the system is set in State by LManLoadState */ 
      vis_StateGetSystem (state,&system);
      if(system == STATE_LOCAL) {
         vis_StateSetObject (state,VIS_GRIDFUN,gridfun);
         vis_StateSetHashTable (state,VIS_COORDSYS,hashcsys);
         vis_StateSetObject (state,VIS_IDTRAN,idtrannsys);
         vis_StateTransform (state,STATE_GLOBAL,NULL);
                   /* loop over requested nodes */
         vis_StateSetDerive (state,datatype);
         printf("global system\n");
         for(n = 0; n < numids; n++) {
            if(ids[n] == 0)  continue;
            vis_ConnectNodeAssoc (connect,VIS_USERID,1,&ids[n],&nodenumber);
            printf("%8d",nodenumber);
                   /* vector type */ 
            if(datatype == VIS_VECTOR) {
               vis_StateData (state,1,&ids[n],dvec);
               printf("%14e %14e %14e\n",dvec[0],dvec[1],dvec[2]);
                   /* six dof vector type */ 
            } else if(datatype == VIS_SIXDOF) {
               vis_StateData (state,1,&ids[n],dvec);
               printf("%14e %14e %14e  %14e %14e %14e\n",
                       dvec[0],dvec[1],dvec[2],dvec[3],dvec[4],dvec[5]);
            }
         }
         printf("\n");
      }
                   /* print attributes */
      print_attributes (dataset);
   }

                   /* free memory */ 
   vis_GridFunEnd (gridfun);
   vis_IdTranEnd (idtrannsys);
   vis_StateEnd (state);
   vis_RPropEnd (rprop);
   free(idst_d);
}

/*----------------------------------------------------------------------
                      load element coordinate system indices
----------------------------------------------------------------------*/
static void
load_idtrancid(vdm_LMan *lman, vdm_Library *library, vis_RProp *rprop,
               vis_IdTran *idtrancid)
{
   Vint m;
   Vchar cidname[DATASET_MAXNAME];
   Vint ids, nds;
   vdm_Dataset *dataset;
   vdm_DataFun *datafun;
   Vint ncol;
   Vint *pcid;
                   /* get name of coordinate system id dataset */
   vis_RPropValueString (rprop,RPROP_LINK_CID,cidname);
                   /* find dataset */
   vdm_LibrarySearchDataset (library,cidname,1,&ids,&nds);
   vdm_LibraryGetDataset (library,ids,&dataset);
   vdm_DatasetGetNCol (dataset,&ncol);
   vdm_LManGetObject (lman,VDM_DATAFUN,(Vobject**)&datafun);
   pcid = (Vint*)malloc(ncol*sizeof(Vint));
   vdm_DataFunReadDataset (datafun,ids,pcid);
   for(m = 1; m <= ncol; m++) {
      vis_IdTranSetId (idtrancid,m,pcid[m-1]);
   }
   free(pcid);
}

/*----------------------------------------------------------------------
                      load rotation angle vector
----------------------------------------------------------------------*/
static void
load_staterotang(vdm_LMan *lman, vdm_Library *library, vis_RProp *rprop,
                 vis_State *staterotang)
{
   Vchar raname[DATASET_MAXNAME];
   Vint ids, nds;
   vdm_Dataset *dataset;
   vis_RProp *rproprotang;
   Vint enttype, subtype;
                   /* get name of rotation angle dataset */
   vis_RPropValueString (rprop,RPROP_LINK_ROTANG,raname);
                   /* find dataset */
   vdm_LibrarySearchDataset (library,raname,1,&ids,&nds);
   vdm_LibraryGetDataset (library,ids,&dataset);
   vdm_DatasetEntType (dataset,&enttype,&subtype);
                   /* read rotation angles */
   rproprotang = vis_RPropBegin ();
   vis_RPropDef (rproprotang,enttype,subtype);
   vis_RPropSetDatasetIndex (rproprotang,ids);
   vdm_LManLoadState (lman,staterotang,rproprotang);
   vis_RPropEnd (rproprotang);
}

/*----------------------------------------------------------------------
                      print temperature gradients
----------------------------------------------------------------------*/
static void
print_temp_gradient(vdm_LMan *lman, vdm_Library *library, vis_Model *model)
{
   vdm_Dataset *dataset;
   Vchar dsname[DATASET_MAXNAME];
   Vlong lrec;
   Vint nrow, ncol, ntyp;
   Vint numdatasets;
   Vint ndst_d;
   Vint *idst_d;
   Vint numids, ids[3];
   Vint numel, elemnumber;
   Vint i, n;
   vis_Connect *connect;
   vsy_HashTable *hashcsys, *hasheldt;
   vis_IdTran *idtranesys;
   vis_GridFun *gridfun;
   vis_State *state;
   vis_RProp *rprop;
   Vfloat dvec[3], dmag;
   Vint system;

                   /* determine maximum number of datasets */ 
   vdm_LibraryGetNumDatasets (library,&numdatasets);

                   /* allocate array for dataset indices */ 
   idst_d = (Vint*)malloc(numdatasets*sizeof(Vint));

                   /* search for temp gradient results datasets */
   vdm_LibrarySearchDataset (library,"TEMP_GRAD.*E:*",numdatasets,
                             idst_d,&ndst_d);

   if(ndst_d == 0) {
      free(idst_d);
      return;
   }
                   /* get Connect object created in Model */ 
   vis_ModelGetObject (model,VIS_CONNECT,(Vobject**)&connect);
   vis_ConnectNumber (connect,SYS_ELEM,&numel);

                   /* create a grid function object */
   gridfun = vis_GridFunBegin ();
   vis_ConnectGridFun (connect,gridfun);

                   /* get HashTable of CoordSys objects */
   vis_ModelGetHashTable (model,VIS_COORDSYS,&hashcsys);
                   /* get HashTable of ElemDat objects */
   vis_ModelGetHashTable (model,VIS_ELEMDAT,&hasheldt);

                   /* coordinate system ids */
   idtranesys = vis_IdTranBegin ();
   vis_IdTranDef (idtranesys,numel);

                   /* create state */ 
   state = vis_StateBegin ();

                   /* initialize result property object */ 
   rprop = vis_RPropBegin ();
   vis_RPropDef (rprop,SYS_ELEM,SYS_NONE);

                   /* print first, middle and last element */
   numids = 3;
   ids[0] = 1;  ids[1] = numel/2;  ids[2] = numel;

                   /* loop over datasets */
   for(i = 0; i < ndst_d; i++) {
      vdm_LibraryGetDataset (library,idst_d[i],&dataset);
      vdm_DatasetInq (dataset,dsname,&lrec,&nrow,&ncol,&ntyp);

                   /* print header */
      printf("\n\nDataset: %s\n",dsname);
      printf("\nTemperature Gradients\n");

                   /* load state */ 
      vis_RPropSetDatasetIndex (rprop,idst_d[i]);
      vdm_LManLoadState (lman,state,rprop);

                   /* loop over requested elements */
      for(n = 0; n < numids; n++) {
         if(ids[n] == 0)  continue;
         vis_ConnectElemAssoc (connect,VIS_USERID,1,&ids[n],&elemnumber);
         printf("%8d %8d",ids[n],elemnumber);
         vis_StateSetDerive (state,VIS_VECTOR);
                   /* print components */ 
         vis_StateData (state,1,&ids[n],dvec);
         printf("%14e %14e %14e",dvec[0],dvec[1],dvec[2]);
                   /* print magnitude */ 
         vis_StateSetDerive (state,VIS_VECTOR_MAG);
         vis_StateData (state,1,&ids[n],&dmag);
         printf("  magnitude= %14e\n",dmag);
      }
      printf("\n");

                   /* print global components if originally local components */ 

                   /* the system is set in State by LManLoadState */ 
      vis_StateGetSystem (state,&system);
      if(system == STATE_LOCAL) {
         vis_StateSetObject (state,VIS_GRIDFUN,gridfun);
         vis_StateSetHashTable (state,VIS_COORDSYS,hashcsys);
         vis_StateSetHashTable (state,VIS_ELEMDAT,hasheldt);
         load_idtrancid (lman,library,rprop,idtranesys);
         vis_StateSetObject (state,VIS_IDTRAN,idtranesys);
         vis_StateTransform (state,STATE_GLOBAL,NULL);
                   /* loop over requested elements */
         vis_StateSetDerive (state,VIS_VECTOR);
         printf("global system\n");
         for(n = 0; n < numids; n++) {
            if(ids[n] == 0)  continue;
            vis_ConnectElemAssoc (connect,VIS_USERID,1,&ids[n],&elemnumber);
            printf("%8d %8d",ids[n],elemnumber);
            vis_StateData (state,1,&ids[n],dvec);
            printf("%14e %14e %14e\n",dvec[0],dvec[1],dvec[2]);
         }
         printf("\n");
      }
                   /* print attributes */
      print_attributes (dataset);
   }

                   /* free memory */ 
   vis_GridFunEnd (gridfun);
   vis_IdTranEnd (idtranesys);
   vis_StateEnd (state);
   vis_RPropEnd (rprop);
   free(idst_d);
}

/*----------------------------------------------------------------------
                      print stresses
----------------------------------------------------------------------*/
static void
print_stress(vdm_LMan *lman, vdm_Library *library, vis_Model *model)
{
   vdm_Dataset *dataset;
   Vchar dsname[DATASET_MAXNAME];
   Vlong lrec;
   Vint nrow, ncol, ntyp;
   Vint numdatasets;
   Vint nds, ndst_s;
   Vint *idst_s;
   Vint numids, ids[3];
   Vint nix;
   Vint numel, maxelno, elemnumber, complexmode;
   Vint i, j, n;
   vis_Connect *connect;
   vsy_HashTable *hashcsys, *hasheldt, *hasheprop;
   vis_IdTran *idtranesys;
   vis_GridFun *gridfun;
   vis_State *state;
   vis_State *staterotang;
   vis_RProp *rprop;
   Vfloat (*sten)[6], *smean, (*cten)[12];
   Vint system;
   Vint enttype, subtype;

                   /* determine maximum number of datasets */
   vdm_LibraryGetNumDatasets (library,&numdatasets);

                   /* allocate array for dataset indices */
   idst_s = (Vint*)malloc(numdatasets*sizeof(Vint));

                   /* search for stress results datasets */
   vdm_LibrarySearchDataset (library,"S.*EL:*",numdatasets,idst_s,&nds);
   vdm_LibrarySearchDataset (library,"S.*E:*",numdatasets,&idst_s[nds],&ndst_s);
   ndst_s += nds;
   if(ndst_s == 0) {
      free(idst_s);
      return;
   }
                   /* get Connect object created in Model */
   vis_ModelGetObject (model,VIS_CONNECT,(Vobject**)&connect);
   vis_ConnectNumber (connect,SYS_ELEM,&numel);

                   /* find maximum number of element nodes */
   vis_ConnectMaxElemNode (connect,&maxelno);

                   /* allocate arrays to fit maximum element node data */ 
   sten  = (Vfloat(*)[6])malloc(2*maxelno*6*sizeof(Vfloat));
   cten = (Vfloat(*)[12])sten;
   smean = (Vfloat*)malloc(maxelno*sizeof(Vfloat));

                   /* create a grid function object */
   gridfun = vis_GridFunBegin ();
   vis_ConnectGridFun (connect,gridfun);

                   /* get HashTable of CoordSys objects */
   vis_ModelGetHashTable (model,VIS_COORDSYS,&hashcsys);
                   /* get HashTable of ElemDat objects */
   vis_ModelGetHashTable (model,VIS_ELEMDAT,&hasheldt);
                   /* get HashTable of EProp objects */
   vis_ModelGetHashTable (model,VIS_EPROP,&hasheprop);

                   /* element coordinate system ids into IdTran object */
   idtranesys = vis_IdTranBegin ();
   vis_IdTranDef (idtranesys,numel);

                   /* create state and install GridFun object */
   state = vis_StateBegin ();
   vis_StateSetObject (state,VIS_GRIDFUN,gridfun);

                   /* instance result property object */
   rprop = vis_RPropBegin ();

                   /* print first, middle and last element */
   numids = 3;
   ids[0] = 1;  ids[1] = numel/2;  ids[2] = numel;
                   /* loop over stress datasets */
   for(i = 0; i < ndst_s; i++) {
      vdm_LibraryGetDataset (library,idst_s[i],&dataset);
      vdm_DatasetInq (dataset,dsname,&lrec,&nrow,&ncol,&ntyp);
      if(nrow != 6)  continue;
      vdm_DatasetEntType (dataset,&enttype,&subtype);

                   /* print header */
      printf("\n\nDataset: %s\n",dsname);
      printf("\nStresses\n");

                   /* set entity type and dataset index */ 
      vis_RPropDef (rprop,enttype,subtype);
      vis_RPropSetDatasetIndex (rprop,idst_s[i]);
                   /* load state */
      vdm_LManLoadState (lman,state,rprop);
      vis_StateGetComplexMode (state,&complexmode);

                   /* print stress components first */ 
      vis_StateSetDerive (state,VIS_TENSOR);

                   /* loop over requested elements */
      for(n = 0; n < numids; n++) {
         if(ids[n] == 0)  continue;
         vis_ConnectElemAssoc (connect,VIS_USERID,1,&ids[n],&elemnumber);
         printf("%8d, component stresses\n",elemnumber);

         nix = 1;
                   /* if element node get number of nodes */
         if(subtype == SYS_NODE) {
            vis_ConnectElemNum (connect,SYS_NODE,ids[n],&nix);
         }
         vis_StateData (state,1,&ids[n],(Vfloat*)sten);

                   /* loop over nodes in element */ 
         for(j = 0; j < nix; j++) {
            if(complexmode == SYS_COMPLEX_REAL) {
               printf(" %12.5e %12.5e %12.5e %12.5e %12.5e %12.5e\n",
                       sten[j][0],sten[j][1],sten[j][2],
                       sten[j][3],sten[j][4],sten[j][5]);
            } else {
               printf(" %12.5e %12.5e(i) %12.5e %12.5e(i) %12.5e %12.5e(i)\n",
                       cten[j][0],cten[j][1],cten[j][2],
                       cten[j][3],cten[j][4],cten[j][5]);
               printf(" %12.5e %12.5e(i) %12.5e %12.5e(i) %12.5e %12.5e(i)\n",
                       cten[j][6],cten[j][7],cten[j][8],
                       cten[j][9],cten[j][10],cten[j][11]);
            }
         }
      }
                   /* skip derived quantities if complex data */ 
      if(complexmode != SYS_COMPLEX_REAL)  continue;
                   /* print mean stress second */
      vis_StateSetDerive (state,VIS_TENSOR_MEAN);

                   /* loop over requested elements */
      for(n = 0; n < numids; n++) {
         if(ids[n] == 0)  continue;
         vis_ConnectElemAssoc (connect,VIS_USERID,1,&ids[n],&elemnumber);
         printf("%8d, mean stress\n",elemnumber);

         nix = 1;
                   /* if element node get number of nodes */
         if(subtype == SYS_NODE) {
            vis_ConnectElemNum (connect,SYS_NODE,ids[n],&nix);
         }
         vis_StateData (state,1,&ids[n],smean);

                   /* loop over nodes in element */
         for(j = 0; j < nix; j++) {
            printf(" %12.5e\n",smean[j]);
         }
      }
      printf("\n");
      vis_StateSetDerive (state,VIS_TENSOR);

                   /* print stress in global if originally in local */ 
                   /* the system is set in State by LManLoadState */ 
      vis_StateGetSystem (state,&system);
      if(system == STATE_LOCAL || system == STATE_ROTANG) {
         vis_StateSetObject (state,VIS_GRIDFUN,gridfun);
         if(system == STATE_LOCAL) {
            vis_StateSetHashTable (state,VIS_COORDSYS,hashcsys);
            vis_StateSetHashTable (state,VIS_ELEMDAT,hasheldt);
            load_idtrancid (lman,library,rprop,idtranesys);
            vis_StateSetObject (state,VIS_IDTRAN,idtranesys);
         } else if(system == STATE_ROTANG) {
            staterotang = vis_StateBegin();
            vis_StateSetObject (staterotang,VIS_GRIDFUN,gridfun);
            load_staterotang (lman,library,rprop,staterotang);
            vis_StateSetObject (state,VIS_STATE_ROTANG,staterotang);
         }
         vis_StateTransform (state,STATE_GLOBAL,NULL);
         printf("global system\n");

                   /* loop over requested elements */
         for(n = 0; n < numids; n++) {
            if(ids[n] == 0)  continue;
            vis_ConnectElemAssoc (connect,VIS_USERID,1,&ids[n],&elemnumber);
            printf("%8d, component stresses\n",elemnumber);

            nix = 1;
                   /* if element node get number of nodes */
            if(subtype == SYS_NODE) {
               vis_ConnectElemNum (connect,SYS_NODE,ids[n],&nix);
            }
            vis_StateData (state,1,&ids[n],(Vfloat*)sten);

                   /* loop over nodes in element */
            for(j = 0; j < nix; j++) {
               printf(" %12.5e %12.5e %12.5e %12.5e %12.5e %12.5e\n",
                       sten[j][0],sten[j][1],sten[j][2],
                       sten[j][3],sten[j][4],sten[j][5]);
            }
         }
      }
      printf("\n");
      if(system == STATE_ROTANG) {
         vis_StateEnd (staterotang);
      }
                   /* print in material system */ 
      vis_StateSetHashTable (state,VIS_COORDSYS,hashcsys);
      vis_StateSetHashTable (state,VIS_ELEMDAT,hasheldt);
      vis_StateSetObject (state,VIS_IDTRAN,NULL);
      vis_StateTransform (state,STATE_MATERIAL,NULL);
      if(vis_StateError (state))  continue;
                   /* loop over requested elements */
      printf("material system\n");
      for(n = 0; n < numids; n++) {
         if(ids[n] == 0)  continue;
         vis_ConnectElemAssoc (connect,VIS_USERID,1,&ids[n],&elemnumber);
         printf("%8d, component stresses\n",elemnumber);

         nix = 1;
                   /* if element node get number of nodes */
         if(subtype == SYS_NODE) {
            vis_ConnectElemNum (connect,SYS_NODE,ids[n],&nix);
         }
         vis_StateData (state,1,&ids[n],(Vfloat*)sten);

                   /* loop over nodes in element */
         for(j = 0; j < nix; j++) {
            printf(" %12.5e %12.5e %12.5e %12.5e %12.5e %12.5e\n",
                    sten[j][0],sten[j][1],sten[j][2],
                    sten[j][3],sten[j][4],sten[j][5]);
         }
      }
                   /* print attributes */
      print_attributes (dataset);
   }
                   /* free memory */
   vis_GridFunEnd (gridfun);
   vis_IdTranEnd (idtranesys);
   vis_StateEnd (state);
   vis_RPropEnd (rprop);
   free(idst_s);
   free(sten);
   free(smean);
}

/*----------------------------------------------------------------------
                      print link to section, layers
----------------------------------------------------------------------*/
static void
print_linksection(vdm_LMan *lman, vdm_Library *library, vdm_Dataset *dataset)
{
   Vint i, m;
   Vint iat, nat, iatl, natl;
   vdm_Attribute *attribute;
   vdm_Dataset *datasetsect, *datasetlays;
   Vint idssect, ndssect;
   Vint idslays, ndslays, ind;
   Vint ipos, ilay;
   Vint *psec, *play;
   Vchar dsname[DATASET_MAXNAME];
   Vchar cvalue[ATTRIBUTE_MAXVALUE];
   Vlong lrec, lreclays;
   Vint nrow, ncol, ntyp;
   vdm_DataFun *datafun;
   Vint lpos, nsec;
   static Vchar *lposnames[12] = {
     "Sec",
     "Mid",
     "BT ",
     "BMT",
     "Ipt",
     "BM ",
     "MT ",
     "Bot",
     "Top",
     "B1M",
     "M1T",
     "B5T" };
                   /* look for Link to Section */ 
   vdm_DatasetSearchAttribute (dataset,"Link.Section",1,&iat,&nat);
   if(nat == 0)  return;
                   /* look for Link to Layers */ 
   vdm_DatasetSearchAttribute (dataset,"Link.Layers",1,&iatl,&natl);
                   /* read section dataset */ 
   vdm_DatasetGetAttribute (dataset,iat,&attribute);
   vdm_AttributeValueString (attribute,cvalue);
   vdm_LibrarySearchDataset (library,cvalue,1,&idssect,&ndssect);
   vdm_LibraryGetDataset (library,idssect,&datasetsect);
   vdm_DatasetInq (datasetsect,dsname,&lrec,&nrow,&ncol,&ntyp);
   psec = (Vint*)malloc(ncol*sizeof(Vint));
   vdm_LManGetObject (lman,VDM_DATAFUN,(Vobject**)&datafun);
   vdm_DataFunReadDataset (datafun,idssect,psec);
                   /* read layers dataset */ 
   if(natl) {
      vdm_DatasetGetAttribute (dataset,iatl,&attribute);
      vdm_AttributeValueString (attribute,cvalue);
      vdm_LibrarySearchDataset (library,cvalue,1,&idslays,&ndslays);
      vdm_LibraryGetDataset (library,idslays,&datasetlays);
      vdm_DatasetGetLRec (datasetlays,&lreclays);
      play = (Vint*)malloc(lreclays*sizeof(Vint));
      vdm_DataFunReadDataset (datafun,idslays,play);
   }
                   /* print first element with 2 or more sections */ 
                   /* loop over elements */
   ind = 0;
   for(m = 0; m < ncol; m++) {
      lpos = (psec[m] >> 24) & 0xff;
      nsec = psec[m] & 0xffffff;
      if(nsec >= 2) {
         printf("Section information\n");
         printf("elem= %d, nsec= %d\n",m+1,nsec);
         for(i = 0; i < nsec; i++) {
            if(natl == 0) {
               if(lpos == SYS_LAYERPOSITION_BOTTOP) {
                  if(i%2 == 0) {
                     ipos = SYS_LAYERPOSITION_BOT;
                  } else {
                     ipos = SYS_LAYERPOSITION_TOP;
                  }
                  ilay = i/2 + 1;
               } else if(lpos == SYS_LAYERPOSITION_BOTMID) {
                  if(i%2 == 0) {
                     ipos = SYS_LAYERPOSITION_BOT;
                  } else {
                     ipos = SYS_LAYERPOSITION_MID;
                  }
                  ilay = i/2 + 1;
               } else if(lpos == SYS_LAYERPOSITION_MIDTOP) {
                  if(i%2 == 0) {
                     ipos = SYS_LAYERPOSITION_MID;
                  } else {
                     ipos = SYS_LAYERPOSITION_TOP;
                  }
                  ilay = i/2 + 1;
               } else if(lpos == SYS_LAYERPOSITION_BOTMIDTOP) {
                  if(i%3 == 0) {
                     ipos = SYS_LAYERPOSITION_BOT;
                  } else if(i%3 == 1) {
                     ipos = SYS_LAYERPOSITION_MID;
                  } else {
                     ipos = SYS_LAYERPOSITION_TOP;
                  }
                  ilay = i/3 + 1;
               } else if(lpos == SYS_LAYERPOSITION_B5T) {
                  if(i%5 == 0) {
                     ipos = SYS_LAYERPOSITION_BOT;
                  } else if(i%5 == 1) {
                     ipos = SYS_LAYERPOSITION_B1M;
                  } else if(i%5 == 2) {
                     ipos = SYS_LAYERPOSITION_MID;
                  } else if(i%5 == 3) {
                     ipos = SYS_LAYERPOSITION_M1T;
                  } else {
                     ipos = SYS_LAYERPOSITION_TOP;
                  }
                  ilay = i/5 + 1;
               } else {
                  ipos = lpos;
                  ilay = i + 1;
               }
            } else {
               ipos = (play[ind+i] >> 24) & 0xff;
               ilay = play[ind+i] & 0xffffff;
            }
            printf("section= %d, layer= %d, position= %s\n",
                    i+1,ilay,lposnames[ipos]);
         }
         break;
      }
      ind += nsec;
   }
   free(psec);
   if(natl) {
      free(play);
   }
}

/*----------------------------------------------------------------------
                      print result
----------------------------------------------------------------------*/
static void
print_result(vdm_LMan *lman, vdm_Library *library, vis_Model *model)
{
   Vint i, j, k, n;
   vdm_Dataset *dataset;
   Vchar dsname[DATASET_MAXNAME];
   Vchar dsroot[DATASET_MAXNAME];
   Vchar caux[DATASET_MAXNAME];
   Vchar dime[DATASET_MAXNAME];
   Vchar andata[ATTRIBUTE_MAXVALUE];
   Vchar ancont[ATTRIBUTE_MAXVALUE];
   Vlong lrec;
   Vint nrow, ncol, ntyp;
   Vint numdatasets;
   Vint index, id, elnoid;
   Vint maxelno, nix, *ix;
   vis_Connect *connect;
   vis_GridFun *gridfun;
   vis_State *state;
   vis_RProp *rprop;
   Vint type, hist, cplx, sect, nument, enttype, subtype, datatype;
   Vint nqua, iqua[SYS_NQUA_MAX];
   Vchar cqua[DATASET_MAXNAME];
   Vint id1, id2, id3;
   Vint system, flag, stat;
   Vint ncmp, nsec;
   Vfloat *res;
   Vint *pos, *lay;
   Vint mres, msec, maxdat, maxloc, maxsec;
   Vint numno, ne[VIS_MAX_MAXJ];

                   /* determine maximum number of datasets */
   vdm_LibraryGetNumDatasets (library,&numdatasets);

                   /* get Connect object created in Model */
   vis_ModelGetObject (model,VIS_CONNECT,(Vobject**)&connect);

                   /* find maximum number of element nodes */
   vis_ConnectMaxElemNode (connect,&maxelno);

                   /* allocate connectivity array to fit maximum number */
   ix = (Vint*)malloc(maxelno*sizeof(Vint));

                   /* create a grid function object */
   gridfun = vis_GridFunBegin ();
   vis_ConnectGridFun (connect,gridfun);

                   /* create state and install GridFun object */
   state = vis_StateBegin ();
   vis_StateSetObject (state,VIS_GRIDFUN,gridfun);

                   /* create result property object */
   rprop = vis_RPropBegin ();

                   /* pointer for returned results data */ 
   res = NULL;
   pos = NULL;
   lay = NULL;
   mres = 0;
   msec = 0;
                   /* loop over datasets */
   for(i = 0; i < numdatasets; i++) {
      vdm_LibraryGetDataset (library,i,&dataset);

                   /* identify result quantity */ 
      vdm_DatasetResult (dataset,dsroot,&type,&hist,
                         &nqua,iqua,cqua,&cplx,caux,&sect,&enttype,&subtype,
                         &id1,&id2,&id3);
                   /* not a result */ 
      if(type == SYS_RES_NONE) {
         continue;
      }
                   /* get dataset name and parameters */ 
      vdm_DatasetInq (dataset,dsname,&lrec,&nrow,&ncol,&ntyp);

                   /* get DataType attribute */ 
      vdm_DatasetDataType (dataset,andata,&datatype);

                   /* get Contents attribute */ 
      vdm_DatasetContents (dataset,ancont);

                   /* get result physical dimensions */
      vdm_DatasetDimensions (dataset,dime);

                   /* print dataset name */
      printf("\n\nDataset: %s\n",dsname);

                   /* print DataType, Contents and dimensions */ 
      printf("DataType: %s\n",andata);
      printf("Contents: %s\n",ancont);
      printf("Dimensions: %s\n",dime);
                   /* skip history datasets */ 
      if(hist) {
         continue;
      }
                   /* skip non-entity datasets */ 
      if(enttype == 0) {
         print_attributes (dataset);
         continue;
      }
                   /* skip dof parent datasets */ 
      if(enttype == SYS_DOF) {
         print_attributes (dataset);
         continue;
      }
                   /* print section and layer position */ 
                   /* useful for obtaining section information without
                      needing to load the entire State */
      if(sect == SYS_ELEMSEC_ALL) {
         print_linksection (lman,library,dataset);
      }
                   /* load state from dataset */ 
      vis_RPropDef (rprop,enttype,subtype);
      vis_RPropSetDatasetIndex (rprop,i);
      vdm_LManLoadState (lman,state,rprop);

                   /* number of entities, datatype */
      vis_StateInq (state,&nument,&enttype,&subtype,&datatype);

                   /* maximum data size, number of locations and sections */ 
      vis_StateDataMax (state,&maxdat,&maxloc,&maxsec);
      if(maxdat > mres) {
         mres = maxdat;
         res = (Vfloat*)realloc(res,mres*sizeof(Vfloat));
      }
      if(maxsec > msec) {
         msec = maxsec;
         pos = (Vint*)realloc(pos,msec*sizeof(Vint));
         lay = (Vint*)realloc(lay,msec*sizeof(Vint));
      }
                   /* query local or global system */ 
      vis_StateGetSystem (state,&system);
      if(system == STATE_GLOBAL) {
         printf("system= Global\n");
      } else {
         printf("system= Local\n");
      }
                   /* query engineering strain flag */
      vis_StateGetEngineeringStrain (state,&flag);
      if(flag) {
         printf("strain= Engineering\n");
      }
                   /* query number of components */
      vis_StateNumDerive (state,&ncmp);

                   /* return all sections */
      vis_StateSetSection (state,0);

                   /* loop through all entities */
      for(index = 1; index <= nument; index++) {
                   /* select entities to ignore for whatever reason */ 
         if(index != 1)  continue;
                   /* print entity id */ 
         if(enttype == SYS_NODE) {
            vis_ConnectNodeAssoc (connect,VIS_USERID,1,&index,&id);
            printf("node= %d\n",id);
         } else if(enttype == SYS_ELEM  ||
                   enttype == SYS_FACE  ||  enttype == SYS_EDGE) {
            vis_ConnectElemAssoc (connect,VIS_USERID,1,&index,&id);
            printf("elem= %d\n",id);
         } else if(enttype == SYS_MODE) {
            printf("mode= %d\n",id);
         }
                   /* see if data defined */
         vis_StateDataStat (state,1,&index,&stat);
         if(stat == 0) {
            printf(" no data\n");
            continue;
         }
                   /* get results data for entity */ 
         vis_StateData (state,1,&index,res);
                   /* print data */ 
                   /* data at node */
         if(enttype == SYS_NODE) {
            for(j = 0; j < ncmp; j++) {
               printf(" %e",res[j]);
            }
            printf("\n");
                   /* data at element face or edge */
         } else if(enttype == SYS_FACE  ||  enttype == SYS_EDGE) {
            vis_StateDataEnt (state,index,&numno,ne);
                   /* element face or edge */
            if(subtype == SYS_NONE) {
               for(k = 0; k < numno; k++) {
                  printf("%4d",ne[k]);
                  for(j = 0; j < ncmp; j++) {
                     printf(" %e",res[k*ncmp+j]);
                  }
                  printf("\n");
               }
                   /* element face or edge node */
            } else {
               for(k = 0; k < numno; k++) {
                  printf("%4d",ne[k]);
                  vis_ConnectElemCon (connect,enttype,i,ne[k],&nix,ix);
                  for(n = 0; n < nix; n++) {
                     printf("%4d",n+1);
                     for(j = 0; j < ncmp; j++) {
                        printf(" %e",res[k*ncmp*nix+n*ncmp+j]);
                     }
                     printf("\n");
                  }
               }
            }
                   /* data at element */
         } else if(enttype == SYS_ELEM) {
                   /* get number of sections */ 
            vis_StateDataSect (state,1,&index,&nsec);
                   /* get layer position */ 
            vis_StateDataLayers (state,index,pos,lay);
                   /* element */
            if(subtype == SYS_NONE) {
               for(k = 0; k < nsec; k++) {
                  if(nsec > 1) {
                     print_section (pos[k],lay[k]);
                  }
                  for(j = 0; j < ncmp; j++) {
                     printf(" %e",res[k*ncmp+j]);
                  }
                  printf("\n");
               }
                   /* element node */
            } else {
               vis_ConnectElemNode (connect,index,&nix,ix);
               for(k = 0; k < nsec; k++) {
                  if(nsec > 1) {
                     print_section (pos[k],lay[k]);
                  }
                  for(n = 0; n < nix; n++) {
                     vis_ConnectNodeAssoc (connect,VIS_USERID,1,&ix[n],&elnoid);
                     printf("node= %d\n",elnoid);
                     for(j = 0; j < ncmp; j++) {
                        printf(" %e",res[k*ncmp*nix+n*ncmp+j]);
                     }
                     printf("\n");
                  }
               }
            }
                   /* data at mode */
         } else if(enttype == SYS_MODE) {
            for(j = 0; j < ncmp; j++) {
               printf(" %e",res[j]);
            }
            printf("\n");
         }
      }
                   /* print attributes */
      print_attributes (dataset);
   }
                   /* free memory */
   vis_GridFunEnd (gridfun);
   vis_StateEnd (state);
   vis_RPropEnd (rprop);
   if(res) {
      free(res);
   }
   if(pos) {
      free(pos);
      free(lay);
   }
   free(ix);
}

/*----------------------------------------------------------------------
                      print section and type
----------------------------------------------------------------------*/
static void
print_section(Vint lpos, Vint isec)
{
   printf("section= %d",isec);
   if(lpos == SYS_LAYERPOSITION_NONE) {
      printf(" none");
   } else if(lpos == SYS_LAYERPOSITION_MID) {
      printf(" middle");
   } else if(lpos == SYS_LAYERPOSITION_BOT) {
      printf(" bottom");
   } else if(lpos == SYS_LAYERPOSITION_TOP) {
      printf(" top");
   } else if(lpos == SYS_LAYERPOSITION_INTPNT) {
      printf(" eip");
   }
   printf("\n");
}

/*----------------------------------------------------------------------
                      print dataset attributes
----------------------------------------------------------------------*/
static void
print_attributes(vdm_Dataset *dataset)
{
   int j, k;
   vdm_Attribute *attribute;
   Vint numatts;
   Vint atleng, attype;
   Vchar atname[ATTRIBUTE_MAXNAME];
   Vchar  cvalue[ATTRIBUTE_MAXVALUE];
   Vint    *ivalue = (Vint*)cvalue;
   Vfloat  *rvalue = (Vfloat*)cvalue;
   Vdouble *dvalue = (Vdouble*)cvalue;

                   /* loop over attributes */
   vdm_DatasetGetNumAttributes (dataset,&numatts);
   for(j = 0; j < numatts; j++) {
      vdm_DatasetGetAttribute (dataset,j,&attribute);
      vdm_AttributeInq (attribute,atname,&atleng,&attype);
      printf("    Attribute: %s\n               ",atname);
      if(attype == SYS_INTEGER) {
         vdm_AttributeValueInteger (attribute,ivalue);
         for(k = 0; k < atleng; k++)  printf("%i  ",ivalue[k]);
      } else if(attype == SYS_FLOAT) {
         vdm_AttributeValueFloat (attribute,rvalue);
         for(k = 0; k < atleng; k++)  printf("%e  ",rvalue[k]);
      } else if(attype == SYS_CHAR) {
         vdm_AttributeValueString (attribute,cvalue);
         printf("%s  ",cvalue);
      } else if(attype == SYS_DOUBLE) {
         vdm_AttributeValueDouble (attribute,dvalue);
         for(k = 0; k < atleng; k++)  printf("%e  ",dvalue[k]);
      }
      printf("\n");
   }
}

7.4. Example 3a, Read and Print Results History Data

This example illustrates using VisTools global modules to store the model and results history data read from a library device. It is similar to Example 3, except that the History module is used instead of the State module.

History results are read into History objects using vdm_LManLoadHistory(). The result property object, RProp is used in this case to pass the dataset name to vdm_LManLoadHistory(). The vdm_LManLoadHistory() function will populate the RProp and History objects with result properties such as title, subtitle, contents, numeric identifiers, etc. Any History object which is configured to hold element node data must have knowledge of the element connectivity. This is done by instancing a GridFun object, loading it with function pointers as an abstract interface to the Connect object and setting it as an attribute object into the History object using vis_HistorySetObject(). The function vdm_LManLoadHistory() loads results data into History objects in the local coordinate system in which they appear on the library device.

Note the use of the function vis_HistoryDataStat() to query for undefined components of a data type.

#include <stdlib.h>
#include "base/base.h"
#include "vis/visdata.h"
#include "vdm/vdm.h"

static void
print_displacement(vdm_LMan *lman, vdm_Library *library, vis_Model *model);
static void
print_stress(vdm_LMan *lman, vdm_Library *library, vis_Model *model);
static void
print_attributes(vdm_Dataset *dataset);

/*----------------------------------------------------------------------
                     Read and Print Results History Data
----------------------------------------------------------------------*/
int
main(int argc, char **argv)
{
   char inputfile[256];
   Vint filetype;
   vdm_NASLib  *naslib;
   vdm_NatLib  *natlib;
   vdm_SDRCLib *sdrclib;
   vdm_ANSLib  *anslib;
   vdm_ABALib  *abalib;
   vdm_D3DLib  *d3dlib;
   vdm_DataFun *datafun;
   vdm_Library *library;
   vdm_LMan  *lman;
   vis_Model *model;

                   /* check input arguments */ 
   if(argc < 2) {
      fprintf(stderr,"Usage: %s inputfile\n",argv[0]);
      fprintf(stderr," inputfile is blank, 'rod.op2' is assumed\n");
      strcpy(inputfile,"rod.op2");
   } else {
      strcpy(inputfile,argv[1]);
   }
                   /* create data function object */
   datafun = vdm_DataFunBegin ();

                   /* determine file type from file extension */
   if(strstr(inputfile,".unv") != NULL) {
      filetype = VDM_SDRC_UNIVERSAL;
      sdrclib = vdm_SDRCLibBegin ();
      vdm_SDRCLibDataFun (sdrclib,datafun);
   } else if(strstr(inputfile,".op2") != NULL) {
      filetype = VDM_NASTRAN_OUTPUT2;
      naslib = vdm_NASLibBegin ();
      vdm_NASLibDataFun (naslib,datafun);
   } else if(strstr(inputfile,".vdm") != NULL) {
      filetype = VDM_NATIVE;
      natlib = vdm_NatLibBegin ();
      vdm_NatLibDataFun (natlib,datafun);
   } else if(strstr(inputfile,".rst") != NULL) {
      filetype = VDM_ANSYS_RESULT;
      anslib = vdm_ANSLibBegin ();
      vdm_ANSLibDataFun (anslib,datafun);
   } else if(strstr(inputfile,".fil") != NULL) {
      filetype = VDM_ABAQUS_FIL;
      abalib = vdm_ABALibBegin ();
      vdm_ABALibDataFun (abalib,datafun);
   } else if(strstr(inputfile,"d3thdt") != NULL) {
      filetype = VDM_LSTC_HISTORY;
      d3dlib = vdm_D3DLibBegin ();
      vdm_D3DLibDataFun (d3dlib,datafun);
   } else {
      fprintf(stderr,"Error: Bad input file %s\n",inputfile);
      exit(1);
   }
                   /* open library device */
   vdm_DataFunOpen (datafun,0,inputfile,filetype);

                   /* instance Model object for finite element model */ 
   model = vis_ModelBegin();

                   /* use Library Manager object to load model */ 
   lman = vdm_LManBegin ();
   vdm_LManSetObject (lman,VDM_DATAFUN,datafun);
   vdm_LManLoadModel (lman,model);

                   /* get library object */ 
   vdm_DataFunGetLibrary (datafun,&library);

                   /* access and print displacment history */ 
   print_displacement (lman,library,model);

                   /* access and print stress history */ 
   print_stress (lman,library,model);

                   /* close library device */ 
   vdm_DataFunClose (datafun);

                   /* delete objects in Model created by LManLoadModel */ 
   vis_ModelDelete (model);

                   /* free objects */ 
   vdm_DataFunEnd (datafun);
   if(filetype == VDM_SDRC_UNIVERSAL) {
      vdm_SDRCLibEnd (sdrclib);
   } else if(filetype == VDM_NASTRAN_OUTPUT2) {
      vdm_NASLibEnd (naslib);
   } else if(filetype == VDM_NATIVE) {
      vdm_NatLibEnd (natlib);
   } else if(filetype == VDM_ANSYS_RESULT) {
      vdm_ANSLibEnd (anslib);
   } else if(filetype == VDM_ABAQUS_FIL) {
      vdm_ABALibEnd (abalib);
   } else if(filetype == VDM_LSTC_HISTORY) {
      vdm_D3DLibEnd (d3dlib);
   }
   vdm_LManEnd (lman);
   vis_ModelEnd (model);
   return 0;
}

/*----------------------------------------------------------------------
                      print displacment history
----------------------------------------------------------------------*/
static void
print_displacement(vdm_LMan *lman, vdm_Library *library, vis_Model *model)
{
   Vint i, j, k, n;
   vdm_Dataset *dataset;
   Vchar dsname[DATASET_MAXNAME];
   Vlong lrec;
   Vint nrow, ncol, ntyp;
   Vint numdatasets;
   Vint ndst;
   Vint *idst;
   Vint *inds, *stps;
   Vfloat *tstp;
   Vint nodenumber;
   vis_Connect *connect;
   vis_GridFun *gridfun;
   vis_History *history;
   vis_RProp *rprop;
   Vfloat dvec[6], dmag, rmag;
   Vint nstat, stat[6];
   Vint numstp, nument, enttype, subtype, datatype;
   Vchar indepname[81];
   Vint thermalflag;

                   /* query maximum number of datasets */ 
   vdm_LibraryGetNumDatasets (library,&numdatasets);

                   /* allocate array for dataset indices */ 
   idst = (Vint*)malloc(numdatasets*sizeof(Vint));

                   /* search for node history results datasets */
                   /* displacement, velocity, accleration */
   thermalflag = 0;
   vdm_LibrarySearchDataset (library,"HIST.D.*N:*",numdatasets,idst,&ndst);
   if(ndst == 0) {
      vdm_LibrarySearchDataset (library,"HIST.V.*N:*",numdatasets,idst,&ndst);
   }
   if(ndst == 0) {
      vdm_LibrarySearchDataset (library,"HIST.A.*N:*",numdatasets,idst,&ndst);
   }
                   /* if no displacement, search for temperature */ 
   if(ndst == 0) {
      thermalflag = 1;
      vdm_LibrarySearchDataset (library,"HIST.TEMP.*N:*",numdatasets,
                                idst,&ndst);
   }
   if(ndst == 0) {
      free(idst);
      return;
   }
                   /* get Connect object created in Model */ 
   vis_ModelGetObject (model,VIS_CONNECT,(Vobject**)&connect);

                   /* create a grid function object */
   gridfun = vis_GridFunBegin ();
   vis_ConnectGridFun (connect,gridfun);

                   /* create history */ 
   history = vis_HistoryBegin ();
   vis_HistorySetObject (history,VIS_GRIDFUN,gridfun);

                   /* initialize result property object */ 
   rprop = vis_RPropBegin ();
   vis_RPropDef (rprop,SYS_NODE,SYS_NONE);

                   /* loop over displacement datasets */
   for(i = 0; i < ndst; i++) {
      vdm_LibraryGetDataset (library,idst[i],&dataset);
      vdm_DatasetInq (dataset,dsname,&lrec,&nrow,&ncol,&ntyp);

                   /* print header */
      printf("\n\nDataset: %s\n",dsname);
      if(thermalflag == 0) {
         printf("\nDisplacement History\n");
      } else {
         printf("\nTemperature History\n");
      }
                   /* load history */ 
      vis_RPropSetDatasetName (rprop,dsname);
      vdm_LManLoadHistory (lman,history,rprop);

                   /* query history for number of steps, indices, etc. */ 
      vis_HistoryInq (history,&numstp,&nument,&enttype,&subtype,&datatype);

                   /* get step numbers */ 
      stps = (Vint*)malloc(numstp*sizeof(Vint));
      vis_HistorySteps (history,&numstp,stps);

                   /* get independent variable */ 
      tstp = (Vfloat*)malloc(numstp*sizeof(Vfloat));
      vis_HistoryIndepSteps (history,tstp);
      vis_HistoryGetIndepName (history,indepname);

                   /* get index numbers */ 
      inds = (Vint*)malloc(nument*sizeof(Vint));
      vis_HistoryIndices (history,&nument,inds);

                   /* loop over nodes */
      for(n = 0; n < nument; n++) {
         vis_ConnectNodeAssoc (connect,VIS_USERID,1,&inds[n],&nodenumber);
         printf("node= %8d\n",nodenumber);
                   /* get defined components and count them */ 
         vis_HistoryDataStat (history,inds[n],stat);
         nstat = 0;
         for(k = 0; k < nrow; k++) {
            if(stat[k])  nstat++;
         }
         if(nstat == 0) {
            printf("No data\n");
            continue;
         }
                   /* loop over steps */
         for(j = 0; j < numstp; j++) {
            vis_HistorySetDerive (history,datatype);
            printf("step= %4d",stps[j]);
            if(indepname[0] != '\0')  {
               printf(" %s= %f",indepname,tstp[j]);
            } else {
               printf("\n");
            }
            vis_HistoryData (history,stps[j],1,&inds[n],dvec);
                   /* print only defined datatype components */ 
            if(nstat != nrow) {
               for(k = 0; k < nrow; k++) {
                  if(stat[k] == 0) {
                     printf("   no data     ");
                  } else {
                     printf("%14e ",dvec[k]);
                  }
               }
               printf("\n");
               continue;
            }
                   /* print complete datatype */ 
                   /* scalar type */ 
            if(datatype == VIS_SCALAR) {
               printf("%14e\n",dvec[0]);
                   /* vector type */ 
            } else if(datatype == VIS_VECTOR) {
                   /* print components */ 
               printf("%14e %14e %14e",dvec[0],dvec[1],dvec[2]);
                   /* print magnitude */ 
               vis_HistorySetDerive (history,VIS_VECTOR_MAG);
               vis_HistoryData (history,stps[j],1,&inds[n],&dmag);
               printf("  mag= %14e\n",dmag);
                   /* six dof vector type */ 
            } else if(datatype == VIS_SIXDOF) {
                   /* print components */ 
               printf("%14e %14e %14e %14e %14e %14e",
                       dvec[0],dvec[1],dvec[2],dvec[3],dvec[4],dvec[5]);
                   /* print magnitudes */ 
               vis_HistorySetDerive (history,VIS_SIXDOF_TMAG);
               vis_HistoryData (history,stps[j],1,&inds[n],&dmag);
               vis_HistorySetDerive (history,VIS_SIXDOF_RMAG);
               vis_HistoryData (history,stps[j],1,&inds[n],&rmag);
               printf("  mag= %14e %14e\n",dmag,rmag);
            }
         }
      }
      printf("\n");
      free(tstp);
      free(stps);
      free(inds);

                   /* print attributes */
      print_attributes (dataset);
   }

                   /* free memory */ 
   vis_GridFunEnd (gridfun);
   vis_HistoryEnd (history);
   vis_RPropEnd (rprop);
   free(idst);
}

/*----------------------------------------------------------------------
                      print stresses
----------------------------------------------------------------------*/
static void
print_stress(vdm_LMan *lman, vdm_Library *library, vis_Model *model)
{
   vdm_Dataset *dataset;
   Vchar dsname[DATASET_MAXNAME];
   Vlong lrec;
   Vint nrow, ncol, ntyp;
   Vint numdatasets;
   Vint ndst;
   Vint *idst;
   Vint *inds, *stps;
   Vfloat *tstp;
   Vint nix, *ix, *ixd;
   Vint elemnumber;
   Vint i, j, k, m, n;
   vis_Connect *connect;
   vis_GridFun *gridfun;
   vis_History *history;
   vis_RProp *rprop;
   Vint maxelno;
   Vfloat *sten;
   Vint nstat, *stat;
   Vint numstp, nument, enttype, subtype, datatype;
   Vchar indepname[81];
   Vint thermalflag;

                   /* determine maximum number of datasets */
   vdm_LibraryGetNumDatasets (library,&numdatasets);

                   /* allocate array for dataset indices */
   idst = (Vint*)malloc(numdatasets*sizeof(Vint));

                   /* search for stress,strain results datasets */
   thermalflag = 0;
   subtype = SYS_NODE;
   vdm_LibrarySearchDataset (library,"HIST.S*.*EL:*",numdatasets,idst,&ndst);
   if(ndst == 0) {
      vdm_LibrarySearchDataset (library,"HIST.E*.*EL:*",numdatasets,idst,&ndst);
   }
   if(ndst == 0) {
      thermalflag = 1;
      subtype = SYS_NONE;
      vdm_LibrarySearchDataset (library,"HIST.HEAT_FLUX.*E:*",numdatasets,
                                idst,&ndst);
   }
   if(ndst == 0) {
      free(idst);
      return;
   }
                   /* get Connect object created in Model */
   vis_ModelGetObject (model,VIS_CONNECT,(Vobject**)&connect);

                   /* find maximum number of element nodes */
   vis_ConnectMaxElemNode (connect,&maxelno);
                   /* allocate arrays for maximum element node stress data */
   sten = (Vfloat*)malloc(maxelno*6*sizeof(Vfloat));
   stat = (Vint*)malloc(maxelno*6*sizeof(Vint));
                   /* allocate arrays for maximum element node connectivity */
   ix = (Vint*)malloc(maxelno*sizeof(Vint));
   ixd = (Vint*)malloc(maxelno*sizeof(Vint));

                   /* create a grid function object */
   gridfun = vis_GridFunBegin ();
   vis_ConnectGridFun (connect,gridfun);

                   /* create history and install GridFun object */
   history = vis_HistoryBegin ();
   vis_HistorySetObject (history,VIS_GRIDFUN,gridfun);

                   /* initialize result property object */
   rprop = vis_RPropBegin ();
   vis_RPropDef (rprop,SYS_ELEM,subtype);

                   /* loop over stress datasets */
   for(i = 0; i < ndst; i++) {
      vdm_LibraryGetDataset (library,idst[i],&dataset);
      vdm_DatasetInq (dataset,dsname,&lrec,&nrow,&ncol,&ntyp);

                   /* print header */
      printf("\n\nDataset: %s\n",dsname);
      if(thermalflag == 0) {
         printf("\nStress History\n");
      } else {
         printf("\nHeat Flux History\n");
      }

      vis_RPropSetDatasetName (rprop,dsname);
      vdm_LManLoadHistory (lman,history,rprop);

                   /* query history for number of steps, indices, etc. */
      vis_HistoryInq (history,&numstp,&nument,&enttype,&subtype,&datatype);

                   /* get step numbers */
      stps = (Vint*)malloc(numstp*sizeof(Vint));
      vis_HistorySteps (history,&numstp,stps);

                   /* get independent variable */
      tstp = (Vfloat*)malloc(numstp*sizeof(Vfloat));
      vis_HistoryIndepSteps (history,tstp);
      vis_HistoryGetIndepName (history,indepname);

                   /* get index numbers */
      inds = (Vint*)malloc(nument*sizeof(Vint));
      vis_HistoryIndices (history,&nument,inds);

                   /* loop over elements */
      for(n = 0; n < nument; n++) {
         vis_ConnectElemAssoc (connect,VIS_USERID,1,&inds[n],&elemnumber);
         printf("elem= %8d\n",elemnumber);
                   /* single node or element value */
         if(subtype == SYS_NONE) {
            nix = 1;
                   /* get nodes in element and query user node ids */
         } else {
            vis_ConnectElemNode (connect,inds[n],&nix,ix);
            vis_ConnectNodeAssoc (connect,VIS_USERID,nix,ix,ixd);
         }
                   /* get defined components and count them */
         vis_HistoryDataStat (history,inds[n],stat);
         nstat = 0;
         for(k = 0; k < nrow*nix; k++) {
            if(stat[k])  nstat++;
         }
         if(nstat == 0) {
            printf("No data\n");
            continue;
         }
                   /* loop over steps */
         for(j = 0; j < numstp; j++) {
            vis_HistorySetDerive (history,datatype);
            printf("step= %4d",stps[j]);
            if(indepname[0] != '\0')  {
               printf(" %s= %f\n",indepname,tstp[j]);
            } else {
               printf("\n");
            }
            vis_HistoryData (history,stps[j],1,&inds[n],(Vfloat*)sten);

                   /* node or element */ 
            if(subtype == SYS_NONE) {
               for(k = 0; k < nrow; k++) {
                  if(stat[k] == 0) {
                     printf("  no data    ");
                  } else {
                     printf("%12.5e ",sten[k]);
                  }
               }
               printf("\n");
                   /* element node */ 
            } else {
               for(m = 0; m < nix; m++) {
                  printf(" %8d ",ixd[m]);
                  for(k = 0; k < nrow; k++) {
                     if(stat[m*nrow+k] == 0) {
                        printf("  no data    ");
                     } else {
                        printf("%12.5e ",sten[m*nrow+k]);
                     }
                  }
                  printf("\n");
               }
            }
         }
      }
      printf("\n");
      free(tstp);
      free(stps);
      free(inds);
                   /* print attributes */
      print_attributes (dataset);
   }
                   /* free memory */
   vis_GridFunEnd (gridfun);
   vis_HistoryEnd (history);
   vis_RPropEnd (rprop);
   free(idst);
   free(sten);
   free(stat);
   free(ix);
   free(ixd);
}

/*----------------------------------------------------------------------
                      print dataset attributes
----------------------------------------------------------------------*/
static void
print_attributes(vdm_Dataset *dataset)
{
   int j, k;
   vdm_Attribute *attribute;
   Vint numatts;
   Vint atleng, attype;
   Vchar atname[ATTRIBUTE_MAXNAME];
   Vchar  cvalue[ATTRIBUTE_MAXVALUE];
   Vint    *ivalue = (Vint*)cvalue;
   Vfloat  *rvalue = (Vfloat*)cvalue;
   Vdouble *dvalue = (Vdouble*)cvalue;

                   /* loop over attributes */
   vdm_DatasetGetNumAttributes (dataset,&numatts);
   for(j = 0; j < numatts; j++) {
      vdm_DatasetGetAttribute (dataset,j,&attribute);
      vdm_AttributeInq (attribute,atname,&atleng,&attype);
      printf("    Attribute: %s\n               ",atname);
      if(attype == SYS_INTEGER) {
         vdm_AttributeValueInteger (attribute,ivalue);
         for(k = 0; k < atleng; k++)  printf("%i  ",ivalue[k]);
      } else if(attype == SYS_FLOAT) {
         vdm_AttributeValueFloat (attribute,rvalue);
         for(k = 0; k < atleng; k++)  printf("%e  ",rvalue[k]);
      } else if(attype == SYS_CHAR) {
         vdm_AttributeValueString (attribute,cvalue);
         printf("%s  ",cvalue);
      } else if(attype == SYS_DOUBLE) {
         vdm_AttributeValueDouble (attribute,dvalue);
         for(k = 0; k < atleng; k++)  printf("%e  ",dvalue[k]);
      }
      printf("\n");
   }
}

7.5. Example 3b, Read and Print Remeshing Results

This example illustrates traversing a library dataset hierarchy. This is the case, for example, when a results file contains multiple mesh topologies due to adaptive remeshing of some kind. Remeshed topologies exist in a library as a dataset named REMESH.L:id where id normally represents an integer sequentially assigned to the mesh. This dataset has a special datatype, SYS_NODATATYPE, and the resulting dataset is termed a library dataset. It represents a sublibrary. Use vdm_DataFunLibDataset() to change to the sublibrary represented by the dataset. The function print_toc can be called to traverse this sublibrary. Then pop back to the parent library and continue. A sublibrary containing a remeshed model will contain a complete set of model related datasets and possible associated results datasets. The function print_model illustrates using vdm_LManLoadModel() and vdm_LManLoadState() for a remeshed model.

#include <stdlib.h>
#include "base/base.h"
#include "vdm/vdm.h"

static void
print_toc(vdm_DataFun *datafun);
static void
print_attributes(vdm_Dataset *dataset);
static void
print_model(vdm_DataFun *datafun);

/*----------------------------------------------------------------------
                     Read and Print Remeshing Results
----------------------------------------------------------------------*/
int
main(int argc, char **argv)
{
   char inputfile[256];
   vdm_MarcLib    *marclib;
   vdm_D3DLib     *d3dlib;
   vdm_EnSightLib *ensightlib;
   vdm_DataFun *datafun;
   Vint filetype;
   Vint numnp, numel;

   if(argc < 2) {
      fprintf(stderr,"Usage: %s inputfile\n",argv[0]);
      fprintf(stderr," inputfile is blank, 'impact.t19' is assumed\n");
      strcpy(inputfile,"impact.t19");
   } else {
      strcpy(inputfile,argv[1]);
   }
                   /* create data function object */
   datafun = vdm_DataFunBegin ();

                   /* determine file type from file extension */
   if(strstr(inputfile,"d3plot") != NULL) {
      filetype = SYS_LSTC_STATE;
      d3dlib = vdm_D3DLibBegin ();
      vdm_D3DLibDataFun (d3dlib,datafun);
   } else if(strstr(inputfile,".t16") != NULL  ||
             strstr(inputfile,".t19") != NULL) {
      filetype = SYS_MARC_POST;
      marclib = vdm_MarcLibBegin ();
      vdm_MarcLibDataFun (marclib,datafun);
   } else if(strstr(inputfile,".case") != NULL  ||
             strstr(inputfile,".encas") != NULL) {
      filetype = SYS_ENSIGHT;
      ensightlib = vdm_EnSightLibBegin ();
      vdm_EnSightLibDataFun (ensightlib,datafun);
   } else {
      fprintf(stderr,"Error: Bad input file %s\n",inputfile);
      exit(1);
   }
                   /* open library device */
   vdm_DataFunOpen (datafun,0,inputfile,filetype);

                   /* get number of nodes and elements */ 
   vdm_DataFunGetNumEntities (datafun,SYS_NODE,&numnp);
   vdm_DataFunGetNumEntities (datafun,SYS_ELEM,&numel);
   printf("number of nodes= %d\n",numnp);
   printf("number of elems= %d\n",numel);

                   /* traverse tables of contents */ 
   print_toc (datafun);
                   /* load model and states */
   print_model (datafun);

                   /* close library device */ 
   vdm_DataFunClose (datafun);

                   /* free objects */ 
   vdm_DataFunEnd (datafun);
   if(filetype == SYS_LSTC_STATE) {
      vdm_D3DLibEnd (d3dlib);
   } else if(filetype == SYS_MARC_POST) {
      vdm_MarcLibEnd (marclib);
   } else if(filetype == SYS_ENSIGHT) {
      vdm_EnSightLibEnd (ensightlib);
   }
   return 0;
}

/*----------------------------------------------------------------------
                      print toc
----------------------------------------------------------------------*/
static void
print_toc(vdm_DataFun *datafun)
{
   Vint i;
   vdm_Library *library;
   vdm_Dataset *dataset;
   Vint numdatasets;
   Vchar dsname[DATASET_MAXNAME];
   Vlong lrec;
   Vint nrow, ncol, ntyp;
   Vint type;
   Vfloat *d;

   vdm_DataFunGetLibrary (datafun,&library);
   vdm_LibraryGetNumDatasets (library,&numdatasets);
                   /* loop through datasets */
   for(i = 0; i < numdatasets; i++) {
      vdm_LibraryGetDataset (library,i,&dataset);
      vdm_DatasetInq (dataset,dsname,&lrec,&nrow,&ncol,&ntyp);
      printf("\n\nDataset: %s\n",dsname);
      printf("lrec= %lld, nrow= %d, ncol= %d, ntyp= %d\n",lrec,nrow,ncol,ntyp);
      print_attributes (dataset);
                   /* library dataset */ 
      if(ntyp == SYS_NODATATYPE) {
         vdm_DataFunLibDataset (datafun,VDM_LIBDATASET_PUSH,i);
         print_toc (datafun);
         vdm_DataFunLibDataset (datafun,VDM_LIBDATASET_POP,0);
                   /* possible displacement or coordinate result dataset */ 
      } else {
         vdm_DatasetResType (dataset,&type);
         if(type == SYS_RES_X  ||  type == SYS_RES_D) {
            d = (Vfloat*)malloc((size_t)lrec*sizeof(Vfloat));
            vdm_DataFunReadDataset (datafun,i,d);
            printf("d[0]= %e, d[1]= %e, d[2]= %e\n",d[0],d[1],d[2]);
            free(d);
         }
      }
   }
}

/*----------------------------------------------------------------------
                      print dataset attributes
----------------------------------------------------------------------*/
static void
print_attributes(vdm_Dataset *dataset)
{
   int j, k;
   vdm_Attribute *attribute;
   Vint numatts;
   Vint atleng, attype;
   Vchar atname[ATTRIBUTE_MAXNAME];
   Vchar  cvalue[ATTRIBUTE_MAXVALUE];
   Vint    *ivalue = (Vint*)cvalue;
   Vfloat  *rvalue = (Vfloat*)cvalue;
   Vdouble *dvalue = (Vdouble*)cvalue;

                   /* loop over attributes */
   vdm_DatasetGetNumAttributes (dataset,&numatts);
   for(j = 0; j < numatts; j++) {
      vdm_DatasetGetAttribute (dataset,j,&attribute);
      vdm_AttributeInq (attribute,atname,&atleng,&attype);
      printf("    Attribute: %s\n               ",atname);
      if(attype == SYS_INTEGER) {
         vdm_AttributeValueInteger (attribute,ivalue);
         for(k = 0; k < atleng; k++)  printf("%i  ",ivalue[k]);
      } else if(attype == SYS_FLOAT) {
         vdm_AttributeValueFloat (attribute,rvalue);
         for(k = 0; k < atleng; k++)  printf("%e  ",rvalue[k]);
      } else if(attype == SYS_CHAR) {
         vdm_AttributeValueString (attribute,cvalue);
         printf("%s  ",cvalue);
      } else if(attype == SYS_DOUBLE) {
         vdm_AttributeValueDouble (attribute,dvalue);
         for(k = 0; k < atleng; k++)  printf("%e  ",dvalue[k]);
      }
      printf("\n");
   }
}

/*----------------------------------------------------------------------
                      print model and coordinates
----------------------------------------------------------------------*/
static void
print_model(vdm_DataFun *datafun)
{
   Vint i, j;
   vdm_Library *library;
   vdm_Dataset *dataset;
   Vchar dsname[DATASET_MAXNAME];
   Vint numdatasets;
   Vlong lrec;
   Vint nrow, ncol, ntyp, type;
   vdm_LMan  *lman;
   vis_Model *model;
   vis_Connect *connect;
   vis_GridFun *gridfun;
   vis_State *state;
   vis_RProp *rprop;
   Vint enttype, subtype, numel, numnp;
   Vint id, ndat, nloc, nsec;
   Vfloat d[16];

                   /* instance Model object for finite element model */
   model = vis_ModelBegin();
                   /* use Library Manager object to load model */
   lman = vdm_LManBegin ();
   vdm_LManSetObject (lman,VDM_DATAFUN,datafun);
   vdm_LManLoadModel (lman,model);
                   /* get Connect object created in Model */
   vis_ModelGetObject (model,VIS_CONNECT,(Vobject**)&connect);
   vis_ConnectNumber (connect,SYS_ELEM,&numel);
   vis_ConnectNumber (connect,SYS_NODE,&numnp);
   printf("numel= %d\n",numel);
   printf("numnp= %d\n",numnp);
                   /* create a grid function object */
   gridfun = vis_GridFunBegin ();
   vis_ConnectGridFun (connect,gridfun);

   vdm_DataFunGetLibrary (datafun,&library);
   vdm_LibraryGetNumDatasets (library,&numdatasets);
                   /* loop through datasets */
   for(i = 0; i < numdatasets; i++) {
      vdm_LibraryGetDataset (library,i,&dataset);
      vdm_DatasetInq (dataset,dsname,&lrec,&nrow,&ncol,&ntyp);
                   /* library dataset */
      if(ntyp == SYS_NODATATYPE) {
         printf("\n\nLib Dataset: %s\n",dsname);
         vdm_DataFunLibDataset (datafun,VDM_LIBDATASET_PUSH,i);
         print_model (datafun);
         vdm_DataFunLibDataset (datafun,VDM_LIBDATASET_POP,0);
                   /* possible coordinate dataset */
      } else {
         vdm_DatasetResType (dataset,&type);
         vdm_DatasetEntType (dataset,&enttype,&subtype);
         if(enttype != SYS_NODE)  continue;
         if(type == SYS_RES_X) {
            printf("\n\nCoordinate Dataset: %s\n",dsname);
            state = vis_StateBegin ();
            vis_StateSetObject (state,VIS_GRIDFUN,gridfun);
            rprop = vis_RPropBegin ();
            vis_RPropDef (rprop,SYS_NODE,SYS_NONE);
            vis_RPropSetDatasetIndex (rprop,i);
            vdm_LManLoadState (lman,state,rprop);
                   /* print coordinates for first node */ 
            id = 1;
            vis_StateDataNum (state,id,&ndat,&nloc,&nsec);
            vis_StateData (state,1,&id,d);
            printf("node 1, x= ");
            for(j = 0; j < ndat; j++) {
               printf(" %e",d[j]);
            }
            printf("\n");
            vis_StateEnd (state);
            vis_RPropEnd (rprop);
         }
      }
   }
   vis_ModelDelete (model);
   vis_ModelEnd (model);
   vis_GridFunEnd (gridfun);
   vdm_LManEnd (lman);
}

7.6. Example 3c, Read and Print Results History Summary

This example illustrates accessing and printing summaries of the history results related datasets.

#include <stdlib.h>
#include "base/base.h"
#include "vis/visdata.h"
#include "vdm/vdm.h"

static void
print_histinfo(vdm_DataFun *datafun, vdm_Library *library,
               vis_IdTran *idtrannode, vis_IdTran *idtranelem);
static void
print_index(Vint enttype, vis_IdTran *idtran, vdm_DataFun *datafun,
            vdm_Library *library, vdm_Attribute *attribute);
static void
print_step(vdm_DataFun *datafun,
           vdm_Library *library, vdm_Attribute *attribute,
           Vint indep, Vchar *indepname, vdm_Attribute *attributev);

/*----------------------------------------------------------------------
                     Read and Print Results History Summary
----------------------------------------------------------------------*/
int
main(int argc, char **argv)
{
   char inputfile[256];
   vdm_NASLib    *naslib;
   vdm_NatLib    *natlib;
   vdm_SDRCLib   *sdrclib;
   vdm_ANSLib    *anslib;
   vdm_ABALib    *abalib;
   vdm_DataFun   *datafun;
   vdm_Library   *library;
   Vint filetype;
   Vint i;
   Vint ndst, idst;
   Vint *ptrint;
   Vint numnp, numel;
   vis_IdTran *idtrannode, *idtranelem;

                   /* check input arguments */ 
   if(argc < 2) {
      fprintf(stderr,"Usage: %s inputfile\n",argv[0]);
      fprintf(stderr," inputfile is blank, 'cantilever.unv' is assumed\n");
      strcpy(inputfile,"cantilever.unv");
   } else {
      strcpy(inputfile,argv[1]);
   }
                   /* create data function object */
   datafun = vdm_DataFunBegin ();

                   /* determine file type from file extension */
   if(strstr(inputfile,".unv") != NULL) {
      filetype = VDM_SDRC_UNIVERSAL;
      sdrclib = vdm_SDRCLibBegin ();
      vdm_SDRCLibDataFun (sdrclib,datafun);
   } else if(strstr(inputfile,".op2") != NULL) {
      filetype = VDM_NASTRAN_OUTPUT2;
      naslib = vdm_NASLibBegin ();
      vdm_NASLibDataFun (naslib,datafun);
   } else if(strstr(inputfile,".vdm") != NULL) {
      filetype = VDM_NATIVE;
      natlib = vdm_NatLibBegin ();
      vdm_NatLibDataFun (natlib,datafun);
   } else if(strstr(inputfile,".rst") != NULL) {
      filetype = VDM_ANSYS_RESULT;
      anslib = vdm_ANSLibBegin ();
      vdm_ANSLibDataFun (anslib,datafun);
   } else if(strstr(inputfile,".fil") != NULL) {
      filetype = VDM_ABAQUS_FIL;
      abalib = vdm_ABALibBegin ();
      vdm_ABALibDataFun (abalib,datafun);
   } else {
      fprintf(stderr,"Error: Bad input file %s\n",inputfile);
      exit(1);
   }
                   /* open library device */
   vdm_DataFunOpen (datafun,0,inputfile,filetype);

                   /* query number of nodes and elements */ 
   vdm_DataFunGetNumEntities (datafun,SYS_NODE,&numnp);
   vdm_DataFunGetNumEntities (datafun,SYS_ELEM,&numel);

                   /* get library object */ 
   vdm_DataFunGetLibrary (datafun,&library);

                   /* establish node identifiers */ 
   vdm_LibrarySearchDataset (library,"NID.N",1,&idst,&ndst);
   idtrannode = vis_IdTranBegin ();
   vis_IdTranDef (idtrannode,numnp);
   if(ndst) {
      ptrint = (Vint*)malloc(numnp*sizeof(Vint));
      vdm_DataFunReadDataset (datafun,idst,ptrint);
      for(i = 1; i <= numnp; i++) {
         vis_IdTranSetId (idtrannode,i,ptrint[i-1]);
      }
      free(ptrint);
   }
                   /* establish element identifiers */ 
   vdm_LibrarySearchDataset (library,"EID.E",1,&idst,&ndst);
   idtranelem = vis_IdTranBegin ();
   vis_IdTranDef (idtranelem,numel);
   if(ndst) {
      ptrint = (Vint*)malloc(numel*sizeof(Vint));
      vdm_DataFunReadDataset (datafun,idst,ptrint);
      for(i = 1; i <= numel; i++) {
         vis_IdTranSetId (idtranelem,i,ptrint[i-1]);
      }
      free(ptrint);
   }
                   /* print history information */ 
   print_histinfo (datafun,library,idtrannode,idtranelem);

                   /* free IdTran objects */ 
   vis_IdTranEnd (idtrannode);
   vis_IdTranEnd (idtranelem);

                   /* close library device */ 
   vdm_DataFunClose (datafun);

                   /* free objects */ 
   vdm_DataFunEnd (datafun);
   if(filetype == VDM_SDRC_UNIVERSAL) {
      vdm_SDRCLibEnd (sdrclib);
   } else if(filetype == VDM_NASTRAN_OUTPUT2) {
      vdm_NASLibEnd (naslib);
   } else if(filetype == VDM_NATIVE) {
      vdm_NatLibEnd (natlib);
   } else if(filetype == VDM_ANSYS_RESULT) {
      vdm_ANSLibEnd (anslib);
   } else if(filetype == VDM_ABAQUS_FIL) {
      vdm_ABALibEnd (abalib);
   }
   return 0;
}

/*----------------------------------------------------------------------
                      print history information
----------------------------------------------------------------------*/
static void
print_histinfo(vdm_DataFun *datafun, vdm_Library *library,
               vis_IdTran *idtrannode, vis_IdTran *idtranelem)
{
   Vint i;
   vdm_Dataset *dataset;
   vdm_Attribute *attribute;
   vdm_Attribute *attributev;
   Vchar dsroot[DATASET_MAXNAME], caux[DATASET_MAXNAME];
   Vint type, hist, cplx, sect, enttype, subtype;
   Vint nqua, iqua[SYS_NQUA_MAX];
   Vchar cqua[DATASET_MAXNAME];
   Vint id1, id2, id3;
   Vchar dsname[DATASET_MAXNAME];
   Vlong lrec;
   Vint nrow, ncol, ntyp;
   Vchar cvalue[ATTRIBUTE_MAXVALUE];
   Vint numdatasets;
   Vint ndst, *idst;
   Vint natt, iatt;
   Vint indep, nattv, iattv;
   Vchar indepname[81];

                   /* query maximum number of datasets */ 
   vdm_LibraryGetNumDatasets (library,&numdatasets);

                   /* allocate array for dataset indices */
   idst = (Vint*)malloc(numdatasets*sizeof(Vint));

                   /* search for all history related datasets */ 
   vdm_LibrarySearchDataset (library,"HIST.*",numdatasets,idst,&ndst);
   if(ndst == 0) {
      free(idst);
      return;
   }
                   /* loop over history datasets */
   for(i = 0; i < ndst; i++) {
      vdm_LibraryGetDataset (library,idst[i],&dataset);

                   /* identify result quantity information */
      vdm_DatasetResult (dataset,dsroot,&type,&hist,
                         &nqua,iqua,cqua,&cplx,caux,&sect,&enttype,&subtype,
                         &id1,&id2,&id3);

                   /* skip if not results type */
      if(type == SYS_RES_NONE) {
         continue;
      }
                   /* skip if imaginary or phase */
      if(cplx) {
         continue;
      }
                   /* print dataset name, etc. */ 
      vdm_DatasetInq (dataset,dsname,&lrec,&nrow,&ncol,&ntyp);
      printf("Dataset: %s\n",dsname);
      if(enttype == SYS_NODE) {
         printf("Node result\n");
      } else if(enttype == SYS_ELEM) {
         if(subtype == SYS_NONE) {
            printf("Element result\n");
         } else {
            printf("Element node result\n");
         }
      }
                   /* query Contents */ 
      vdm_DatasetSearchAttribute (dataset,"Contents",1,&iatt,&natt);
      if(natt) {
         vdm_DatasetGetAttribute (dataset,iatt,&attribute);
         vdm_AttributeValueString (attribute,cvalue);
         printf("Contents: %s\n",cvalue);
      }
                   /* query Link.Complex */ 
      vdm_DatasetSearchAttribute (dataset,"Link.Complex",1,&iatt,&natt);
      if(natt) {
         vdm_DatasetGetAttribute (dataset,iatt,&attribute);
         vdm_AttributeValueString (attribute,cvalue);
         printf("Link.Complex: %s\n",cvalue);
      }
                   /* query Link.Index */ 
      vdm_DatasetSearchAttribute (dataset,"Link.Index",1,&iatt,&natt);
      if(natt) {
         vdm_DatasetGetAttribute (dataset,iatt,&attribute);
         if(enttype == SYS_NODE) {
            print_index (enttype,idtrannode,datafun,library,attribute);
         } else {
            print_index (enttype,idtranelem,datafun,library,attribute);
         }
      }
                   /* query Link.Step */ 
      vdm_DatasetSearchAttribute (dataset,"Link.Step",1,&iatt,&natt);
                   /* query Link to independent variable */ 
      vdm_DatasetSearchAttribute (dataset,"Link.Time",1,&iattv,&nattv);
      indep = 1;
      strcpy(indepname,"Time");
      if(nattv == 0) {
         vdm_DatasetSearchAttribute (dataset,"Link.Frequency",1,&iattv,&nattv);
         indep = 2;
         strcpy(indepname,"Frequency");
      }
      if(nattv == 0) {
         vdm_DatasetSearchAttribute (dataset,"Link.LoadFactor",1,&iattv,&nattv);
         indep = 3;
         strcpy(indepname,"LoadFactor");
      }
      if(natt) {
         vdm_DatasetGetAttribute (dataset,iatt,&attribute);
         if(nattv) {
            vdm_DatasetGetAttribute (dataset,iattv,&attributev);
            print_step (datafun,library,attribute,indep,indepname,attributev);
         } else {
            print_step (datafun,library,attribute,0,NULL,NULL);
         }
      }
      printf("\n");
   }
                   /* free memory */ 
   free(idst);
}

/*----------------------------------------------------------------------
                      print index dataset
----------------------------------------------------------------------*/
static void
print_index(Vint enttype, vis_IdTran *idtran, vdm_DataFun *datafun,
            vdm_Library *library, vdm_Attribute *attribute)
{
   Vint i;
   Vchar cvalue[ATTRIBUTE_MAXVALUE];
   Vint idst, ndst;
   vdm_Dataset *dataset;
   Vchar dsname[DATASET_MAXNAME];
   Vlong lrec;
   Vint nrow, ncol, ntyp;
   Vint index, id;
   Vint *inds;

   vdm_AttributeValueString (attribute,cvalue);
   vdm_LibrarySearchDataset (library,cvalue,1,&idst,&ndst);
   vdm_LibraryGetDataset (library,idst,&dataset);

                   /* ncol is the number of entities, nrow is 1 */ 
   vdm_DatasetInq (dataset,dsname,&lrec,&nrow,&ncol,&ntyp);

                   /* read and print entity indices */ 
   inds = (Vint*)malloc(ncol*sizeof(Vint));
   vdm_DataFunReadDataset (datafun,idst,inds);

                   /* use IdTran to get user id */ 
   for(i = 0; i < ncol; i++) {
      index = inds[i];
      vis_IdTranGetId (idtran,index,&id);
      if(enttype == SYS_NODE) {
         printf("node index= %d, id= %d\n",index,id);
      } else {
         printf("element index= %d, id= %d\n",index,id);
      }
   }
   
   free(inds);
}

/*----------------------------------------------------------------------
                      print step and independent variable datasets
----------------------------------------------------------------------*/
static void
print_step(vdm_DataFun *datafun,
           vdm_Library *library, vdm_Attribute *attribute,
           Vint indep, Vchar *indepname, vdm_Attribute *attributev)
{
   Vint i;
   Vchar cvalue[ATTRIBUTE_MAXVALUE], cvaluev[ATTRIBUTE_MAXVALUE];
   Vint idst, ndst, idstv, ndstv;
   vdm_Dataset *dataset, *datasetv;
   Vchar dsname[DATASET_MAXNAME];
   Vlong lrec;
   Vint nrow, ncol, ntyp;
   Vint *inds;
   Vfloat *indv;

   vdm_AttributeValueString (attribute,cvalue);
   vdm_LibrarySearchDataset (library,cvalue,1,&idst,&ndst);
   vdm_LibraryGetDataset (library,idst,&dataset);

                   /* ncol is the number of steps, nrow is 1 */ 
   vdm_DatasetInq (dataset,dsname,&lrec,&nrow,&ncol,&ntyp);

                   /* read step numbers */ 
   inds = (Vint*)malloc(ncol*sizeof(Vint));
   vdm_DataFunReadDataset (datafun,idst,inds);

                   /* read independent variable values */ 
   if(indep) {
      vdm_AttributeValueString (attributev,cvaluev);
      vdm_LibrarySearchDataset (library,cvaluev,1,&idstv,&ndstv);
      vdm_LibraryGetDataset (library,idstv,&datasetv);
      vdm_DatasetInq (datasetv,dsname,&lrec,&nrow,&ncol,&ntyp);
      indv = (Vfloat*)malloc(ncol*sizeof(Vfloat));
      vdm_DataFunReadDataset (datafun,idstv,indv);
   }

   for(i = 0; i < ncol; i++) {
      printf("stepnumber= %d",inds[i]);
      if(indep) {
         printf(", %s= %e",indepname,indv[i]);
      }
      printf("\n");
   }

   free(inds);
   if(indep) {
      free(indv);
   }
}

7.7. Example 3d, Read and Print Reduced Matrix Data

This example illustrates using VisTools global modules to store the model and reduced matrix data read from a library device. It is similar to Example 3, except that the RedMat module is used instead of the State module.

Reduced matrix results are read into RedMat objects using vdm_LManLoadRedMat(). The result property object, RProp is used in this case to pass the dataset name to vdm_LManLoadRedMat(). The vdm_LManLoadRedMat() function will populate the RedMat object with the node index, degree of freedom type and associated data value.

#include <stdlib.h>
#include "base/base.h"
#include "vis/visdata.h"
#include "vdm/vdm.h"
#include "datafile.h"

static void
print_redmat(vdm_LMan *lman, vdm_Library *library, vis_Model *model);

/*----------------------------------------------------------------------
                     Read and Print Reduced Matrix Data
----------------------------------------------------------------------*/
int
main(int argc, char **argv)
{
   Vint i;
   char inputfile[256];
   vdm_DataFun   *datafun;
   vdm_Library   *library;
   vdm_LMan      *lman;
   Vint filetype, filetype1;
   Vint numnp, numel;
   vis_Model *model;
   vis_Connect *connect;
   Vint ierr;
                   /* check input arguments */ 
   if(argc < 2) {
      fprintf(stderr,"Usage: %s inputfile [appendfile]\n",argv[0]);
      exit(0);
   } else {
      strcpy(inputfile,argv[1]);
   }
                   /* create data function object */
   datafun = vdm_DataFunBegin ();

   datafiletype(inputfile,&filetype);
   if(filetype == 0) {
      fprintf(stderr,"Error: Bad input file %s\n",inputfile);
      exit(0);
   }
   datafileinit(filetype,datafun);
                   /* set convention to support sparse datasets */
   vdm_DataFunSetConvention (datafun,VDM_CONVENTION_SPARSE);
                   /* open library device */
   vdm_DataFunOpen (datafun,0,inputfile,filetype);
                   /* check for error */
   ierr = vdm_DataFunError(datafun);
   if(ierr) {
      fprintf(stderr,"Error: opening file %s\n",inputfile);
      exit(0);
   }
                   /* look for appended file */ 
   for(i = 2; i < argc; i++) {
      if(strstr(argv[i],".op2") != NULL) {
         filetype1 = VDM_NASTRAN_OUTPUT2;
      } else if(strstr(argv[i],".unv") != NULL  ||
                strstr(argv[i],".bun") != NULL) {
         filetype1 = VDM_SDRC_UNIVERSAL;
      } else if(strstr(argv[i],".vdm") != NULL) {
         filetype1 = VDM_NATIVE;
      } else if(strstr(argv[i],".dis") != NULL) {
         filetype1 = VDM_PATRAN_RESULT;
      } else if(strstr(argv[i],".q") != NULL) {
         filetype1 = VDM_PLOT3D_SOLUTION;
      } else if(strstr(argv[i],".dat") != NULL) {
         filetype1 = VDM_FLUENT_MESH;
      } else if(strstr(argv[i],".cgns") != NULL) {
         filetype1 = VDM_CGNS;
      } else {
         fprintf(stderr,"Error: Bad appended file %s\n",argv[i]);
         exit(0);
      }
      vdm_DataFunAppend (datafun,argv[i],filetype1);
                   /* check for error */
      ierr = vdm_DataFunError(datafun);
      if(ierr) {
         fprintf(stderr,"Error: appending file %s to file %s\n",
                 argv[i],argv[1]);
         exit(0);
      }
   }
                   /* instance Model object for finite element model */ 
   model = vis_ModelBegin();

                   /* use Library Manager object to load model */ 
   lman = vdm_LManBegin ();
   vdm_LManSetObject (lman,VDM_DATAFUN,datafun);
   vdm_LManLoadModel (lman,model);

                   /* get Connect object created in Model */ 
   vis_ModelGetObject (model,VIS_CONNECT,(Vobject**)&connect);
   vis_ConnectNumber (connect,SYS_NODE,&numnp);
   vis_ConnectNumber (connect,SYS_ELEM,&numel);
   printf("number of nodes= %d\n",numnp);
   printf("number of elems= %d\n",numel);

                   /* get library object */ 
   vdm_DataFunGetLibrary (datafun,&library);

                   /* access and print reduced matrices and vectors */ 
   print_redmat (lman,library,model);

                   /* close library device */ 
   vdm_DataFunClose (datafun);

                   /* delete objects in Model created by LManLoadModel */ 
   vis_ModelDelete (model);

   datafileterm(filetype,datafun);
                   /* free objects */ 
   vdm_DataFunEnd (datafun);

   vdm_LManEnd (lman);
   vis_ModelEnd (model);
   return 0;
}

/*----------------------------------------------------------------------
                      print reduced matrices and vectors
----------------------------------------------------------------------*/
static void
print_redmat(vdm_LMan *lman, vdm_Library *library, vis_Model *model)
{
   Vint i, j, k, n;
   vdm_Dataset *dataset;
   Vchar dsname[DATASET_MAXNAME];
   Vchar dsroot[DATASET_MAXNAME];
   Vchar caux[DATASET_MAXNAME];
   Vchar andata[ATTRIBUTE_MAXVALUE];
   Vchar ancont[ATTRIBUTE_MAXVALUE];
   Vlong lrec;
   Vint nrow, ncol, ntyp;
   Vint ncols, *cols;
   Vint numdatasets;
   Vint ndofs, redmattype, index, doftag, sparse;
   Vint nval;
   Vlong nent;
   Vfloat fv[2];
   vis_RedMat *redmat;
   vis_RProp *rprop;
   Vint type, hist, cplx, sect, enttype, subtype, datatype;
   Vint nqua, iqua[SYS_NQUA_MAX];
   Vchar cqua[DATASET_MAXNAME];
   Vint id1, id2, id3;

                   /* determine maximum number of datasets */
   vdm_LibraryGetNumDatasets (library,&numdatasets);

                   /* create redmat */
   redmat = vis_RedMatBegin ();

                   /* create result property object */
   rprop = vis_RPropBegin ();

                   /* loop over datasets */
   for(n = 0; n < numdatasets; n++) {
      vdm_LibraryGetDataset (library,n,&dataset);

                   /* identify result quantity */ 
      vdm_DatasetResult (dataset,dsroot,&type,&hist,
                         &nqua,iqua,cqua,&cplx,caux,&sect,&enttype,&subtype,
                         &id1,&id2,&id3);
                   /* not a matrix result */ 
      if(type != SYS_RES_K_MAT &&
         type != SYS_RES_M_MAT &&
         type != SYS_RES_D_MAT &&
         type != SYS_RES_L_VEC) {
         continue;
      }
                   /* get dataset name and parameters */ 
      vdm_DatasetInq (dataset,dsname,&lrec,&nrow,&ncol,&ntyp);

                   /* get DataType attribute */ 
      vdm_DatasetDataType (dataset,andata,&datatype);

                   /* get Contents attribute */ 
      vdm_DatasetContents (dataset,ancont);

                   /* print dataset name */
      printf("\n\nDataset: %s\n",dsname);

                   /* print DataType and Contents */ 
      printf("DataType: %s\n",andata);
      printf("Contents: %s\n",ancont);

                   /* load state from dataset */ 
      vis_RPropDef (rprop,SYS_DOF,SYS_NONE);
      vis_RPropSetDatasetIndex (rprop,n);
      vdm_LManLoadRedMat (lman,redmat,rprop);
                   /* number of entities, datatype */
      vis_RedMatInq (redmat,&ndofs,&redmattype);
                   /* number of matrix entries, number of values per entry */
                   /* nval = 1 real, nval= 2 complex */
      vis_RedMatNum (redmat,&nent,&nval);
      vis_RedMatSparse (redmat,&sparse);

                   /* sparse matrix */ 
      if(redmattype == SYS_MATRIX_SYMM && sparse) {
         cols = (Vint*)malloc(ndofs*sizeof(Vint));
         for(i = 1; i <= ndofs; i++) {
            vis_RedMatGetDof (redmat,i,&index,&doftag);
            printf("   i= %2d, index= %d, doftag= %d\n",i,index,doftag);
            vis_RedMatDataCols (redmat,i,&ncols,cols);
            for(k = 0; k < ncols; ++k) {
               j = cols[k];
               printf("   row= %d, col= %d",i,j);
               vis_RedMatData (redmat,i,j,fv);
               if(nval == 1) {
                  printf("  fv= %11.4e\n",fv[0]);
               } else if(nval == 2) {
                  printf("  fv= %11.4e %11.4e(i)\n",fv[0],fv[1]);
               }
            }
         }
         free(cols);
         continue;
      }
                   /* not sparse */
                   /* loop through dofs */
      for(j = 1; j <= ndofs; j++) {
         vis_RedMatGetDof (redmat,j,&index,&doftag);
         printf("   j= %2d, index= %d, doftag= %d\n",j,index,doftag);
         if(redmattype == SYS_VECTOR) {
            i = 1;
            printf("   i= %d, j= %d",i,j);
            vis_RedMatData (redmat,i,j,fv);
            if(nval == 1) {
               printf("  fv= %11.4e\n",fv[0]);
            } else if(nval == 2) {
               printf("  fv= %11.4e %11.4e(i)\n",fv[0],fv[1]);
            }
         } else if(redmattype == SYS_MATRIX_DIAG) {
            i = j;
            printf("   i= %d, j= %d",i,j);
            vis_RedMatData (redmat,i,j,fv);
            if(nval == 1) {
               printf("  fv= %11.4e\n",fv[0]);
            } else if(nval == 2) {
               printf("  fv= %11.4e %11.4e(i)\n",fv[0],fv[1]);
            }
         } else if(redmattype == SYS_MATRIX_SYMM) {
            for(i = 1; i <= j; ++i) {
               printf("   i= %d, j= %d",i,j);
               vis_RedMatData (redmat,i,j,fv);
               if(nval == 1) {
                  printf("  fv= %11.4e\n",fv[0]);
               } else if(nval == 2) {
                  printf("  fv= %11.4e %11.4e(i)\n",fv[0],fv[1]);
               }
            }
         }
      }
   }
                   /* free memory */
   vis_RedMatEnd (redmat);
   vis_RPropEnd (rprop);
}

7.8. Example 3e, Read and Print Particle Data

This example illustrates using VisTools global modules to store particle data read from a library device. It is similar to Example 3, except that the State module is used with a parent entity type of SYS_PARTICLE. No particle related information is contained in the model, all particle data are treated as result data.

#include <stdlib.h>
#include "base/base.h"
#include "vis/visdata.h"
#include "vdm/vdm.h"
#include "datafile.h"

static void
print_particle(vdm_LMan *lman, vdm_Library *library);

/*----------------------------------------------------------------------
                     Read and Print Particle Data
----------------------------------------------------------------------*/
int
main(int argc, char **argv)
{
   char inputfile[256];
   vdm_DataFun   *datafun;
   vdm_Library   *library;
   vdm_LMan      *lman;
   Vint filetype, ierr;
                   /* check input arguments */ 
   if(argc < 2) {
      fprintf(stderr,"Usage: %s inputfile [appendfile]\n",argv[0]);
      exit(0);
   } else {
      strcpy(inputfile,argv[1]);
   }
                   /* create data function object */
   datafun = vdm_DataFunBegin ();

   datafiletype(inputfile,&filetype);
   if(filetype == 0) {
      fprintf(stderr,"Error: Bad input file %s\n",inputfile);
      exit(0);
   }
   datafileinit(filetype,datafun);
                   /* set convention to support sparse datasets */
   vdm_DataFunSetConvention (datafun,VDM_CONVENTION_SPARSE);
                   /* open library device */
   vdm_DataFunOpen (datafun,0,inputfile,filetype);
                   /* check for error */
   ierr = vdm_DataFunError(datafun);
   if(ierr) {
      fprintf(stderr,"Error: opening file %s\n",inputfile);
      exit(0);
   }
                   /* use Library Manager object */ 
   lman = vdm_LManBegin ();
   vdm_LManSetObject (lman,VDM_DATAFUN,datafun);

                   /* get library object */ 
   vdm_DataFunGetLibrary (datafun,&library);

                   /* access and print particle results */ 
   print_particle (lman,library);

                   /* close library device */ 
   vdm_DataFunClose (datafun);

   datafileterm(filetype,datafun);
                   /* free objects */ 
   vdm_DataFunEnd (datafun);

   vdm_LManEnd (lman);
   return 0;
}

/*----------------------------------------------------------------------
                      print particle scalars and vectors
----------------------------------------------------------------------*/
static void
print_particle(vdm_LMan *lman, vdm_Library *library)
{
   Vint i, n;
   vdm_Dataset *dataset;
   Vchar dsname[DATASET_MAXNAME];
   Vchar dsroot[DATASET_MAXNAME];
   Vchar caux[DATASET_MAXNAME];
   Vchar andata[ATTRIBUTE_MAXVALUE];
   Vchar ancont[ATTRIBUTE_MAXVALUE];
   Vlong lrec;
   Vint nrow, ncol, ntyp;
   Vint numdatasets;
   Vint nument;
   vis_RProp *rprop;
   vis_State *state;
   Vfloat fv[16];
   Vint type, hist, cplx, sect, enttype, subtype, datatype;
   Vint nqua, iqua[SYS_NQUA_MAX];
   Vchar cqua[DATASET_MAXNAME];
   Vint id1, id2, id3;

                   /* determine maximum number of datasets */
   vdm_LibraryGetNumDatasets (library,&numdatasets);

                   /* create state */
   state = vis_StateBegin ();

                   /* create result property object */
   rprop = vis_RPropBegin ();

                   /* loop over datasets */
   for(n = 0; n < numdatasets; n++) {
      vdm_LibraryGetDataset (library,n,&dataset);

                   /* identify result quantity */ 
      vdm_DatasetResult (dataset,dsroot,&type,&hist,
                         &nqua,iqua,cqua,&cplx,caux,&sect,&enttype,&subtype,
                         &id1,&id2,&id3);
                   /* not a particle result */ 
      if(enttype != SYS_PARTICLE) {
         continue;
      }
                   /* get dataset name and parameters */ 
      vdm_DatasetInq (dataset,dsname,&lrec,&nrow,&ncol,&ntyp);

                   /* get DataType attribute */ 
      vdm_DatasetDataType (dataset,andata,&datatype);

                   /* get Contents attribute */ 
      vdm_DatasetContents (dataset,ancont);

                   /* print dataset name */
      printf("\n\nDataset: %s\n",dsname);

                   /* print DataType and Contents */ 
      printf("DataType: %s\n",andata);
      printf("Contents: %s\n",ancont);

                   /* load state from dataset */ 
      vis_RPropDef (rprop,SYS_PARTICLE,SYS_NONE);
      vis_RPropSetDatasetIndex (rprop,n);
      vdm_LManLoadState (lman,state,rprop);

      vis_StateInq (state,&nument,&enttype,&subtype,&datatype);
                   /* loop over entities */ 
      for(i = 1; i <= nument; i++) {
                   /* check for entities to be printed */
         if(i != 1  &&  i != nument) {
            continue;
         }
         vis_StateData (state,1,&i,fv);
         if(datatype == VIS_SCALAR) {
            printf("particle= %d, scalar= %14e\n",i,fv[0]);
                   /* vector type */
         } else if(datatype == VIS_VECTOR) {
            printf("particle= %d, vector= %14e %14e %14e\n",
                    i,fv[0],fv[1],fv[2]);
         }
      }
   }
                   /* free memory */
   vis_StateEnd (state);
   vis_RPropEnd (rprop);
}

7.9. Example 3f, Read and Print Modal and Panel Contribution Results

This example illustrates using VisTools global modules to read modal and panel history data from a library device. It is similar to Example 3a, except that the History module is used with a parent entity type of SYS_MODE or SYS_PANEL.

#include <stdlib.h>
#include "base/base.h"
#include "vis/visdata.h"
#include "vdm/vdm.h"
#include "datafile.h"

static void
print_hist(vdm_DataFun *datafun, vdm_Library *library, vis_Model *model);

/*----------------------------------------------------------------------
                     Read and Print Modal and Panel Contribution Results
----------------------------------------------------------------------*/
int
main(int argc, char **argv)
{
   char inputfile[256];
   vdm_DataFun   *datafun;
   vdm_Library   *library;
   vdm_LMan      *lman;
   Vint filetype;
   Vint numnp, numel;
   vis_Model *model;
   vis_Connect *connect;
   Vint ierr;

                   /* check input arguments */ 
   if(argc < 2) {
      fprintf(stderr,"Usage: %s inputfile [appendfile]\n",argv[0]);
      exit(1);
   } else {
      strcpy(inputfile,argv[1]);
   }
                   /* create data function object */
   datafun = vdm_DataFunBegin ();

   datafiletype(inputfile,&filetype);
   if(filetype == 0) {
      fprintf(stderr,"Error: Bad input file %s\n",inputfile);
      exit(1);
   }
   datafileinit(filetype,datafun);
                   /* set convention to support sparse datasets */
   vdm_DataFunSetConvention (datafun,VDM_CONVENTION_SPARSE);
                   /* open library device */
   vdm_DataFunOpen (datafun,0,inputfile,filetype);
                   /* check for error */
   ierr = vdm_DataFunError(datafun);
   if(ierr) {
      fprintf(stderr,"Error: opening file %s\n",inputfile);
      exit(0);
   }
                   /* instance Model object for finite element model */ 
   model = vis_ModelBegin();

                   /* use Library Manager object to load model */ 
   lman = vdm_LManBegin ();
   vdm_LManSetObject (lman,VDM_DATAFUN,datafun);
   vdm_LManLoadModel (lman,model);

                   /* get Connect object created in Model */ 
   vis_ModelGetObject (model,VIS_CONNECT,(Vobject**)&connect);
   vis_ConnectNumber (connect,SYS_NODE,&numnp);
   vis_ConnectNumber (connect,SYS_ELEM,&numel);
   printf("number of nodes= %d\n",numnp);
   printf("number of elems= %d\n",numel);

                   /* get library object */ 
   vdm_DataFunGetLibrary (datafun,&library);

                   /* access and print modal contribution histories */ 
   print_hist (datafun,library,model);

                   /* close library device */ 
   vdm_DataFunClose (datafun);

                   /* delete objects in Model created by LManLoadModel */ 
   vis_ModelDelete (model);

   datafileterm(filetype,datafun);
                   /* free objects */ 
   vdm_DataFunEnd (datafun);

   vdm_LManEnd (lman);
   vis_ModelEnd (model);
   return 0;
}

/*----------------------------------------------------------------------
                      print histories
----------------------------------------------------------------------*/
static void
print_hist(vdm_DataFun *datafun, vdm_Library *library, vis_Model *model)
{
   Vint i, j, k, n;
   vdm_Dataset *dataset, *datasetlink;
   Vchar dsname[DATASET_MAXNAME];
   Vchar dsroot[DATASET_MAXNAME];
   Vchar caux[DATASET_MAXNAME];
   Vchar andata[ATTRIBUTE_MAXVALUE];
   Vchar ancont[ATTRIBUTE_MAXVALUE];
   Vchar dslink[DATASET_MAXNAME];
   Vint ids[2], nds, ind;
   Vlong lrec, lreclink;
   Vint nrow, ncol, ntyp, nrowlink, ncollink, ntyplink;
   Vint numdatasets;
   Vint type, hist, cplx, sect, enttype, subtype, datatype;
   Vint nqua, iqua[SYS_NQUA_MAX];
   Vchar cqua[DATASET_MAXNAME];
   Vint id1, id2, id3;
   Vfloat *res, *freq;
   Vint maxres, maxdat, maxfreq;
   Vint complexflag;
   Vint iatts[2], natts;
   vdm_Attribute *attribute;
   Vint nodeid;

                   /* determine maximum number of datasets */
   vdm_LibraryGetNumDatasets (library,&numdatasets);

                   /* pointer for returned results data */ 
   res = NULL;
   maxres = 0;
   freq = NULL;
   maxfreq = 0;
                   /* loop over datasets */
   for(i = 0; i < numdatasets; i++) {
      vdm_LibraryGetDataset (library,i,&dataset);

                   /* identify result quantity */ 
      vdm_DatasetResult (dataset,dsroot,&type,&hist,
                         &nqua,iqua,cqua,&cplx,caux,&sect,&enttype,&subtype,
                         &id1,&id2,&id3);
                   /* test for no result */
      if(type == SYS_RES_NONE) {
         continue;
      }
                   /* skip non-history datasets */ 
      if(hist == 0) {
         continue;
      }
                   /* skip anything but mode and panel entities */
      if(enttype != SYS_MODE  &&
         enttype != SYS_PANEL) {
         continue;
      }
                   /* get dataset name and parameters */ 
      vdm_DatasetInq (dataset,dsname,&lrec,&nrow,&ncol,&ntyp);

                   /* get DataType attribute */ 
      vdm_DatasetDataType (dataset,andata,&datatype);

                   /* get Contents attribute */ 
      vdm_DatasetContents (dataset,ancont);

                   /* print dataset name */
      printf("\n\nDataset: %s\n",dsname);

                   /* print DataType and Contents */ 
      printf("DataType: %s\n",andata);
      printf("Contents: %s\n",ancont);

                   /* test overall result type */ 
      if(type == SYS_RES_D) {
         printf("result: Displacement\n");
      } else if(type == SYS_RES_V) {
         printf("result: Velocity\n");
      } else if(type == SYS_RES_A) {
         printf("result: Acceleration\n");
      } else if(type == SYS_RES_PRES) {
         printf("result: Pressure\n");
      }
                   /* test qualifiers */
      for(n = 0; n < nqua; n++) {
         if(iqua[n] == SYS_QUA_TX) {
            printf("qualifier: TX component\n");
         } else if(iqua[n] == SYS_QUA_TY) {
            printf("qualifier: TY component\n");
         } else if(iqua[n] == SYS_QUA_TZ) {
            printf("qualifier: TZ component\n");
         } else if(iqua[n] == SYS_QUA_RX) {
            printf("qualifier: RX component\n");
         } else if(iqua[n] == SYS_QUA_RY) {
            printf("qualifier: RY component\n");
         } else if(iqua[n] == SYS_QUA_RZ) {
            printf("qualifier: RZ component\n");
         } else if(iqua[n] == SYS_QUA_ABS) {
            printf("qualifier: Abs\n");
         } else if(iqua[n] == SYS_QUA_NORM) {
            printf("qualifier: Norm\n");
         } else if(iqua[n] == SYS_QUA_MODAL) {
            printf("qualifier: Modal\n");
         } else if(iqua[n] == SYS_QUA_PANEL) {
            printf("qualifier: Panel\n");
         }
      }
                   /* parse cqua, "Node-n */ 
      if(cqua[0] != '\0') {
         sscanf(&cqua[5],"%d",&nodeid);
         printf("node= %d\n",nodeid);
      }
               /* find link to associated response frequencies */ 
               /* there should be a frequency for each column in the history */
      vdm_DatasetSearchAttribute (dataset,"Link.Frequency",1,iatts,&natts);
      if(natts) {
         vdm_DatasetGetAttribute (dataset,iatts[0],&attribute);
         vdm_AttributeValueString (attribute,dslink);
         vdm_LibrarySearchDataset (library,dslink,1,ids,&nds);
         vdm_LibraryGetDataset (library,ids[0],&datasetlink);
         vdm_DatasetInq (datasetlink,dslink,
                        &lreclink,&nrowlink,&ncollink,&ntyplink);
         maxdat = lreclink*sizeof(Vfloat);
         if(maxdat > maxfreq) {
            maxfreq = maxdat;
            freq = (Vfloat*)realloc(freq,maxfreq*sizeof(Vfloat));
         }
         vdm_DataFunReadDataset (datafun,ids[0],freq);
      }
                   /* compute length of data in dataset */ 
      complexflag = 0;
      maxdat = lrec*sizeof(Vfloat);
      if(cplx == SYS_COMPLEX_REALIMAGINARY ||
         cplx == SYS_COMPLEX_MAGNITUDEPHASE) {
         complexflag = 1;
         maxdat *= 2;
      }
      if(maxdat > maxres) {
         maxres = maxdat;
         res = (Vfloat*)realloc(res,maxres*sizeof(Vfloat));
      }
                   /* read data */ 
      vdm_DataFunReadDataset (datafun,i,res);
      ind = 0;
      for(j = 0; j < ncol; j++) {
         for(k = 0; k < nrow; k++) {
            if(natts) {
               printf("frequency= %e\n",freq[j]);
            }
            if(complexflag == 0) {
               printf("col= %d, row= %d, val= %e\n",j,k,res[ind]);
            } else {
               printf("col= %d, row= %d, val= %e %e(i)\n",
                       j,k,res[2*ind],res[2*ind+1]);
            }
            ind += 1;
         }
      }
   }
                   /* free memory */
   free(res);
   free(freq);
}

7.10. Example 4, Export all Datasets

This example illustrates using the LMan to print the table of contents of all datasets on a library and export the contents of all datasets to file exam4.exp. Exporting the contents of library datasets writes the contents in an ASCII representation. The LMan object accepts a DataFun object as an attribute using vdm_LManSetObject(). This example also illustrates a technique for initializing a DataFun object with one of several possible of external library types.

#include "base/base.h"
#include "vdm/vdm.h"

static Vchar *vdmname[] = {
   "VDM_NATIVE",
   "VDM_LSTC_STATE",
   "VDM_ABAQUS_FILBIN",
   "VDM_ABAQUS_INPUT",
   "VDM_NASTRAN_OUTPUT2",
   "VDM_NASTRAN_BULKDATA",
   "VDM_SDRC_UNIVERSAL",
   "VDM_PAM_DAISY",
   "VDM_ANSYS_RESULT",
   "VDM_MECHANICA_STUDY",
   "VDM_PAT_NEUTRAL",
   NULL };

static Vint vdmtype[] = {
   VDM_NATIVE,
   VDM_LSTC_STATE,
   VDM_ABAQUS_FILBIN,
   VDM_ABAQUS_INPUT,
   VDM_NASTRAN_OUTPUT2,
   VDM_NASTRAN_BULKDATA,
   VDM_SDRC_UNIVERSAL,
   VDM_PAM_DAISY,
   VDM_ANSYS_RESULT,
   VDM_MECHANICA_STUDY,
   VDM_PAT_NEUTRAL };

/*----------------------------------------------------------------------
                      Export all Datasets
----------------------------------------------------------------------*/
int
main(int argc, char **argv)
{
   vdm_LMan *lman;

   vdm_SDRCLib *sdrclib;
   vdm_RASLib  *raslib;
   vdm_D3DLib  *d3dlib;
   vdm_ABALib  *abalib;
   vdm_ABAFil  *abafil;
   vdm_ANSLib  *anslib;
   vdm_NASLib  *naslib;
   vdm_NASFil  *nasfil;
   vdm_PatLib  *patlib;
   vdm_PAMLib  *pamlib;
   vdm_NatLib  *natlib;

   Vint i;
   vdm_DataFun *datafun;
   char inputfile[256];
   Vint filetype;

                   /* determine input file type */ 
   if(argc < 3) {
      fprintf(stderr,"Usage: %s filetype pathname\n",argv[0]);
      fprintf(stderr," VDM_SDRC_UNIVERSAL bumper.unv is assumed\n");
      filetype = VDM_SDRC_UNIVERSAL;
      strcpy(inputfile,"bumper.unv");
   } else {
      for(i = 0; vdmname[i]; i++) {
         if(!strcmp(argv[1],vdmname[i])) {
            filetype = vdmtype[i];
            strcpy(inputfile,argv[2]);
            break;
         }
      }
      if(vdmname[i] == NULL) {
         fprintf(stderr,"Error: %s unrecognized file type\n",argv[0]);
      }
   }

                   /* create data function object */
   datafun = vdm_DataFunBegin ();

                   /* create library device and fill data functions */
   if(filetype == VDM_SDRC_UNIVERSAL) {
      sdrclib = vdm_SDRCLibBegin ();
      vdm_SDRCLibDataFun (sdrclib,datafun);
   } else if(filetype == VDM_MECHANICA_STUDY) {
      raslib = vdm_RASLibBegin ();
      vdm_RASLibDataFun (raslib,datafun);
   } else if(filetype == VDM_LSTC_STATE) {
      d3dlib = vdm_D3DLibBegin ();
      vdm_D3DLibDataFun (d3dlib,datafun);
   } else if(filetype == VDM_ABAQUS_FILBIN) {
      abalib = vdm_ABALibBegin ();
      vdm_ABALibDataFun (abalib,datafun);
   } else if(filetype == VDM_ABAQUS_INPUT) {
      abafil = vdm_ABAFilBegin ();
      vdm_ABAFilDataFun (abafil,datafun);
   } else if(filetype == VDM_ANSYS_RESULT) {
      anslib = vdm_ANSLibBegin ();
      vdm_ANSLibDataFun (anslib,datafun);
   } else if(filetype == VDM_PAT_NEUTRAL) {
      patlib = vdm_PatLibBegin ();
      vdm_PatLibDataFun (patlib,datafun);
   } else if(filetype == VDM_NASTRAN_OUTPUT2) {
      naslib = vdm_NASLibBegin ();
      vdm_NASLibDataFun (naslib,datafun);
   } else if(filetype == VDM_NASTRAN_BULKDATA) {
      nasfil = vdm_NASFilBegin ();
      vdm_NASFilDataFun (nasfil,datafun);
   } else if(filetype == VDM_PAM_DAISY) {
      pamlib = vdm_PAMLibBegin ();
      vdm_PAMLibDataFun (pamlib,datafun);
   } else if(filetype == VDM_NATIVE) {
      natlib = vdm_NatLibBegin ();
      vdm_NatLibDataFun (natlib,datafun);
   }

                   /* open library device */
   vdm_DataFunOpen (datafun,0,inputfile,filetype);

                   /* check for error */ 
   if(vdm_DataFunError(datafun)) {
      fprintf(stderr,"Error: opening file %s\n",inputfile);

                   /* load model */ 
   } else {
      lman = vdm_LManBegin ();
      vdm_LManSetObject (lman,VDM_DATAFUN,datafun);
      vdm_LManSetParami (lman,LMAN_VERBOSE,SYS_ON);
      vdm_LManTOC (lman,"*");
      vdm_LManExport (lman,"*","exam4.exp");
      vdm_LManEnd (lman);
   }
                   /* close library device */ 
   vdm_DataFunClose (datafun);

                   /* free objects */ 
   vdm_DataFunEnd (datafun);

   if(filetype == VDM_SDRC_UNIVERSAL) {
      vdm_SDRCLibEnd (sdrclib);
   } else if(filetype == VDM_MECHANICA_STUDY) {
      vdm_RASLibEnd (raslib);
   } else if(filetype == VDM_LSTC_STATE) {
      vdm_D3DLibEnd (d3dlib);
   } else if(filetype == VDM_ABAQUS_FILBIN) {
      vdm_ABALibEnd (abalib);
   } else if(filetype == VDM_ABAQUS_INPUT) {
      vdm_ABAFilEnd (abafil);
   } else if(filetype == VDM_ANSYS_RESULT) {
      vdm_ANSLibEnd (anslib);
   } else if(filetype == VDM_PAT_NEUTRAL) {
      vdm_PatLibEnd (patlib);
   } else if(filetype == VDM_NASTRAN_OUTPUT2) {
      vdm_NASLibEnd (naslib);
   } else if(filetype == VDM_NASTRAN_BULKDATA) {
      vdm_NASFilEnd (nasfil);
   } else if(filetype == VDM_PAM_DAISY) {
      vdm_PAMLibEnd (pamlib);
   } else if(filetype == VDM_NATIVE) {
      vdm_NatLibEnd (natlib);
   }
   return 0;
}

7.11. Example 5, Open and Append Files

This example illustrates opening a library device and appending additional files. The file type of the opened and appended files is determined by examining the file extension typical of the file type. The first file on the command line is opened. The model and result datasets on the file are listed. The second and subsequent files on the command line are appended. The model datasets of any appended file are ignored. Only the results datasets on the appended files are added to the list of datasets on the library. Note that for some file types, VDM_CGNS for example, there is the possibility of duplicate dataset name due to non-unique identifiers. In the case of VDM_CGNS, use vdm_LibraryMaxIds() to query for the maximum result numeric identifiers and use vdm_DataFunSetIds() to set the base identifier to use for the appended datasets.

#include <stdlib.h>
#include "base/base.h"
#include "vdm/vdm.h"

/*----------------------------------------------------------------------
                      Open and Append Files
----------------------------------------------------------------------*/
int
main(int argc, char **argv)
{
   vdm_LMan *lman;
                   /* primary libraries */ 
   vdm_SDRCLib *sdrclib;
   vdm_RASLib  *raslib;
   vdm_ABALib  *abalib;
   vdm_ABAFil  *abafil;
   vdm_ANSLib  *anslib;
   vdm_ANSFil  *ansfil;
   vdm_D3DFil  *d3dfil;
   vdm_D3DLib  *d3dlib;
   vdm_NASLib  *naslib;
   vdm_NatLib  *natlib;
   vdm_NASFil  *nasfil;
   vdm_STLFil  *stlfil;
   vdm_PAMLib  *pamlib;
   vdm_PatLib  *patlib;
   vdm_PLOT3DLib *plot3dlib;
   vdm_FLUENTLib *fluentlib;
   vdm_CGNSVLib *cgnsvlib;
   vdm_EnSightLib *ensightlib;
   vdm_STARCCMLib *starccmlib;
   vdm_SAMCEFLib *samceflib;
   vdm_TecplotLib *tecplotlib;
   vdm_MarcLib *marclib;
   vdm_DataFun *datafun;
   vdm_Library *library;
   Vint filetype, filetype1;
   Vint ierr;
   Vint i;
   Vint id1, id2, id3;

                   /* determine input file type */ 
   if(argc < 2) {
      fprintf(stderr,"Usage: %s pathname appendpathname\n",argv[0]);
      exit(0);
   }

                   /* create data function object */
   datafun = vdm_DataFunBegin ();

                   /* determine first file type from file extension */
   if(strstr(argv[1],".bdf") != NULL  ||
      strstr(argv[1],".dat") != NULL) {
      filetype = VDM_NASTRAN_BULKDATA;
      nasfil = vdm_NASFilBegin();
      vdm_NASFilDataFun (nasfil,datafun);
   } else if(strstr(argv[1],".op2") != NULL  ||
             strstr(argv[1],".OP2") != NULL) {
      filetype = VDM_NASTRAN_OUTPUT2;
      naslib = vdm_NASLibBegin();
      vdm_NASLibDataFun (naslib,datafun);
   } else if(strstr(argv[1],".rst") != NULL) {
      filetype = VDM_ANSYS_RESULT;
      anslib = vdm_ANSLibBegin();
      vdm_ANSLibDataFun (anslib,datafun);
   } else if(strstr(argv[1],".cdb") != NULL) {
      filetype = VDM_ANSYS_INPUT;
      ansfil = vdm_ANSFilBegin();
      vdm_ANSFilDataFun (ansfil,datafun);
   } else if(strstr(argv[1],".fil") != NULL) {
      filetype = VDM_ABAQUS_FIL;
      abalib = vdm_ABALibBegin();
      vdm_ABALibDataFun (abalib,datafun);
   } else if(strstr(argv[1],".inp") != NULL) {
      filetype = VDM_ABAQUS_INPUT;
      abafil = vdm_ABAFilBegin();
      vdm_ABAFilDataFun (abafil,datafun);
   } else if(strstr(argv[1],".odb") != NULL) {
      filetype = VDM_ABAQUS_ODB;
      abalib = vdm_ABALibBegin();
      vdm_ABALibDataFun (abalib,datafun);
   } else if(strstr(argv[1],".k") != NULL ||
             strstr(argv[1],".key") != NULL  ||
             strstr(argv[1],".dyn") != NULL  ||
             strstr(argv[1],".DYN") != NULL) {
      filetype = VDM_LSTC_INPUT;
      d3dfil = vdm_D3DFilBegin();
      vdm_D3DFilDataFun (d3dfil,datafun);
   } else if(strstr(argv[1],"d3plot") != NULL) {
      filetype = VDM_LSTC_STATE;
      d3dlib = vdm_D3DLibBegin();
      vdm_D3DLibDataFun (d3dlib,datafun);
   } else if(strstr(argv[1],".neu") != NULL) {
      filetype = VDM_MECHANICA_STUDY;
      raslib = vdm_RASLibBegin();
      vdm_RASLibDataFun (raslib,datafun);}
   else if(strstr(argv[1],".des") != NULL) {
      filetype = SYS_SAMCEF;
      samceflib = vdm_SAMCEFLibBegin();
      vdm_SAMCEFLibDataFun (samceflib,datafun);
   } else if(strstr(argv[1],".unv") != NULL  ||
             strstr(argv[1],".bun") != NULL) {
      filetype = VDM_SDRC_UNIVERSAL;
      sdrclib = vdm_SDRCLibBegin();
      vdm_SDRCLibDataFun (sdrclib,datafun);
   } else if(strstr(argv[1],".stl") != NULL) {
      filetype = VDM_STL;
      stlfil = vdm_STLFilBegin();
      vdm_STLFilDataFun (stlfil,datafun);
   } else if(strstr(argv[1],".STL") != NULL) {
      filetype = VDM_STLBIN;
      stlfil = vdm_STLFilBegin();
      vdm_STLFilDataFun (stlfil,datafun);
   } else if(strstr(argv[1],".vdm") != NULL) {
      filetype = VDM_NATIVE;
      natlib = vdm_NatLibBegin();
      vdm_NatLibDataFun (natlib,datafun);
   } else if(strstr(argv[1],".dsy") != NULL  ||
             strstr(argv[1],".DSY") != NULL) {
      filetype = VDM_PAM_DAISY;
      pamlib = vdm_PAMLibBegin();
      vdm_PAMLibDataFun (pamlib,datafun);
   } else if(strstr(argv[1],".out") != NULL) {
      filetype = VDM_PATRAN_NEUTRAL;
      patlib = vdm_PatLibBegin();
      vdm_PatLibDataFun (patlib,datafun);
   } else if(strstr(argv[1],".x") != NULL) {
      filetype = VDM_PLOT3D_GRID;
      plot3dlib = vdm_PLOT3DLibBegin();
      vdm_PLOT3DLibSetGridType (plot3dlib,PLOT3DLIB_MULTIPLE,3,SYS_OFF);
      vdm_PLOT3DLibDataFun (plot3dlib,datafun);
   } else if(strstr(argv[1],".cas") != NULL) {
      filetype = VDM_FLUENT_MESH;
      fluentlib = vdm_FLUENTLibBegin();
      vdm_FLUENTLibDataFun (fluentlib,datafun);
   } else if(strstr(argv[1],".cgns") != NULL) {
      filetype = VDM_CGNS;
      cgnsvlib = vdm_CGNSVLibBegin();
      vdm_CGNSVLibDataFun (cgnsvlib,datafun);
   } else if(strstr(argv[1],".encas") != NULL) {
      filetype = VDM_ENSIGHT;
      ensightlib = vdm_EnSightLibBegin();
      vdm_EnSightLibDataFun (ensightlib,datafun);
   } else if(strstr(argv[1],".ccm") != NULL) {
      filetype = VDM_STARCCM;
      starccmlib = vdm_STARCCMLibBegin();
      vdm_STARCCMLibDataFun (starccmlib,datafun);
   } else if(strstr(argv[1],".plt") != NULL) {
      filetype = VDM_TECPLOT;
      tecplotlib = vdm_TecplotLibBegin();
      vdm_TecplotLibDataFun (tecplotlib,datafun);
   } else if(strstr(argv[1],".t16") != NULL) {
      filetype = VDM_MARC_POST;
      marclib = vdm_MarcLibBegin();
      vdm_MarcLibDataFun (marclib,datafun);
   } else {
      fprintf(stderr,"Error: Bad input file %s\n",argv[1]);
      exit(0);
   }
                   /* set conventions */ 
   vdm_DataFunSetConvention (datafun,VDM_CONVENTION_SPARSE);

                   /* open library device */
   vdm_DataFunOpen (datafun,0,argv[1],filetype);
   vdm_DataFunGetLibrary (datafun,&library);

                   /* check for error */ 
   ierr = vdm_DataFunError(datafun);
   if(ierr) {
      fprintf(stderr,"Error: opening file %s\n",argv[1]);
      exit(0);
   }
                   /* instance lman object */
   lman = vdm_LManBegin ();
   vdm_LManSetObject (lman,VDM_DATAFUN,datafun);
   vdm_LManSetParami (lman,LMAN_VERBOSE,SYS_ON);
   vdm_LManTOC (lman,"*");

                   /* append library devices */
   for(i = 2; i < argc; i++) {
      if(strstr(argv[i],".op2") != NULL  ||
         strstr(argv[i],".OP2") != NULL) {
         filetype1 = VDM_NASTRAN_OUTPUT2;
      } else if(strstr(argv[i],".unv") != NULL  ||
                strstr(argv[i],".bun") != NULL  ||
                strstr(argv[i],".bud") != NULL) {
         filetype1 = VDM_SDRC_UNIVERSAL;
      } else if(strstr(argv[i],".vdm") != NULL) {
         filetype1 = VDM_NATIVE;
      } else if(strstr(argv[i],".dis") != NULL) {
         filetype1 = VDM_PATRAN_RESULT;
      } else if(strstr(argv[i],".q") != NULL) {
         filetype1 = VDM_PLOT3D_SOLUTION;
      } else if(strstr(argv[i],".dat") != NULL ||
                strstr(argv[i],".cas") != NULL) {
         filetype1 = VDM_FLUENT_MESH;
      } else if(strstr(argv[i],".cgns") != NULL) {
         filetype1 = VDM_CGNS;
      } else {
         fprintf(stderr,"Error: Bad input file %s\n",argv[i]);
         exit(0);
      }
                   /* set Ids computation for certain appended file types */ 
      if(filetype1 == VDM_CGNS) {
         vdm_LibraryMaxIds (library,&id1,&id2,&id3);
         vdm_DataFunSetIds (datafun,VDM_IDS_BASE,id1+1,0,0);
      }
      vdm_DataFunAppend (datafun,argv[i],filetype1);

                   /* check for error */ 
      ierr = vdm_DataFunError(datafun);
      if(ierr) {
         fprintf(stderr,"Error: appending file %s to file %s\n",
                 argv[i],argv[1]);
         exit(0);
      }
      vdm_LManTOC (lman,"*");
   }
                   /* now export all datasets */ 
   vdm_LManExport (lman,"*","exam5.exp");
   vdm_LManEnd (lman);

                   /* close library device */ 
   vdm_DataFunClose (datafun);

                   /* free objects */ 
   vdm_DataFunEnd (datafun);

   if(filetype == VDM_NASTRAN_BULKDATA) {
      vdm_NASFilEnd (nasfil);
   } else if(filetype == VDM_SDRC_UNIVERSAL) {
      vdm_SDRCLibEnd (sdrclib);
   } else if(filetype == VDM_MECHANICA_STUDY) {
      vdm_RASLibEnd (raslib);
   } else if(filetype == VDM_ABAQUS_FIL) {
      vdm_ABALibEnd (abalib);
   } else if(filetype == VDM_ABAQUS_INPUT) {
      vdm_ABAFilEnd (abafil);
   } else if(filetype == VDM_ANSYS_RESULT) {
      vdm_ANSLibEnd (anslib);
   } else if(filetype == VDM_ANSYS_INPUT) {
      vdm_ANSFilEnd (ansfil);
   } else if(filetype == VDM_NASTRAN_OUTPUT2) {
      vdm_NASLibEnd (naslib);
   } else if(filetype == VDM_LSTC_INPUT) {
      vdm_D3DFilEnd (d3dfil);
   } else if(filetype == VDM_LSTC_STATE) {
      vdm_D3DLibEnd (d3dlib);
   } else if(filetype == VDM_NATIVE) {
      vdm_NatLibEnd (natlib);
   } else if(filetype == VDM_PAM_DAISY) {
      vdm_PAMLibEnd (pamlib);
   } else if(filetype == VDM_PATRAN_NEUTRAL) {
      vdm_PatLibEnd (patlib);
   } else if(filetype == VDM_PLOT3D_GRID) {
      vdm_PLOT3DLibEnd (plot3dlib);
   } else if(filetype == VDM_FLUENT_MESH) {
      vdm_FLUENTLibEnd (fluentlib);
   } else if(filetype == VDM_CGNS) {
      vdm_CGNSVLibEnd (cgnsvlib);
   } else if(filetype == VDM_SAMCEF) {
      vdm_SAMCEFLibEnd (samceflib);
   } else if(filetype == VDM_ENSIGHT) {
      vdm_EnSightLibEnd (ensightlib);
   } else if(filetype == VDM_STARCCM) {
      vdm_STARCCMLibEnd (starccmlib);
   } else if(filetype == VDM_TECPLOT) {
      vdm_TecplotLibEnd (tecplotlib);
   } else if(filetype == VDM_MARC_POST) {
      vdm_MarcLibEnd (marclib);
   }
   return 0;
}

7.12. Example 5a, Open Files without Model Data

This example illustrates an option to appending results only files. Files which can be appended may also be opened directly if a compatible Connect object has been previously set using vdm_DataFunSetConnect(). This Connect object provides the model context.

In this example two files are opened. The first contains model information, the second does not. The first file is opened and the Model object is loaded using vdm_LManLoadModel() and the Connect object is retrieved using vis_ModelGetObject(). A second DataFun object is instanced for the results only file and the Connect object is set using vdm_DataFunSetConnect(). The second file is then opened. This second DataFun object will only reveal the results datasets contained on the results only file.

Note that the Connect object can come from any source as long it is compatible with the results data.

#include <stdlib.h>
#include "base/base.h"
#include "vdm/vdm.h"

/*----------------------------------------------------------------------
                      Open Files without Model Data
----------------------------------------------------------------------*/
int
main(int argc, char **argv)
{
   vdm_LMan *lman;
                   /* primary libraries */ 
   vdm_SDRCLib *sdrclib, *sdrclib1;
   vdm_RASLib  *raslib;
   vdm_ABALib  *abalib;
   vdm_ABAFil  *abafil;
   vdm_ANSLib  *anslib;
   vdm_ANSFil  *ansfil;
   vdm_D3DLib  *d3dlib;
   vdm_NASLib  *naslib, *naslib1;
   vdm_NatLib  *natlib;
   vdm_NASFil  *nasfil;
   vdm_STLFil  *stlfil;
   vdm_PAMLib  *pamlib;
   vdm_PatLib  *patlib;
   vdm_SAMCEFLib *samceflib;
   vdm_PLOT3DLib *plot3dlib;
   vdm_FLUENTLib *fluentlib;
   vdm_CGNSVLib *cgnsvlib;
   vdm_TecplotLib *tecplotlib;
   vdm_DataFun *datafun, *datafun1;

   vis_Model *model;
   vis_Connect *connect;
   Vint filetype, filetype1;
   Vint ierr;

   if(argc < 2) {
      fprintf(stderr,"Usage: %s modelpathname resultpathname\n",argv[0]);
      exit(0);
   }
                   /* create data function object */
   datafun = vdm_DataFunBegin ();

                   /* determine model file type from file extension */
   if(strstr(argv[1],".bdf") != NULL  ||
      strstr(argv[1],".dat") != NULL) {
      filetype = VDM_NASTRAN_BULKDATA;
      nasfil = vdm_NASFilBegin();
      vdm_NASFilDataFun (nasfil,datafun);
   } else if(strstr(argv[1],".op2") != NULL) {
      filetype = VDM_NASTRAN_OUTPUT2;
      naslib = vdm_NASLibBegin();
      vdm_NASLibDataFun (naslib,datafun);
   } else if(strstr(argv[1],".rst") != NULL) {
      filetype = VDM_ANSYS_RESULT;
      anslib = vdm_ANSLibBegin();
      vdm_ANSLibDataFun (anslib,datafun);
   } else if(strstr(argv[1],".cdb") != NULL) {
      filetype = VDM_ANSYS_INPUT;
      ansfil = vdm_ANSFilBegin();
      vdm_ANSFilDataFun (ansfil,datafun);
   } else if(strstr(argv[1],".fil") != NULL) {
      filetype = VDM_ABAQUS_FIL;
      abalib = vdm_ABALibBegin();
      vdm_ABALibDataFun (abalib,datafun);
   } else if(strstr(argv[1],".inp") != NULL) {
      filetype = VDM_ABAQUS_INPUT;
      abafil = vdm_ABAFilBegin();
      vdm_ABAFilDataFun (abafil,datafun);
   } else if(strstr(argv[1],".odb") != NULL) {
      filetype = VDM_ABAQUS_ODB;
      abalib = vdm_ABALibBegin();
      vdm_ABALibDataFun (abalib,datafun);
   } else if(strstr(argv[1],"d3plot") != NULL) {
      filetype = VDM_LSTC_STATE;
      d3dlib = vdm_D3DLibBegin();
      vdm_D3DLibDataFun (d3dlib,datafun);
   } else if(strstr(argv[1],".neu") != NULL) {
      filetype = VDM_MECHANICA_STUDY;
      raslib = vdm_RASLibBegin();
      vdm_RASLibDataFun (raslib,datafun);
   } else if(strstr(argv[1],".des") != NULL) {
      filetype = SYS_SAMCEF;
      samceflib = vdm_SAMCEFLibBegin();
      vdm_SAMCEFLibDataFun (samceflib,datafun);
   } else if(strstr(argv[1],".unv") != NULL  ||
             strstr(argv[1],".bun") != NULL) {
      filetype = VDM_SDRC_UNIVERSAL;
      sdrclib = vdm_SDRCLibBegin();
      vdm_SDRCLibDataFun (sdrclib,datafun);
   } else if(strstr(argv[1],".stl") != NULL) {
      filetype = VDM_STL;
      stlfil = vdm_STLFilBegin();
      vdm_STLFilDataFun (stlfil,datafun);
   } else if(strstr(argv[1],".STL") != NULL) {
      filetype = VDM_STLBIN;
      stlfil = vdm_STLFilBegin();
      vdm_STLFilDataFun (stlfil,datafun);
   } else if(strstr(argv[1],".vdm") != NULL) {
      filetype = VDM_NATIVE;
      natlib = vdm_NatLibBegin();
      vdm_NatLibDataFun (natlib,datafun);
   } else if(strstr(argv[1],".dsy") != NULL  ||
             strstr(argv[1],".DSY") != NULL) {
      filetype = VDM_PAM_DAISY;
      pamlib = vdm_PAMLibBegin();
      vdm_PAMLibDataFun (pamlib,datafun);
   } else if(strstr(argv[1],".out") != NULL) {
      filetype = VDM_PATRAN_NEUTRAL;
      patlib = vdm_PatLibBegin();
      vdm_PatLibDataFun (patlib,datafun);
   } else if(strstr(argv[1],".x") != NULL) {
      filetype = VDM_PLOT3D_GRID;
      plot3dlib = vdm_PLOT3DLibBegin();
      vdm_PLOT3DLibSetGridType (plot3dlib,PLOT3DLIB_MULTIPLE,3,SYS_OFF);
      vdm_PLOT3DLibDataFun (plot3dlib,datafun);
   } else if(strstr(argv[1],".cas") != NULL) {
      filetype = VDM_FLUENT_MESH;
      fluentlib = vdm_FLUENTLibBegin();
      vdm_FLUENTLibDataFun (fluentlib,datafun);
   } else if(strstr(argv[1],".cgns") != NULL) {
      filetype = VDM_CGNS;
      cgnsvlib = vdm_CGNSVLibBegin();
      vdm_CGNSVLibDataFun (cgnsvlib,datafun);
   } else if(strstr(argv[1],".plt") != NULL) {
      filetype = VDM_TECPLOT;
      tecplotlib = vdm_TecplotLibBegin();
      vdm_TecplotLibDataFun (tecplotlib,datafun);
   } else {
      fprintf(stderr,"Error: Bad input file %s\n",argv[1]);
      exit(0);
   }
                   /* set conventions */ 
   vdm_DataFunSetConvention (datafun,VDM_CONVENTION_SPARSE);

                   /* open library device */
   vdm_DataFunOpen (datafun,0,argv[1],filetype);

                   /* check for error */ 
   ierr = vdm_DataFunError(datafun);
   if(ierr) {
      fprintf(stderr,"Error: opening file %s\n",argv[1]);
      exit(0);
   }
                   /* instance lman object */
   lman = vdm_LManBegin ();
   vdm_LManSetObject (lman,VDM_DATAFUN,datafun);
   vdm_LManSetParami (lman,LMAN_VERBOSE,SYS_ON);
   vdm_LManTOC (lman,"*");

                   /* instance Model object for finite element model */
   model = vis_ModelBegin();
   vdm_LManLoadModel (lman,model);
   vis_ModelGetObject (model,VIS_CONNECT,(Vobject**)&connect);

                   /* create data function object */
   datafun1 = vdm_DataFunBegin ();
                   /* open result library devices */
   if(strstr(argv[2],".op2") != NULL) {
      filetype1 = VDM_NASTRAN_OUTPUT2;
      naslib1 = vdm_NASLibBegin();
      vdm_NASLibDataFun (naslib1,datafun1);
   } else if(strstr(argv[2],".unv") != NULL  ||
             strstr(argv[2],".bun") != NULL  ||
             strstr(argv[2],".bud") != NULL) {
      filetype1 = VDM_SDRC_UNIVERSAL;
      sdrclib1 = vdm_SDRCLibBegin();
      vdm_SDRCLibDataFun (sdrclib1,datafun1);
   } else if(strstr(argv[2],".vdm") != NULL) {
      filetype1 = VDM_NATIVE;
   } else if(strstr(argv[2],".dis") != NULL) {
      filetype1 = VDM_PATRAN_RESULT;
   } else if(strstr(argv[2],".q") != NULL) {
      filetype1 = VDM_PLOT3D_SOLUTION;
   } else if(strstr(argv[2],".dat") != NULL) {
      filetype1 = VDM_FLUENT_MESH;
   } else if(strstr(argv[2],".cgns") != NULL) {
      filetype1 = VDM_CGNS;
   } else {
      fprintf(stderr,"Error: Bad input file %s\n",argv[2]);
      exit(0);
   }
                   /* set conventions */ 
   vdm_DataFunSetConvention (datafun,VDM_CONVENTION_SPARSE);
                   /* set Connect */ 
   vdm_DataFunSetConnect (datafun1,connect);

   vdm_LManSetObject (lman,VDM_DATAFUN,datafun1);
   vdm_DataFunOpen (datafun1,0,argv[2],filetype1);

                   /* check for error */ 
   ierr = vdm_DataFunError(datafun1);
   if(ierr) {
      fprintf(stderr,"Error: opening file %s\n",argv[2]);
      exit(0);
   }
   vdm_LManTOC (lman,"*");
                   /* now export result datasets */ 
   vdm_LManExport (lman,"*","exam5a.exp");

                   /* close library devices */ 
   vdm_DataFunClose (datafun1);
   vdm_DataFunClose (datafun);

                   /* free objects */ 
   vdm_DataFunEnd (datafun1);
   vdm_DataFunEnd (datafun);
   vdm_LManEnd (lman);
   vis_ModelDelete (model);
   vis_ModelEnd (model);

   if(filetype == VDM_SDRC_UNIVERSAL) {
      vdm_SDRCLibEnd (sdrclib);
   } else if(filetype == VDM_MECHANICA_STUDY) {
      vdm_RASLibEnd (raslib);
   } else if(filetype == VDM_ABAQUS_FIL) {
      vdm_ABALibEnd (abalib);
   } else if(filetype == VDM_ABAQUS_INPUT) {
      vdm_ABAFilEnd (abafil);
   } else if(filetype == VDM_ANSYS_RESULT) {
      vdm_ANSLibEnd (anslib);
   } else if(filetype == VDM_ANSYS_INPUT) {
      vdm_ANSFilEnd (ansfil);
   } else if(filetype == VDM_NASTRAN_OUTPUT2) {
      vdm_NASLibEnd (naslib);
   } else if(filetype == VDM_LSTC_STATE) {
      vdm_D3DLibEnd (d3dlib);
   } else if(filetype == VDM_NATIVE) {
      vdm_NatLibEnd (natlib);
   } else if(filetype == VDM_PAM_DAISY) {
      vdm_PAMLibEnd (pamlib);
   } else if(filetype == VDM_SAMCEF) {
      vdm_SAMCEFLibEnd (samceflib);
   } else if(filetype == VDM_PATRAN_NEUTRAL) {
      vdm_PatLibEnd (patlib);
   } else if(filetype == VDM_PLOT3D_GRID) {
      vdm_PLOT3DLibEnd (plot3dlib);
   } else if(filetype == VDM_FLUENT_MESH) {
      vdm_FLUENTLibEnd (fluentlib);
   } else if(filetype == VDM_CGNS) {
      vdm_CGNSVLibEnd (cgnsvlib);
   } else if(filetype == VDM_TECPLOT) {
      vdm_TecplotLibEnd (tecplotlib);
   }
   if(filetype1 == VDM_SDRC_UNIVERSAL) {
      vdm_SDRCLibEnd (sdrclib1);
   } else if(filetype == VDM_NASTRAN_OUTPUT2) {
      vdm_NASLibEnd (naslib1);
   }
   return 0;
}

7.13. Example 6, Read and Print Finite Element Model in Fluent Form

This example illustrates processing input model sources to print them in a Fluent compatible form.

#include <stdlib.h>
#include <math.h>
#include <ctype.h>
#include "base/base.h"
#include "vis/visdata.h"
#include "vdm/vdm.h"

static void
print_fluent(vis_Model *model);
static void
check_2d(vis_Model *model, Vint *flag_2d);
static void
convert_2d(vis_Model *model);
static void
mod_partid_elemset(vis_Model *model);
static void
add_inter_nodeset(vis_Model *model);
static void
add_inter_elementset(vis_Model *model);
static void
process_ensight(vis_Model *model);
static void
process_shelltointer(vis_Model *model);
static void
process_contacttoshell(vis_Model *model);
static void
ignore_periodic1d(vis_Model *model);

/*----------------------------------------------------------------------
                     Read and Print Finite Element Model in Fluent Form
----------------------------------------------------------------------*/
int
main(int argc, char **argv)
{
   Vchar inputfile[256];
   Vchar suffix[256];
   Vint i, slen;

   vdm_NASFil    *nasfil;
   vdm_NASLib    *naslib;
   vdm_NatLib    *natlib;
   vdm_SDRCLib   *sdrclib;
   vdm_ANSFil    *ansfil;
   vdm_ANSLib    *anslib;
   vdm_ABAFil    *abafil;
   vdm_ABALib    *abalib;
   vdm_D3DFil    *d3dfil;
   vdm_D3DLib    *d3dlib;
   vdm_HMAFil    *hmafil;
   vdm_STLFil    *stlfil;
   vdm_PLOT3DLib  *plot3dlib;
   vdm_FLUENTLib  *fluentlib;
   vdm_EnSightLib *ensightlib;
   vdm_TecplotLib *tecplotlib;
   vdm_MarcLib   *marclib;
   vdm_CGNSVLib  *cgnsvlib;
   vdm_PatLib  *patlib;
   vdm_RASLib  *raslib;
   Vint ierr;

   vdm_DataFun   *datafun;
   vdm_LMan      *lman;
   Vint filetype;
   vis_Model *model;
   Vint flag_2d;

                   /* check input arguments */ 
   if(argc < 2) {
      fprintf(stderr,"Usage: %s inputfile\n",argv[0]);
      fprintf(stderr," inputfile is blank, 'cantilever.unv' is assumed\n");
      strcpy(inputfile,"cantilever.unv");
   } else {
      strcpy(inputfile,argv[1]);
   }
                   /* find suffix */ 
   slen = (Vint)strlen(inputfile);
   for(i = slen-2; i != 0; i--) {
      if(inputfile[i] == '.') {
         strcpy(suffix,&inputfile[i]);
         break;
      }
   }
                   /* create data function object */
   datafun = vdm_DataFunBegin ();

                   /* determine file type from file extension */
   if(strstr(suffix,".unv") != NULL) {
      filetype = VDM_SDRC_UNIVERSAL;
      sdrclib = vdm_SDRCLibBegin ();
      vdm_SDRCLibDataFun (sdrclib,datafun);
   } else if(strstr(suffix,".dat") != NULL  ||
             strstr(suffix,".bdf") != NULL  ||
             strstr(suffix,".nas") != NULL) {
      filetype = VDM_NASTRAN_BULKDATA;
      nasfil = vdm_NASFilBegin ();
      vdm_NASFilDataFun (nasfil,datafun);
   } else if(strstr(suffix,".op2") != NULL) {
      filetype = VDM_NASTRAN_OUTPUT2;
      naslib = vdm_NASLibBegin ();
      vdm_NASLibDataFun (naslib,datafun);
   } else if(strstr(suffix,".vdm") != NULL) {
      filetype = VDM_NATIVE;
      natlib = vdm_NatLibBegin ();
      vdm_NatLibDataFun (natlib,datafun);
   } else if(strstr(suffix,".cdb") != NULL  ||
             strstr(suffix,".ans") != NULL) {
      filetype = VDM_ANSYS_INPUT;
      ansfil = vdm_ANSFilBegin ();
      vdm_ANSFilDataFun (ansfil,datafun);
   } else if(strstr(suffix,".rst") != NULL  ||
             strstr(suffix,".rth") != NULL  ||
             strstr(suffix,".rmg") != NULL  ||
             strstr(suffix,".rfl") != NULL) {
      filetype = VDM_ANSYS_RESULT;
      anslib = vdm_ANSLibBegin ();
      vdm_ANSLibDataFun (anslib,datafun);
   } else if(strstr(suffix,".inp") != NULL) {
      filetype = VDM_ABAQUS_INPUT;
      abafil = vdm_ABAFilBegin ();
      vdm_ABAFilDataFun (abafil,datafun);
   } else if(strstr(suffix,".fil") != NULL) {
      filetype = VDM_ABAQUS_FIL;
      abalib = vdm_ABALibBegin ();
      vdm_ABALibDataFun (abalib,datafun);
   } else if(strstr(suffix,".odb") != NULL) {
      filetype = VDM_ABAQUS_ODB;
      abalib = vdm_ABALibBegin ();
      vdm_ABALibDataFun (abalib,datafun);
   } else if(strstr(suffix,".k")   != NULL  ||
             strstr(suffix,".dyn") != NULL) {
      filetype = VDM_LSTC_INPUT;
      d3dfil = vdm_D3DFilBegin();
      vdm_D3DFilDataFun (d3dfil,datafun);
   } else if(strstr(suffix,"d3plot") != NULL ||
             strstr(suffix,"D3PLOT") != NULL) {
      filetype = VDM_LSTC_STATE;
      d3dlib = vdm_D3DLibBegin();
      vdm_D3DLibDataFun (d3dlib,datafun);
   } else if(strstr(suffix,".hma") != NULL) {
      filetype = VDM_HYPERMESH_ASCII;
      hmafil = vdm_HMAFilBegin();
      vdm_HMAFilDataFun (hmafil,datafun);
   } else if(strstr(suffix,".stl") != NULL) {
      filetype = VDM_STL;
      stlfil = vdm_STLFilBegin();
      vdm_STLFilDataFun (stlfil,datafun);
   } else if(strstr(suffix,".STL") != NULL) {
      filetype = VDM_STLBIN;
      stlfil = vdm_STLFilBegin();
      vdm_STLFilDataFun (stlfil,datafun);
   } else if(strstr(suffix,".x") != NULL  ||
             strstr(suffix,".xyz") != NULL ||
             strstr(suffix,".p3d") != NULL ||
             strstr(suffix,".bin") != NULL ||
             strstr(suffix,".grd") != NULL) {
      filetype = VDM_PLOT3D_GRID;
      plot3dlib = vdm_PLOT3DLibBegin();
      vdm_PLOT3DLibDataFun (plot3dlib,datafun);
   } else if(strstr(suffix,".case") != NULL ||
             strstr(suffix,".encas") != NULL) {
      filetype = VDM_ENSIGHT;
      ensightlib = vdm_EnSightLibBegin();
      vdm_EnSightLibDataFun (ensightlib,datafun);
   } else if(strstr(suffix,".plt") != NULL) {
      filetype = VDM_TECPLOT;
      tecplotlib = vdm_TecplotLibBegin();
      vdm_TecplotLibDataFun (tecplotlib,datafun);
   } else if(strstr(suffix,".cas") != NULL ||
             strstr(suffix,".msh") != NULL) {
      filetype = VDM_FLUENT_MESH;
      fluentlib = vdm_FLUENTLibBegin();
      vdm_FLUENTLibDataFun (fluentlib,datafun);
   } else if(strstr(suffix,".t16") != NULL ||
             strstr(suffix,".t19") != NULL) {
      filetype = VDM_MARC_POST;
      marclib = vdm_MarcLibBegin();
      vdm_MarcLibDataFun (marclib,datafun);
   } else if(strstr(suffix,".cgns") != NULL) {
      filetype = VDM_CGNS;
      cgnsvlib = vdm_CGNSVLibBegin();
      vdm_CGNSVLibDataFun (cgnsvlib,datafun);
   } else if(strstr(suffix,".out") != NULL) {
      filetype = VDM_PATRAN_NEUTRAL;
      patlib = vdm_PatLibBegin();
      vdm_PatLibDataFun (patlib,datafun);
   } else if(strstr(suffix,".neu") != NULL) {
      filetype = VDM_MECHANICA_STUDY;
      raslib = vdm_RASLibBegin();
      vdm_RASLibDataFun (raslib,datafun);
   } else {
      fprintf(stderr,"Error: Bad input file %s\n",inputfile);
      exit(1);
   }
                   /* double precision is used to represent node location */ 
   vdm_DataFunSetConvention (datafun,
                             VDM_CONVENTION_DOUBLE|
                             VDM_CONVENTION_CONVERTPOLY);
                   /* open library device */
   vdm_DataFunOpen (datafun,0,inputfile,filetype);

                   /* check for error */
   ierr = vdm_DataFunError(datafun);
   if(ierr) {
      fprintf(stderr,"Error: opening file %s\n",inputfile);
      goto labelcleanup;
   }
                   /* instance Model object for finite element model */ 
   model = vis_ModelBegin();

                   /* use Library Manager object to load model */ 
   lman = vdm_LManBegin ();
   vdm_LManSetObject (lman,VDM_DATAFUN,datafun);
   vdm_LManLoadModel (lman,model);

                   /* check for 2D */
   check_2d (model,&flag_2d);
                   /* force conversion to 2D */
   if(flag_2d) {
      convert_2d (model);
   }
                   /* ignore CGNS periodic 1D line elements */
   if(filetype == VDM_CGNS) {
      ignore_periodic1d (model);
   }
                   /* modify partid by element set,
                      add interface elements for each node set */ 
   if(filetype == VDM_SDRC_UNIVERSAL ||
      filetype == VDM_PATRAN_NEUTRAL) {
      mod_partid_elemset (model);
      add_inter_nodeset (model);
   }
                   /* add interface elements for each node set */ 
   if(filetype == VDM_ABAQUS_INPUT ||
      filetype == VDM_ANSYS_INPUT) {
      add_inter_nodeset (model);
   }
   if(filetype == VDM_ANSYS_RESULT) {
      process_contacttoshell (model);
   }
                   /* Ensight file, merge nodes, convert shell to interface */ 
   if(filetype == VDM_ENSIGHT) {
      process_ensight (model);
      process_shelltointer (model);
   }
                   /* NASTRAN .bdf file, convert shell to interface */
   if(filetype == VDM_NASTRAN_BULKDATA ||
      filetype == VDM_TECPLOT ||
      filetype == VDM_CGNS) {
      process_shelltointer (model);
   }
                   /* add interface elements for each element entity set */ 
   if(filetype == VDM_CGNS ||
      filetype == VDM_PLOT3D_GRID ||
      filetype == VDM_STARCCM ||
      filetype == VDM_FLUENT_MESH) {
      add_inter_elementset (model);
   }
                   /* traverse Model and print in Fluent form */ 
   print_fluent (model);
                   /* delete objects in Model created by LManLoadModel */ 
   vis_ModelDelete (model);
   vdm_LManEnd (lman);
   vis_ModelEnd (model);

                   /* close library device */
labelcleanup:;
   vdm_DataFunClose (datafun);

                   /* free objects */ 
   vdm_DataFunEnd (datafun);
   if(filetype == VDM_SDRC_UNIVERSAL) {
      vdm_SDRCLibEnd (sdrclib);
   } else if(filetype == VDM_NASTRAN_BULKDATA) {
      vdm_NASFilEnd (nasfil);
   } else if(filetype == VDM_NASTRAN_OUTPUT2) {
      vdm_NASLibEnd (naslib);
   } else if(filetype == VDM_NATIVE) {
      vdm_NatLibEnd (natlib);
   } else if(filetype == VDM_ANSYS_INPUT) {
      vdm_ANSFilEnd (ansfil);
   } else if(filetype == VDM_ANSYS_RESULT) {
      vdm_ANSLibEnd (anslib);
   } else if(filetype == VDM_ABAQUS_INPUT) {
      vdm_ABAFilEnd (abafil);
   } else if(filetype == VDM_ABAQUS_FIL  ||
             filetype == VDM_ABAQUS_ODB) {
      vdm_ABALibEnd (abalib);
   } else if(filetype == VDM_LSTC_INPUT) {
      vdm_D3DFilEnd (d3dfil);
   } else if(filetype == VDM_LSTC_STATE) {
      vdm_D3DLibEnd (d3dlib);
   } else if(filetype == VDM_HYPERMESH_ASCII) {
      vdm_HMAFilEnd (hmafil);
   } else if(filetype == VDM_STL ||
             filetype == VDM_STLBIN) {
      vdm_STLFilEnd (stlfil);
   } else if(filetype == VDM_PLOT3D_GRID) {
      vdm_PLOT3DLibEnd (plot3dlib);
   } else if(filetype == VDM_FLUENT_MESH) {
      vdm_FLUENTLibEnd (fluentlib);
   } else if(filetype == VDM_ENSIGHT) {
      vdm_EnSightLibEnd (ensightlib);
   } else if(filetype == VDM_TECPLOT) {
      vdm_TecplotLibEnd (tecplotlib);
   } else if(filetype == VDM_MARC_POST) {
      vdm_MarcLibEnd (marclib);
   } else if(filetype == VDM_CGNS) {
      vdm_CGNSVLibEnd (cgnsvlib);
   } else if(filetype == VDM_PATRAN_NEUTRAL) {
      vdm_PatLibEnd (patlib);
   } else if(filetype == VDM_MECHANICA_STUDY) {
      vdm_RASLibEnd (raslib);
   }
   return 0;
}

/*----------------------------------------------------------------------
                      check 2d
----------------------------------------------------------------------*/
static void
check_2d(vis_Model *model, Vint *flag_2d)
{
   Vint n;
   vis_Connect *connect;
   Vint numnp, numel, ndim;
   Vint shape, maxi, maxj, maxk;
   Vdouble x[3];

   *flag_2d = 0;
                   /* get connect object */ 
   vis_ModelGetObject (model,VIS_CONNECT,(Vobject**)&connect);
                   /* check for 2D */ 
   vis_ConnectDimension (connect,&ndim);
   if(ndim == 2) {
      return;
   }
                   /* 3D, check for 2D */ 
   vis_ConnectNumber (connect,SYS_ELEM,&numel);
                   /* 3D shapes */ 
   for(n = 1; n <= numel; n++) {
      vis_ConnectTopology (connect,n,&shape,&maxi,&maxj,&maxk);
      if(shape == SYS_SHAPETET ||
         shape == SYS_SHAPEPYR ||
         shape == SYS_SHAPEWED ||
         shape == SYS_SHAPEHEX ||
         shape == SYS_SHAPEPOLYHED) {
         return;
      }
   }
                   /* no 3D shapes, check for zero or very small z coordinate */ 
   vis_ConnectNumber (connect,SYS_NODE,&numnp);
   for(n = 1; n <= numnp; n++) {
      vis_ConnectCoordsdv (connect,1,&n,(Vdouble(*)[3])x);
      if(fabs(x[2]) > 1.e-12) {
         return;
      }
   }
   *flag_2d = 1;
}

/*----------------------------------------------------------------------
                      convert 2d
----------------------------------------------------------------------*/
static void
convert_2d(vis_Model *model)
{
   Vint n;
   vis_Connect *connect;
   Vint numel;
   Vint shape, maxi, maxj, maxk;
   Vint featype;
                   /* get connect object */ 
   vis_ModelGetObject (model,VIS_CONNECT,(Vobject**)&connect);
                   /* set 2D */
   vis_ConnectSetDimension (connect,2);
                   /* find out current number of elements */
   vis_ConnectNumber (connect,SYS_ELEM,&numel);
                   /* loop through elements */
                   /* convert 2d shells and membranes to solids */
                   /* convert 1d beams and trusses to interfaces */
   for(n = 1; n <= numel; n++) {
      vis_ConnectTopology (connect,n,&shape,&maxi,&maxj,&maxk);
      vis_ConnectElemAssoc (connect,VIS_FEATYPE,1,&n,&featype);
      if((featype == VIS_ELEM_SHELL || featype == VIS_ELEM_MEMBRANE) &&
         (shape == VIS_SHAPETRI  ||  shape == VIS_SHAPEQUAD)) {
         vis_ConnectSetElemAssoc (connect,VIS_FEATYPE,n,SYS_ELEM_SOLID);
         vis_ConnectSetElemAssoc (connect,VIS_FEASPEC,n,0);
      }
      if((featype == VIS_ELEM_BEAM  || featype == VIS_ELEM_TRUSS) &&
          shape == VIS_SHAPELINE) {
         vis_ConnectSetElemAssoc (connect,VIS_FEATYPE,n,SYS_ELEM_INTER);
         vis_ConnectSetElemAssoc (connect,VIS_FEASPEC,n,SYS_INTER_WALL);
      }
   }
}

/*----------------------------------------------------------------------
                      modify part id for each element set
----------------------------------------------------------------------*/
static void
mod_partid_elemset(vis_Model *model)
{
   Vint n, m;
   Vint numel;
   Vint id;
   vsy_HashTable *esethash;
   vis_Connect *connect;
   vis_IdTran *idtran;
   Vint iset;
   Vint numindices;
   Vchar name[256];
   Vint maxpartid, partid;

                   /* get connect object */
   vis_ModelGetObject (model,VIS_CONNECT,(Vobject**)&connect);
   vis_ConnectNumber (connect,SYS_ELEM,&numel);
                   /* get hashtable of elem sets */
   vis_ModelGetHashTable (model,VIS_IDTRAN_ELEM,&esethash);
   if(esethash == NULL)  return;
                   /* find highest partid */ 
   maxpartid = 0;
   for(m = 1; m <= numel; m++) {
      vis_ConnectElemAssoc (connect,VIS_PARTID,1,&m,&partid);
      if(partid > maxpartid)  maxpartid = partid;
   }
                   /* loop through elem sets */
   vsy_HashTableInitIter (esethash);
   while(vsy_HashTableNextIter(esethash,&iset,(Vobject**)&idtran),idtran) {
      vis_IdTranGetName (idtran,name);
      maxpartid += 1;
      vis_ConnectSetPartName (connect,maxpartid,name);
      vis_IdTranCount (idtran,IDTRAN_NUMINDICES,&numindices);
      for(n = 1; n <= numindices; n++) {
         vis_IdTranGetId (idtran,n,&id);
         vis_ConnectSetElemAssoc (connect,VIS_PARTID,id,maxpartid);
      }
   }
}

/*----------------------------------------------------------------------
                      ignore periodic 1D elements
----------------------------------------------------------------------*/
static void
ignore_periodic1d(vis_Model *model)
{
   vis_Connect *connect;
   Vint numel, n, featype, feaspec;

   vis_ModelGetObject (model,VIS_CONNECT,(Vobject**)&connect);
   vis_ConnectNumber (connect,SYS_ELEM,&numel);
   for(n = 1; n <= numel; ++n) {
      vis_ConnectElemAssoc (connect,VIS_FEATYPE,1,&n,&featype);
      vis_ConnectElemAssoc (connect,VIS_FEASPEC,1,&n,&feaspec);
      if(featype == SYS_ELEM_INTER && feaspec == SYS_INTER_PERIODIC) {
         vis_ConnectSetElemAssoc (connect,VIS_FEATYPE,n,SYS_ELEM_UNDEFINED);
      }
   }
}

/*----------------------------------------------------------------------
                      add interface elements for each node set
----------------------------------------------------------------------*/
static void
add_inter_nodeset(vis_Model *model)
{
   Vint i, j, n;
   vsy_HashTable *nsethash;
   vis_Connect *connect;
   vis_IdTran *idtran;
   Vint iset;
   Vint numnp, numel;
   Vint ndim;
   Vint index;
   Vint surftype, nfaces;
   vis_Group *groupsurf, *groupfree, *groupnode;
   Vint nix;
   Vint ix[VIS_MAXCELLNODE];
   Vint shape, maxi, maxj;
   Vint iwhole, numset, imatch;
   Vint featype, feaspec;
   Vint intel, newel;
   Vint namelen;
   Vchar name[256], namelow[256], namestg[256];
   Vint numpar, numchd;
   Vint maxpartid, partid;

                   /* get connect object */ 
   vis_ModelGetObject (model,VIS_CONNECT,(Vobject**)&connect);
                   /* get hashtable of node sets */ 
   vis_ModelGetHashTable (model,VIS_IDTRAN_NODE,&nsethash);
   if(nsethash == NULL)  return;

                   /* find out current number of nodes and elements */ 
   vis_ConnectNumber (connect,SYS_NODE,&numnp);
   vis_ConnectNumber (connect,SYS_ELEM,&numel);

                   /* determine spatial dimension and surface type */ 
   vis_ConnectDimension (connect,&ndim);
   if(ndim == 2) {
      surftype = SYS_EDGE;
   } else {
      surftype = SYS_FACE;
   }
                   /* generate kernel */ 
   vis_ConnectKernel (connect,0);

                   /* generate working node groups */ 
   groupnode = vis_GroupBegin ();
   vis_GroupDef (groupnode,numnp,SYS_NODE,SYS_NONE);

                   /* generate group of surface element faces */ 
   groupsurf = vis_GroupBegin ();
   vis_GroupDef (groupsurf,numel,SYS_ELEM,surftype);
   groupfree = vis_GroupBegin ();
   vis_GroupDef (groupfree,numel,SYS_ELEM,surftype);
   if(surftype == SYS_EDGE) {
      vis_ConnectEdgeGroup (connect,CONNECT_ELEM,NULL,groupsurf);
   } else {
      vis_ConnectFaceGroup (connect,CONNECT_ELEM,NULL,groupsurf);
   }
   vis_GroupCount (groupsurf,&numpar,&numchd);

                   /* no surface elements so use solid element faces */ 
   if(numpar == 0) {
      if(surftype == SYS_EDGE) {
         vis_ConnectEdgeGroup (connect,CONNECT_UNIQUE,NULL,groupsurf);
         vis_ConnectEdgeGroup (connect,CONNECT_FREE,NULL,groupfree);
      } else {
         vis_ConnectFaceGroup (connect,CONNECT_UNIQUE,NULL,groupsurf);
         vis_ConnectFaceGroup (connect,CONNECT_FREE,NULL,groupfree);
      }
   }
                   /* find highest partid */ 
   maxpartid = 0;
   for(n = 1; n <= numel; n++) {
      vis_ConnectElemAssoc (connect,VIS_PARTID,1,&n,&partid);
      if(partid > maxpartid)  maxpartid = partid;
   }

   newel = numel;
                   /* loop through node sets */ 
   vsy_HashTableInitIter (nsethash);
   while(vsy_HashTableNextIter(nsethash,&iset,(Vobject**)&idtran),idtran) {
                   /* convert idtran to group for performance */ 
      vis_GroupClear (groupnode);
      vis_GroupIdTran (groupnode,idtran);
      iwhole = 1;
                   /* process node sets which do not reference entire solid */
      for(n = 1; n <= numel; n++) {
         vis_ConnectElemAssoc (connect,VIS_FEATYPE,1,&n,&featype);
         if(featype != SYS_ELEM_SOLID)  continue;
                   /* check to see if node set covers whole element */ 
         numset = 0;
         vis_ConnectElemNode (connect,n,&nix,ix);
         for(i = 0; i < nix; i++) {
            vis_GroupGetIndex (groupnode,ix[i],&index);
            if(index)  numset += 1;
         }
         if(numset != nix) {
            iwhole = 0;
            break;
         }
      }
      if(iwhole)  continue;

                   /* set interface special type */ 
      vis_IdTranGetName (idtran,name);

                   /* convert name to lower case */ 
                   /* convert _ to - */
      namelen = (int)strlen(name);
      for(i = 0; i < namelen; i++) {
         namelow[i] = tolower(name[i]);
         if(namelow[i] == '_')  namelow[i] = '-';
      }
                   /* set names from IDEAS and rampant export */ 
      if(strncmp(namelow,"symmetry",8) == 0) {
         feaspec = SYS_INTER_SYMMETRY;
      } else if(strncmp(namelow,"inlet",5) == 0 ||
                strncmp(namelow,"pinlet",6) == 0 ||
                strncmp(namelow,"pressure-inlet",14) == 0) {
         feaspec = SYS_INTER_INLET;
      } else if(strncmp(namelow,"outlet",6) == 0 ||
                strncmp(namelow,"poutlet",7) == 0 ||
                strncmp(namelow,"pressure-outlet",15) == 0) {
         feaspec = SYS_INTER_OUTLET;
      } else if(strncmp(namelow,"fan",3) == 0) {
         feaspec = SYS_INTER_FAN;
      } else if(strncmp(namelow,"velocity-inlet",14) == 0 ||
                strncmp(namelow,"vinlet",6) == 0) {
         feaspec = SYS_INTER_INLET_VELOCITY;
      } else if(strncmp(namelow,"outflow",7) == 0) {
         feaspec = SYS_INTER_OUTFLOW;
      } else {
         feaspec = SYS_INTER_WALL;
      }
      if(strncmp(namelow,"interior",8) == 0) {
         continue;
      }
                   /* create and set name */ 
      sprintf(namestg,"%s",name);
      maxpartid += 1;
      vis_ConnectSetPartName (connect,maxpartid,namestg);

                   /* loop through unique element faces */
      for(n = 1; n <= numel; n++) {
         if(vis_GroupElem(groupsurf,n) == 0)  continue;
         vis_ConnectElemNum (connect,surftype,n,&nfaces);

                   /* loop through element faces */
         for(j = 1; j <= nfaces; j++) {
            if(vis_GroupElemEnt(groupsurf,n,j) == 0)  continue;
            if(numpar == 0) {
               if(vis_GroupElemEnt(groupfree,n,j) == 0)  continue;
            }
            vis_ConnectElemCon (connect,surftype,n,j,&nix,ix);

                   /* check each node on face for match in node set */ 
            imatch = 1;
            for(i = 0; i < nix; i++) {
               vis_GroupGetIndex (groupnode,ix[i],&index);
               if(index == 0) {
                  imatch = 0;
                  break;
               }
            }
            if(imatch == 0)  continue;
                   /* create interface element */ 
            if(nfaces != 1) {
               vis_ConnectElemTopo (connect,surftype,n,j,&shape,&maxi,&maxj);
               newel += 1;
               vis_ConnectSetTopology (connect,newel,shape,maxi,maxj,0);
               vis_ConnectSetElemNode (connect,newel,ix);
               intel = newel;
            } else {
               intel = n;
            }
            vis_ConnectSetElemAssoc (connect,VIS_FEATYPE,intel,SYS_ELEM_INTER);
            vis_ConnectSetElemAssoc (connect,VIS_FEASPEC,intel,feaspec);
            vis_ConnectSetElemAssoc (connect,VIS_PARTID,intel,maxpartid);
         }
      }
   }
                   /* destroy objects */ 
   vis_GroupEnd (groupsurf);
   vis_GroupEnd (groupfree);
   vis_GroupEnd (groupnode);
}

/*----------------------------------------------------------------------
                      add interface elements for each element entity set
----------------------------------------------------------------------*/
static void
add_inter_elementset(vis_Model *model)
{
   Vint i, n;
   vsy_HashTable *eenthash;
   vis_Connect *connect;
   Vint numel;
   Vint iset;
   vis_IdTran *idtran;
   Vint nument, enttype, subtype;
   Vint featype, feaspec, partid, maxpartid;
   Vint id, no;
   Vint shape, maxi, maxj;
   Vint nix;
   Vint ix[VIS_MAXCELLNODE];
   Vchar name[256];

                   /* get connect object */
   vis_ModelGetObject (model,VIS_CONNECT,(Vobject**)&connect);
   vis_ConnectNumber (connect,SYS_ELEM,&numel);
                   /* get hashtable of elem sets */
   vis_ModelGetHashTable (model,VIS_IDTRAN_ELEMENT,&eenthash);
   if(eenthash == NULL)  return;

                   /* find highest partid */
   maxpartid = 0;
   for(n = 1; n <= numel; n++) {
      vis_ConnectElemAssoc (connect,VIS_PARTID,1,&n,&partid);
      if(partid > maxpartid)  maxpartid = partid;
   }
                   /* loop through element entity sets */
   vsy_HashTableInitIter (eenthash);
   while(vsy_HashTableNextIter(eenthash,&iset,(Vobject**)&idtran),idtran) {
      vis_IdTranGetName (idtran,name);
      vis_IdTranGetEntType (idtran,&enttype,&subtype);
      vis_IdTranGetType (idtran,&featype);
      vis_IdTranGetSpec (idtran,&feaspec);
      maxpartid += 1;
      vis_ConnectSetPartName (connect,maxpartid,name);
      vis_IdTranInq (idtran,&nument);
      for(i = 1; i <= nument; i++) {
         vis_IdTranGetId (idtran,i,&id);
         vis_IdTranGetEnt (idtran,i,&no);
         vis_ConnectElemTopo (connect,subtype,id,no,&shape,&maxi,&maxj);
         vis_ConnectElemCon (connect,subtype,id,no,&nix,ix);
         numel += 1;
         vis_ConnectSetTopology (connect,numel,shape,maxi,maxj,0);
         vis_ConnectSetElemNode (connect,numel,ix);
         vis_ConnectSetElemAssoc (connect,VIS_FEATYPE,numel,featype);
         vis_ConnectSetElemAssoc (connect,VIS_FEASPEC,numel,feaspec);
         vis_ConnectSetElemAssoc (connect,VIS_PARTID,numel,maxpartid);
      }
   }
}

/*----------------------------------------------------------------------
                      merge nodes and change shell elements to interfaces
----------------------------------------------------------------------*/
static void
process_ensight(vis_Model *model)
{
   vis_Connect *connect;

   vis_ModelGetObject (model,VIS_CONNECT,(Vobject**)&connect);
                   /* merge all coincident nodes */ 
   vis_ConnectSetParamf (connect,CONNECT_TOLERANCE,.0000001);
   vis_ConnectMerge (connect,NULL);
}

/*----------------------------------------------------------------------
                      change shell elements to interfaces
----------------------------------------------------------------------*/
static void
process_shelltointer(vis_Model *model)
{
   Vint i, n;
   Vint numel, featype, feaspec, partid;
   vis_Connect *connect;
   Vint namelen;
   Vchar name[256], namelow[256];

   vis_ModelGetObject (model,VIS_CONNECT,(Vobject**)&connect);
                   /* change shell elements to interface elements */ 
   vis_ConnectNumber (connect,SYS_ELEM,&numel);
   for(n = 1; n <= numel; n++) {
      vis_ConnectElemAssoc (connect,VIS_FEATYPE,1,&n,&featype);
      vis_ConnectElemAssoc (connect,VIS_PARTID,1,&n,&partid);
                   /* shell and inter only */ 
      if(featype != SYS_ELEM_SHELL && featype != SYS_ELEM_INTER)  continue;
                   /* no partid */ 
      if(partid == 0)  continue;
      vis_ConnectPartName (connect,partid,name);
      namelen = (int)strlen(name);
      for(i = 0; i < namelen; i++) {
         namelow[i] = tolower(name[i]);
      }
      vis_ConnectElemAssoc (connect,VIS_FEASPEC,1,&n,&feaspec);
      if(strncmp(namelow,"sym",3) == 0 ||
         strncmp(namelow,"symmetry",8) == 0) {
         feaspec = SYS_INTER_SYMMETRY;
      } else if(strncmp(namelow,"pi",2) == 0 ||
                strncmp(namelow,"inlet",5) == 0  ||
                strncmp(namelow,"pinlet",6) == 0 ||
                strncmp(namelow,"pressure-inlet",14) == 0){
        feaspec = SYS_INTER_INLET_PRESSURE;
      } else if(strncmp(namelow,"po",2) == 0 ||
                strncmp(namelow,"outlet",6) == 0  ||
                strncmp(namelow,"poutlet",7) == 0 ||
                strncmp(namelow,"pressure-outlet",15) == 0) {
        feaspec = SYS_INTER_OUTLET_PRESSURE;
      } else if(strncmp(namelow,"fan",3) == 0) {
        feaspec = SYS_INTER_FAN;
      } else if(strncmp(namelow,"vinlet",6) == 0         ||
                strncmp(namelow,"velocity-inlet",14) == 0){
        feaspec = SYS_INTER_INLET_VELOCITY;
      } else if(strncmp(namelow,"outflow",7) == 0) {
        feaspec = SYS_INTER_OUTFLOW;
      } else if(strncmp(namelow,"inte",4) == 0 ||
                strncmp(namelow,"baff",4) == 0 ||
                strncmp(namelow,"peri",4) == 0 ||
                strncmp(namelow,"interface",9)== 0){
        feaspec = SYS_INTER_INTERFACE;
      } else if(strncmp(namelow,"mass",4) == 0 ||
                strncmp(namelow,"mass-flow-inlet",15) == 0){
        feaspec = SYS_INTER_INLET_MASSFLOW;
      } else if(strncmp(namelow,"axis",4) == 0){
        feaspec = SYS_INTER_AXIS;
      } else if(strncmp(namelow,"fan",3) == 0) {
        feaspec = SYS_INTER_FAN;
      } else if(strncmp(namelow,"pfield",6) == 0 ||
                strncmp(namelow,"pressure-far-field",12) == 0){
        feaspec = SYS_INTER_PRESSURE_FARFIELD;
      } else if(featype == SYS_ELEM_SHELL) {
         feaspec = SYS_INTER_WALL;
      }
      if(featype == SYS_ELEM_SHELL) {
         vis_ConnectSetElemAssoc (connect,VIS_FEATYPE,n,SYS_ELEM_INTER);
      }
      vis_ConnectSetElemAssoc (connect,VIS_FEASPEC,n,feaspec);
   }
}

/*----------------------------------------------------------------------
                      change contact elements to plot
----------------------------------------------------------------------*/
static void
process_contacttoshell(vis_Model *model)
{
   Vint n;
   Vint numel, featype, feaspec;
   vis_Connect *connect;

   vis_ModelGetObject (model,VIS_CONNECT,(Vobject**)&connect);
                   /* change shell elements to interface elements */ 
   vis_ConnectNumber (connect,SYS_ELEM,&numel);
   for(n = 1; n <= numel; n++) {
      vis_ConnectElemAssoc (connect,VIS_FEATYPE,1,&n,&featype);
      vis_ConnectElemAssoc (connect,VIS_FEASPEC,1,&n,&feaspec);
      if(featype == SYS_ELEM_INTER && feaspec == SYS_INTER_CONTACT) {
         vis_ConnectSetElemAssoc (connect,VIS_FEATYPE,n,SYS_ELEM_SHELL);
         vis_ConnectSetElemAssoc (connect,VIS_FEASPEC,n,0);
      }
   }
}

/*----------------------------------------------------------------------
                      traverse and print in Fluent form
----------------------------------------------------------------------*/
static void
print_fluent(vis_Model *model)
{
   Vint i, j, k;
   vdm_FLUENTLib *fluentlibw;
   Vint ndim;
   Vint numcell, numface, numnode;
   Vint numcellzone, numfacezone;
   Vint zoneid, ifirst, ilast, type, etype, ftype;
   Vint num, nfx, nx, lenv;
   Vint *e, *v, *cr, *cl;
   Vdouble *x;
   Vchar zname[256];
   Vchar path[256];
   FILE *fd;
                   /* open output file */
   strcpy(path,"exam6.msh");
   fd = fopen(path,"w");
   if(fd == NULL) {
      fprintf(stderr,"Can not open output file: %s\n",path);
      exit(1);
   }
                   /* instance FLUENTLib for access */
   fluentlibw = vdm_FLUENTLibBegin();
                   /* initialize */
   vdm_FLUENTLibInit (fluentlibw,model);

                   /* grid, dimensions */
   fprintf(fd,"(0 \"Grid:\")\n");
   vdm_FLUENTLibDimension (fluentlibw,&ndim);
   fprintf(fd,"(0 \"Dimensions:\")\n");
   fprintf(fd,"(2 %d)\n",ndim);
   fprintf(fd,"\n");

                   /* overall cell, face, node */
   vdm_FLUENTLibNumEntities (fluentlibw,&numcell,&numface,&numnode);
   if(numcell == 0) {
      fprintf(fd,"(12 (0 0 0 0))\n");
   } else {
      fprintf(fd,"(12 (0 1 %x 0))\n",numcell);
   }
   fprintf(fd,"(13 (0 1 %x 0))\n",numface);
   fprintf(fd,"(10 (0 1 %x 0 %d))\n",numnode,ndim);

                   /* write nodes */
   fprintf(fd,"\n");
   fprintf(fd,"(10 (1 1 %x 1 %d)(\n",numnode,ndim);
   x = (Vdouble*)malloc(numnode*ndim*sizeof(Vdouble));
   vdm_FLUENTLibNode (fluentlibw,x);
                   /* print 1 node to a line */
   for(i = 0; i < numnode; i++) {
      if(ndim == 2) {
         fprintf(fd,"%16.9e %16.9e",x[2*i],x[2*i+1]);
      } else {
         fprintf(fd,"%25.16e %25.16e %25.16e",x[3*i],x[3*i+1],x[3*i+2]);
      }
      if(i+1 != numnode) {
         fprintf(fd,"\n");
      }
   }
   fprintf(fd,"))\n");
   free(x);

                   /* get number of cell zones and face zones */ 
   vdm_FLUENTLibNumCellZone (fluentlibw,&numcellzone);
   vdm_FLUENTLibNumFaceZone (fluentlibw,&numfacezone);

                   /* write faces, cycle through face zones */
   for(i = 1; i <= numfacezone; i++) {
      fprintf(fd,"\n");
      vdm_FLUENTLibFaceZoneParam (fluentlibw,i,&ifirst,&ilast,&type,&ftype);
                   /* assign zoneid */ 
      zoneid = i + numcellzone;
      fprintf(fd,"(13 (%x %x %x %x %x)(\n",zoneid,ifirst,ilast,type,ftype);
      num = ilast - ifirst + 1;
                   /* allocate memory */ 
                   /* variable or polygon face type */ 
      if(ftype == 0  ||  ftype == 5) {
         e = (Vint*)malloc(num*sizeof(Vint));
         vdm_FLUENTLibFaceZoneType (fluentlibw,i,e);
         lenv = 0;
         for(j = 0; j < num; j++) {
            lenv += e[j];
         }
      } else {
         lenv = ftype*num;
      }
      v  = (Vint*)malloc(lenv*sizeof(Vint));
      cl = (Vint*)malloc(num*sizeof(Vint));
      cr = (Vint*)malloc(num*sizeof(Vint));
                   /* get face zone data */ 
      vdm_FLUENTLibFaceZone (fluentlibw,i,v,cr,cl);
      nx = 0;
      for(j = 0; j < num; j++) {
                   /* variable or polygon face type */ 
         if(ftype == 0  ||  ftype == 5) {
            fprintf(fd,"%x ",e[j]);
            nfx = e[j];
                   /* constant face type */ 
         } else {
            nfx = ftype;
         }
                   /* face vertices */ 
         for(k = 0; k < nfx; k++) {
            fprintf(fd,"%x ",v[nx++]);
         }
                   /* face adjacent cells */ 
         fprintf(fd,"%x %x",cr[j],cl[j]);
         if(j+1 == num) {
            fprintf(fd,"))\n");
         } else {
            fprintf(fd,"\n");
         }
      }
                   /* free memory */ 
      free(v);
      free(cl);
      free(cr);
      if(ftype == 0  ||  ftype == 5) {
         free(e);
      }
   }

                   /* write cells, cycle through cell zones */
   for(i = 1; i <= numcellzone; i++) {
      fprintf(fd,"\n");
      vdm_FLUENTLibCellZoneParam (fluentlibw,i,&ifirst,&ilast,&type,&etype);
                   /* assign zoneid */
      zoneid = i;
                   /* constant element type */
      if(etype != 0) {
         fprintf(fd,"(12 (%x %x %x %x %x))\n",zoneid,ifirst,ilast,type,etype);
                   /* variable element type */
      } else {
         fprintf(fd,"(12 (%x %x %x %x %x)(\n",zoneid,ifirst,ilast,type,etype);
         num = ilast - ifirst + 1;
         e = (Vint*)malloc(num*sizeof(Vint));
         vdm_FLUENTLibCellZoneType (fluentlibw,i,e);
                   /* print 10 to a line */
         for(j = 1; j <= num; j++) {
            fprintf(fd,"%d ",e[j-1]);
            if(j%10 == 0  ||  j == num) {
               fprintf(fd,"\n");
            }
         }
         fprintf(fd,"))\n");
         free(e);
      }
   }
   fprintf(fd,"\n");

                   /* write zones */
   fprintf(fd,"(0 \"Zones:\")\n");
   for(i = 1; i <= numcellzone; i++) {
      vdm_FLUENTLibCellZoneName (fluentlibw,i,zname);
      zoneid = i;
      fprintf(fd,"(45 (%d %s)())\n",zoneid,zname);
   }
   for(i = 1; i <= numfacezone; i++) {
      vdm_FLUENTLibFaceZoneName (fluentlibw,i,zname);
      zoneid = i + numcellzone;
      fprintf(fd,"(45 (%d %s)())\n",zoneid,zname);
   }
                   /* summarize to standard output */ 
   printf("Zones:\n");
   for(i = 1; i <= numcellzone; i++) {
      vdm_FLUENTLibCellZoneName (fluentlibw,i,zname);
      zoneid = i;
      printf("%d %s\n",zoneid,zname);
   }
   for(i = 1; i <= numfacezone; i++) {
      vdm_FLUENTLibFaceZoneName (fluentlibw,i,zname);
      zoneid = i + numcellzone;
      printf("%d %s\n",zoneid,zname);
   }
                   /* terminate */
   vdm_FLUENTLibTerm (fluentlibw);
                   /* delete */
   vdm_FLUENTLibEnd (fluentlibw);
                   /* close file */ 
   fclose(fd);
}

7.14. Example 7, Read and Write Input Decks

This example illustrates reading input decks into a VisTools Model object and writing the Model to another input deck format. The loading of the input into the Model object is done in the main program by the function vdm_LManLoadModel(). The writing of the model to the output file is done in the example function write_output by the function vdm_LManSaveModel(). Note that when writing models, the status must be set to VDM_STATUS_NEW using function vdm_DataFunSetStatus().

#include <stdlib.h>
#include <math.h>
#include <ctype.h>
#include "base/base.h"
#include "vis/visdata.h"
#include "vdm/vdm.h"

void
write_output(vis_Model *model, Vchar *outputfile);

/*----------------------------------------------------------------------
                     Read and Write Input Decks
----------------------------------------------------------------------*/
int
main(int argc, char **argv)
{
   Vchar inputfile[256];
   Vchar outputfile[256];
   Vchar suffix[256];
   Vint i, slen;

   vdm_NASFil  *nasfil;
   vdm_ANSFil  *ansfil;
   vdm_ABAFil  *abafil;
   vdm_D3DFil  *d3dfil;
   vdm_STLFil  *stlfil;
   vdm_OBJFil  *objfil;
   vdm_SDRCLib *sdrclib;
   vdm_TecplotLib *tecplotlib;
   vdm_NatLib  *natlib;
   Vint ierr;

   vdm_DataFun   *datafun;
   vdm_LMan      *lman;
   Vint filetype;
   vis_Model *model;
                   /* check input arguments */ 
   if(argc < 2) {
      fprintf(stderr,"Usage: %s inputfile outputfile\n",argv[0]);
      fprintf(stderr," inputfile  is blank, 'cantilever.unv' is assumed\n");
      fprintf(stderr," outputfile is blank, 'exam7vis.bdf' is assumed\n");
      strcpy(inputfile,"cantilever.unv");
      strcpy(outputfile,"exam7vis.bdf");
   } else if(argc < 3) {
      fprintf(stderr,"Usage: %s inputfile outputfile\n",argv[0]);
      fprintf(stderr," outputfile is blank, 'exam7vis.bdf' is assumed\n");
      strcpy(inputfile,argv[1]);
      strcpy(outputfile,"exam7vis.bdf");
   } else {
      strcpy(inputfile,argv[1]);
      strcpy(outputfile,argv[2]);
   }
                   /* find input file suffix */ 
   slen = (Vint)strlen(inputfile);
   for(i = slen-2; i != 0; i--) {
      if(inputfile[i] == '.') {
         strcpy(suffix,&inputfile[i]);
         break;
      }
   }
                   /* create data function object */
   datafun = vdm_DataFunBegin ();

                   /* determine file type from file extension */
   if(strstr(suffix,".unv") != NULL) {
      filetype = VDM_SDRC_UNIVERSAL;
      sdrclib = vdm_SDRCLibBegin ();
      vdm_SDRCLibDataFun (sdrclib,datafun);
   } else if(strstr(suffix,".dat") != NULL  ||
             strstr(suffix,".bdf") != NULL) {
      filetype = VDM_NASTRAN_BULKDATA;
      nasfil = vdm_NASFilBegin ();
      vdm_NASFilDataFun (nasfil,datafun);
   } else if(strstr(suffix,".cdb") != NULL  ||
             strstr(suffix,".ans") != NULL) {
      filetype = VDM_ANSYS_INPUT;
      ansfil = vdm_ANSFilBegin ();
      vdm_ANSFilDataFun (ansfil,datafun);
   } else if(strstr(suffix,".inp") != NULL) {
      filetype = VDM_ABAQUS_INPUT;
      abafil = vdm_ABAFilBegin ();
      vdm_ABAFilDataFun (abafil,datafun);
   } else if(strstr(suffix,".stl") != NULL) {
      filetype = VDM_STL;
      stlfil = vdm_STLFilBegin ();
      vdm_STLFilDataFun (stlfil,datafun);
   } else if(strstr(suffix,".obj") != NULL) {
      filetype = VDM_OBJ;
      objfil = vdm_OBJFilBegin ();
      vdm_OBJFilDataFun (objfil,datafun);
   } else if(strstr(suffix,".plt") != NULL) {
      filetype = VDM_TECPLOT;
      tecplotlib = vdm_TecplotLibBegin ();
      vdm_TecplotLibDataFun (tecplotlib,datafun);
   } else if(strstr(suffix,".k")   != NULL  ||
             strstr(suffix,".dyn") != NULL) {
      filetype = VDM_LSTC_INPUT;
      d3dfil = vdm_D3DFilBegin();
      vdm_D3DFilDataFun (d3dfil,datafun);
   } else if(strstr(suffix,".vdm") != NULL) {
      filetype = VDM_NATIVE;
      natlib = vdm_NatLibBegin ();
      vdm_NatLibDataFun (natlib,datafun);
   } else {
      fprintf(stderr,"Error: Bad input file %s\n",inputfile);
      exit(1);
   }
                   /* double precision is used to represent node location */ 
   vdm_DataFunSetConvention (datafun,VDM_CONVENTION_DOUBLE);
                   /* open library device */
   vdm_DataFunOpen (datafun,0,inputfile,filetype);

                   /* check for error */
   ierr = vdm_DataFunError(datafun);
   if(ierr) {
      fprintf(stderr,"Error: opening file %s\n",inputfile);
      goto labelcleanup;
   }
                   /* instance Model object for finite element model */ 
   model = vis_ModelBegin();

                   /* use Library Manager object to load model */ 
   lman = vdm_LManBegin ();
   vdm_LManSetObject (lman,VDM_DATAFUN,datafun);
   vdm_LManLoadModel (lman,model);
                   /* write output file */ 
   write_output (model,outputfile);

                   /* delete objects in Model created by LManLoadModel */ 
   vis_ModelDelete (model);
   vdm_LManEnd (lman);
   vis_ModelEnd (model);

                   /* close library device */
labelcleanup:;
   vdm_DataFunClose (datafun);

                   /* free objects */ 
   vdm_DataFunEnd (datafun);
   if(filetype == VDM_SDRC_UNIVERSAL) {
      vdm_SDRCLibEnd (sdrclib);
   } else if(filetype == VDM_NASTRAN_BULKDATA) {
      vdm_NASFilEnd (nasfil);
   } else if(filetype == VDM_ANSYS_INPUT) {
      vdm_ANSFilEnd (ansfil);
   } else if(filetype == VDM_ABAQUS_INPUT) {
      vdm_ABAFilEnd (abafil);
   } else if(filetype == VDM_STL) {
      vdm_STLFilEnd (stlfil);
   } else if(filetype == VDM_OBJ) {
      vdm_OBJFilEnd (objfil);
   } else if(filetype == VDM_TECPLOT) {
      vdm_TecplotLibEnd (tecplotlib);
   } else if(filetype == VDM_LSTC_INPUT) {
      vdm_D3DFilEnd (d3dfil);
   } else if(filetype == VDM_NATIVE) {
      vdm_NatLibEnd (natlib);
   }
   return 0;
}

/*----------------------------------------------------------------------
                      write to output file
----------------------------------------------------------------------*/
void
write_output(vis_Model *model, Vchar *outputfile)
{
   Vchar suffix[256];
   Vint i, slen;
   vdm_NASFil  *nasfil;
   vdm_NASLib  *naslib;
   vdm_ANSFil  *ansfil;
   vdm_ABAFil  *abafil;
   vdm_SDRCLib *sdrclib;
   vdm_RASFil  *rasfil;
   vdm_STLFil  *stlfil;
   vdm_OBJFil  *objfil;
   vdm_TecplotLib *tecplotlib;
   vdm_NatLib  *natlib;
   Vint ierr;
   vdm_DataFun   *datafun;
   vdm_LMan      *lman;
   Vint filetype;

                   /* find output file suffix */
   slen = (Vint)strlen(outputfile);
   for(i = slen-2; i != 0; i--) {
      if(outputfile[i] == '.') {
         strcpy(suffix,&outputfile[i]);
         break;
      }
   }
                   /* create data function object */
   datafun = vdm_DataFunBegin ();
                   /* determine file type from file extension */
   if(strstr(suffix,".unv") != NULL) {
      filetype = VDM_SDRC_UNIVERSAL;
      sdrclib = vdm_SDRCLibBegin ();
      vdm_SDRCLibDataFun (sdrclib,datafun);
   } else if(strstr(suffix,".dat") != NULL  ||
             strstr(suffix,".bdf") != NULL) {
      filetype = VDM_NASTRAN_BULKDATA;
      nasfil = vdm_NASFilBegin ();
      vdm_NASFilDataFun (nasfil,datafun);
   } else if(strstr(suffix,".op2") != NULL) {
      filetype = VDM_NASTRAN_OUTPUT2;
      naslib = vdm_NASLibBegin ();
      vdm_NASLibDataFun (naslib,datafun);
   } else if(strstr(suffix,".cdb") != NULL  ||
             strstr(suffix,".ans") != NULL) {
      filetype = VDM_ANSYS_INPUT;
      ansfil = vdm_ANSFilBegin ();
      vdm_ANSFilDataFun (ansfil,datafun);
   } else if(strstr(suffix,".inp") != NULL) {
      filetype = VDM_ABAQUS_INPUT;
      abafil = vdm_ABAFilBegin ();
      vdm_ABAFilDataFun (abafil,datafun);
   } else if(strstr(suffix,".fnf") != NULL) {
      filetype = VDM_MECHANICA_FNF;
      rasfil = vdm_RASFilBegin ();
      vdm_RASFilDataFun (rasfil,datafun);
   } else if(strstr(suffix,".stl") != NULL) {
      filetype = VDM_STL;
      stlfil = vdm_STLFilBegin ();
      vdm_STLFilDataFun (stlfil,datafun);
   } else if(strstr(suffix,".STL") != NULL) {
      filetype = VDM_STLBIN;
      stlfil = vdm_STLFilBegin ();
      vdm_STLFilDataFun (stlfil,datafun);
   } else if(strstr(suffix,".obj") != NULL) {
      filetype = VDM_OBJ;
      objfil = vdm_OBJFilBegin ();
      vdm_OBJFilDataFun (objfil,datafun);
   } else if(strstr(suffix,".plt") != NULL) {
      filetype = VDM_TECPLOT;
      tecplotlib = vdm_TecplotLibBegin ();
      vdm_TecplotLibDataFun (tecplotlib,datafun);
   } else if(strstr(suffix,".vdm") != NULL) {
      filetype = VDM_NATIVE;
      natlib = vdm_NatLibBegin ();
      vdm_NatLibDataFun (natlib,datafun);
   } else {
      fprintf(stderr,"Error: Bad output file %s\n",outputfile);
      exit(1);
   }
                   /* new file */
   vdm_DataFunSetStatus (datafun,VDM_STATUS_NEW);
                   /* open library device */
   vdm_DataFunOpen (datafun,0,outputfile,filetype);
                   /* check for error */
   ierr = vdm_DataFunError(datafun);
   if(ierr) {
      fprintf(stderr,"Error: opening file %s\n",outputfile);
      goto labelcleanup;
   }
                   /* use Library Manager object to save model */
   lman = vdm_LManBegin ();
   vdm_LManSetObject (lman,VDM_DATAFUN,datafun);
   vdm_LManSaveModel (lman,model);
                                                                                
                   /* delete objects in Model created by LManLoadModel */
   vdm_LManEnd (lman);
                   /* close library device */
labelcleanup:;
   vdm_DataFunClose (datafun);
                                                                                
                   /* free objects */
   vdm_DataFunEnd (datafun);
   if(filetype == VDM_SDRC_UNIVERSAL) {
      vdm_SDRCLibEnd (sdrclib);
   } else if(filetype == VDM_NASTRAN_BULKDATA) {
      vdm_NASFilEnd (nasfil);
   } else if(filetype == VDM_ANSYS_INPUT) {
      vdm_ANSFilEnd (ansfil);
   } else if(filetype == VDM_ABAQUS_INPUT) {
      vdm_ABAFilEnd (abafil);
   } else if(filetype == VDM_MECHANICA_FNF) {
      vdm_RASFilEnd (rasfil);
   } else if(filetype == VDM_STL || filetype == VDM_STLBIN) {
      vdm_STLFilEnd (stlfil);
   } else if(filetype == VDM_OBJ) {
      vdm_OBJFilEnd (objfil);
   } else if(filetype == VDM_TECPLOT) {
      vdm_TecplotLibEnd (tecplotlib);
   } else if(filetype == VDM_NATIVE) {
      vdm_NatLibEnd (natlib);
   }
}

7.15. Example 8, Remotely Access Any File Format

This example illustrates the use of the DataIPC module to allow models residing on a client machine to be read by an application on a server machine. The network connection is done using the machine’s hostname and the randomly selected port 10000.

The behavior of DataIPC is different on the server and the client sides. On the client, a DataFun object is filled with the functions and data of DataIPC. The DataFun object can then be used like in any other VdmTools application, through vdm_DataFunOpen(), vdm_DataFunReadDataset(), etc. It can also be set in a LMan object to be used with vdm_LManTOC(), vdm_LManLoadModel(), and vdm_LManLoadState(). Once the DataFun object loaded with DataIPC is finished, it must send a final signal to the server with vdm_DataIPCStopServer().

On the server side a DataFun object of the type that will be required by the client is set in the DataIPC object. In the example, the file type is passed as an argument to the client application so it can select the VdmTools module to be loaded. Once the connection is established the server is put in a listening mode with vdm_DataIPCStartServer(). This mode is then terminated by the client when vdm_DataIPCStopServer() is sent through the socket connection. Once the listening mode is terminated the socket is disconnected and the application ends.

#include <stdlib.h>
#include "base/base.h"
#include "vdm/vdm.h"

#define BUFSIZE 256

static Vint magic = 1234;

                   /* data structure for server */
typedef struct {
   vsy_VSocket *vsocket;
   Vint        cid;
} exam8struct;

                   /* monitor function for server */
static void
exam8monitor(vdm_DataIPC *p, Vobject *obj)
{
   Vint ierr;

   ierr = vdm_DataIPCError (p);
   if(ierr) {
      vdm_DataIPCAbort (p);
   }
}
                   /* read and write functions for server */
static void
exam8reads(exam8struct *inst, Vint num, Vchar *buf)
{
   vsy_VSocketRead(inst->vsocket,inst->cid,num,buf);
}
static void
exam8writes(exam8struct *inst, Vint num, Vchar *buf)
{
   vsy_VSocketWrite(inst->vsocket,inst->cid,num,buf);
}

                   /* read and write functions for client */
static void
exam8readc(vsy_VSocket *vsocket, Vint num, Vchar *buf)
{
   vsy_VSocketRead(vsocket,0,num,buf);
}
static void
exam8writec(vsy_VSocket *vsocket, Vint num, Vchar *buf)
{
   vsy_VSocketWrite(vsocket,0,num,buf);
}

                   /* 4-byte swapping function */
static void
exam8swap4(Vchar *num)
{
   Vchar c;

   c = num[0];
   num[0] = num[3];
   num[3] = c;
   c = num[1];
   num[1] = num[2];
   num[2] = c;
}

static void
server(exam8struct *inst)
{
   vdm_NASFil  *nasfil;
   vdm_NASLib  *naslib;
   vdm_SDRCLib *sdrclib;
   vdm_DataFun *datafun;
   vdm_DataIPC *dataipc;
   Vint swap, imagic, size, filetype;
   Vchar filename[BUFSIZE];

   /* retrieve magic number to determine swapping */
   swap = 0;
   vsy_VSocketRead (inst->vsocket,inst->cid,sizeof(Vint),(Vchar*)&imagic);
   if(imagic != magic) {
      exam8swap4((Vchar*)&imagic);
      if(imagic != 1234) {
         swap = -1;
      } else {
         swap = 1;
      }
   }
   if(swap == -1) {
      vsy_VSocketWrite (inst->vsocket,inst->cid,sizeof(Vint),(Vchar*)&swap);
      vsy_VSocketClose (inst->vsocket,inst->cid);
      printf("Invalid magic number detected\n");
      return;
   }

   /* send magic number to determine swapping */
   vsy_VSocketWrite (inst->vsocket,inst->cid,sizeof(Vint),(Vchar*)&magic);

   /* retrieve filetype and filename */
   vsy_VSocketRead (inst->vsocket,inst->cid,sizeof(Vint),(Vchar*)&filetype);
   if(swap)  exam8swap4((Vchar*)&filetype);
   vsy_VSocketReadString (inst->vsocket,inst->cid,BUFSIZE,filename,&size);
   if(filetype != SYS_NASTRAN_OUTPUT2  &&
      filetype != SYS_NASTRAN_BULKDATA &&
      filetype != SYS_SDRC_UNIVERSAL) {
      vsy_VSocketClose (inst->vsocket,inst->cid);
      printf("Unsupported filetype= %d\n",filetype);
      return;
   }
   vsy_VSocketWriteString (inst->vsocket,inst->cid,"ok");

   /* setup VdmTools data structures */
   datafun = vdm_DataFunBegin ();
   dataipc = vdm_DataIPCBegin ();
   vdm_DataIPCDef (dataipc,DATAIPC_SERVER);
   vdm_DataIPCSetSwap (dataipc,swap);

   if(filetype == SYS_NASTRAN_OUTPUT2) {
      naslib = vdm_NASLibBegin ();
      vdm_NASLibDataFun (naslib,datafun);
   } else if(filetype == SYS_NASTRAN_BULKDATA) {
      nasfil = vdm_NASFilBegin ();
      vdm_NASFilDataFun (nasfil,datafun);
   } else if(filetype == SYS_SDRC_UNIVERSAL) {
      sdrclib = vdm_SDRCLibBegin ();
      vdm_SDRCLibDataFun (sdrclib,datafun);
   }
   vdm_DataIPCSetObject (dataipc,VDM_DATAFUN,(Vobject*)datafun);

   vdm_DataIPCSetFunction (dataipc,DATAIPC_FUN_MONITOR,
                           (Vfunc*)exam8monitor,NULL);
   vdm_DataIPCSetFunction (dataipc,DATAIPC_FUN_WRITE,(Vfunc*)exam8writes,
                           (Vobject*)inst);
   vdm_DataIPCSetFunction (dataipc,DATAIPC_FUN_READ,(Vfunc*)exam8reads,
                           (Vobject*)inst);

   /* put server in receive-command mode */
   vdm_DataIPCStartServer (dataipc);

                   /* cleanup */
   vdm_DataIPCEnd (dataipc);
   vdm_DataFunEnd (datafun);
   if(filetype == SYS_NASTRAN_OUTPUT2) {
      vdm_NASLibEnd (naslib);
   } else if(filetype == SYS_NASTRAN_BULKDATA) {
      vdm_NASFilEnd (nasfil);
   } else if(filetype == SYS_SDRC_UNIVERSAL) {
      vdm_SDRCLibEnd (sdrclib);
   }
   vsy_VSocketClose (inst->vsocket,inst->cid);
}

/*----------------------------------------------------------------------
                       Remotely Access Any File Format
----------------------------------------------------------------------*/
static int
main_server()
{
   vsy_VSocket *vsocket;
   Vint cid, flag;
   Vchar hostname[BUFSIZE];
   exam8struct inst;

                   /* Get info about this host */
   vut_MachInfoHostName (&flag,hostname);
   if(flag == 0) {
      printf("Unable to retrieve host name\n");
      return 0;
   }
                   /* Instance and set up VSocket */
   vsocket = vsy_VSocketBegin ();
   vsy_VSocketSetParami (vsocket,VSOCKET_WAITTIME,10000);
   vsy_VSocketSetParami (vsocket,VSOCKET_MAXCONNECTIONS,10);
   vsy_VSocketDef (vsocket,VSOCKET_SERVER,VSOCKET_NET);
   vsy_VSocketSetNet (vsocket,10000,hostname);
   vsy_VSocketOpen (vsocket);
   vsy_VSocketAccept (vsocket,&cid);

   inst.vsocket  = vsocket;
   inst.cid      = cid;
                   /* call server */ 
   server(&inst);
                   /* shut server down and cleanup */
   vsy_VSocketClose (vsocket,0);
   vsy_VSocketEnd (vsocket);
   return 0;
}

/*----------------------------------------------------------------------
                       Remotely Access Any File Format
----------------------------------------------------------------------*/
static void
main_client(Vchar filename[])
{
   vdm_LMan *lman;
   vdm_DataFun *datafun;
   vdm_DataIPC *dataipc;
   vsy_VSocket *vsocket;
   Vchar hostname[BUFSIZE], buffer[BUFSIZE];
   Vint flag, swap, imagic, size, filetype;

   if(strstr(filename,".op2")) {
      filetype = SYS_NASTRAN_OUTPUT2;
   } else if(strstr(filename,".dat")) {
      filetype = SYS_NASTRAN_BULKDATA;
   } else if(strstr(filename,".unv")) {
      filetype = SYS_SDRC_UNIVERSAL;
   } else {
      fprintf(stderr,"Unsupported file type\n");
      return;
   }
                   /* Get info about this host */
   vut_MachInfoHostName (&flag,hostname);
   if(flag == 0) {
      printf("Unable to retrieve host name\n");
      return;
   }
                   /* Instance and set up VSocket */
   vsocket = vsy_VSocketBegin ();
   vsy_VSocketSetParami (vsocket,VSOCKET_WAITTIME,1000);
   vsy_VSocketDef (vsocket,VSOCKET_CLIENT,VSOCKET_NET);
   vsy_VSocketSetNet (vsocket,10000,hostname);
   vsy_VSocketOpen (vsocket);
   if(vsy_VSocketError (vsocket)) {
      vsy_VSocketEnd (vsocket);
      return;
   }
                   /* send magic number */
   vsy_VSocketWrite (vsocket,0,sizeof(Vint),(Vchar*)&magic);

                   /* receive magic number */
   swap = 0;
   vsy_VSocketRead (vsocket,0,sizeof(Vint),(Vchar*)&imagic);
   if(imagic != magic) {
      exam8swap4((Vchar*)&imagic);
      if(imagic != magic) {
         vsy_VSocketClose (vsocket,0);
         return;
      } else {
         swap = 1;
      }
   }
                   /* send filetype and filename */
   vsy_VSocketWrite (vsocket,0,sizeof(Vint),(Vchar*)&filetype);
   vsy_VSocketWriteString (vsocket,0,filename);
   vsy_VSocketReadString (vsocket,0,BUFSIZE,buffer,&size);
   if(strcmp(buffer,"ok")) {
      vsy_VSocketClose (vsocket,0);
      printf("Server did not acknowledge filetype and filename\n");
      return;
   }
                   /* create data function object */
   datafun = vdm_DataFunBegin ();
   dataipc = vdm_DataIPCBegin ();
   vdm_DataIPCSetSwap (dataipc,swap);
   vdm_DataIPCDef (dataipc,DATAIPC_CLIENT);
   vdm_DataIPCDataFun (dataipc,datafun);

   vdm_DataIPCSetFunction (dataipc,DATAIPC_FUN_WRITE,(Vfunc*)exam8writec,
                           (Vobject*)vsocket);
   vdm_DataIPCSetFunction (dataipc,DATAIPC_FUN_READ,(Vfunc*)exam8readc,
                           (Vobject*)vsocket);

                   /* open library device */
   vdm_DataFunOpen (datafun,0,filename,filetype);
   if(vdm_DataFunError(datafun))  goto labelabort;

                   /* check for error and try to upgrade */ 
   lman = vdm_LManBegin ();
   vdm_LManSetObject (lman,VDM_DATAFUN,datafun);
   vdm_LManSetParami (lman,LMAN_VERBOSE,SYS_ON);
   vdm_LManTOC (lman,"*");
   vdm_LManExport (lman,"*","exam8.exp");
   vdm_LManEnd (lman);
   vdm_DataFunClose (datafun);

labelabort:
   vdm_DataIPCStopServer (dataipc);
   vsy_VSocketClose (vsocket,0);

                   /* free objects */ 
   vdm_DataFunEnd (datafun);
   vdm_DataIPCEnd (dataipc);
   vsy_VSocketEnd (vsocket);
}

static void
start_server(char *arg)
{
   Vchar sys[BUFSIZE];

#ifdef VKI_ARCH_WIN32
   STARTUPINFO si;
   PROCESS_INFORMATION pi;

   sprintf(sys,"%s s s s s",arg);
   ZeroMemory( &si, sizeof(si) );
   si.cb = sizeof(si);
   ZeroMemory( &pi, sizeof(pi) );
   if(!CreateProcess(NULL,sys,NULL,NULL,FALSE,0,NULL,NULL,&si,&pi)) {
      printf("SERVER: Unable to start child process\n");
      exit(0);
   }
#else
   sprintf(sys,"%s s s s s &",arg);
   system(sys);
#endif
}

int
main(int argc, char *argv[])
{
                   /* no input: use cantilever.unv */
   if(argc == 1) {
      fprintf(stderr,"Usage: %s pathname\n",argv[0]);
      fprintf(stderr," cantilever.unv is assumed\n");
      start_server (argv[0]);
      main_client ("cantilever.unv");
      printf("Client terminated\n");
                   /* one argument: file to open */
   } else if(argc == 2) {
      start_server (argv[0]);
      main_client (argv[1]);
      printf("Client terminated\n");
                   /* internal use, process started by start_server */
   } else {
      main_server();
      printf("Server terminated\n");
   }
   return 0;
}

7.16. Example 8a, Remotely Writing a Model in Native Vdm Format

This example illustrates the use of the DataIPC module to allow models residing on a client machine to be written by an application on a server machine in VDM_NATIVE format. Like in exam8 the network connection is done using the machine’s hostname and the randomly selected port 10000. The client and server sides of the connection reside in separate programs, the client side is in exam8a2.c and the server side is in exam8a1.c.

The behavior of DataIPC is different on the server and the client sides. On the client, a DataFun object is filled with the functions and data of DataIPC. The DataFun object can then be used like in any other VdmTools application, through vdm_DataFunOpen(), vdm_DataFunReadDataset(), etc. It can also be set in a LMan object to be used with vdm_LManTOC(), vdm_LManLoadModel(), and vdm_LManLoadState(). Once the client DataFun object loaded with DataIPC is finished, it must send a final signal to the server with vdm_DataIPCStopServer(). In this example the client loads a Model object and then uses DataIPC to remotely save the model using Natlib.

On the server side a DataFun object connected to a VDM_NATIVE interface is established. Once the connection is established the server is put in a listening mode with vdm_DataIPCStartServer(). This mode is then terminated by the client when vdm_DataIPCStopServer() is sent through the socket connection. Once the listening mode is terminated the socket is disconnected and the application ends.

#include <stdlib.h>
#include "base/base.h"
#include "vdm/vdm.h"

static Vint magic = 1234;

                   /* data structure for server */
typedef struct {
   vsy_VSocket *vsocket;
   Vint        cid;
} exam8struct;

                   /* read and write functions for server */
static void
exam8reads(exam8struct *inst, Vint num, Vchar *buf)
{
   vsy_VSocketRead(inst->vsocket,inst->cid,num,buf);
}
static void
exam8writes(exam8struct *inst, Vint num, Vchar *buf)
{
   vsy_VSocketWrite(inst->vsocket,inst->cid,num,buf);
}

                   /* 4-byte swapping function */
static void
exam8swap4(Vchar *num)
{
   Vchar c;

   c = num[0];
   num[0] = num[3];
   num[3] = c;
   c = num[1];
   num[1] = num[2];
   num[2] = c;
}

static void
server(exam8struct *inst)
{
   vdm_NatLib  *natlib;
   vdm_DataFun *datafun;
   vdm_DataIPC *dataipc;
   Vint swap, imagic;

   /* retrieve magic number to determine swapping */
   swap = 0;
   vsy_VSocketRead (inst->vsocket,inst->cid,sizeof(Vint),(Vchar*)&imagic);
   if(imagic != magic) {
      exam8swap4((Vchar*)&imagic);
      if(imagic != 1234) {
         swap = -1;
      } else {
         swap = 1;
      }
   }
   if(swap == -1) {
      vsy_VSocketWrite (inst->vsocket,inst->cid,sizeof(Vint),(Vchar*)&swap);
      vsy_VSocketClose (inst->vsocket,inst->cid);
      printf("Invalid magic number detected\n");
      return;
   }

   /* send magic number to determine swapping */
   vsy_VSocketWrite (inst->vsocket,inst->cid,sizeof(Vint),(Vchar*)&magic);

   /* setup VdmTools data structures */
   datafun = vdm_DataFunBegin ();
   dataipc = vdm_DataIPCBegin ();
   vdm_DataIPCDef (dataipc,DATAIPC_SERVER);
   vdm_DataIPCSetSwap (dataipc,swap);
   natlib  = vdm_NatLibBegin ();
   vdm_NatLibDataFun (natlib,datafun);
   vdm_DataIPCSetObject (dataipc,VDM_DATAFUN,(Vobject*)datafun);

   vdm_DataIPCSetFunction (dataipc,DATAIPC_FUN_WRITE,(Vfunc*)exam8writes,
                           (Vobject*)inst);
   vdm_DataIPCSetFunction (dataipc,DATAIPC_FUN_READ,(Vfunc*)exam8reads,
                           (Vobject*)inst);

   /* put server in receive-command mode */
   vdm_DataIPCStartServer (dataipc);

                   /* cleanup */
   vdm_DataIPCEnd (dataipc);
   vdm_DataFunEnd (datafun);
   vdm_NatLibEnd  (natlib);
   vsy_VSocketClose (inst->vsocket,inst->cid);
}

/*----------------------------------------------------------------------
                       Save a VDM_NATIVE file remotely
----------------------------------------------------------------------*/
int
main()
{
   vsy_VSocket *vsocket;
   Vint cid, flag;
   Vchar hostname[256];
   exam8struct inst;

                   /* Get info about this host */
   vut_MachInfoHostName (&flag,hostname);
   if(flag == 0) {
      printf("Unable to retrieve host name\n");
      return 0;
   }
   printf("This example requires that exam8a2 also be running\n");
                   /* Instance and set up VSocket */
   vsocket = vsy_VSocketBegin ();
   vsy_VSocketSetParami (vsocket,VSOCKET_WAITTIME,10000);
   vsy_VSocketSetParami (vsocket,VSOCKET_MAXCONNECTIONS,10);
   vsy_VSocketDef (vsocket,VSOCKET_SERVER,VSOCKET_NET);
   vsy_VSocketSetNet (vsocket,10000,hostname);
   vsy_VSocketOpen (vsocket);
   vsy_VSocketAccept (vsocket,&cid);

   inst.vsocket  = vsocket;
   inst.cid      = cid;
                   /* call server */ 
   server (&inst);
                   /* shut server down and cleanup */
   vsy_VSocketClose (vsocket,0);
   vsy_VSocketEnd (vsocket);
   return 0;
}
#include <stdlib.h>
#include "base/base.h"
#include "vdm/vdm.h"

static Vint magic = 1234;

                   /* read and write functions for client */
static void
exam8readc(vsy_VSocket *vsocket, Vint num, Vchar *buf)
{
   vsy_VSocketRead(vsocket,0,num,buf);
}

static void
exam8writec(vsy_VSocket *vsocket, Vint num, Vchar *buf)
{
   vsy_VSocketWrite(vsocket,0,num,buf);
}
                   /* 4-byte swapping function */
static void
exam8swap4(Vchar *num)
{
   Vchar c;

   c = num[0];
   num[0] = num[3];
   num[3] = c;
   c = num[1];
   num[1] = num[2];
   num[2] = c;
}

/*----------------------------------------------------------------------
                       Save a VDM_NATIVE file remotely
----------------------------------------------------------------------*/
int
main(int argc, char *argv[])
{
   vdm_LMan *lman;
   vdm_DataFun *datafun;
   vdm_DataIPC *dataipc;
   vsy_VSocket *vsocket;
   Vchar hostname[256];
   Vint flag, swap, imagic, filetype;
   vdm_NASLib  *naslib;
   vdm_NASFil  *nasfil;
   vdm_SDRCLib *sdrclib;
   vis_Model   *model;
   vdm_Library *library;
   vis_RProp   *rprop = NULL;
   vis_State   *state = NULL;
   Vint ndst, idst;
   Vchar filename[256];

   if(argc == 1) {
      fprintf(stderr,"Usage: %s pathname\n",argv[0]);
      fprintf(stderr," cantilever.unv is assumed\n");
      strcpy(filename,"cantilever.unv");
   } else {
      strcpy(filename,argv[1]);
   }
   printf("This example requires that exam8a1 also be running\n");

   datafun = vdm_DataFunBegin ();
   if(strstr(filename,".op2")) {
      filetype = SYS_NASTRAN_OUTPUT2;
      naslib = vdm_NASLibBegin ();
      vdm_NASLibDataFun (naslib,datafun);
   } else if(strstr(filename,".dat")) {
      filetype = SYS_NASTRAN_BULKDATA;
      nasfil = vdm_NASFilBegin ();
      vdm_NASFilDataFun (nasfil,datafun);
   } else if(strstr(filename,".unv")) {
      filetype = SYS_SDRC_UNIVERSAL;
      sdrclib = vdm_SDRCLibBegin ();
      vdm_SDRCLibDataFun (sdrclib,datafun);
   } else {
      fprintf(stderr,"Unsupported file type\n");
      return 1;
   }
                   /* Load model */
   lman = vdm_LManBegin ();
   vdm_LManSetObject (lman,VDM_DATAFUN,(Vobject*)datafun);
   vdm_DataFunOpen (datafun,0,filename,filetype);
   if(vdm_DataFunError (datafun)) {
      printf("Cannot open file %s\n",filename);
      return 1;
   }
   model = vis_ModelBegin ();
   vdm_LManLoadModel (lman,model);
   vdm_DataFunGetLibrary (datafun,&library);
   vdm_LibrarySearchDataset (library,"D.N:1",1,&ndst,&idst);
   if(ndst) {
      rprop = vis_RPropBegin ();
      vis_RPropSetDatasetName (rprop,"D.N:1");
      state = vis_StateBegin ();
      vdm_LManLoadState (lman,state,rprop);
   }

   vdm_DataFunClose (datafun);
   vdm_DataFunEnd (datafun);
   vdm_LManEnd (lman);

                   /* Get info about this host */
   vut_MachInfoHostName (&flag,hostname);
   if(flag == 0) {
      printf("Unable to retrieve host name\n");
      return 1;
   }
                   /* Instance and set up VSocket */
   vsocket = vsy_VSocketBegin ();
   vsy_VSocketSetParami (vsocket,VSOCKET_WAITTIME,1000);
   vsy_VSocketDef (vsocket,VSOCKET_CLIENT,VSOCKET_NET);
   vsy_VSocketSetNet (vsocket,10000,hostname);
   vsy_VSocketOpen (vsocket);
   if(vsy_VSocketError (vsocket)) {
      vsy_VSocketEnd (vsocket);
      return 1;
   }
                   /* send magic number */
   vsy_VSocketWrite (vsocket,0,sizeof(Vint),(Vchar*)&magic);

                   /* receive magic number */
   swap = 0;
   vsy_VSocketRead (vsocket,0,sizeof(Vint),(Vchar*)&imagic);
   if(imagic != magic) {
      exam8swap4((Vchar*)&imagic);
      if(imagic != magic) {
         vsy_VSocketClose (vsocket,0);
         return 1;
      } else {
         swap = 1;
      }
   }
                   /* create data function object */
   datafun = vdm_DataFunBegin ();
   dataipc = vdm_DataIPCBegin ();
   vdm_DataIPCSetSwap (dataipc,swap);
   vdm_DataIPCDef (dataipc,DATAIPC_CLIENT);
   vdm_DataIPCDataFun (dataipc,datafun);

   vdm_DataIPCSetFunction (dataipc,DATAIPC_FUN_WRITE,(Vfunc*)exam8writec,
                           (Vobject*)vsocket);
   vdm_DataIPCSetFunction (dataipc,DATAIPC_FUN_READ,(Vfunc*)exam8readc,
                           (Vobject*)vsocket);

                   /* open library device */
   vdm_DataFunSetStatus (datafun,VDM_STATUS_NEW);
   vdm_DataFunOpen (datafun,0,"exam8a.vdm",VDM_NATIVE);
   if(vdm_DataFunError(datafun))  goto labelabort;

                   /* check for error and try to upgrade */ 
   lman = vdm_LManBegin ();
   vdm_LManSetObject (lman,VDM_DATAFUN,datafun);
   vdm_LManSetParami (lman,LMAN_VERBOSE,SYS_ON);
   vdm_LManSaveModel (lman,model);
   if(ndst) {
      vdm_LManSaveState (lman,state,rprop);
      vis_RPropEnd (rprop);
      vis_StateEnd (state);
   }
   vdm_LManEnd (lman);
   vdm_DataFunClose (datafun);
   vis_ModelDelete (model);
   vis_ModelEnd (model);

labelabort:
   vdm_DataIPCStopServer (dataipc);
   vsy_VSocketClose (vsocket,0);

                   /* free objects */ 
   vdm_DataFunEnd (datafun);
   vdm_DataIPCEnd (dataipc);
   vsy_VSocketEnd (vsocket);
   return 0;
}

7.17. Example 9, Read and Transform Stress/Strain State Data

This example illustrates reading stress or strain data and transforming it from the element local system to the global coordinate system and optionally the element material coordinate system. A stress or strain state may be initially in local element coordinate systems. The local systems are represented either by a set of local coordinate system identifiers and associated data or a set of rotation angles for each element system. For the case of a set of local system identifiers, the State object must be given the HashTable of coordinate systems and associated element data as well as an IdTran object containing the integer valued local system identifiers. For the case of a set of rotation angles, the State object must be given another State object containing the rotation angles for each element.

The stress or strain values are then transformed to the global system by calling vis_StateTransform() with option STATE_GLOBAL.

In order to transform to the material system, the State object requires the HashTable of coordinate systems and associated element data. if a material system exists for any of the queried elements, the State is transformed to the material system.

#include <stdlib.h>
#include "base/base.h"
#include "vis/visdata.h"
#include "vdm/vdm.h"
#include "datafile.h"

static void
print_stress(vdm_LMan *lman, vdm_Library *library, vis_Model *model);

/*----------------------------------------------------------------------
                     Read and Transform Stress/Strain State Data
----------------------------------------------------------------------*/
int
main(int argc, char **argv)
{
   char inputfile[256];
   vdm_DataFun   *datafun;
   vdm_Library   *library;
   vdm_LMan      *lman;
   Vint filetype;
   Vint numnp, numel;
   vis_Model *model;
   vis_Connect *connect;
   Vint ierr;

                   /* check input arguments */ 
   if(argc < 2) {
      fprintf(stderr,"Usage: %s inputfile [appendfile]\n",argv[0]);
      fprintf(stderr," inputfile is blank, 'cantilever.unv' is assumed\n");
      strcpy(inputfile,"cantilever.unv");
   } else {
      strcpy(inputfile,argv[1]);
   }
                   /* create data function object */
   datafun = vdm_DataFunBegin ();

   datafiletype(inputfile,&filetype);
   if(filetype == 0) {
      fprintf(stderr,"Error: Bad input file %s\n",inputfile);
      exit(1);
   }
   datafileinit(filetype,datafun);
                   /* set convention to support sparse datasets */
   vdm_DataFunSetConvention (datafun,VDM_CONVENTION_SPARSE);
                   /* open library device */
   vdm_DataFunOpen (datafun,0,inputfile,filetype);
                   /* check for error */
   ierr = vdm_DataFunError(datafun);
   if(ierr) {
      fprintf(stderr,"Error: opening file %s\n",inputfile);
      exit(0);
   }
                   /* instance Model object for finite element model */ 
   model = vis_ModelBegin();

                   /* use Library Manager object to load model */ 
   lman = vdm_LManBegin ();
   vdm_LManSetObject (lman,VDM_DATAFUN,datafun);
   vdm_LManLoadModel (lman,model);

                   /* get Connect object created in Model */ 
   vis_ModelGetObject (model,VIS_CONNECT,(Vobject**)&connect);
   vis_ConnectNumber (connect,SYS_NODE,&numnp);
   vis_ConnectNumber (connect,SYS_ELEM,&numel);
   printf("number of nodes= %d\n",numnp);
   printf("number of elems= %d\n",numel);

                   /* get library object */ 
   vdm_DataFunGetLibrary (datafun,&library);

                   /* access and transform stress results */ 
   print_stress (lman,library,model);

                   /* close library device */ 
   vdm_DataFunClose (datafun);

                   /* delete objects in Model created by LManLoadModel */ 
   vis_ModelDelete (model);

   datafileterm(filetype,datafun);
                   /* free objects */ 
   vdm_DataFunEnd (datafun);

   vdm_LManEnd (lman);
   vis_ModelEnd (model);
   return 0;
}

/*----------------------------------------------------------------------
                      load coordinate system indices
----------------------------------------------------------------------*/
static void
load_idtrancid(vdm_LMan *lman, vdm_Library *library, vis_RProp *rprop,
               vis_IdTran *idtrancid)
{
   Vint m;
   Vchar cidname[DATASET_MAXNAME];
   Vint ids, nds;
   vdm_Dataset *dataset;
   vdm_DataFun *datafun;
   Vint ncol;
   Vint *pcid;
                   /* get name of coordinate system id dataset */
   vis_RPropValueString (rprop,RPROP_LINK_CID,cidname);
                   /* find dataset */
   vdm_LibrarySearchDataset (library,cidname,1,&ids,&nds);
   vdm_LibraryGetDataset (library,ids,&dataset);
   vdm_DatasetGetNCol (dataset,&ncol);
   vdm_LManGetObject (lman,VDM_DATAFUN,(Vobject**)&datafun);
   pcid = (Vint*)malloc(ncol*sizeof(Vint));
   vdm_DataFunReadDataset (datafun,ids,pcid);
   for(m = 1; m <= ncol; m++) {
      vis_IdTranSetId (idtrancid,m,pcid[m-1]);
   }
   free(pcid);
}

/*----------------------------------------------------------------------
                      load rotation angle vector
----------------------------------------------------------------------*/
static void
load_staterotang(vdm_LMan *lman, vdm_Library *library, vis_RProp *rprop,
                 vis_State *staterotang)
{
   Vchar raname[DATASET_MAXNAME];
   Vint ids, nds;
   vdm_Dataset *dataset;
   vis_RProp *rproprotang;
   Vint enttype, subtype;
                   /* get name of rotation angle dataset */
   vis_RPropValueString (rprop,RPROP_LINK_ROTANG,raname);
                   /* find dataset */
   vdm_LibrarySearchDataset (library,raname,1,&ids,&nds);
   vdm_LibraryGetDataset (library,ids,&dataset);
   vdm_DatasetEntType (dataset,&enttype,&subtype);
                   /* read rotation angles */
   rproprotang = vis_RPropBegin ();
   vis_RPropDef (rproprotang,enttype,subtype);
   vis_RPropSetDatasetIndex (rproprotang,ids);
   vdm_LManLoadState (lman,staterotang,rproprotang);
   vis_RPropEnd (rproprotang);
}

/*----------------------------------------------------------------------
                      print stresses
----------------------------------------------------------------------*/
static void
print_stress(vdm_LMan *lman, vdm_Library *library, vis_Model *model)
{
   vdm_Dataset *dataset;
   Vchar dsname[DATASET_MAXNAME];
   Vlong lrec;
   Vint nrow, ncol, ntyp;
   Vint numdatasets;
   Vint nds, ndst_s;
   Vint *idst_s;
   Vint numids, ids[3];
   Vint nix;
   Vint numel, maxelno, elemnumber;
   Vint i, j, n;
   vis_Connect *connect;
   vsy_HashTable *hashcsys, *hasheldt;
   vis_IdTran *idtranesys;
   vis_GridFun *gridfun;
   vis_State *state;
   vis_State *staterotang;
   vis_RProp *rprop;
   Vfloat (*sten)[6];
   Vint system;
   Vint enttype, subtype;
   Vint cmatflag, cmatid, matflag;

                   /* determine maximum number of datasets */
   vdm_LibraryGetNumDatasets (library,&numdatasets);

                   /* allocate array for dataset indices */
   idst_s = (Vint*)malloc(numdatasets*sizeof(Vint));

                   /* search for stress results datasets */
   vdm_LibrarySearchDataset (library,"S.*EL:*",numdatasets,idst_s,&nds);
   vdm_LibrarySearchDataset (library,"S.*E:*",numdatasets,&idst_s[nds],&ndst_s);
   ndst_s += nds;
   if(ndst_s == 0) {
      free(idst_s);
      return;
   }
                   /* get Connect object created in Model */
   vis_ModelGetObject (model,VIS_CONNECT,(Vobject**)&connect);
   vis_ConnectNumber (connect,SYS_ELEM,&numel);

                   /* find maximum number of element nodes */
   vis_ConnectMaxElemNode (connect,&maxelno);

                   /* allocate arrays to fit maximum element node data */ 
   sten  = (Vfloat(*)[6])malloc(maxelno*6*sizeof(Vfloat));

                   /* create a grid function object */
   gridfun = vis_GridFunBegin ();
   vis_ConnectGridFun (connect,gridfun);

                   /* get HashTable of CoordSys objects */
   vis_ModelGetHashTable (model,VIS_COORDSYS,&hashcsys);
                   /* get HashTable of ElemDat objects */
   vis_ModelGetHashTable (model,VIS_ELEMDAT,&hasheldt);

                   /* install coordinate system ids into IdTran object */
   idtranesys = vis_IdTranBegin ();
   vis_IdTranDef (idtranesys,numel);

                   /* create state and install GridFun object */
   state = vis_StateBegin ();
   vis_StateSetObject (state,VIS_GRIDFUN,gridfun);

                   /* instance result property object */
   rprop = vis_RPropBegin ();

                   /* print first, middle and last element */
                   /* customize these ids if necessary */
   numids = 3;
   ids[0] = 1;  ids[1] = numel/2;  ids[2] = numel;

                   /* loop over stress datasets */
   for(i = 0; i < ndst_s; i++) {
      vdm_LibraryGetDataset (library,idst_s[i],&dataset);
      vdm_DatasetInq (dataset,dsname,&lrec,&nrow,&ncol,&ntyp);
      if(nrow != 6)  continue;
      vdm_DatasetEntType (dataset,&enttype,&subtype);

                   /* print header */
      printf("\n\nDataset: %s\n",dsname);
      printf("\nStresses\n");

                   /* set entity type and dataset index */ 
      vis_RPropDef (rprop,enttype,subtype);
      vis_RPropSetDatasetIndex (rprop,idst_s[i]);
                   /* load state */
      vdm_LManLoadState (lman,state,rprop);
                   /* get the system set in State by LManLoadState */ 
      vis_StateGetSystem (state,&system);
      if(system == STATE_LOCAL) {
         printf("local system\n");
      } else if(system == STATE_ROTANG) {
         printf("RotAng system\n");
      } else if(system == STATE_GLOBAL) {
         printf("global system\n");
      }
                   /* print stress components first */ 
      vis_StateSetDerive (state,VIS_TENSOR);

                   /* loop over requested elements */
      for(n = 0; n < numids; n++) {
         if(ids[n] == 0)  continue;
         vis_ConnectElemAssoc (connect,VIS_USERID,1,&ids[n],&elemnumber);
         printf("%8d, component stresses\n",elemnumber);

         nix = 1;
                   /* if element node get number of nodes */
         if(subtype == SYS_NODE) {
            vis_ConnectElemNum (connect,SYS_NODE,ids[n],&nix);
         }
         vis_StateData (state,1,&ids[n],(Vfloat*)sten);

                   /* loop over nodes in element */ 
         for(j = 0; j < nix; j++) {
            printf(" %12.5e %12.5e %12.5e %12.5e %12.5e %12.5e\n",
                    sten[j][0],sten[j][1],sten[j][2],
                    sten[j][3],sten[j][4],sten[j][5]);
         }
      }
                   /* print stress in global if originally in local */ 
      if(system == STATE_LOCAL || system == STATE_ROTANG) {
         vis_StateSetObject (state,VIS_GRIDFUN,gridfun);
         vis_StateSetHashTable (state,VIS_COORDSYS,hashcsys);
         vis_StateSetHashTable (state,VIS_ELEMDAT,hasheldt);
         if(system == STATE_LOCAL) {
            load_idtrancid (lman,library,rprop,idtranesys);
            vis_StateSetObject (state,VIS_IDTRAN,idtranesys);
         } else if(system == STATE_ROTANG) {
            staterotang = vis_StateBegin();
            vis_StateSetObject (staterotang,VIS_GRIDFUN,gridfun);
            load_staterotang (lman,library,rprop,staterotang);
            vis_StateSetObject (state,VIS_STATE_ROTANG,staterotang);
         }
         vis_StateTransform (state,STATE_GLOBAL,NULL);
         printf("global system\n");
         matflag = 0;

                   /* loop over requested elements */
         for(n = 0; n < numids; n++) {
            if(ids[n] == 0)  continue;
            vis_ConnectElemAssoc (connect,VIS_USERID,1,&ids[n],&elemnumber);
            printf("%8d, component stresses\n",elemnumber);
                   /* check for material system */ 
            vis_ConnectElemAssoc (connect,VIS_CMATFLAG,1,&ids[n],&cmatflag);
            if(cmatflag) {
               vis_ConnectElemAssoc (connect,VIS_CMATID,1,&ids[n],&cmatid);
               if(cmatid)  matflag = 1;
            }

            nix = 1;
                   /* if element node get number of nodes */
            if(subtype == SYS_NODE) {
               vis_ConnectElemNum (connect,SYS_NODE,ids[n],&nix);
            }
            vis_StateData (state,1,&ids[n],(Vfloat*)sten);

                   /* loop over nodes in element */
            for(j = 0; j < nix; j++) {
               printf(" %12.5e %12.5e %12.5e %12.5e %12.5e %12.5e\n",
                       sten[j][0],sten[j][1],sten[j][2],
                       sten[j][3],sten[j][4],sten[j][5]);
            }
         }
         if(matflag == 0)  continue;
                   /* now transform to material */ 
         vis_StateTransform (state,STATE_MATERIAL,NULL);
         printf("material system\n");
         for(n = 0; n < numids; n++) {
            if(ids[n] == 0)  continue;
            vis_ConnectElemAssoc (connect,VIS_USERID,1,&ids[n],&elemnumber);
            printf("%8d, component stresses\n",elemnumber);
            nix = 1;
            if(subtype == SYS_NODE) {
               vis_ConnectElemNum (connect,SYS_NODE,ids[n],&nix);
            }
            vis_StateData (state,1,&ids[n],(Vfloat*)sten);
            for(j = 0; j < nix; j++) {
               printf(" %12.5e %12.5e %12.5e %12.5e %12.5e %12.5e\n",
                       sten[j][0],sten[j][1],sten[j][2],
                       sten[j][3],sten[j][4],sten[j][5]);
            }
         }
      }
      printf("\n");
      if(system == STATE_ROTANG) {
         vis_StateEnd (staterotang);
      }
   }
                   /* free memory */
   vis_GridFunEnd (gridfun);
   vis_IdTranEnd (idtranesys);
   vis_StateEnd (state);
   vis_RPropEnd (rprop);
   free(idst_s);
   free(sten);
}

7.18. Example 10, Using a Monitor Function

This example illustrates using a monitor function to monitor the progress of opening a file using vdm_DataFunOpen(). The opening of a file can often be time consuming. In some cases the interface must read all the information on the file to be able to establish a basic understanding of the model and develop a list of the associated solution results. A separate callback function must be defined for each interface that requires monitoring. For example, the NASLib interface monitor function, naslib_monitor is required because of the appearance of the interface object as the first argument of the callback. This monitor function is set in NASLib using vdm_NASLibSetFunction(). A similar methodology is used for all interface objects.

In this example we use a generic function, monitor_loadmodel which only requires a DataFun object to test for the progress of the file opening operation. The progress may be monitored by querying for the progress phase and data source. The phase may be one of three integer values, VDM_PHASE_OPENMODEL, VDM_PHASE_OPENMODELCOMPLETE and VDM_PHASE_OPENRESULT. The source is an interface dependent string which describes the current position in the file which is being read. The phase is queried using the function vdm_DataFunGetInteger() with type VDM_PHASE and the source is queried using the function vdm_DataFunGetString() with type VDM_SOURCE. When the phase value VDM_PHASE_OPENMODELCOMPLETE is encountered, the simulation model may be loaded using vdm_LManLoadModel().

#include <stdlib.h>
#include "base/base.h"
#include "vis/visdata.h"
#include "vdm/vdm.h"

static void
monitor_loadmodel(vdm_DataFun *datafun)
{
   Vint phase;
   vis_Model *model;
   vis_Connect *connect;
   vdm_LMan *lman;
   Vchar source[256];
   Vint numnp, numel;

   vdm_DataFunGetInteger (datafun,VDM_PHASE,&phase);
   vdm_DataFunGetString (datafun,VDM_SOURCE,source);
   printf("phase= %d\n",phase);
   printf("source= %s\n",source);
                   /* load model when open model is complete */ 
   if(phase == VDM_PHASE_OPENMODEL) {
      printf("Opening model\n");
   } else if(phase == VDM_PHASE_OPENMODELCOMPLETE) {
      printf("Open model complete, load model\n");
      model = vis_ModelBegin ();
      lman = vdm_LManBegin ();
      vdm_LManSetObject (lman,VDM_DATAFUN,datafun);
      vdm_LManLoadModel (lman,model);
                   /* print number of nodes and elements */ 
      vis_ModelGetObject (model,VIS_CONNECT,(Vobject**)&connect);
      vis_ConnectNumber (connect,SYS_NODE,&numnp);
      vis_ConnectNumber (connect,SYS_ELEM,&numel);
      printf("Number of nodes= %d\n",numnp);
      printf("Number of elems= %d\n",numel);
      vis_ModelDelete (model);
      vis_ModelEnd (model);
      vdm_LManEnd (lman);
   } else if(phase == VDM_PHASE_OPENRESULT) {
      printf("Opening results\n");
   }
}

static void
nasfil_monitor(vdm_NASFil *nasfil, vdm_DataFun *datafun)
{
   monitor_loadmodel (datafun);
}

static void
naslib_monitor(vdm_NASLib *naslib, vdm_DataFun *datafun)
{
   monitor_loadmodel (datafun);
}

static void
sdrclib_monitor(vdm_SDRCLib *sdrclib, vdm_DataFun *datafun)
{
   monitor_loadmodel (datafun);
}

static void
fluentlib_monitor(vdm_FLUENTLib *fluentlib, vdm_DataFun *datafun)
{
   monitor_loadmodel (datafun);
}

/*----------------------------------------------------------------------
                      Using a Monitor Function
----------------------------------------------------------------------*/
int
main(int argc, char **argv)
{
   char inputfile[256];
   vdm_NASFil  *nasfil;
   vdm_NASLib  *naslib;
   vdm_SDRCLib *sdrclib;
   vdm_FLUENTLib *fluentlib;
   vdm_DataFun *datafun;
   Vint filetype;

   if(argc < 2) {
      fprintf(stderr,"Usage: %s inputfile\n",argv[0]);
      fprintf(stderr," inputfile is blank, 'bumper.unv' is assumed\n");
      strcpy(inputfile,"bumper.unv");
   } else {
      strcpy(inputfile,argv[1]);
   }

                   /* create data function object */
   datafun = vdm_DataFunBegin ();

                   /* determine file type from file extension */
   if(strstr(inputfile,".bdf") != NULL  ||
      strstr(inputfile,".dat") != NULL) {
      filetype = VDM_NASTRAN_BULKDATA;
      nasfil = vdm_NASFilBegin ();
      vdm_NASFilSetFunction (nasfil,SYS_FUNCTION_MONITOR,
                      (void(*)(vdm_NASFil*,Vobject*))nasfil_monitor,datafun);
      vdm_NASFilDataFun (nasfil,datafun);
      printf("Nastran Bulk Data File: %s\n",inputfile);
   } else if(strstr(inputfile,".op2") != NULL) {
      filetype = VDM_NASTRAN_OUTPUT2;
      naslib = vdm_NASLibBegin ();
      vdm_NASLibSetFunction (naslib,SYS_FUNCTION_MONITOR,
                      (void(*)(vdm_NASLib*,Vobject*))naslib_monitor,datafun);
      vdm_NASLibDataFun (naslib,datafun);
      printf("Nastran Output2 File: %s\n",inputfile);
   } else if(strstr(inputfile,".unv") != NULL) {
      filetype = VDM_SDRC_UNIVERSAL;
      sdrclib = vdm_SDRCLibBegin ();
      vdm_SDRCLibSetFunction (sdrclib,SYS_FUNCTION_MONITOR,
                      (void(*)(vdm_SDRCLib*,Vobject*))sdrclib_monitor,datafun);
      vdm_SDRCLibDataFun (sdrclib,datafun);
      printf("SDRC Universal File: %s\n",inputfile);
   } else if(strstr(inputfile,".cas") != NULL  ||
             strstr(inputfile,".msh") != NULL) {
      filetype = VDM_FLUENT_MESH;
      fluentlib = vdm_FLUENTLibBegin();
      vdm_FLUENTLibSetFunction (fluentlib,SYS_FUNCTION_MONITOR,
                  (void(*)(vdm_FLUENTLib*,Vobject*))fluentlib_monitor,datafun);
      vdm_FLUENTLibDataFun (fluentlib,datafun);
      printf("Fluent Mesh File: %s\n",inputfile);
   } else {
      fprintf(stderr,"Error: Bad input file %s\n",inputfile);
      exit(1);
   }
                   /* open library device */
   vdm_DataFunOpen (datafun,0,inputfile,filetype);

                   /* close library device and delete interface */
   vdm_DataFunClose (datafun);
   vdm_DataFunEnd (datafun);
   if(filetype == VDM_NASTRAN_BULKDATA) {
      vdm_NASFilEnd (nasfil);
   } else if(filetype == VDM_NASTRAN_OUTPUT2) {
      vdm_NASLibEnd (naslib);
   } else if(filetype == VDM_SDRC_UNIVERSAL) {
      vdm_SDRCLibEnd (sdrclib);
   } else if(filetype == VDM_FLUENT_MESH) {
      vdm_FLUENTLibEnd (fluentlib);
   }
   return 0;
}

7.19. Example 11, Reading Multiple Domains

This example illustrates reading output from a device interface which supports multiple domains. Multiple domains are normally associated with the execution of a simulation program which has been run in parallel mode. Domain decomposition is naturally associated with highly parallelized simulations. The function vdm_DataFunNumDomains() has been specifically designed to determine the number of domains. It may be optionally called before opening the library device. If the number of domains is zero, then the library device does not support multiple domains or the specific file does not contain multiple domains. If the number of domains is non-zero then each domain may be opened individually with a separate call to vdm_DataFunOpen() in which the domain to open is specified in the second argument. The motivation for opening each domain individually is to perform this operation in parallel for each domain. This is guaranteed to be able to be done by any device interface which supports multiple domains.

#include <stdio.h>
#include "base/base.h"
#include "vdm/vdm.h"

                   /* flag to always open all domains */
static Vint openall = 0;

/*----------------------------------------------------------------------
                      Reading Multiple Domains
----------------------------------------------------------------------*/
int
main(int argc, char **argv)
{
   char inputfile[256];
   vdm_OpenFOAMLib *openfoamlib, **ofdom;
   vdm_SDRCLib     *sdrclib, **sddom;
   vdm_DataFun     *datafun, **dfdom;
   vdm_Library     *library;
   Vint filetype, numdomains, n;

   if(argc < 2) {
      fprintf(stderr,"Usage: %s inputfile\n",argv[0]);
      fprintf(stderr," inputfile is blank, 'cantilever.unv' is assumed\n");
      strcpy(inputfile,"cantilever.unv");
   } else {
      strcpy(inputfile,argv[1]);
   }
                   /* create data function object */
   datafun = vdm_DataFunBegin ();

                   /* determine file type from file extension */
   if(strstr(inputfile,"controlDict") != NULL) {
      filetype = SYS_OPENFOAM;
      openfoamlib = vdm_OpenFOAMLibBegin ();
      vdm_OpenFOAMLibDataFun (openfoamlib,datafun);
      printf("OpenFOAM File: %s\n",inputfile);
   } else if(strstr(inputfile,".unv") != NULL) {
      filetype = SYS_SDRC_UNIVERSAL;
      sdrclib = vdm_SDRCLibBegin ();
      vdm_SDRCLibDataFun (sdrclib,datafun);
      printf("SDRC Universal File: %s\n",inputfile);
   } else {
      fprintf(stderr,"Error: Bad input file %s\n",inputfile);
      exit(1);
   }
                   /* query file for number of domains */
   vdm_DataFunNumDomains (datafun,inputfile,filetype,&numdomains);
   printf("numdom= %d\n",numdomains);
                   /* open all domains */ 
   if(numdomains == 0 || openall) {
      printf("Opening all domains\n");
      vdm_DataFunOpen (datafun,0,inputfile,filetype);
      vdm_DataFunGetLibrary (datafun,&library);
      vdm_LibraryTOC (library,"*",0);
      vdm_DataFunClose (datafun);
                   /* open individual domains, each may be in parallel */ 
   } else {
      printf("Opening individual domains\n");
                   /* instance multiple datafun objects */
      dfdom = (vdm_DataFun**)malloc (numdomains*sizeof(vdm_DataFun*));
      for(n = 0; n < numdomains; n++) {
         dfdom[n] = vdm_DataFunBegin ();
      }
      if(filetype == SYS_SDRC_UNIVERSAL) {
         sddom = (vdm_SDRCLib**)malloc (numdomains*sizeof(vdm_SDRCLib*));
         for(n = 0; n < numdomains; n++) {
            sddom[n] = vdm_SDRCLibBegin ();
            vdm_SDRCLibDataFun (sddom[n],dfdom[n]);
         }
      } else if(filetype == SYS_OPENFOAM) {
         ofdom =(vdm_OpenFOAMLib**)malloc (numdomains*sizeof(vdm_OpenFOAMLib*));
         for(n = 0; n < numdomains; n++) {
            ofdom[n] = vdm_OpenFOAMLibBegin ();
            vdm_OpenFOAMLibDataFun (ofdom[n],dfdom[n]);
         }
      }
                   /* open all datafun objects */
      for(n = 0; n < numdomains; n++) {
         printf("Opening file for processor= %d\n",n+1);
         vdm_DataFunOpen (dfdom[n],n+1,inputfile,filetype);
      }
                   /* work with each datafun: in this case, print TOC */
      for(n = 0; n < numdomains; n++) {
         printf("\nWorking with processor= %d\n",n+1);
         vdm_DataFunGetLibrary (dfdom[n],&library);
         vdm_LibraryTOC (library,"*",0);
      }
                   /* close all datafun objects */
      for(n = 0; n < numdomains; n++) {
         printf("Closing file for processor= %d\n",n+1);
         vdm_DataFunClose (dfdom[n]);
      }
                   /* delete multiple datafun objects */
      if(filetype == SYS_SDRC_UNIVERSAL) {
         for(n = 0; n < numdomains; n++) {
            vdm_SDRCLibEnd (sddom[n]);
         }
         free (sddom);
      } else if(filetype == SYS_OPENFOAM) {
         for(n = 0; n < numdomains; n++) {
            vdm_OpenFOAMLibEnd (ofdom[n]);
         }
         free (ofdom);
      }
      for(n = 0; n < numdomains; n++) {
         vdm_DataFunEnd (dfdom[n]);
      }
      free (dfdom);
   }
                   /* delete initial interface */
   printf("Cleaning up\n");
   vdm_DataFunEnd (datafun);
   if(filetype == SYS_OPENFOAM) {
      vdm_OpenFOAMLibEnd (openfoamlib);
   } else if(filetype == SYS_SDRC_UNIVERSAL) {
      vdm_SDRCLibEnd (sdrclib);
   }
   return 0;
}

7.20. Example 12, Load Model and Results and Save to Native File

This example illustrates reading the model and results data from an input file and saving it to a Native file. There are two possible Native file formats, VDM_NATIVE, which uses a proprietary file format and VDM_NATIVE_HDF which uses the public HDF5 file format.

#include <stdlib.h>
#include "base/base.h"
#include "vis/visdata.h"
#include "vdm/vdm.h"
#include "datafile.h"

static void
loadandsave_result(vdm_LMan *lman, vdm_LMan *lmanw,
                   vdm_Library *library, vis_Model *model);

/*----------------------------------------------------------------------
                     Load Model and Results and Save to Native File
----------------------------------------------------------------------*/
int
main(int argc, char **argv)
{
   char inputfile[256];
   char outputfile[256];
   vdm_DataFun *datafun;
   vdm_Library *library;
   vdm_LMan    *lman;
   Vint filetype;
   Vint numnp, numel;
   vis_Model *model;
   vis_Connect *connect;
   Vint ierr;
   vdm_DataFun *datafunw;
   vdm_LMan    *lmanw;
   vdm_NatLib  *natlib;
   Vint filetypew;

                   /* check input arguments */ 
   if(argc < 3) {
      fprintf(stderr,"Usage: %s inputfile outputfile\n",argv[0]);
      exit(1);
   } else {
      strcpy(inputfile,argv[1]);
      strcpy(outputfile,argv[2]);
   }
                   /* create input data function object */
   datafun = vdm_DataFunBegin ();
   datafiletype(inputfile,&filetype);
   if(filetype == 0) {
      fprintf(stderr,"Error: Bad input file %s\n",inputfile);
      exit(1);
   }
   datafileinit(filetype,datafun);
                   /* set convention to support sparse datasets */
   vdm_DataFunSetConvention (datafun,VDM_CONVENTION_SPARSE);
                   /* open library device */
   vdm_DataFunOpen (datafun,0,inputfile,filetype);
                   /* check for error */
   ierr = vdm_DataFunError(datafun);
   if(ierr) {
      fprintf(stderr,"Error: opening file %s\n",inputfile);
      exit(0);
   }
                   /* select native file type, use file extension .vdm */ 
   filetypew = VDM_NATIVE;
                   /* uncomment below for HDF5 file type, use .vh5 */
/*
*/
   filetypew = VDM_NATIVE_HDF5;
                   /* create output data function object */ 
   datafunw = vdm_DataFunBegin ();
   natlib = vdm_NatLibBegin ();
   vdm_NatLibDataFun (natlib,datafunw);
                   /* new file */
   vdm_DataFunSetStatus (datafunw,VDM_STATUS_NEW);
                   /* open library device */
   vdm_DataFunOpen (datafunw,0,outputfile,filetypew);
                   /* check for error */
   ierr = vdm_DataFunError(datafunw);
   if(ierr) {
      fprintf(stderr,"Error: opening file %s\n",outputfile);
      exit(1);
   }
                   /* use Library Manager object to save model */
   lmanw = vdm_LManBegin ();
   vdm_LManSetObject (lmanw,VDM_DATAFUN,datafunw);
   vdm_LManSetParami (lmanw,LMAN_SAVERESULT_PRE,SYS_DOUBLE);

                   /* instance Model object for simulation model */ 
   model = vis_ModelBegin();

                   /* use Library Manager object to load model */ 
   lman = vdm_LManBegin ();
   vdm_LManSetObject (lman,VDM_DATAFUN,datafun);
   vdm_LManLoadModel (lman,model);

                   /* get Connect object created in Model */ 
   vis_ModelGetObject (model,VIS_CONNECT,(Vobject**)&connect);
   vis_ConnectNumber (connect,SYS_NODE,&numnp);
   vis_ConnectNumber (connect,SYS_ELEM,&numel);
   printf("number of nodes= %d\n",numnp);
   printf("number of elems= %d\n",numel);

                   /* get library object */ 
   vdm_DataFunGetLibrary (datafun,&library);

                   /* save model */ 
   vdm_LManSaveModel (lmanw,model);
                   /* load and save all results */ 
   loadandsave_result (lman,lmanw,library,model);

                   /* close library devices */ 
   vdm_DataFunClose (datafun);
   vdm_DataFunClose (datafunw);

                   /* delete objects in Model created by LManLoadModel */ 
   vis_ModelDelete (model);

   datafileterm(filetype,datafun);
                   /* free objects */ 
   vdm_DataFunEnd (datafun);
   vdm_LManEnd (lman);
   vis_ModelEnd (model);

   vdm_DataFunEnd (datafunw);
   vdm_LManEnd (lmanw);
   vdm_NatLibEnd (natlib);
   return 0;
}

/*----------------------------------------------------------------------
                      load and save results
----------------------------------------------------------------------*/
static void
loadandsave_result(vdm_LMan *lman, vdm_LMan *lmanw,
                   vdm_Library *library, vis_Model *model)
{
   Vint i;
   vdm_Dataset *dataset;
   Vchar dsname[DATASET_MAXNAME];
   Vchar dsroot[DATASET_MAXNAME];
   Vchar caux[DATASET_MAXNAME];
   Vchar andata[ATTRIBUTE_MAXVALUE];
   Vchar ancont[ATTRIBUTE_MAXVALUE];
   Vchar andesc[ATTRIBUTE_MAXVALUE];
   Vlong lrec;
   Vint nrow, ncol, ntyp;
   Vint numdatasets;
   Vint istate, ihistory, iredmat;
   vis_Connect *connect;
   vis_GridFun *gridfun;
   vis_State *state;
   vis_History *history;
   vis_RedMat *redmat;
   vis_RProp *rprop;
   Vint type, hist, cplx, sect, enttype, subtype, datatype;
   Vint nqua, iqua[SYS_NQUA_MAX];
   Vchar cqua[DATASET_MAXNAME];
   Vint id1, id2, id3;

                   /* determine maximum number of datasets */
   vdm_LibraryGetNumDatasets (library,&numdatasets);

                   /* get Connect object created in Model */
   vis_ModelGetObject (model,VIS_CONNECT,(Vobject**)&connect);

                   /* create a grid function object */
   gridfun = vis_GridFunBegin ();
   vis_ConnectGridFun (connect,gridfun);

                   /* create state and install GridFun object */
   state = vis_StateBegin ();
   vis_StateSetObject (state,VIS_GRIDFUN,gridfun);
                   /* create history and install GridFun object */
   history = vis_HistoryBegin ();
   vis_HistorySetObject (history,VIS_GRIDFUN,gridfun);
                   /* create redmat object */
   redmat = vis_RedMatBegin ();

                   /* create result property object */
   rprop = vis_RPropBegin ();

                   /* loop over datasets */
   for(i = 0; i < numdatasets; i++) {
      vdm_LibraryGetDataset (library,i,&dataset);

                   /* identify result quantity */ 
      vdm_DatasetResult (dataset,dsroot,&type,&hist,
                         &nqua,iqua,cqua,&cplx,caux,&sect,&enttype,&subtype,
                         &id1,&id2,&id3);
                   /* not a result */ 
      if(type == SYS_RES_NONE) {
         continue;
      }
                   /* get dataset name and parameters */ 
      vdm_DatasetInq (dataset,dsname,&lrec,&nrow,&ncol,&ntyp);
                   /* get Description attribute, Model datasets only */ 
      vdm_DatasetDescription (dataset,andesc);
                   /* a model dataset */ 
      if(andesc[0] != '\0') {
         continue;
      }

      istate = 0;
      ihistory = 0;
      iredmat = 0;
                   /* RedMat */ 
      if(enttype == SYS_DOF) {
         iredmat = 1;
                   /* Node, Element, Mode, Panel, Particle History or State */ 
      } else if(enttype == SYS_NODE || enttype == SYS_ELEM  ||
                enttype == SYS_MODE || enttype == SYS_PANEL ||
                enttype == SYS_PARTICLE) {
         if(hist) {
            ihistory = 1;
         } else {
            istate = 1;
         }
      }
                   /* get DataType attribute */ 
      vdm_DatasetDataType (dataset,andata,&datatype);

                   /* get Contents attribute */ 
      vdm_DatasetContents (dataset,ancont);

                   /* print dataset name */
      printf("\n\nDataset: %s\n",dsname);

                   /* print DataType and Contents */ 
      printf("DataType: %s\n",andata);
      printf("Contents: %s\n",ancont);

                   /* load from dataset */ 
      vis_RPropDef (rprop,enttype,subtype);
      vis_RPropSetDatasetIndex (rprop,i);
      if(iredmat) {
         vdm_LManLoadRedMat (lman,redmat,rprop);
         vdm_LManSaveRedMat (lmanw,redmat,rprop);
      } else if(istate) {
         vdm_LManLoadState (lman,state,rprop);
         vdm_LManSaveState (lmanw,state,rprop);
      } else if(ihistory) {
         vdm_LManLoadHistory (lman,history,rprop);
         vdm_LManSaveHistory (lmanw,history,rprop);
      }
   }
                   /* free memory */
   vis_GridFunEnd (gridfun);
   vis_StateEnd (state);
   vis_HistoryEnd (history);
   vis_RedMatEnd (redmat);
   vis_RPropEnd (rprop);
}

7.21. Example 13, Save Model Using MemLib

This example illustrates reading the model and an optional results dataset from an input file and saving it to a memory object managed by the MemLib object. Initially the input file is opened and the model and optional result dataset are loaded into a Model and State object. The input file is closed and the model is saved to a MemLib object. The user can then query for the length of the memory object in bytes and allocate user memory for the data. This is done using the vdm_MemLibStreamNum() and vdm_MemLibStream() functions. The same operation is performed on an optional result dataset.

For illustration perposes the user memory objects are restored to a single MemLib object. A “TOC” is performed to show the restored datasets.

#include <stdlib.h>
#include "base/base.h"
#include "vis/visdata.h"
#include "vdm/vdm.h"
#include "datafile.h"

/*----------------------------------------------------------------------
                     Save Model Using MemLib
----------------------------------------------------------------------*/
int
main(int argc, char **argv)
{
   char inputfile[256];
   vdm_DataFun   *datafun;
   vdm_LMan      *lman;
   vdm_MemLib    *memlib;
   vdm_Library   *library;
   vis_RProp     *rprop;
   vis_Model     *model;
   vis_State     *state;
   vis_GridFun   *gridfun;
   vis_Connect   *connect;
   Vint filetype, idst, ndst, hasstate;
   Vlong nbytes;
   Vchar *bytesmodel, *bytesdisp;
   Vint ierr;

                   /* check input arguments */ 
   if(argc < 2) {
      fprintf(stderr,"Usage: %s inputfile [result_dataset]\n",argv[0]);
      fprintf(stderr," inputfile is blank, 'cantilever.unv' is assumed\n");
      strcpy(inputfile,"cantilever.unv");
   } else {
      strcpy(inputfile,argv[1]);
   }
                   /* create data function object */
   datafun = vdm_DataFunBegin ();

   datafiletype(inputfile,&filetype);
   if(filetype == 0) {
      fprintf(stderr,"Error: Bad input file %s\n",inputfile);
      exit(1);
   }
   datafileinit(filetype,datafun);
                   /* open library device */
   vdm_DataFunOpen (datafun,0,inputfile,filetype);
                   /* check for error */
   ierr = vdm_DataFunError(datafun);
   if(ierr) {
      fprintf(stderr,"Error: opening file %s\n",inputfile);
      exit(0);
   }
                   /* load model */
   lman = vdm_LManBegin ();
   vdm_LManSetObject (lman,VDM_DATAFUN,(Vobject*)datafun);
   model = vis_ModelBegin ();
   vdm_LManLoadModel (lman,model);
   vdm_LManTOC (lman,"*");

                   /* load result if it exists */
   hasstate = 0;
   if(argc >= 3) {
      vdm_DataFunGetLibrary (datafun,&library);
      vdm_LibrarySearchDataset (library,argv[2],1,&idst,&ndst);
      if(ndst) {
         hasstate = 1;
         rprop = vis_RPropBegin ();
         vis_RPropDef (rprop,SYS_NODE,SYS_NONE);
         vis_RPropSetDatasetName (rprop,argv[2]);
         state = vis_StateBegin ();
         gridfun = vis_GridFunBegin ();
         vis_ModelGetObject (model,VIS_CONNECT,(Vobject**)&connect);
         vis_ConnectGridFun (connect,gridfun);
         vis_StateSetObject (state,VIS_GRIDFUN,(Vobject*)gridfun);
         vdm_LManLoadState (lman,state,rprop);
      }
   }
                   /* close and clean-up input file */
   vdm_DataFunClose (datafun);
   datafileterm (filetype,datafun);
   vdm_DataFunEnd (datafun);
   vdm_LManEnd (lman);

                   /* save model in first MemLib DataFun */
   datafun = vdm_DataFunBegin ();
   memlib = vdm_MemLibBegin ();
   vdm_MemLibDataFun (memlib,datafun);
   vdm_DataFunSetStatus (datafun,VDM_STATUS_NEW);
   vdm_DataFunOpen (datafun,0,NULL,VDM_MEMORY);
   lman = vdm_LManBegin ();
   vdm_LManSetObject (lman,VDM_DATAFUN,(Vobject*)datafun);
   vdm_LManSaveModel (lman,model);
   vdm_LManEnd (lman);

                   /* determine size and save model data in memory */
   vdm_MemLibStreamNum (memlib,&nbytes);
   printf("nbytes with model= %lld\n",nbytes);
   bytesmodel = (Vchar*)malloc(nbytes);
   vdm_MemLibStream (memlib,bytesmodel);
   vdm_DataFunClose (datafun);
   vdm_DataFunEnd (datafun);
   vdm_MemLibEnd (memlib);

                   /* save result in second MemLib DataFun */
   if(hasstate) {
      datafun = vdm_DataFunBegin ();
      memlib = vdm_MemLibBegin ();
      vdm_MemLibDataFun (memlib,datafun);
      vdm_DataFunSetStatus (datafun,VDM_STATUS_NEW);
      vdm_DataFunOpen (datafun,0,NULL,VDM_MEMORY);
      lman = vdm_LManBegin ();
      vdm_LManSetObject (lman,VDM_DATAFUN,(Vobject*)datafun);
      vdm_LManSaveState (lman,state,rprop);
      vdm_LManEnd (lman);
      vis_RPropEnd (rprop);
      vis_StateEnd (state);
      vis_GridFunEnd (gridfun);
   }
   vis_ModelDelete (model);
   vis_ModelEnd (model);

                   /* determine size and save result in memory */
   if(hasstate) {
      vdm_MemLibStreamNum (memlib,&nbytes);
      printf("nbytes with result= %lld\n",nbytes);
      bytesdisp = (Vchar*)malloc(nbytes);
      vdm_MemLibStream (memlib,bytesdisp);
      vdm_DataFunClose (datafun);
      vdm_DataFunEnd (datafun);
      vdm_MemLibEnd (memlib);
   }
                   /* re-load model */
   datafun = vdm_DataFunBegin ();
   memlib = vdm_MemLibBegin ();
   vdm_MemLibDataFun (memlib,datafun);
   vdm_DataFunSetStatus (datafun,VDM_STATUS_OLD);
   vdm_DataFunOpen (datafun,0,bytesmodel,VDM_MEMORY);

                   /* append state onto model */
   if(hasstate) {
      vdm_DataFunAppend (datafun,bytesdisp,SYS_MEMORY);
   }

   lman = vdm_LManBegin ();
   vdm_LManSetObject (lman,VDM_DATAFUN,(Vobject*)datafun);
   vdm_LManTOC (lman,"*");
   vdm_MemLibEnd (memlib);
   vdm_DataFunEnd (datafun);
   vdm_LManEnd (lman);
   free(bytesmodel);
   if(hasstate) {
      free(bytesdisp);
   }

   return 0;
}