/*
** Header: @(#) castofranc.c 1.8 10 May 1996 17:56:40  Last Update: 01 Aug 1995
*/

/********************************************************************
   This file translates one or more casca files to an input file
   suitable for Franc with capability of layers.
  
   AUTHOR : Dr. Daniel Swenson, originally for cracker
            Hacked by Sudhir
            Rehacked by Krish

            Complete rewrite: 8-17-94  Mark A. James
            
********************************************************************/


/*
**  General comment by Dan Swenson about the purpose of this program.  
**
**  The ansys/franc translator does a search to ensure that faces are never 
**  added that completely encircle an empty space unless that is actually a 
**  hole.  If that happens (that is, you add a circle of elements around a 
**  space), the topology gets confused and thinks that the space is a hole 
**  (face type 1, I believe).  Then when you try to add the last element to 
**  fill the hole, things don't work right.  We talked to Wash about this 
**  and there did not seem to be a way around the problem other than ensuring
**  that this situation never occurrs.  The translator's search makes sure 
**  that elements are added in a wave, never encircling a space unless a hole 
**  is really intended.  Experience shows that this may regularly be 
**  necessary for ansys generated meshes, and periodically necessary for 
**  casca generated meshes.  
**
*/

/*
**  Note that this software assumes T6 and Q8 elements... 
**  No Q4 and T3!
*/

#include <stdio.h>
#include <string.h>
#include <stdlib.h>


#define Calloc(n,t) ((t*)calloc( n, sizeof(t) ))
#define Free(p)  if(p) { free( p ) ; }
#define Realloc( p, n, t ) ((t*)realloc( p, (n)*sizeof(t) ))

#define REC_NUM 10
#define REC_LEN 5

#define LEN   512 
#define NUMNODES 8              /* Number of nodes for each element */
#define NUMEDGES 4              /* Number of edges for each element */
#define NUM_MAT_PROPS 12

#ifndef True
#define True    1
#define False   0
#endif

#define Prob_Undefined      -1
#define Prob_Axisymmetric   0
#define Prob_PlaneStress    1
#define Prob_PlaneStrain    2
#define Prob_Bending        3


typedef char Name[LEN] ;

typedef struct {
   double   x, y ;
   int      number ;
}  Node ;

typedef struct {
   int      mat_id ;
   double   mat_props[NUM_MAT_PROPS];
}  Material ;

typedef struct {
   int    head ;
   int    tail ;
   int    right_elem ;
   int    right_elem_edge ;
   int    left_elem ;
   int    left_elem_edge ;
}  Edge ;

typedef struct {
   int    num_nodes ;
   int    node[NUMNODES] ;        /* Nodes for each element */
   int    material ;
   int    map_status ;
   int    edges[NUMEDGES] ;
}  Element ;

typedef struct {
    Name      file_name ;
    Name      title ;
    int       num_nodes ;
    int       num_elems ;
    int       num_mats ;
    int       num_edges ;
    int       num_edges_alloced ;
    int       num_mapped ;
    int       prob_type ;
    int       prev_elem ;
    int       *mat_map ;
    int       *elem_map ;
    Material  *mats ;
    Node      *nodes ;
    Element   *elems ;
    Edge      *edges ;
}  Layer ;

typedef struct {
    Name       file_name ;
    Name       title ;
    int        num_layers ;
    int        num_mats ;
    int        one_mat ;
    int        renumber_elements ;
    int        prob_type ;
    Layer      *layers ;
}  Mesh ;




void LayerAllocate( layer ) 
    Layer  *layer ;
{
    layer->mat_map = Calloc( layer->num_mats, int ) ;
    layer->mats = Calloc( layer->num_mats, Material ) ;
    layer->elem_map = Calloc( layer->num_elems, int ) ;
    layer->elems = Calloc( layer->num_elems, Element ) ;
    layer->nodes = Calloc( layer->num_nodes, Node ) ;
}

void LayerFree( layer ) 
    Layer  *layer ;
{
}


void extract( line, len, num, n )
    char *line ;
    int len; /* length od each sub-record to extract */
    int num; /* number of sub-records to extract */
    int *n; 
{
    char   dig[256] ;
    int    i ;
    
    if (len > 255) {
        perror(" extract: length out of range") ;
    }
    
    for( i = 0  ; i < num ; ++i ) {
        strncpy( dig, line+i*len, len ) ;
        dig[len] = '\0' ;
        n[i] = atoi(dig) ;
    }
}


void ReadLayer( layer, fp )
    Layer  *layer ;
    FILE   *fp ;
{
    char   line[LEN];
    int    rec[REC_NUM];

    int    i, j ;
    int    idum ;
    
    fgets( layer->title, LEN, fp ) ;
    
    fgets(line, LEN, fp);
    sscanf(line, "%d %d %d %d", &layer->num_nodes, &layer->num_elems,
        &layer->num_mats, &layer->prob_type);

    LayerAllocate( layer ) ;
    
    for( i = 0 ; i < layer->num_mats ; ++i ) {
        fscanf( fp, "%d", &layer->mats[i].mat_id);
        for ( j = 0 ; j < NUM_MAT_PROPS; ++j ){
           fscanf( fp, "%lf", &layer->mats[i].mat_props[j]);
        }
    }

    /* read the extra newline character after fscanf from above */
    fgets(line, LEN, fp);

    for( i = 0 ; i < layer->num_elems ; ++i ) {

        /* parse the fortran style records */
        fgets(line, LEN, fp);
        extract(line, REC_LEN, REC_NUM, rec);
        
        layer->elems[i].material = rec[1];

        for( j = 0 ;  j < NUMNODES ; ++j ){
            layer->elems[i].node[j] = rec[j + 2];
        }
        
        for( j = 0 ; j < NUMNODES ; ++j ) {
            if ( layer->elems[i].node[j] == 0 ) {
                layer->elems[i].num_nodes = j ;
                break ;
            }
        }
        if ( layer->elems[i].num_nodes == 0 ) {
            layer->elems[i].num_nodes = NUMNODES ;
        }
    }
    
    for( i = 0 ; i < layer->num_nodes ; ++i ) {
        fscanf( fp, "%d ", &idum );
        fscanf( fp, "%lf %lf", &layer->nodes[i].x, &layer->nodes[i].y) ;
    }
}

void ReadData( mesh ) 
    Mesh *mesh ;
{
    int    i ;
    FILE   *fp ;

    for( i = 0 ; i < mesh->num_layers ; ++i ) {
        fp = fopen( mesh->layers[i].file_name, "r") ;
        if( fp == NULL ) {
            fprintf(stderr, "\n*** Problems opening data file \"%s\" ***\n\n", 
                       mesh->layers[i].file_name ) ;
            exit(0) ;
        }
        ReadLayer( &mesh->layers[i], fp ) ;
        fclose( fp ) ;
    }
}

void StripNewline( string ) 
    char  *string ;
{
    char *str ;
    
    /*  
    *   strip the newline character, strtok() seems to behave differently
    *   for a zero length string (only a newline in the string)
    */
    for( str = string ; *str != '\0' ; ++str ) {
        if ( *str == '\n' ) {
            *str = '\0' ;
        }
    }
}

int  SuffixChk( str, suf ) 
    char   *str ;
    char   *suf ;
{
    char   *s ;
    
    s = strstr( str, suf ) ;
    
    if ( s ) {
        return ( strcmp(s,suf) == 0 ) ;
    }
    
    return 0 ;
}

void ValidateFileName( name, len ) 
    char  *name ;    
    int   len ;
{
    /*
    *   If the name is missing the suffix, and if there is room in the
    *   string, add the suffix
    */
    if ( SuffixChk( name, ".inp" ) == 0 ) {
        if ( (int)(strlen(name) + 4) < (int)len ) {
            strcat( name, ".inp" ) ;
        }
    }
}

void GetFileName( name, len, fp ) 
    char  *name ;    
    int   len ;
    FILE  *fp ;
{
    fgets(name,len,fp) ;
    StripNewline( name ) ;
    ValidateFileName( name, len ) ;
}

void GetFiles( mesh )
    Mesh *mesh ;
{
    int    i ;
    
    fprintf(stderr,"\n") ;
    
    for( i = 0 ; i < mesh->num_layers ; ++i ) {
        
        fprintf(stderr,"Enter name of f2d/L .inp file: ") ; fflush(stderr) ;
        /* fgets(mesh->layers[i].file_name,LEN,stdin) ; */
        GetFileName(mesh->layers[i].file_name,LEN,stdin) ;
        /* StripNewline( mesh->layers[i].file_name ) ; */
    }
    
    fprintf(stderr,"\nEnter name for layered .inp file: ") ; fflush(stderr) ;
    /* fgets(mesh->file_name,LEN,stdin) ; */
    GetFileName(mesh->file_name,LEN,stdin) ;
    /* StripNewline( mesh->file_name ) ; */
    
    fprintf(stderr, "\nEnter problem title: ") ; fflush(stderr) ;
    fgets( mesh->title,LEN,stdin) ;
    StripNewline( mesh->title ) ;
}

void ProcessMaterials( mesh ) 
    Mesh *mesh ;
{
    int    i, j ;
    
    for( i = 0 ; i < mesh->num_layers ; ++i ) {
        for( j = 0 ; j < mesh->layers[i].num_mats ; ++j ) {
            if ( mesh->one_mat ) {
                mesh->layers[i].mat_map[j] = 1 ;
            } 
            else {
                mesh->layers[i].mat_map[j] = mesh->num_mats + j + 1 ;
            }
        }
        mesh->num_mats += mesh->layers[i].num_mats ;
    }    
    
    if ( mesh->one_mat ) {
        mesh->num_mats = 1 ;
    }
}


#define alloc_quantum   100

static Edge null_edge ;

Edge *NewEdge( layer )
    Layer *layer ;
{    
    if ( layer->edges == 0 ) {
        layer->num_edges_alloced = alloc_quantum ;
        layer->edges = Calloc( layer->num_edges_alloced, Edge ) ;
    }
    else if ( layer->num_edges == layer->num_edges_alloced ) {
        int  num = layer->num_edges_alloced ;
        layer->num_edges_alloced += alloc_quantum ;
        layer->edges = Realloc( layer->edges, layer->num_edges_alloced, Edge ) ;
        while( num < layer->num_edges_alloced ) {
            layer->edges[num++] = null_edge ;
        }
    }
    return &layer->edges[layer->num_edges++] ;
}

void AddEdge( layer, head, tail, el, ed ) 
    Layer   *layer ;
    int     head ;
    int     tail ;
    int     el ;
    int     ed ;
{
    int  i ;
    int  found = 0 ;
    Edge *edges = layer->edges ;
    
    for( i = 0 ; i < layer->num_edges ; ++i ) {
        if ( edges[i].head == head || edges[i].tail == head ) {
            if ( edges[i].head == tail || edges[i].tail == tail ) {
                found = 1 ;
                break ;
            }
        }
    }
    if ( found ) {
        edges[i].left_elem = el + 1 ;
        edges[i].left_elem_edge = ed + 1 ; 
        layer->elems[el].edges[ed] = i+1 ;       
    }
    else {
        Edge *edge ;
        edge = NewEdge( layer ) ;
        edge->head = head ;
        edge->tail = tail ;
        edge->right_elem = el + 1 ;
        edge->right_elem_edge = ed + 1 ;        
        layer->elems[el].edges[ed] = layer->num_edges ;       
    }
}

void ProcessEdges( layer ) 
    Layer  *layer ;
{
    int   i ;
    
    for( i = 0 ; i < layer->num_elems ; ++i ) {
        int  j ; 
        int  *node = layer->elems[i].node ;
        int  nn = layer->elems[i].num_nodes ;
        for( j = 0 ; j < nn/2 ; ++j ) {
            int   head = node[(j*2+2)%nn] ;
            int   tail = node[j*2] ;
            AddEdge( layer, head, tail, i, j ) ;
        }
    }
}

#define Fail  -1
#define MapWaiting 0 
#define MapFinished 1

int  CountAdjElem( layer, test ) 
    Layer  *layer ;
    int    test ;
{
    int      j ; 
    int      num = 0 ; 
    Element  *elems = layer->elems ;
    int      *adj = elems[test].edges ;
    Edge     *edges = layer->edges ;

    /*
    **  The adjacency list uses 1 based indexing (rather than 0 based)
    **  because 0 is the default initialized "empty or error" state.
    **  Note that this assumes T6 and Q8 elements.
    */
    
    /*
    *   Count the number of elements adjacent to this one that have already
    *   been renumbered.  Note that none of the elements adjacent to this one
    *   should be "done" because an element is not done until all of the 
    *   adjacent elements are added.
    */
    
    for( j = 0 ; j < elems[test].num_nodes/2 ; ++j ) {
        int  rs ;
        int  ls ;
        int  e ;
        
        e = adj[j] - 1 ;
        
        if ( edges[e].right_elem > 0 ) {
            rs = elems[edges[e].right_elem-1].map_status ;
            if ( rs == MapFinished ) {
                num += 1 ;
            }
        } 
        if ( edges[e].left_elem > 0 ) {
            ls = elems[edges[e].left_elem-1].map_status ;
            if ( ls == MapFinished ) {
                num += 1 ;
            }
        }
    }
    
    return num ;
}

int  GetAdjElem( layer, test ) 
    Layer  *layer ;
    int    test ;
{
    int      j ; 
    int      num ; 
    int      max_num = -1 ;
    int      max_elem = Fail ;
    Element  *elems = layer->elems ;
    int      *adj = elems[test].edges ;
    Edge     *edges = layer->edges ;

    /*
    **  The adjacency list uses 1 based indexing (rather than 0 based)
    **  because 0 is the default initialized "empty or error" state.
    **  Note that this assumes T6 and Q8 elements.
    */
    
    /*
    *   Loop on the edges for this element and find the element with
    *   the most common edges.  This helps us add elements in a wave front.
    */
    for( j = 0 ; j < elems[test].num_nodes/2 ; ++j ) {
        int  rs ;
        int  ls ;
        int  e ;
        
        e = adj[j] - 1 ;
        
        if ( edges[e].right_elem > 0 ) {
            rs = elems[edges[e].right_elem-1].map_status ;
            if ( rs == MapWaiting ) {
                num = CountAdjElem( layer, edges[e].right_elem-1 ) ;
                if ( num > max_num ) {
                    max_num = num ;
                    max_elem = edges[e].right_elem-1 ;
                }
            }
        } 
        if ( edges[e].left_elem > 0 ) {
            ls = elems[edges[e].left_elem-1].map_status ;
            if ( ls == MapWaiting ) {
                num = CountAdjElem( layer, edges[e].left_elem-1 ) ;
                if ( num > max_num ) {
                    max_num = num ;
                    max_elem = edges[e].left_elem-1 ;
                }
            }
        }
    }
    
    return max_elem ;
}

int  GetFirstElem( layer ) 
    Layer  *layer ;
{
    int      i, j ; 
    Element  *elems = layer->elems ;
    Edge     *edges = layer->edges ;

    for( i = 0 ; i < layer->num_elems ; ++i ) {
        int  *adj = elems[i].edges ;
    
        /*
        **  The adjacency list uses 1 based indexing (rather than 0 based)
        **  because 0 is the default initialized "empty or error" state.
        **  Note that this assumes T6 and Q8 elements.
        */

        for( j = 0 ; j < elems[i].num_nodes/2 ; ++j ) {
            int  e ;

            /*  any element on the boundary will do */
            
            e = adj[j] - 1 ;
            if ( edges[e].right_elem == 0 || edges[e].left_elem == 0 ) {
                return i ;
            }
        }
    }
    
    return 0 ;
}

int  GetBruteForceElem( layer ) 
    Layer  *layer ;
{
    int  i ;
    
    for( i = 0 ; i < layer->num_elems ; ++i ) {
        if ( layer->elems[i].map_status == MapFinished ) {
            int  forced = GetAdjElem( layer, i ) ;
            if ( forced != Fail ) {
                return forced ;
            }
        }
    }

    fprintf(stderr,"ERROR - no more elements to Process!\n") ;
    exit(1) ;
}

int  GetElem( layer ) 
    Layer  *layer ;
{
    int  elem ;
    
    /*
    *   Get an element on the boundary if this is the first time
    */
    if ( layer->num_mapped == 0 ) {
        return GetFirstElem( layer ) ;
    }
    
    /*
    *   Look for an element adjacent to the current element 
    *   (on the wave front).  If there are none, search globally
    *   for an element on the wavefront.
    */
    elem = GetAdjElem( layer, layer->prev_elem ) ;
    if ( elem == Fail ) {
        return GetBruteForceElem( layer ) ;
    }
    
    return elem ;
}

void UpdateMapStatus( layer, elem ) 
    Layer  *layer ;
    int    elem ;
{
    Element  *elems = layer->elems ;
    int      *adj = elems[elem].edges ;
    Edge     *edges = layer->edges ;

    layer->prev_elem = elem ;
    elems[elem].map_status = MapFinished ;
}

void RenumberNodes( layer ) 
    Layer  *layer ;
{
    int       i, j ;
    int       num_nodes = 0 ;
    Element   *elems = layer->elems ;
    Node      *nodes = layer->nodes ;
    
    /*
    *   Mark the nodes with their new node numbers and update the number
    *   in the element connectivity list.
    */
    for( j = 0 ; j < layer->num_elems ; ++j ) {
        int  *node = elems[j].node ;
        for( i = 0 ; i < elems[j].num_nodes ; ++i ) {
            if ( nodes[node[i]-1].number == 0 ) {
                ++num_nodes ;
                nodes[node[i]-1].number = num_nodes ;
            }
            node[i] = nodes[node[i]-1].number ;
        }
    }
    
    /*
    *   Now compress out all of the unused nodes.
    */
    for( i = j = 0 ; j < layer->num_nodes ; ++j ) {
        if ( nodes[j].number > 0 ) {
            if ( j > i ) {
                nodes[i] = nodes[j] ;
            }
            ++i ;
        }
    }
    
    if ( i < num_nodes ) {
        fprintf(stderr,"ERROR - problem during node compression!\n") ;
        abort() ;
    }
    
    layer->num_nodes = num_nodes ;
}

void RenumberElements( layer ) 
    Layer  *layer ;
{
    int  e ;

    while( layer->num_mapped < layer->num_elems ) {
        e = layer->elem_map[layer->num_mapped++] = GetElem( layer ) ;
        UpdateMapStatus( layer, e ) ;
    }
}

void ProcessNodes( mesh ) 
    Mesh *mesh ;
{
    int  i ;
    
    for( i = 0 ; i < mesh->num_layers ; ++i ) {
        Layer  *layer = &mesh->layers[i] ;
        RenumberNodes( layer ) ;
    }
}

void ProcessElements( mesh ) 
    Mesh *mesh ;
{
    int  i, j ;
    
    if ( mesh->renumber_elements ) {
        for( i = 0 ; i < mesh->num_layers ; ++i ) {
            Layer  *layer = &mesh->layers[i] ;
            ProcessEdges( layer ) ;
            RenumberElements( layer ) ;
        }
    }
    else {
        for( i = 0 ; i < mesh->num_layers ; ++i ) {
            Layer  *layer = &mesh->layers[i] ;
            for( j = 0 ; j < mesh->layers[i].num_elems ; ++j ) {
                layer->elem_map[j] = j ;
            }
        }
    }
}

void ProcessProbType( mesh ) 
    Mesh *mesh ;
{    
    if ( mesh->prob_type == Prob_Undefined ) {
        mesh->prob_type =  mesh->layers[0].prob_type ;
    }
}

int  MapElem( layer, elem ) 
    Layer  *layer ;
    int    elem ;
{
    return layer->elem_map[elem] ;
}

int  MapMat( layer, elem ) 
    Layer  *layer ;
    int    elem ;
{
    return layer->mat_map[layer->elems[elem].material-1] ;
}

void ProcessData( mesh ) 
    Mesh *mesh ;
{
    int    i, j, k ;
    FILE   *fp ;

    ProcessProbType( mesh ) ;
    ProcessMaterials( mesh ) ;
    ProcessElements( mesh ) ;
    ProcessNodes( mesh ) ;
    
    if ( strlen(mesh->file_name) == 0 ) {
        fp = stdout ;
    }
    else {
        fp = fopen(mesh->file_name, "w") ;
        if( fp == NULL ) {
            fprintf(stderr,"\n*** Problems opening output file \"%s\" ***\n\n", 
                       mesh->file_name ) ;
            exit(0) ;
        }
    }
    
    fprintf( fp, "%.40s\n", mesh->title) ;

    fprintf( fp, "%5d %5d %5d\n", 
        mesh->num_layers, mesh->num_mats, mesh->prob_type ) ;

    if ( mesh->one_mat ) {
        Material  *mat = &mesh->layers[0].mats[0] ;
        fprintf( fp, "%5d", mat->mat_id ) ;
        for( k = 0 ; k < NUM_MAT_PROPS ; ++k ) {
            fprintf( fp,"%10.2E", mat->mat_props[k]) ;
        }
        fprintf( fp,"\n" ) ;
    }
    else {
        for( i = 0 ; i < mesh->num_layers ; ++i ) {
            for( j = 0 ; j < mesh->layers[i].num_mats ; ++j ) {
                Material  *mat = &mesh->layers[i].mats[j] ;
                fprintf( fp, "%5d", mat->mat_id ) ;
                for( k = 0 ; k < NUM_MAT_PROPS ; ++k ) {
                    fprintf( fp,"%10.2E", mat->mat_props[k]) ;
                }
                fprintf( fp,"\n" ) ;
            }
        }
    }
    
    for( i = 0 ; i < mesh->num_layers ; ++i ) {
        int mat ;
        int elem ;
        
        fprintf( fp,"%5d %5d\n", 
            mesh->layers[i].num_nodes, mesh->layers[i].num_elems ) ;
             
        for( j = 0 ; j < mesh->layers[i].num_elems ; ++j ) {
            elem = MapElem( &mesh->layers[i], j ) ;
            mat = MapMat( &mesh->layers[i], elem ) ;
            fprintf( fp, "%5d %5d %5d %5d %5d %5d %5d %5d %5d %5d\n",
                      j+1, mat,
                      mesh->layers[i].elems[elem].node[0],
                      mesh->layers[i].elems[elem].node[1],
                      mesh->layers[i].elems[elem].node[2],
                      mesh->layers[i].elems[elem].node[3],
                      mesh->layers[i].elems[elem].node[4],
                      mesh->layers[i].elems[elem].node[5],
                      mesh->layers[i].elems[elem].node[6],
                      mesh->layers[i].elems[elem].node[7] );
        }
        
        /*
        *   The nodes have been renumbered and compressed, but not
        *   reordered.  Here we reorder them by brute force.
        */
        for( k = 0 ; k < mesh->layers[i].num_nodes ; ++k ) {
            for( j = 0 ; j < mesh->layers[i].num_nodes ; ++j ) {
                if ( mesh->layers[i].nodes[j].number == k+1 ) {
                    fprintf( fp, "%5d %22.6E %22.6E\n",
                         k+1, mesh->layers[i].nodes[j].x, 
                              mesh->layers[i].nodes[j].y ) ;
                    break ;
                }
            }
        }
    }
    
    fclose( fp ) ;
}
 

int PromptYesNo( prompt ) 
    char  *prompt ;
{
    int   rtn ;
    char  line[LEN] ;
    
    for(;;) {
        fprintf(stderr,"%s (y,n): ", prompt ) ; fflush(stderr) ;
        fgets(line, LEN, stdin) ;

        if ( line[0] == 'y' || line[0] == 'Y' ) {
            rtn = True ;
            break ;
        }
        else if ( line[0] == 'n' || line[0] == 'N' ) {
            rtn = False ;
            break ;
        }
    }
    
    return rtn ;
}

#define OPTIONS  "[-search | -nosearch] [-onemat] [-o out_file] \n\
[-bending | -axisymmetric | -planestress | -planestrain] franc_files..."

void arg_error(argc, argv, bad)
int argc ;
char **argv ;
int bad ;
{
    fprintf(stderr,"Bad argument: %s\n", argv[bad] ) ;
    fprintf(stderr,"Usage: %s %s\n", argv[0], OPTIONS ) ;
    exit(1) ;
}

static int   perform_search = True ;       /* default is to perform search */
static int   one_mat = False ;             /* compress out materials */
static int   prob_type = Prob_Undefined ;  

Mesh *MeshAlloc( num ) 
    int num ;
{
    Mesh  *mesh ;
    
    mesh = Calloc( 1, Mesh ) ;
    mesh->num_layers = num ;
    mesh->layers = Calloc( num, Layer ) ;
    mesh->one_mat = one_mat ;
    mesh->renumber_elements = perform_search ;
    mesh->prob_type = prob_type ;
    
    return mesh ;
}

Mesh *ProcessArgs( argc, argv )
int argc ;
char **argv ;
{
    int   i, j ;
    Name  file_name ;    
    Mesh  *mesh = 0 ;

    file_name[0] = '\0' ;

    for( i = 1 ; i < argc ; ++i ) {
        if ( *argv[i] == '-' ) {
            if ( strcmp( argv[i], "-search" ) == 0 ) {
                perform_search = 1 ;
            }
            else if ( strcmp( argv[i], "-nosearch" ) == 0 ) {
                perform_search = 0 ;
            }
            else if ( strcmp( argv[i], "-onemat" ) == 0 ) {
                one_mat = True ;
            }
            else if ( strcmp( argv[i], "-bending" ) == 0 ) {
                prob_type = Prob_Bending ;
            }
            else if ( strcmp( argv[i], "-axisymmetric" ) == 0 ) {
                prob_type = Prob_Axisymmetric ;
            }
            else if ( strcmp( argv[i], "-planestress" ) == 0 ) {
                prob_type = Prob_PlaneStress ;
            }
            else if ( strcmp( argv[i], "-planestrain" ) == 0 ) {
                prob_type = Prob_PlaneStrain ;
            }
            else if ( strcmp( argv[i], "-o" ) == 0 ) {
                if ( ++i < argc ) {
                    strcpy( file_name, argv[i] ) ;
                    ValidateFileName( file_name, LEN ) ;
                }
            }
            else {
                arg_error(argc,argv,1) ;  
            }
        }
        else {
            break ;
        }
    }
    
    /*
    *   Look for files on the command line
    */
    if ( i < argc ) {
        mesh = MeshAlloc( argc-i ) ;
        for( j = 0 ; i < argc ; ++i, ++j ) {
            strcpy( mesh->layers[j].file_name, argv[i] ) ;
            ValidateFileName( mesh->layers[j].file_name, LEN ) ;
        }
        
        if ( strlen(file_name) > 0 ) {
            strcpy( mesh->file_name, file_name ) ;
            ValidateFileName( mesh->file_name, LEN ) ;
        }
    }
    
    return mesh ;
}

#define CHK_MESH_PROMPT  "Check mesh for holes"
#define CMPRSS_MAT_PROMPT "Map all materials"
#define PURPOSE "\nThis program translates franc files into layered franc format\n"

int main(argc, argv)
int argc ;
char **argv ;
{
    char  line[LEN] ;
    Mesh  *mesh ;
    int   num ;
    
    mesh = ProcessArgs( argc, argv ) ;
    
    if ( mesh == 0 ) {
        fprintf(stderr, PURPOSE ) ;
        fprintf(stderr,"For file names; .inp is assumed \n"); 

        /* perform_search = PromptYesNo( CHK_MESH_PROMPT ) ; */
        /* one_mat = PromptYesNo( CMPRSS_MAT_PROMPT ) ; one_mat = !one_mat ; */

        fprintf(stderr,"\nEnter number of layers : "); 
        fflush( stdout ) ;
        fgets( line, LEN, stdin ) ;
        sscanf( line,"%d",&num );
        
        mesh = MeshAlloc( num ) ;

        GetFiles( mesh ) ;
    }
    
    ReadData( mesh ) ;
    ProcessData( mesh ) ;

    return 0 ;
}

