/* ----------------------------------------------------------------  */
/* readFoam                                        7.07.2005 Wittig  */
/* ----------------------------------------------------------------  */


#include <cgx.h>
#include <sys/dir.h>

#define R_GAS    287.1
#define kappa    1.4
#define cp_air      1003.

#define MAXINTEGER 2147483647
#define MAXFLOAT   1.e32

#define TEST     0

#define MAX_ENTITIES      100
#define RESULT_KEY        "time"
#define CHECK_INPUT       0

extern Alias     *alias;
extern Sets      *set;
extern SumGeo    anzGeo[1];
extern SumAsci   sumAsci[1];

int calcAddEntities( Summen *anz, Nodes *node, Elements *elem, Datasets *lcase)
{
  int lc, n, i, j;
  int T_indx=-1, U_indx=-1, p_indx=-1;

  double ps, us, ts, pt, tt, rho, ma;

  for (lc=0; lc<anz->l; lc++)
  {
    n=0; while(n<lcase[lc].ncomps)
    {
      /* search U entities */
      if(compare(lcase[lc].compName[n], "U;1", 3)==3)
      {
        lcase[lc].ncomps++;

        if ( (lcase[lc].nmax = (int *)realloc(lcase[lc].nmax , lcase[lc].ncomps * sizeof(int))) == NULL )
          printf("\n\n ERROR: realloc failure\n\n" );
        if ( (lcase[lc].nmin = (int *)realloc(lcase[lc].nmin , lcase[lc].ncomps * sizeof(int))) == NULL )
          printf("\n\n ERROR: realloc failure\n\n" );
        if ( (lcase[lc].max = (float *)realloc(lcase[lc].max, lcase[lc].ncomps * sizeof(float))) == NULL )
          printf("\n\n ERROR: realloc failure\n\n" );
        if ( (lcase[lc].min = (float *)realloc( lcase[lc].min,lcase[lc].ncomps * sizeof(float))) == NULL )
          printf("\n\n ERROR: realloc failure\n\n" );
        if ( (lcase[lc].dat = (float **)realloc(lcase[lc].dat, lcase[lc].ncomps * sizeof(float *))) == NULL )
          printf("\n\n ERROR: realloc failure\n\n" );
        if ( (lcase[lc].icname = (unsigned char **)realloc(lcase[lc].icname, lcase[lc].ncomps * sizeof(unsigned char *))) == NULL )
          printf("\n\n ERROR: realloc failure\n\n" );
        if ( (lcase[lc].compName = (unsigned char **)realloc(lcase[lc].compName, lcase[lc].ncomps * sizeof(unsigned char *))) == NULL )
          printf("\n\n ERROR: realloc failure\n\n" );
        if ( (lcase[lc].compName[lcase[lc].ncomps-1] = (unsigned char *)malloc( MAX_LINE_LENGTH * sizeof(unsigned char))) == NULL )
          printf("\n\n ERROR: malloc failed\n\n" );
        if ( (lcase[lc].dat[lcase[lc].ncomps-1]      = (float *)malloc( (anz->nmax+1) * sizeof(float))) == NULL )
          printf("\n\n ERROR: malloc failed\n\n" );	               
        if ( (lcase[lc].icname[lcase[lc].ncomps-1]   = (unsigned char *)malloc( MAX_LINE_LENGTH * sizeof(unsigned char))) == NULL )
          printf("\n\n ERROR: malloc failed\n\n" );
        lcase[lc].max[lcase[lc].ncomps-1]=-MAXFLOAT;
        lcase[lc].min[lcase[lc].ncomps-1]=MAXFLOAT;
        
        if ( (lcase[lc].ictype = (int *)realloc(lcase[lc].ictype, lcase[lc].ncomps * sizeof(int))) == NULL )
          printf("\n\n ERROR: realloc failure\n\n" );
        if ( (lcase[lc].icind1 = (int *)realloc(lcase[lc].icind1, lcase[lc].ncomps * sizeof(int))) == NULL )
          printf("\n\n ERROR: realloc failure\n\n" );
        if ( (lcase[lc].icind2 = (int *)realloc( lcase[lc].icind2,lcase[lc].ncomps * sizeof(int))) == NULL )
          printf("\n\n ERROR: realloc failure\n\n" );
        if ( (lcase[lc].iexist = (int *)realloc(lcase[lc].iexist, lcase[lc].ncomps * sizeof(int))) == NULL )
          printf("\n\n ERROR: realloc failure\n\n" );
        
        lcase[lc].ictype[lcase[lc].ncomps-1] = 1;
        lcase[lc].icind1[lcase[lc].ncomps-1] = 0;
        lcase[lc].icind2[lcase[lc].ncomps-1] = 0;
        lcase[lc].iexist[lcase[lc].ncomps-1] = 0;

        /* calculate the velocity */
        sprintf(lcase[lc].compName[lcase[lc].ncomps-1],"|U| ");
        for(i=0; i<anz->n; i++)
	{
          lcase[lc].dat[lcase[lc].ncomps-1][node[i].nr]=sqrt( lcase[lc].dat[n][node[i].nr]*lcase[lc].dat[n][node[i].nr]+lcase[lc].dat[n+1][node[i].nr]*lcase[lc].dat[n+1][node[i].nr]+lcase[lc].dat[n+2][node[i].nr]*lcase[lc].dat[n+2][node[i].nr]);
          if(lcase[lc].dat[lcase[lc].ncomps-1][node[i].nr] > lcase[lc].max[lcase[lc].ncomps-1])
          {
             lcase[lc].max[lcase[lc].ncomps-1]=lcase[lc].dat[lcase[lc].ncomps-1][node[i].nr];
             lcase[lc].nmax[lcase[lc].ncomps-1]=node[i].nr;
          }
          if(lcase[lc].dat[lcase[lc].ncomps-1][node[i].nr] < lcase[lc].min[lcase[lc].ncomps-1])
          {
             lcase[lc].min[lcase[lc].ncomps-1]=lcase[lc].dat[lcase[lc].ncomps-1][node[i].nr];
             lcase[lc].nmin[lcase[lc].ncomps-1]=node[i].nr;
          }
	}
      }
      n++;
    }

    n=0; while(n<lcase[lc].ncomps)
    {
      /* search TT entity (usually has to be created manually) */
      /* PT entity has to exist also (usually has to be created manually) */
      if(compare(lcase[lc].compName[n], "TT;", 3)==3)
      {
        lcase[lc].ncomps+=3;

        if ( (lcase[lc].nmax = (int *)realloc(lcase[lc].nmax , lcase[lc].ncomps * sizeof(int))) == NULL )
          printf("\n\n ERROR: realloc failure\n\n" );
        if ( (lcase[lc].nmin = (int *)realloc(lcase[lc].nmin , lcase[lc].ncomps * sizeof(int))) == NULL )
          printf("\n\n ERROR: realloc failure\n\n" );
        if ( (lcase[lc].max = (float *)realloc(lcase[lc].max, lcase[lc].ncomps * sizeof(float))) == NULL )
          printf("\n\n ERROR: realloc failure\n\n" );
        if ( (lcase[lc].min = (float *)realloc( lcase[lc].min,lcase[lc].ncomps * sizeof(float))) == NULL )
          printf("\n\n ERROR: realloc failure\n\n" );
        if ( (lcase[lc].dat = (float **)realloc(lcase[lc].dat, lcase[lc].ncomps * sizeof(float *))) == NULL )
          printf("\n\n ERROR: realloc failure\n\n" );
        if ( (lcase[lc].icname = (unsigned char **)realloc(lcase[lc].icname, lcase[lc].ncomps * sizeof(unsigned char *))) == NULL )
          printf("\n\n ERROR: realloc failure\n\n" );
        if ( (lcase[lc].compName = (unsigned char **)realloc(lcase[lc].compName, lcase[lc].ncomps * sizeof(unsigned char *))) == NULL )
          printf("\n\n ERROR: realloc failure\n\n" );

        for(i=lcase[lc].ncomps-3; i<lcase[lc].ncomps; i++)
	{
          if ( (lcase[lc].compName[i] = (unsigned char *)malloc( MAX_LINE_LENGTH * sizeof(unsigned char))) == NULL )
            printf("\n\n ERROR: malloc failed\n\n" );
          if ( (lcase[lc].dat[i]      = (float *)malloc( (anz->nmax+1) * sizeof(float))) == NULL )
            printf("\n\n ERROR: malloc failed\n\n" );	               
          if ( (lcase[lc].icname[i]   = (unsigned char *)malloc( MAX_LINE_LENGTH * sizeof(unsigned char))) == NULL )
            printf("\n\n ERROR: malloc failed\n\n" );
          lcase[lc].max[i]=-MAXFLOAT;
          lcase[lc].min[i]=MAXFLOAT;
	}
        
        if ( (lcase[lc].ictype = (int *)realloc(lcase[lc].ictype, lcase[lc].ncomps * sizeof(int))) == NULL )
          printf("\n\n ERROR: realloc failure\n\n" );
        if ( (lcase[lc].icind1 = (int *)realloc(lcase[lc].icind1, lcase[lc].ncomps * sizeof(int))) == NULL )
          printf("\n\n ERROR: realloc failure\n\n" );
        if ( (lcase[lc].icind2 = (int *)realloc( lcase[lc].icind2,lcase[lc].ncomps * sizeof(int))) == NULL )
          printf("\n\n ERROR: realloc failure\n\n" );
        if ( (lcase[lc].iexist = (int *)realloc(lcase[lc].iexist, lcase[lc].ncomps * sizeof(int))) == NULL )
          printf("\n\n ERROR: realloc failure\n\n" );
        
        for(i=lcase[lc].ncomps-3; i<lcase[lc].ncomps; i++)
	{
          lcase[lc].ictype[i] = 1;
          lcase[lc].icind1[i] = 0;
          lcase[lc].icind2[i] = 0;
          lcase[lc].iexist[i] = 0;
	}

        /* calculate the velocity */
        sprintf(lcase[lc].compName[lcase[lc].ncomps-3],"T ");
        sprintf(lcase[lc].compName[lcase[lc].ncomps-2],"p ");
        sprintf(lcase[lc].compName[lcase[lc].ncomps-1],"Ma ");

        /* determine the location of TT, U and PT */
        T_indx=n;
        for(i=0; i<lcase[lc].ncomps; i++)
        {
          if(compare(lcase[lc].compName[i], "|U|", 3)==3) U_indx=i;
          if(compare(lcase[lc].compName[i], "PT;", 3)==3) p_indx=i;
	}

        if((U_indx!=-1)&&(p_indx!=-1))
	{
         for(i=0; i<anz->n; i++)
	 {
          pt=lcase[lc].dat[p_indx][node[i].nr];
          us=lcase[lc].dat[U_indx][node[i].nr];
          tt=lcase[lc].dat[T_indx][node[i].nr];
          ts=tt - us*us*.5/cp_air;
	  ps = pt*pow( (ts/tt), (kappa/(kappa-1)) );
          rho=ps/R_GAS/ts;
          ma=us/sqrt(kappa*R_GAS*ts);
          lcase[lc].dat[lcase[lc].ncomps-3][node[i].nr]=ts;
          lcase[lc].dat[lcase[lc].ncomps-2][node[i].nr]=ps;
          lcase[lc].dat[lcase[lc].ncomps-1][node[i].nr]=ma;

          for(j=lcase[lc].ncomps-3; j<lcase[lc].ncomps; j++)
	  {
            if(lcase[lc].dat[j][node[i].nr] > lcase[lc].max[j])
            {
              lcase[lc].max[j]=lcase[lc].dat[j][node[i].nr];
              lcase[lc].nmax[j]=node[i].nr;
            }
            if(lcase[lc].dat[j][node[i].nr] < lcase[lc].min[j])
            {
              lcase[lc].min[j]=lcase[lc].dat[j][node[i].nr];
              lcase[lc].nmin[j]=node[i].nr;
            }
	  }
         }
	}
      }
      n++;
    }

    n=0; while(n<lcase[lc].ncomps)
    {
      /* search T entity */
      if(compare(lcase[lc].compName[n], "T;", 2)==2)
      {
        lcase[lc].ncomps+=3;

        if ( (lcase[lc].nmax = (int *)realloc(lcase[lc].nmax , lcase[lc].ncomps * sizeof(int))) == NULL )
          printf("\n\n ERROR: realloc failure\n\n" );
        if ( (lcase[lc].nmin = (int *)realloc(lcase[lc].nmin , lcase[lc].ncomps * sizeof(int))) == NULL )
          printf("\n\n ERROR: realloc failure\n\n" );
        if ( (lcase[lc].max = (float *)realloc(lcase[lc].max, lcase[lc].ncomps * sizeof(float))) == NULL )
          printf("\n\n ERROR: realloc failure\n\n" );
        if ( (lcase[lc].min = (float *)realloc( lcase[lc].min,lcase[lc].ncomps * sizeof(float))) == NULL )
          printf("\n\n ERROR: realloc failure\n\n" );
        if ( (lcase[lc].dat = (float **)realloc(lcase[lc].dat, lcase[lc].ncomps * sizeof(float *))) == NULL )
          printf("\n\n ERROR: realloc failure\n\n" );
        if ( (lcase[lc].icname = (unsigned char **)realloc(lcase[lc].icname, lcase[lc].ncomps * sizeof(unsigned char *))) == NULL )
          printf("\n\n ERROR: realloc failure\n\n" );
        if ( (lcase[lc].compName = (unsigned char **)realloc(lcase[lc].compName, lcase[lc].ncomps * sizeof(unsigned char *))) == NULL )
          printf("\n\n ERROR: realloc failure\n\n" );

        for(i=lcase[lc].ncomps-3; i<lcase[lc].ncomps; i++)
	{
          if ( (lcase[lc].compName[i] = (unsigned char *)malloc( MAX_LINE_LENGTH * sizeof(unsigned char))) == NULL )
            printf("\n\n ERROR: malloc failed\n\n" );
          if ( (lcase[lc].dat[i]      = (float *)malloc( (anz->nmax+1) * sizeof(float))) == NULL )
            printf("\n\n ERROR: malloc failed\n\n" );	               
          if ( (lcase[lc].icname[i]   = (unsigned char *)malloc( MAX_LINE_LENGTH * sizeof(unsigned char))) == NULL )
            printf("\n\n ERROR: malloc failed\n\n" );
          lcase[lc].max[i]=-MAXFLOAT;
          lcase[lc].min[i]=MAXFLOAT;
	}
        
        if ( (lcase[lc].ictype = (int *)realloc(lcase[lc].ictype, lcase[lc].ncomps * sizeof(int))) == NULL )
          printf("\n\n ERROR: realloc failure\n\n" );
        if ( (lcase[lc].icind1 = (int *)realloc(lcase[lc].icind1, lcase[lc].ncomps * sizeof(int))) == NULL )
          printf("\n\n ERROR: realloc failure\n\n" );
        if ( (lcase[lc].icind2 = (int *)realloc( lcase[lc].icind2,lcase[lc].ncomps * sizeof(int))) == NULL )
          printf("\n\n ERROR: realloc failure\n\n" );
        if ( (lcase[lc].iexist = (int *)realloc(lcase[lc].iexist, lcase[lc].ncomps * sizeof(int))) == NULL )
          printf("\n\n ERROR: realloc failure\n\n" );
        
        for(i=lcase[lc].ncomps-3; i<lcase[lc].ncomps; i++)
	{
          lcase[lc].ictype[i] = 1;
          lcase[lc].icind1[i] = 0;
          lcase[lc].icind2[i] = 0;
          lcase[lc].iexist[i] = 0;
	}

        /* calculate the velocity */
        sprintf(lcase[lc].compName[lcase[lc].ncomps-3],"TT ");
        sprintf(lcase[lc].compName[lcase[lc].ncomps-2],"PT ");
        sprintf(lcase[lc].compName[lcase[lc].ncomps-1],"Ma ");

        /* determine the location of T, U and p */
        T_indx=n;
        for(i=0; i<lcase[lc].ncomps; i++)
        {
          if(compare(lcase[lc].compName[i], "|U|", 3)==3) U_indx=i;
          if(compare(lcase[lc].compName[i], "p;", 2)==2) p_indx=i;
	}

        if((U_indx!=-1)&&(p_indx!=-1))
	{
         for(i=0; i<anz->n; i++)
         {
          ps=lcase[lc].dat[p_indx][node[i].nr];
          us=lcase[lc].dat[U_indx][node[i].nr];
          ts=lcase[lc].dat[T_indx][node[i].nr];
          rho=ps/R_GAS/ts;
          tt=us*us*.5/cp_air + ts;
	  pt = ps/pow( (ts/tt), (kappa/(kappa-1)) );
          ma=us/sqrt(kappa*R_GAS*ts);
          lcase[lc].dat[lcase[lc].ncomps-3][node[i].nr]=tt;
          lcase[lc].dat[lcase[lc].ncomps-2][node[i].nr]=pt;
          lcase[lc].dat[lcase[lc].ncomps-1][node[i].nr]=ma;

          for(j=lcase[lc].ncomps-3; j<lcase[lc].ncomps; j++)
	  {
            if(lcase[lc].dat[j][node[i].nr] > lcase[lc].max[j])
            {
              lcase[lc].max[j]=lcase[lc].dat[j][node[i].nr];
              lcase[lc].nmax[j]=node[i].nr;
            }
            if(lcase[lc].dat[j][node[i].nr] < lcase[lc].min[j])
            {
              lcase[lc].min[j]=lcase[lc].dat[j][node[i].nr];
              lcase[lc].nmin[j]=node[i].nr;
            }
	  }
         }
	}
      }
      n++;
    }

  }
  return(1);
}

int readFoam(unsigned char *datin, Summen *anz, Nodes **nptr, Elements **eptr, Datasets **lptr, int ****fptr  )
{
  int i,j,k,l,n,f,s, nodes, length;
  int eface[8], anz_l, ncomps[MAX_ENTITIES], lc_ncomps, entry;
  FILE *handle;
  DIR *dirp,*dirp1;
  struct direct *dp, *dp1;

  unsigned char file[MAX_LINE_LENGTH], rec_str[MAX_LINE_LENGTH];
  unsigned char resultdir[MAX_LOADCASES][MAX_LINE_LENGTH];
  unsigned char dat[2][MAX_LINE_LENGTH];
  unsigned char resultname[MAX_ENTITIES][MAX_LINE_LENGTH];
  unsigned char buffer[MAX_LINE_LENGTH];

  Nodes     *node = NULL;
  Faces     *face = NULL;
  Elements  *elem = NULL;
  Datasets  *lcase= NULL;

  int anz_dat=0, ipuf=0, *vpn=NULL;
  double  fval[10];

  int startFace, nFaces, setNr=-1, fbuf[6], ni[8], formFlag=0;
  int       ***facebuf=NULL;
  int       anz_fb=-1, slavnod[2];

  facebuf=*fptr;

  anz->n=-1;
  anz->f=-1;
  anz->e=-1;
  anz->l=-1;

  /* Open the files and check to see that it was opened correctly */

  /* mesh */
  strcpy(anz->model, "foam");
  printf (" MODEL NAME:  %s\n", anz->model);

  anz->n=anz->f=anz->e=0;
  anz->nmax=-MAXINTEGER;  anz->nmin=MAXINTEGER;
  anz->emax=-MAXINTEGER;  anz->emin=MAXINTEGER;

  printf ("\n Read the Mesh  \n");

  /* nodes */
  /* located in "datin"/constant/polymesh/points */
  sprintf( file, "%s/constant/polyMesh/points", datin);
  handle = fopen (file, "r");
  if ( handle== NULL )
  {
    printf ("\nThe input file \"%s\" could not be opened.\n", file);
  }
  else printf ("\n%s opened\n",file);
  while(1)
  {
    length = frecord( handle, rec_str);
    if (rec_str[length] == (unsigned char)EOF) break;

    /* read data if a block starts */
    if(rec_str[0]=='(')
    {
      if ( (node = (Nodes *)malloc( (anz->n+1) * sizeof(Nodes))) == NULL )
      {  printf("\n\n ERROR: malloc failed, node\n\n") ; exit(1); }
      for(i=0; i<anz->n; i++)
      {
        node[i].nr=i+1;
        node[node[i].nr].indx=i;
        length = frecord( handle, rec_str);
        sscanf(&rec_str[1], "%lf %lf %lf", &node[node[i].nr].nx, &node[node[i].nr].ny, &node[node[i].nr].nz);
#if TEST
        printf (" n=%d x=%lf y=%lf z=%lf \n", node[i].nr, node[node[i].nr].nx, node[node[i].nr].ny, node[node[i].nr].nz); 
#endif
      }
      break;
    }
    else if(length>0) anz->n=atoi(rec_str);
  }
  fclose(handle);
  anz->nmax=anz->n;
  anz->nmin=1;

  /* faces */
  /* located in "datin"/constant/polymesh/faces */
  sprintf( file, "%s/constant/polyMesh/faces", datin);
  handle = fopen (file, "r");
  if ( handle== NULL )
  {
    printf ("\nThe input file \"%s\" could not be opened.\n", file);
  }
  else printf ("\n%s opened\n",file);
  while(1)
  {
    length = frecord( handle, rec_str);
    if (rec_str[length] == (unsigned char)EOF) break;

    /* read data if a block starts */
    if(rec_str[0]=='(')
    {
      if ( (face = (Faces *)malloc( (anz->f+2) * sizeof(Faces))) == NULL )
      {  printf("\n\n ERROR: malloc failed, face\n\n") ; exit(1); }
      for(i=0; i<anz->f; i++)
      {
        face[i].group=0;
        face[i].mat=0;
        face[i].side=NULL;
        length = frecord( handle, rec_str);
        sscanf(rec_str, "%d",&n);
        sscanf(&rec_str[2], "%d %d %d %d %d %d %d %d",&face[i].nod[0],&face[i].nod[1],&face[i].nod[2],&face[i].nod[3],&face[i].nod[4],&face[i].nod[5],&face[i].nod[6],&face[i].nod[7]);
        for(j=0; j<n; j++)  face[i].nod[j]++; /* nodenr is one higher! */

        if(n==3)      face[i].type = 7;  /* TRI3  */ 
        else if(n==6) face[i].type = 8;  /* TRI6  */  
        else if(n==4) face[i].type = 9;  /* QUAD4 */  
        else if(n==8) face[i].type = 10; /* QUAD8 */
        else
        {
          printf("\n\n ERROR: number of nodes:%d of face:%d do not match available types of elements\n",n,i);
          exit(1);
        }

#if TEST
        printf (" f:%d t:%d",i, face[i].type);
        for(j=0; j<n; j++)  printf (" %d",face[i].nod[j]);
        printf ("\n");
#endif
      }
      break;
    }
    else if(length>0) anz->f=atoi(rec_str);
  }
  fclose(handle);

  /* elements */
  /* located in "datin"/constant/polymesh/cells */
  sprintf( file, "%s/constant/polyMesh/cells", datin);
  handle = fopen (file, "r");
  if ( handle== NULL )
  {
    printf ("\nThe input file \"%s\" could not be opened.\n", file);
  }
  else printf ("\n%s opened\n",file);
  while(1)
  {
    length = frecord( handle, rec_str);
    if (rec_str[length] == (unsigned char)EOF) break;

    /* read data if a block starts */
    if(rec_str[0]=='(')
    {
      if ( (elem = (Elements *)malloc( (anz->e+1) * sizeof(Elements))) == NULL )
      {  printf("\n\n ERROR: malloc failed, elem\n\n") ; exit(1); }
      for(i=0; i<anz->e; i++)
      {
	elem[i].nr = i+1;
	elem[i+1].elem_nr = i;
        elem[i].group= 0;
        elem[i].mat = 1;
        length = frecord( handle, rec_str);
        sscanf(rec_str, "%d",&nodes);
        sscanf(&rec_str[2], "%d %d %d %d %d %d",&eface[0],&eface[1],&eface[2],&eface[3],&eface[4],&eface[5]);

        if (nodes==6) /* HEXA8  */
        {
          /* mark the faces as used */
          for(f=0; f<nodes; f++) face[eface[f]].group++;
  
          elem[i].type = 1;
          anz->etype[elem[i].type]++;

          /* bottom */
          if(face[eface[0]].group==1)
          {
            elem[i].nod[0] = face[eface[0]].nod[0];         
            elem[i].nod[4] = face[eface[0]].nod[1];         
            elem[i].nod[7] = face[eface[0]].nod[2];         
            elem[i].nod[3] = face[eface[0]].nod[3];
          }
          else if(face[eface[0]].group==2)
          {
            elem[i].nod[0] = face[eface[0]].nod[0];         
            elem[i].nod[4] = face[eface[0]].nod[3];         
            elem[i].nod[7] = face[eface[0]].nod[2];         
            elem[i].nod[3] = face[eface[0]].nod[1];
          }
          else { printf("ERROR in group:%d\n",face[eface[0]].group); exit(1); }

          /* search face on node 0 and 1 from face0 */
          for(f=2; f<nodes; f++)
          { 
	    for(l=0; l<4; l++)
	    {
              if(face[eface[f]].nod[l]==face[eface[0]].nod[0])
	      {
                slavnod[0]=l;
                goto found_face;
	      }
	    }
	  }
          printf("ERROR: found no slavface for elem:%d\n",i ); exit(1);
        found_face:;
	  for(l=0; l<4; l++)
	  {
	   for(n=1; n<4; n++)
	   {
            if(face[eface[f]].nod[l]==face[eface[0]].nod[n])
            {
              if((l==0)&&(slavnod[0]==1)) slavnod[1]=2;
              else if((l==1)&&(slavnod[0]==2)) slavnod[1]=3;
              else if((l==2)&&(slavnod[0]==3)) slavnod[1]=0;
              else if((l==3)&&(slavnod[0]==0)) slavnod[1]=1;

              else if((l==2)&&(slavnod[0]==1)) slavnod[1]=0;
              else if((l==3)&&(slavnod[0]==2)) slavnod[1]=1;
              else if((l==0)&&(slavnod[0]==3)) slavnod[1]=2;
              else if((l==1)&&(slavnod[0]==0)) slavnod[1]=3;
              else { printf("ERROR: slavnod nod found l:%d slavnod[0]:%d\n",l,slavnod[0]); exit(1); }
              goto found_nodn;
            }
           }
          }
          printf("ERROR: found no slavnod[1] for elem:%d\n",i ); exit(1);
        found_nodn:;

          /* determine the node from face1 at the slavnod[1] */
          for(l=0; l<4; l++)
          {
            if(face[eface[f]].nod[slavnod[1]]==face[eface[1]].nod[l])
	    {
              /* top */
              if(face[eface[1]].group==1)
              {
                if(l==0)
                {
                  elem[i].nod[1] = face[eface[1]].nod[0];         
                  elem[i].nod[2] = face[eface[1]].nod[1];         
                  elem[i].nod[6] = face[eface[1]].nod[2];         
                  elem[i].nod[5] = face[eface[1]].nod[3];
                }        
                else if(l==1)
                {
                  elem[i].nod[1] = face[eface[1]].nod[1];         
                  elem[i].nod[2] = face[eface[1]].nod[2];         
                  elem[i].nod[6] = face[eface[1]].nod[3];         
                  elem[i].nod[5] = face[eface[1]].nod[0];
                }        
                else if(l==2)
                {
                  elem[i].nod[1] = face[eface[1]].nod[2];         
                  elem[i].nod[2] = face[eface[1]].nod[3];         
                  elem[i].nod[6] = face[eface[1]].nod[0];         
                  elem[i].nod[5] = face[eface[1]].nod[1];
                }        
                else if(l==3)
                {
                  elem[i].nod[1] = face[eface[1]].nod[3];         
                  elem[i].nod[2] = face[eface[1]].nod[0];         
                  elem[i].nod[6] = face[eface[1]].nod[1];         
                  elem[i].nod[5] = face[eface[1]].nod[2];
                }        
                else { printf("ERROR: l nod found\n"); exit(1); }
              }
              else if(face[eface[1]].group==2)
              {
                if(l==0)
                {
                  elem[i].nod[1] = face[eface[1]].nod[0];         
                  elem[i].nod[2] = face[eface[1]].nod[3];         
                  elem[i].nod[6] = face[eface[1]].nod[2];         
                  elem[i].nod[5] = face[eface[1]].nod[1];
                }         
                else if(l==1)
                {
                  elem[i].nod[1] = face[eface[1]].nod[1];         
                  elem[i].nod[2] = face[eface[1]].nod[0];         
                  elem[i].nod[6] = face[eface[1]].nod[3];         
                  elem[i].nod[5] = face[eface[1]].nod[2];
                }         
                else if(l==2)
                {
                  elem[i].nod[1] = face[eface[1]].nod[2];         
                  elem[i].nod[2] = face[eface[1]].nod[1];         
                  elem[i].nod[6] = face[eface[1]].nod[0];         
                  elem[i].nod[5] = face[eface[1]].nod[3];
                }         
                else if(l==3)
                {
                  elem[i].nod[1] = face[eface[1]].nod[3];         
                  elem[i].nod[2] = face[eface[1]].nod[2];         
                  elem[i].nod[6] = face[eface[1]].nod[1];         
                  elem[i].nod[5] = face[eface[1]].nod[0];
                }         
                else { printf("ERROR: l nod found\n"); exit(1); }
              }
              else { printf("ERROR in group:%d\n",face[eface[1]].group); exit(1); }
              break;
            }
          }

          for(f=0; f<nodes; f++)
          {
            face[eface[f]].elem_nr=elem[i].nr;
  
            n=0;
            for(j=0; j<8; j++) 
              for(k=0; k<4; k++)
                if(elem[i].nod[j]==face[eface[f]].nod[k])
                  ni[n++]=j+1;
            if (n==4)
            {
              /* check which sides are involved */
              for (j=0; j<6; j++) fbuf[j]=0;
              for (j=0; j<4; j++)
              {
                if ((ni[j]==1)||(ni[j]==2)||(ni[j]==3)||(ni[j]==4)) fbuf[0]++;
                if ((ni[j]==5)||(ni[j]==8)||(ni[j]==7)||(ni[j]==6)) fbuf[1]++;
                  if ((ni[j]==1)||(ni[j]==5)||(ni[j]==6)||(ni[j]==2)) fbuf[2]++;
                if ((ni[j]==2)||(ni[j]==6)||(ni[j]==7)||(ni[j]==3)) fbuf[3]++;
                if ((ni[j]==3)||(ni[j]==7)||(ni[j]==8)||(ni[j]==4)) fbuf[4]++;
                if ((ni[j]==4)||(ni[j]==8)||(ni[j]==5)||(ni[j]==1)) fbuf[5]++;
              }
            }
            for (j=0; j<6; j++)
            {
              /* printf(" j:%d fbuf[j]:%d\n", j, fbuf[j]); */
              if(fbuf[j]==4) face[eface[f]].nr=j;
            }
          }
        }
        else if (nodes==5) /* PE6    */
        {
          elem[i].type = 2; printf("elem-type:pe6 not installed\n"); exit(1);
        }
        else if (nodes==4) /* TET4   */
        {
          elem[i].type = 3; printf("elem-type:tet4 not installed\n"); exit(1); 
        }
        else
        {
          printf("\n\n ERROR: number of faces:%d of element:%d do not match available types of elements\n", nodes, i);
          exit(1);
        }

#if TEST
        printf (" e:%d t:%d",i, elem[i].type);
        for(j=0; j<nodes; j++)  printf (" %d",eface[j]);
        printf ("\n");
        for(j=0; j<8; j++)  printf (" %d",elem[i].nod[j]);
        printf ("\n");
#endif
      }
      break;
    }
    else if(length>0) anz->e=atoi(rec_str);
  }
  fclose(handle);
  anz->emax=anz->e;
  anz->emin=1;


  /* boundaries */
  /* located in "datin"/constant/polymesh/boundary */
  sprintf( file, "%s/constant/polyMesh/boundary", datin);
  handle = fopen (file, "r");
  if ( handle== NULL )
  {
    printf ("\nThe input file \"%s\" could not be opened.\n", file);
  }
  else printf ("\n%s opened\n",file);
  while(1)
  {
    length = frecord( handle, rec_str);
    if (rec_str[length] == (unsigned char)EOF) break;

    /* read data if a block starts */
    if(rec_str[0]=='(')
    {
      while(1)
      {
        length = frecord( handle, rec_str);
        if (rec_str[length] == (unsigned char)EOF) break;
        length = strfind(rec_str, ")");
        if ( length!=-1 ) break;

        length = strfind(rec_str, "{");
        if ( length!=-1 )
        {
          printf("\n   setname:%s\n",  buffer);
          setNr=getSetNr(buffer);
          if(setNr<0) setNr=pre_seta( buffer, "i", 0);
        }
        else sscanf(rec_str, "%s", buffer);

        length = strfind(rec_str, "nFaces");
        if ( length!=-1 )
        {
          sscanf(rec_str,"%*s %d", &nFaces);
          printf("   nFaces:%d\n", nFaces );
        }

        length = strfind(rec_str, "startFace");
        if ( length!=-1 )
        {
          sscanf(rec_str,"%*s %d", &startFace);
          printf("   startFace:%d\n", startFace );
        }

        /* store the faces in the set if the defining block was closed */
        length = strfind(rec_str, "}");
        if ( length!=-1 )
        {
          /* store setNr, element and face for later use in cgx */
          anz_fb++;
          if ( (facebuf= (int ***)realloc(facebuf, (anz_fb+1)* sizeof(int **))) == NULL )
            printf("\n\n ERROR: malloc failed \n\n") ;
          
          if ( (facebuf[anz_fb]= (int **)malloc((anz->emax+1)* sizeof(int *))) == NULL )
            printf("\n\n ERROR: malloc failed \n\n") ;
          for(i=0; i<=anz->emax; i++) 
          {
            if ( (facebuf[anz_fb][i]= (int *)malloc(6* sizeof(int))) == NULL )
              printf("\n\n ERROR: malloc failed \n\n") ;
            for(j=0; j<6; j++)  facebuf[anz_fb][i][j]=0;
          }

          /* store the setNr at elemnr 0 and face 1 */
          facebuf[anz_fb][0][1]=setNr;

          for(j=0; j<nFaces; j++)
          {
            facebuf[anz_fb][face[j+startFace].elem_nr][face[j+startFace].nr]=1;
          }
        }
      }
    }
  }
  fclose(handle);

  /* scan over all project directories and search for results */
  anz_l=0;
  dirp = opendir(datin);
  printf("seach for results in %s\n", datin );
  if (dirp != NULL) while ((dp = readdir(dirp)) != NULL)
  {
    sprintf( resultdir[anz_l], "%s/%s", datin, dp->d_name );

    /* assume the entry is a dir and open it too */
    dirp1 = opendir(resultdir[anz_l]);
    if (dirp1 != NULL) while ((dp1 = readdir(dirp1)) != NULL)
    {
      /* search for a file RESULT_KEY, then a result dir is found */
      if (strlen(dp1->d_name) == strlen(RESULT_KEY) && !strcmp(dp1->d_name, RESULT_KEY))
      {
        printf(" found RESULT_KEY=%s in dir:%s\n",RESULT_KEY,resultdir[anz_l]);
        anz_l++;
      }
    }
    closedir(dirp1);
  }
  closedir(dirp);

  /* store Datasets */
  if ( (lcase = (Datasets *)malloc( (anz_l) * sizeof(Datasets))) == NULL )
    printf("\n\n ERROR: malloc failed, lcase\n\n") ;


  if ( (vpn = (int *)malloc( (anz->nmax+1) * sizeof(int))) == NULL )
    printf("\n\n ERROR: malloc failure\n\n" );	               
  for(i=0; i<=anz->nmax; i++) vpn[i]=0;

  for(l=0; l<anz_l; l++)
  {
    /* search for files in dir */
    dirp = opendir(resultdir[l]);
    entry=-1;
    if (dirp != NULL) while ((dp = readdir(dirp)) != NULL)
    {
      entry++;
      ncomps[entry]=0;
      if (strlen(dp->d_name) >0 )
      {
        printf("  result file %s\n", dp->d_name);

        /* open the dir/file */
        sprintf(file, "%s/%s",resultdir[l],dp->d_name); 
        handle = fopen (file, "r");
        if ( handle== NULL )
        {
          printf ("\nThe input file \"%s\" could not be opened.\n", file);
        }

        /* determine the type of data and create the entity names */
        while(1)
        {
          length = frecord( handle, rec_str);
          /* printf ("record: %s", rec_str); */
          if (rec_str[length] == (unsigned char)EOF) break;
  
          /* read data if the header starts */
          else if(rec_str[0]=='{')
          {
            while(1)
            {
              length = frecord( handle, rec_str);
              /* printf ("record: %s", rec_str); */
              if (rec_str[length] == (unsigned char)EOF) { printf("ERROR\n"); exit(1); }
              if (rec_str[0] == '}') goto foundEntities;

              sscanf(rec_str, "%s %s", dat[0], dat[1]);
              /* printf ("dat:%s| dat:%s|\n",dat[0], dat[1]); */
              if(compareStrings(dat[0], "class")>0)
              {
                if( compare(dat[1], "volScalarField", 14)==14) ncomps[entry]=1;
                else if( compare(dat[1], "volVectorField", 14)==14) ncomps[entry]=3;
                else { printf("Warning; class:%s not known\n",dat[1]); ncomps[entry]=0; }
              }
              if(compareStrings(dat[0], "object")>0)
              { strcpy(resultname[entry],dat[1]); resultname[entry][strlen(dat[1])]=0; }
            }
          }
        } foundEntities:;
        fclose(handle);
        printf ("  resultname:%s entities:%d\n", resultname[entry], ncomps[entry]);
      }
    }
    closedir(dirp);

    n=0; for(i=0; i<=entry; i++) {  n+=ncomps[i]; }
    if(n<1) goto foundNoEntities;

    /* define the lcases */
    anz->l++;

    lcase[anz->l].ncomps  = n;
    lcase[anz->l].compName= NULL;

    lcase[anz->l].value=anz->l;
    lcase[anz->l].irtype = 1;
    i=0; while(resultdir[l][i]!='/') i++;
    sprintf( lcase[anz->l].name,"%s    ", &resultdir[l][i+1]);
    printf ("lcase.name[%d]= %s\n", anz->l, lcase[anz->l].name);
    strcpy(lcase[anz->l].analysis_name,"");
    strcpy(lcase[anz->l].dataset_name,"FOAM");
    strcpy(lcase[anz->l].dataset_text,"");
    lcase[anz->l].step_number=anz->l;
    lcase[anz->l].analysis_type=1;

    if ( (lcase[anz->l].nmax = (int *)malloc( lcase[anz->l].ncomps * sizeof(int))) == NULL )
      printf("\n\n ERROR: malloc failure\n\n" );
    if ( (lcase[anz->l].nmin = (int *)malloc( lcase[anz->l].ncomps * sizeof(int))) == NULL )
      printf("\n\n ERROR: malloc failure\n\n" );
    if ( (lcase[anz->l].max = (float *)malloc( lcase[anz->l].ncomps * sizeof(float))) == NULL )
      printf("\n\n ERROR: malloc failure\n\n" );
    if ( (lcase[anz->l].min = (float *)malloc( lcase[anz->l].ncomps * sizeof(float))) == NULL )
      printf("\n\n ERROR: malloc failure\n\n" );
    if ( (lcase[anz->l].dat = (float **)malloc( lcase[anz->l].ncomps * sizeof(float *))) == NULL )
      printf("\n\n ERROR: malloc failure\n\n" );
    if ( (lcase[anz->l].icname = (unsigned char **)malloc( lcase[anz->l].ncomps * sizeof(unsigned char *))) == NULL )
      printf("\n\n ERROR: malloc failure\n\n" );
    if ( (lcase[anz->l].compName = (unsigned char **)malloc( lcase[anz->l].ncomps * sizeof(unsigned char *))) == NULL )
      printf("\n\n ERROR: malloc failure\n\n" );
    for(i=0; i<lcase[anz->l].ncomps; i++)
    {
      if ( (lcase[anz->l].compName[i] = (unsigned char *)malloc( MAX_LINE_LENGTH * sizeof(unsigned char))) == NULL )
        printf("\n\n ERROR: malloc failed\n\n" );
      if ( (lcase[anz->l].dat[i] = (float *)malloc( (anz->nmax+1) * sizeof(float))) == NULL )
        printf("\n\n ERROR: malloc failed\n\n" );	               
      if ( (lcase[anz->l].icname[i] = (unsigned char *)malloc( MAX_LINE_LENGTH * sizeof(unsigned char))) == NULL )
         printf("\n\n ERROR: malloc failed\n\n" );
      lcase[anz->l].max[i]=-MAXFLOAT;
      lcase[anz->l].min[i]=MAXFLOAT;
    }
    if ( (lcase[anz->l].ictype = (int *)malloc( lcase[anz->l].ncomps * sizeof(int))) == NULL )
      printf("\n\n ERROR: malloc failure\n\n" );
    if ( (lcase[anz->l].icind1 = (int *)malloc( lcase[anz->l].ncomps * sizeof(int))) == NULL )
      printf("\n\n ERROR: malloc failure\n\n" );
    if ( (lcase[anz->l].icind2 = (int *)malloc( lcase[anz->l].ncomps * sizeof(int))) == NULL )
      printf("\n\n ERROR: malloc failure\n\n" );
    if ( (lcase[anz->l].iexist = (int *)malloc( lcase[anz->l].ncomps * sizeof(int))) == NULL )
      printf("\n\n ERROR: malloc failure\n\n" );

    for(i=0; i<lcase[anz->l].ncomps; i++)
    {
      lcase[anz->l].ictype[i] = 1;
      lcase[anz->l].icind1[i] = 0;
      lcase[anz->l].icind2[i] = 0;
      lcase[anz->l].iexist[i] = 0;
      for(j=0; j<=anz->nmax; j++) lcase[anz->l].dat[i][j]=0.;
    }

    /* search for files in dir */
    dirp = opendir(resultdir[l]);

    entry=-1;
    lc_ncomps=0;
    if (dirp != NULL) while ((dp = readdir(dirp)) != NULL)
    {
      entry++;
      if (strlen(dp->d_name) >0 )
      {
        printf("  result file %s\n", dp->d_name);

        /* open the dir/file */
        sprintf(file, "%s/%s",resultdir[l],dp->d_name); 
        handle = fopen (file, "r");
        if ( handle== NULL )
        {
          printf ("\nThe input file \"%s\" could not be opened.\n", file);
        }

        /* check if entities were found in that file */
        if(ncomps[entry]>0)
        {
          for(n=0; n<ncomps[entry]; n++)
          {
            sprintf(lcase[anz->l].compName[lc_ncomps+n],"%s%d ",resultname[entry], n+1);
            if(ncomps[entry]==3)
            {
              lcase[anz->l].ictype[lc_ncomps+n]=2;
              lcase[anz->l].icind1[lc_ncomps+n]=n+1;
            }
	  }

          while(1)
          {
            length = frecord( handle, rec_str);
            if (rec_str[length] == (unsigned char)EOF) break;
        
            /* read "internalField" data */
            length = strfind(rec_str, "internalField");
            if ( length!=-1 )
            { 
              sscanf(rec_str, "%*s %s", buffer);
              if(compareStrings(buffer,"uniform")>0)
              {
                formFlag=1;
                if     (ncomps[entry]==1) sscanf(rec_str, "%*s %*s %lf", &fval[0]); 
                else if(ncomps[entry]==3)
                {
                  length = strfind(rec_str, "(");
                   sscanf(&rec_str[length+1], "%lf %lf %lf", &fval[0], &fval[1], &fval[2]);
		}
                else { printf("ERROR1; class not known\n"); exit(1); }
		printf("%s vals:%lf %lf %lf\n", &rec_str[length], fval[0], fval[1], fval[2]);
	      }
              else
              {
                formFlag=0;
                length = frecord( handle, rec_str);
                anz_dat=atoi(rec_str);
                if(anz->e!=anz_dat)
                { printf("ERROR: sum-data:%d do not match sum-elem:%d\n",anz_dat,anz->e); exit(1); }
                length = frecord( handle, rec_str);
	      }
      
              for(i=0; i<anz->e; i++)
              {
	        if(formFlag==0)
		{
                  length = frecord( handle, rec_str);
                  if     (ncomps[entry]==1) sscanf(rec_str, "%lf", &fval[0]); 
                  else if(ncomps[entry]==3)
                  {
                    sscanf(&rec_str[1], "%lf %lf %lf", &fval[0], &fval[1], &fval[2]);
		  }
                  else { printf("ERROR2; class not known (ncomps:%d)\n",ncomps[entry]); exit(1); }
		}
                if (elem[i].type == 1) ipuf = 8;  /* HEXA8 */
                if (elem[i].type == 2) ipuf = 6;  /* PENTA6 */
                if (elem[i].type == 3) ipuf = 4;  /* TET4 */
                for(n=0; n<ncomps[entry]; n++)
                {
                  for(j=0; j<ipuf; j++)
                  {
                    lcase[anz->l].dat[lc_ncomps+n][elem[i].nod[j]]+=fval[n];
                    if((vpn[0]==0)&&(n==0))
                    {
                      vpn[elem[i].nod[j]]++; /* count the hits */
		    }
                  }
                }
              }
	      vpn[0]=1;
            }
        
            /* read "boundaryField" data */
            length = strfind(rec_str, "boundaryField");
            if ( length!=-1 )
            {
              length = frecord( handle, rec_str);
              while(1)
              {
                length = frecord( handle, rec_str);
                if (rec_str[length] == (unsigned char)EOF) break;
              
                length = strfind(rec_str, "{");
                if ( length!=-1 )
                {
                  printf("\n   setname:%s\n",  buffer);

                  /* reduce the length of the name to the maximum lenght in cgx */
                  buffer[MAX_NAME_LENGTH]=0;
                  setNr=getSetNr(buffer);
                  if(setNr<0) { printf("ERROR; Set:%s in boundaryField not known\n",buffer); exit(1); }

		  while(1)
                  {
                    length = frecord( handle, rec_str);
                    if (rec_str[length] == (unsigned char)EOF) break;
                    if ( strfind(rec_str, "}")!=-1) break;
                    if ( strfind(rec_str, "fixedValue")!=-1)
                    {
		      do{ length = frecord( handle, rec_str); if (rec_str[length] == (unsigned char)EOF) break; }
                      while(strfind(rec_str, "value")==-1);
                      if     (ncomps[entry]==1) sscanf(rec_str, "%*s %*s %lf", &fval[0]); 
                      else if(ncomps[entry]==3)
                      {
                        length = strfind(rec_str, "(");
                        sscanf(&rec_str[length+1], "%lf %lf %lf", &fval[0], &fval[1], &fval[2]);
		      }
                      else { printf("ERROR3; class not known\n"); exit(1); }
		      printf("%s vals:%lf %lf %lf\n", &rec_str[length], fval[0], fval[1], fval[2]);

                      s=-1;
                      for(i=0; i<= anz_fb; i++) if(facebuf[i][0][1]==setNr) s=i;
                      if (s==-1) { printf("ERROR; set not known\n"); exit(1); }
    
                      for(f=0; f<anz->f; f++)
                      {
                        if( facebuf[s][face[f].elem_nr][face[f].nr]==1)
                        { 
                          if (face[f].type == 7) ipuf = 3;  /* TRI3 */
                          else if (face[i].type== 8) ipuf = 6;  /* TRI6  */  
                          else if (face[f].type == 9) ipuf = 4;  /* QU4 */
                          else if (face[f].type == 10) ipuf = 8;  /* QU4 */
                          else
                          {
                            printf("\n\n ERROR: face.type:%d not known\n",face[f].type);
                            exit(1);
                          }
                          for(n=0; n<ncomps[entry]; n++)
                          {
                            for(j=0; j<ipuf; j++)
                            {
			      /* val at this node is only determined by this face */ 
                              /* val has to be multiplied by vpn because it will later be divided by vpn */
                              lcase[anz->l].dat[lc_ncomps+n][face[f].nod[j]]=fval[n]*vpn[face[f].nod[j]];
                            }
                          }
                        }
  	              }
  		    }
  		  }
                }
                else sscanf(rec_str, "%s", buffer);
                
              }
            }

          }
          lc_ncomps+=ncomps[entry];
        }
        fclose(handle);
      }
    }
    closedir(dirp);

    /* divide the nodal values by the amount of contributor elements */
    for(i=0; i<anz->n; i++)
    {
      for(n=0; n<lcase[anz->l].ncomps; n++)
      {
        lcase[anz->l].dat[n][node[i].nr]/=vpn[node[i].nr];

        if(lcase[anz->l].dat[n][node[i].nr] > lcase[anz->l].max[n])
        {
          lcase[anz->l].max[n]=lcase[anz->l].dat[n][node[i].nr];
          lcase[anz->l].nmax[n]=node[i].nr;
        }
        if(lcase[anz->l].dat[n][node[i].nr] < lcase[anz->l].min[n])
        {
          lcase[anz->l].min[n]=lcase[anz->l].dat[n][node[i].nr];
          lcase[anz->l].nmin[n]=node[i].nr;
        }
      }
    }
    foundNoEntities:;
  }
  free(vpn);
  anz->l++;
  elemChecker( anz, node, elem);

  /* calculate additional entities */
  calcAddEntities( anz, node, elem, lcase);

  /* store the nr of facebuffers at elemnr 0 and face 0 of the first facebuf */
  if(facebuf!=NULL)
  {
    facebuf[0][0][0]=anz_fb;
    *fptr= facebuf;
  }
  *nptr =  node; *eptr = elem; *lptr = lcase;
  return (1);
}
