UMACR1.C  - - Example



    umacr?.f files in  the user directory  allow one to create user macro commands.  To set up a user macro command one needs to edit the file
umacr1.f (for example) to include the code one wishes to have executed when the user macro is called from inside FEAP.  The interface can be programed in fortran or it can be programed in C.  In the example that follows a C interface is utilzed.


    The main steps in creating a user macro whether in C or Fortran are The macro name is set in the common variable uct in the common block umac1.  When uct is equal to 'mac1' (for umacr1.f or .c) it should be set to whatever you wish.  On subsequent calls with this name the input argument lct is a string parameter for the command and the input arguments ctl(3) is a real*8 array of parameters.

       A example umacr1.c is given below.  The name of the user macro is set to revr.  The macro itself is used for translating binary restart files from systems that place the leading bit first in a word to systems that place it last and vice-versa.  The use of C as opposed to Fortran is employed here merely for the purposes of illustrating how to interface to C code.  The same operation could like have been written in Fortran also.

      The command itself takes one argument, the name of the original restart file, and outputs a word swapped version of the file using the same name appended with the suffix ".rev".


Source file:

/* $Id: umacr1.c,v 1.2 1999/05/10 08:10:49 sanjay Exp $ */

#include <stdio.h>  /* C Header for input/output needed for this particular user macro routine */

struct {                 /* C definition for common block umac1.h */
    char uct[4];
} umac1_;

struct {                   /*C definition for common block sdata.h */
    int ndf, ndm, nen1, nst, nneq;
} sdata_;

struct {                 /* C definition for common block cdata.h */
    int numnp, numel, nummat, nen, neq, ipr;
} cdata_;
 

void umacr1_(char (* lct)[15],double (* ctl)[3], int *prt)          /* Use trailing underscore for C routine names; define input types */
{

  /*  F E A P  A Finite Element Analysis Program

      Copyright (c) 1984-1999: Robert L. Taylor

      Purpose:  User interface for adding solution command language
                instructions.  C language interface by Sanjay Govindjee

      Inputs:
         (*lct)          - Pointer to Command character parameter string 15
         (*ctl)[3]    - Command numerical parameters
         *prt         - Flag, output if true

      Outputs:
         N.B.  Users are responsible for command actions.  See
               programmers manual for example.
  */

       double get_put_double(FILE *,FILE *);             /* define variables that you will be using */

       int i,get_put_integer(FILE *,FILE *);
       int nnpo,nnlo,nnmo,ndmo,ndfo,fl9sg,dummyi;
       int md,mq,nrt,nh1,nh2;

       FILE *fp , *fpout;

       char out[20];
       void get_put_header(FILE *,FILE *);

       /* Set macro name to REVR in common block umac1 */       /*Set uct variable to name you desire if uct = mac1 */
       if( strcmp(umac1_.uct,"mac1")==0 ) {                                /* command will be known to FEAP as REVR */
                strcpy(umac1_.uct,"revr");
                return;
       }

/* From here down is the source that gets executed when one calls REVR from FEAP;
most of it is associated with the vagaries of C and Fortran file formats and handling.
The order of the reading etc. is compatible with FEAP v7.1f */

       /* Compact lct to strip trailing blanks */           /* LCT comes in with blanks that pad the string to length 15 */
       for(i=0;i<15;i++) if ( (*lct)[i] == ' ') break;       /* with C these need to be stripped; do by inserting an EOS marker */
         (*lct)[i] = '\0';

       /* Open restart file */
       if((fp = fopen((*lct),"r")) == NULL) {
         printf("ERROR * * Can not open file %s\n",lct);
         return;
       }

       /* Open revised restart file */
       strcpy(out,(*lct));
       strcat(out,".rev");
       if((fpout = fopen(out,"w")) == NULL) {
         printf("ERROR * * Can not open file %s\n",out);
         if(fp != NULL) fclose(fp);
         return;
       }

        /* Read/Write line 1 */
        get_put_header(fp,fpout);
        nnpo = get_put_integer(fp,fpout);
        nnlo = get_put_integer(fp,fpout);
        nnmo = get_put_integer(fp,fpout);
        ndmo = get_put_integer(fp,fpout);
        ndfo = get_put_integer(fp,fpout);
        fl9sg = get_put_integer(fp,fpout);
        get_put_header(fp,fpout);

        if ( nnpo != cdata_.numnp || nnlo != cdata_.numel ||
             nnmo != cdata_.nummat || ndmo != sdata_.ndm ||
             ndfo != sdata_.ndf ) {
               printf("\nERROR * * Restart file does not match input file\n");
               fclose(fp);
               fclose(fpout);
               return;
        }

        /* Read/Write line 2 */
        get_put_header(fp,fpout);
        for(i=0;i<3;i++) get_put_double(fp,fpout);    /* theta(3) */
        /* nrk,nrc,nrm */
        for(i=0;i<3;i++) get_put_integer(fp,fpout);
        nrt = get_put_integer(fp,fpout);
        /* noi,numint */
        for(i=0;i<2;i++) get_put_integer(fp,fpout);
        /* alpha, gtan(3) */
        for(i=0;i<4;i++) get_put_double(fp,fpout);
        get_put_header(fp,fpout);

        /* Read/Write line 3 */
        get_put_header(fp,fpout);
        get_put_integer(fp,fpout); /* ntstep */
        /* ttim, dt */
        for(i=0;i<2;i++) get_put_double(fp,fpout);
        /* u(nneq*3) */
        for(i=0;i<sdata_.nneq*3;i++) get_put_double(fp,fpout);
        get_put_header(fp,fpout);

        /* Read/Write line 4 */
        get_put_header(fp,fpout);
        md = get_put_integer(fp,fpout);
        get_put_integer(fp,fpout); /* mv */
        get_put_integer(fp,fpout); /* mf */
        mq = get_put_integer(fp,fpout);
        get_put_header(fp,fpout);

        if( md != 0 ) {
          /* Read/Write line 4b */
          get_put_header(fp,fpout);
          /* EVAL */
          for(i=0;i<mq;i++) get_put_double(fp,fpout);
          get_put_header(fp,fpout);

          /* Read/Write line 4c */
          get_put_header(fp,fpout);
          /* EVEC*/
          for(i=0;i<mq*cdata_.neq;i++) get_put_double(fp,fpout);
          get_put_header(fp,fpout);
        }

        /* Read/Write line 5 */
        get_put_header(fp,fpout);
        /* prop,rlnew,c0,cs01,cs02,ds0,r,det0,xn */
        for(i=0;i<9;i++) get_put_double(fp,fpout);
        fl9sg = get_put_integer(fp,fpout); /* fl9 */
        get_put_header(fp,fpout);

        if ( fl9sg != 0 ) {
          /* Read/Write line 5a */
          get_put_header(fp,fpout);
          /* VEL */
          for(i=0;i<nrt*sdata_.nneq;i++) get_put_double(fp,fpout);
          get_put_header(fp,fpout);
        }

        /* Read/Write line 6 */
        get_put_header(fp,fpout);
        /* FTN */
        for(i=0;i<4*sdata_.nneq;i++) get_put_double(fp,fpout);
        get_put_header(fp,fpout);

        /* Read/Write line 7 */
        get_put_header(fp,fpout);
        get_put_double(fp,fpout); /* rnmax */
        nh1 = get_put_integer(fp,fpout);
        nh2 = get_put_integer(fp,fpout);
        /* H */
        for(i=0;i<nh2-nh1+1;i++) get_put_double(fp,fpout);
        get_put_header(fp,fpout);
 

       /* Close files */
       fclose(fpout);
       fclose(fp);

}

double get_put_double(FILE *fpi,FILE *fpo) {
/* Read 8 bytes for a double and then write it out in reverse */

  union {
    char c[8];
    double value;
  } double_var;

  int i;

  for(i=7;i>-1;i--) double_var.c[i] = getc(fpi);

  for(i=0;i<8;i++) putc(double_var.c[i],fpo);

  return(double_var.value);

}

int get_put_integer(FILE *fpi,FILE *fpo) {
/* Read 4 bytes for a integer and then write it out in reverse */

  union {
    char c[4];
    int value;
  } int_var;

  int i;

  for(i=3;i>-1;i--) int_var.c[i] = getc(fpi);

  for(i=0;i<4;i++) putc(int_var.c[i],fpo);

  return(int_var.value);

}

void get_put_header(FILE *fpi,FILE *fpo) {
/* Read 4 bytes for the recorde header/trailer and write it out in reverse */
  char c[4];
  int i;

  for(i=3;i>-1;i--)  c[i] = getc(fpi);
  for(i=0;i<4;i++) putc(c[i],fpo);

  return;
}
%