/* --------------------------------------------------------------------  */
/*                          CALCULIX                                     */
/*                   - GRAPHICAL INTERFACE -                             */
/*                                                                       */
/*     A 3-dimensional pre- and post-processor for finite elements       */
/*              Copyright (C) 1996 Klaus Wittig                          */
/*                                                                       */
/*     This program is free software; you can redistribute it and/or     */
/*     modify it under the terms of the GNU General Public License as    */
/*     published by the Free Software Foundation; version 2 of           */
/*     the License.                                                      */
/*                                                                       */
/*     This program is distributed in the hope that it will be useful,   */
/*     but WITHOUT ANY WARRANTY; without even the implied warranty of    */ 
/*     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the      */
/*     GNU General Public License for more details.                      */
/*                                                                       */
/*     You should have received a copy of the GNU General Public License */
/*     along with this program; if not, write to the Free Software       */
/*     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.         */
/* --------------------------------------------------------------------  */

#include <cgx.h>


/* --------------------------------------------------------------------  */
/* Userfunctions                                                         */
/* interface to the mesh and datasets                                    */
/*                                                                       */
/* string:  parameter list                                               */
/*                                                                       */
/* Structures: (See the sections ELEMENTS and RESULT FORMAT in the       */
/*              manual and the file extUtil.h                            */
/*                                                                       */
/*                                                                       */
/*                                                                       */
/* --------------------------------------------------------------------  */

extern int       num_olc;          /* nr-of-original-loadcases (lc from input-file) */
extern Scale     scale[1];
                                                                 
void v_scalf( float *A, double *B, double *C )
/**********************************************************/
/* Vektormultiplikation: vektor(C) =  scalar(A)*Vektor(B) */
/**********************************************************/
{
  int i;

  for (i=0; i<3; i++){
         C[i]= *A * B[i];
        }
}
                                                                
void userFunction(unsigned char *string, Summen *sum, Nodes **nptr, Elements **eptr, Datasets **lptr, Faces **fptr, Sets **sptr)
{                                                               
  int i,j,l,n, setNr=0;                                                    
  Nodes *node;                                                  
  Elements *elem;                                               
  Datasets *lcase;
  Faces    *face;                                            
  Sets     *set;
                                                              
  FILE *handle;
  unsigned char buf1[MAX_LINE_LENGTH], buf2[MAX_LINE_LENGTH];
                  
  int en, e, f, nod1=0, nod2=0;
  double p01[3], dh, tf, ts, tref, wl, vf, vs, dv, rho, tau, yplus, pf, ps, R=287.1, nue=1.5e-5;

  int  depSet, nodeOffset=0;
  Summen apre[1];
  Nodes *npre=NULL;                             
  Elements *epre=NULL;                                               
  Datasets *lpre=NULL;
  int ***facebuf=NULL;
  unsigned char entity[MAX_LINE_LENGTH], loadcase[MAX_LINE_LENGTH];

  int sum_lc=0, lmin=0, lmax=MAXVALUE, suml_ini=0;

  int inSet, profSet;
  double vd[3],v1[3], v2[3], v3[3], vn[3], vF[3], evF[3], a1[3], a2[3], factor=0.5;
  double earea, area, eFres, Fres, vFres[3], t1,t2,dt=0.;
  int nodnr, dispFlag, forcFlag;
  double energy;

  node=*nptr;                                                   
  elem=*eptr;                                                   
  lcase=*lptr;                                                  
  face=*fptr;
  set=*sptr;


  if(strlen(string)==0)                         
  {
    printf("  average <common-DATASET-name> <loadcase-nr> <loadcase-nr>\n");
    printf("  maxVals <common-DATASET-name>\n");                                          
    printf("  hydro\n");
    printf("  alpha <set> tref\n");
    printf("  intpol <abqnodefile(target)> <setname> <loadcase_nr> <entity_nr>\n");
    printf("  - interpolates surface-values stored in <setname> to other nodes from abqnodefile.\n");
    printf("    - WARNING: No surface-patch must contain element-edges! Use separate patches.\n");
    printf("  - abqnodefile(target) has nodes from the target mesh for which values are interpolated\n");
    printf("  - setname references nodes which are used as a master for the target nodes\n");
    printf("  - output: abqnodefile.equ, this file contains records with (nodenr,value) -pairs\n");
    printf("  - In case of pressures include them in the target-input-file with a *TEMPERATURE command.\n");
    printf("    Then send this values with the send-command (send set abq pres lcx ey -> see the manual)\n");
    printf("    to create the *DLOAD-commands\n");
    printf("  lift <setin> <setprofil>\n");
    printf("  calcFres <set> <loadcase-nr> <entity-nr>\n");
    printf("  energy <set> <loadcase-nr> <loadcase-nr>\n");
  }                                          

  else if(compare(string, "energy", 6)==6)                         
  {                                                             
    handle = fopen ("energy.out", "w");
    sscanf(string, "%s %s %d %d", buf1, buf2, &lmin, &lmax);
    printf("calculate Energy = SUM(FORC*DISP) for nodes in set:%s between dataset %d and %d\n", buf2, lmin, lmax);
    setNr=getSetNr(buf2);
    suml_ini=sum->l;
    energy=0.;
    for(i=0; i<set[setNr].anz_n; i++)
    {
      nodnr=set[setNr].node[i];
      v1[0]=v1[1]=v1[2]=0;
      a1[0]=a1[1]=a1[2]=0;
      t1=0.;
      dispFlag=forcFlag=0;
      for(l=0; l<suml_ini; l++) if((l+1>=lmin)&&(l+1<=lmax))                              
      {                                                           
        if (compare(lcase[l].name,"DISP",4)==4)
        {
          dispFlag=1;
          // printf("DISP of LC[%d]: %s \n", l, lcase[l].name);
          v2[0]=lcase[l].dat[0][nodnr];
          v2[1]=lcase[l].dat[1][nodnr];
          v2[2]=lcase[l].dat[2][nodnr];
          v_result(v1,v2,vn);
	  // printf("disp of node:%d %f %f %f\n", nodnr, vn[0], vn[1], vn[2]);
          vd[0]=(v1[0]+v2[0])*.5; 
          vd[1]=(v1[1]+v2[1])*.5; 
          vd[2]=(v1[2]+v2[2])*.5;
          v1[0]=v2[0];
          v1[1]=v2[1];
          v1[2]=v2[2];
          t2=lcase[l].value;
          dt=(t2+t1)*.5;
          t1=t2;
	}
        if (compare(lcase[l].name,"FORC",4)==4)
        {
          forcFlag=1;
          // printf("FORC of LC[%d]: %s \n", l, lcase[l].name);
          a2[0]=lcase[l].dat[0][nodnr]; 
          a2[1]=lcase[l].dat[1][nodnr]; 
          a2[2]=lcase[l].dat[2][nodnr]; 
          vF[0]=(a1[0]+a2[0])*.5; 
          vF[1]=(a1[1]+a2[1])*.5; 
          vF[2]=(a1[2]+a2[2])*.5; 
	     printf("forc of node:%d %f %f %f\n", nodnr, a1[0], a1[1], a1[2]);
	     printf("forc of node:%d %f %f %f\n", nodnr, a2[0], a2[1], a2[2]);
	     printf("forc of node:%d %f %f %f\n", nodnr, vF[0], vF[1], vF[2]);
          a1[0]=a2[0];
          a1[1]=a2[1];
          a1[2]=a2[2];
	}
        if ((dispFlag)&&(forcFlag))
	{
          dispFlag=forcFlag=0;
          energy+=v_sprod(vF,vn);
          //energy+=vF[2]*vn[2];
          printf("calc energy:%lf\n", energy);
          fprintf(handle, "%d %lf dav: %lf %lf %lf dd: %lf %lf %lf F: %lf %lf %lf energy: %lf\n",l+1,dt , vd[0],vd[1],vd[2], vn[0],vn[1],vn[2], vF[0],vF[1],vF[2], energy);
	}
      }
    }
    fclose(handle);
  }

  else if(compare(string, "average", 7)==7)                         
  {                                                             
    sscanf(string, "%s %s %d %d", buf1, buf2, &lmin, &lmax);
    printf("search:%s average all entities between dataset %d and %d\n", buf2, lmin, lmax);
    suml_ini=sum->l;
    for(l=0; l<suml_ini; l++)                                     
    {                                                           
      if ((compare(lcase[l].name,buf2,strlen(buf2))==strlen(buf2))&&(l+1>=lmin)&&(l+1<=lmax))
      {
        /* add all entities in a new dataset and divide by the nr of lcases */
  
        if(sum_lc==0)
        {
          /* create a new dataset */
          if ( (lcase = (Datasets *)realloc((Datasets *)lcase, (sum->l+1) * sizeof(Datasets))) == NULL )
            printf("\n\n ERROR: malloc failure\n\n" );
  
          lcase[sum->l].ncomps = lcase[l].ncomps;
          lcase[sum->l].irtype = 1;
          lcase[sum->l].npheader  = 0 ;
          lcase[sum->l].value  = 0 ;
          sprintf(lcase[sum->l].name,"AV:%d:%d",lmin,lmax) ;
    
          if ( (lcase[sum->l].nmax = (int *)malloc( lcase[sum->l].ncomps * sizeof(int))) == NULL )
            printf("\n\n ERROR: malloc failure\n\n" );
          if ( (lcase[sum->l].nmin = (int *)malloc( lcase[sum->l].ncomps * sizeof(int))) == NULL )
            printf("\n\n ERROR: malloc failure\n\n" );
          if ( (lcase[sum->l].max = (float *)malloc( lcase[sum->l].ncomps * sizeof(float))) == NULL )
            printf("\n\n ERROR: malloc failure\n\n" );
          if ( (lcase[sum->l].min = (float *)malloc( lcase[sum->l].ncomps * sizeof(float))) == NULL )
            printf("\n\n ERROR: malloc failure\n\n" );
          if ( (lcase[sum->l].dat = (float **)malloc( lcase[sum->l].ncomps * sizeof(float *))) == NULL )
            printf("\n\n ERROR: malloc failure\n\n" );
          if ( (lcase[sum->l].compName = (unsigned char **)malloc( lcase[sum->l].ncomps * sizeof(unsigned char *))) == NULL )
            printf("\n\n ERROR: malloc failure\n\n" );
          if ( (lcase[sum->l].icname = (unsigned char **)malloc( lcase[sum->l].ncomps * sizeof(unsigned char *))) == NULL )
            printf("\n\n ERROR: malloc failure\n\n" );
          for(i=0; i<lcase[sum->l].ncomps; i++)
          {
            if ( (lcase[sum->l].dat[i] = (float *)malloc( (sum->nmax+1) * sizeof(float))) == NULL )
              printf("\n\n ERROR: malloc failure\n\n" );	               
            if ( (lcase[sum->l].compName[i] = (unsigned char *)malloc( MAX_LINE_LENGTH * sizeof(unsigned char))) == NULL )
               printf("\n\n ERROR: malloc failed\n\n" );
            if ( (lcase[sum->l].icname[i] = (unsigned char *)malloc( MAX_LINE_LENGTH * sizeof(unsigned char))) == NULL )
               printf("\n\n ERROR: malloc failed\n\n" );
            lcase[sum->l].max[i]=-MAXVALUE;
            lcase[sum->l].min[i]=MAXVALUE;
            for(n=0; n<=sum->nmax; n++)
              lcase[sum->l].dat[i][n]=0.;
          }
          if ( (lcase[sum->l].ictype = (int *)malloc( lcase[sum->l].ncomps * sizeof(int))) == NULL )
            printf("\n\n ERROR: malloc failure\n\n" );
          if ( (lcase[sum->l].icind1 = (int *)malloc( lcase[sum->l].ncomps * sizeof(int))) == NULL )
            printf("\n\n ERROR: malloc failure\n\n" );
          if ( (lcase[sum->l].icind2 = (int *)malloc( lcase[sum->l].ncomps * sizeof(int))) == NULL )
            printf("\n\n ERROR: malloc failure\n\n" );
          if ( (lcase[sum->l].iexist = (int *)malloc( lcase[sum->l].ncomps * sizeof(int))) == NULL )
            printf("\n\n ERROR: malloc failure\n\n" );
    
          for(i=0; i<lcase[sum->l].ncomps; i++)
          {
            lcase[sum->l].ictype[i] = 1;
            lcase[sum->l].icind1[i] = i+1;
            lcase[sum->l].icind2[i] = 0;
            lcase[sum->l].iexist[i] = 0;
            strcpy( lcase[sum->l].compName[i], lcase[l].compName[i]);
          }
          sum->l++;
        }


        for(i=0; i<lcase[suml_ini].ncomps; i++)
        {
          for(n=0; n<sum->n; n++)
          {
            lcase[suml_ini].dat[i][node[n].nr]+=lcase[l].dat[i][node[n].nr];
          }
        }

        sum_lc++;

        printf(" %d read dataset:%d %s %lf\n",sum_lc, l+1, lcase[l].name, lcase[l].value);

      }
    }
    for(i=0; i<lcase[suml_ini].ncomps; i++)
    {
      for(n=0; n<sum->n; n++)
      {
        lcase[suml_ini].dat[i][node[n].nr]/=sum_lc;
        if (lcase[suml_ini].dat[i][node[n].nr] >  lcase[suml_ini].max[i])
        {  lcase[suml_ini].max[i]=lcase[suml_ini].dat[i][node[n].nr]; lcase[suml_ini].nmax[i]=node[n].nr;}
        if (lcase[suml_ini].dat[i][node[n].nr] <  lcase[suml_ini].min[i])
        {  lcase[suml_ini].min[i]=lcase[suml_ini].dat[i][node[n].nr]; lcase[suml_ini].nmin[i]=node[n].nr;}
      }
    }
  }

  else if(compare(string, "maxVals", 7)==7)                         
  {                                                             
    handle = fopen ("maxVals.out", "w");
    if (handle==NULL)
    {
      printf (" ERROR: The input file \"%s\" could not be opened.\n\n", "maxVals.out");
      return;
    }
    sscanf(string, "%s %s", buf1, buf2);
    printf("search:%s write in maxVals.out:\n Dataset Value Max(0) Min(0) Max(1) Min(1) ..(entities)\n", buf2);
    for(l=0; l<sum->l; l++)                                     
    {                                                           
      if (compare(lcase[l].name,buf2,strlen(buf2))==strlen(buf2))
      {
       printf("%d %lf\n",l+1, lcase[l].value);
       fprintf(handle, "%d %lf ",l+1, lcase[l].value);
       for(i=0; i<lcase[l].ncomps; i++)
       {
         fprintf(handle, " %lf %lf", lcase[l].max[i], lcase[l].min[i]);
       }
       fprintf(handle, "\n");
      }
     }
    fclose(handle);
  }

  else if(compareStrings(string, "hydro")>0)                         
  {                                                             
    /* calculate the hydrostatic stress and the deviator */     
    for(l=0; l<sum->l; l++)                                     
    {                                                           
      /* use only stresses */
      if (compare(lcase[l].name,"STRESS",6)==6)
      {
        printf(" calc hydrostatic stress and deviator for LC[%d]: %s \n", l, lcase[l].name); 
  
        /* create a new dataset */
        if ( (lcase = (Datasets *)realloc((Datasets *)lcase, (sum->l+1) * sizeof(Datasets))) == NULL )
          printf("\n\n ERROR: malloc failure\n\n" );

        lcase[sum->l].ncomps = 4;
        lcase[sum->l].irtype = 1;
        lcase[sum->l].npheader  = 0 ;
        lcase[sum->l].value  = lcase[l].value ;
  
        if ( (lcase[sum->l].nmax = (int *)malloc( lcase[sum->l].ncomps * sizeof(int))) == NULL )
          printf("\n\n ERROR: malloc failure\n\n" );
        if ( (lcase[sum->l].nmin = (int *)malloc( lcase[sum->l].ncomps * sizeof(int))) == NULL )
          printf("\n\n ERROR: malloc failure\n\n" );
        if ( (lcase[sum->l].max = (float *)malloc( lcase[sum->l].ncomps * sizeof(float))) == NULL )
          printf("\n\n ERROR: malloc failure\n\n" );
        if ( (lcase[sum->l].min = (float *)malloc( lcase[sum->l].ncomps * sizeof(float))) == NULL )
          printf("\n\n ERROR: malloc failure\n\n" );
        if ( (lcase[sum->l].dat = (float **)malloc( lcase[sum->l].ncomps * sizeof(float *))) == NULL )
          printf("\n\n ERROR: malloc failure\n\n" );
        if ( (lcase[sum->l].compName = (unsigned char **)malloc( lcase[sum->l].ncomps * sizeof(unsigned char *))) == NULL )
          printf("\n\n ERROR: malloc failure\n\n" );
        if ( (lcase[sum->l].icname = (unsigned char **)malloc( lcase[sum->l].ncomps * sizeof(unsigned char *))) == NULL )
          printf("\n\n ERROR: malloc failure\n\n" );
        for(i=0; i<lcase[sum->l].ncomps; i++)
        {
          if ( (lcase[sum->l].dat[i] = (float *)malloc( (sum->nmax+1) * sizeof(float))) == NULL )
            printf("\n\n ERROR: malloc failure\n\n" );	               
          if ( (lcase[sum->l].compName[i] = (unsigned char *)malloc( MAX_LINE_LENGTH * sizeof(unsigned char))) == NULL )
             printf("\n\n ERROR: malloc failed\n\n" );
          if ( (lcase[sum->l].icname[i] = (unsigned char *)malloc( MAX_LINE_LENGTH * sizeof(unsigned char))) == NULL )
             printf("\n\n ERROR: malloc failed\n\n" );
          lcase[sum->l].max[i]=-MAXVALUE;
          lcase[sum->l].min[i]=MAXVALUE;
        }
        if ( (lcase[sum->l].ictype = (int *)malloc( lcase[sum->l].ncomps * sizeof(int))) == NULL )
          printf("\n\n ERROR: malloc failure\n\n" );
        if ( (lcase[sum->l].icind1 = (int *)malloc( lcase[sum->l].ncomps * sizeof(int))) == NULL )
          printf("\n\n ERROR: malloc failure\n\n" );
        if ( (lcase[sum->l].icind2 = (int *)malloc( lcase[sum->l].ncomps * sizeof(int))) == NULL )
          printf("\n\n ERROR: malloc failure\n\n" );
        if ( (lcase[sum->l].iexist = (int *)malloc( lcase[sum->l].ncomps * sizeof(int))) == NULL )
          printf("\n\n ERROR: malloc failure\n\n" );
  
        for(i=0; i<lcase[sum->l].ncomps; i++)
        {
          lcase[sum->l].ictype[i] = 1;
          lcase[sum->l].icind1[i] = i+1;
          lcase[sum->l].icind2[i] = 0;
          lcase[sum->l].iexist[i] = 0;
        }
        sprintf( lcase[sum->l].name, "HYD&DEV");
        strcpy( lcase[sum->l].compName[0], "SM");
        strcpy( lcase[sum->l].compName[1], "SXX-SM");
        strcpy( lcase[sum->l].compName[2], "SYY-SM");
        strcpy( lcase[sum->l].compName[3], "SZZ-SM");
  
        for(n=0; n<sum->n; n++)
        {
          /* calc average Princ Stress sigm */
          lcase[sum->l].dat[0][node[n].nr]=
            (lcase[l].dat[8][node[n].nr]+lcase[l].dat[9][node[n].nr]+lcase[l].dat[10][node[n].nr])/3.;
         
          /* calc the deviator */
          for(i=0; i<3; i++)
            lcase[sum->l].dat[i+1][node[n].nr]=lcase[l].dat[i][node[n].nr]-lcase[sum->l].dat[0][node[n].nr];

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

  else if(compare(string, "alpha", 5)==5)                         
  {                                                             
    sscanf(string, "%s %s %lf", buf1, buf2, &tref);
    printf("|%s| set:|%s| |%lf|\n", buf1, buf2,  tref);

    setNr=getSetNr(buf2);
    if (setNr<0)
    {
      printf (" alpha: set:%s does not exist\n", buf2);
      return;
    }

    /* calculate the heat-transver-coefficient alpha */     
    for(l=0; l<sum->l; l++)                                     
    {                                                           
      /* use only duns-results */
      if (compare(lcase[l].name,"duns",4)==4)
      {
        printf(" calc the heat-transver-coefficient alpha for LC[%d]: %s \n", l, lcase[l].name); 
  
        /* create a new dataset */
        if ( (lcase = (Datasets *)realloc((Datasets *)lcase, (sum->l+1) * sizeof(Datasets))) == NULL )
          printf("\n\n ERROR: malloc failure\n\n" );

        lcase[sum->l].ncomps = 7;
        lcase[sum->l].irtype = 1;
        lcase[sum->l].npheader  = 0 ;
        lcase[sum->l].value  = lcase[l].value ;
  
        if ( (lcase[sum->l].nmax = (int *)malloc( lcase[sum->l].ncomps * sizeof(int))) == NULL )
          printf("\n\n ERROR: malloc failure\n\n" );
        if ( (lcase[sum->l].nmin = (int *)malloc( lcase[sum->l].ncomps * sizeof(int))) == NULL )
          printf("\n\n ERROR: malloc failure\n\n" );
        if ( (lcase[sum->l].max = (float *)malloc( lcase[sum->l].ncomps * sizeof(float))) == NULL )
          printf("\n\n ERROR: malloc failure\n\n" );
        if ( (lcase[sum->l].min = (float *)malloc( lcase[sum->l].ncomps * sizeof(float))) == NULL )
          printf("\n\n ERROR: malloc failure\n\n" );
        if ( (lcase[sum->l].dat = (float **)malloc( lcase[sum->l].ncomps * sizeof(float *))) == NULL )
          printf("\n\n ERROR: malloc failure\n\n" );
        if ( (lcase[sum->l].compName = (unsigned char **)malloc( lcase[sum->l].ncomps * sizeof(unsigned char *))) == NULL )
          printf("\n\n ERROR: malloc failure\n\n" );
        if ( (lcase[sum->l].icname = (unsigned char **)malloc( lcase[sum->l].ncomps * sizeof(unsigned char *))) == NULL )
          printf("\n\n ERROR: malloc failure\n\n" );
        for(i=0; i<lcase[sum->l].ncomps; i++)
        {
          if ( (lcase[sum->l].dat[i] = (float *)malloc( (sum->nmax+1) * sizeof(float))) == NULL )
            printf("\n\n ERROR: malloc failure\n\n" );	               
          if ( (lcase[sum->l].compName[i] = (unsigned char *)malloc( MAX_LINE_LENGTH * sizeof(unsigned char))) == NULL )
             printf("\n\n ERROR: malloc failed\n\n" );
          if ( (lcase[sum->l].icname[i] = (unsigned char *)malloc( MAX_LINE_LENGTH * sizeof(unsigned char))) == NULL )
             printf("\n\n ERROR: malloc failed\n\n" );
          lcase[sum->l].max[i]=-MAXVALUE;
          lcase[sum->l].min[i]=MAXVALUE;
        }
        if ( (lcase[sum->l].ictype = (int *)malloc( lcase[sum->l].ncomps * sizeof(int))) == NULL )
          printf("\n\n ERROR: malloc failure\n\n" );
        if ( (lcase[sum->l].icind1 = (int *)malloc( lcase[sum->l].ncomps * sizeof(int))) == NULL )
          printf("\n\n ERROR: malloc failure\n\n" );
        if ( (lcase[sum->l].icind2 = (int *)malloc( lcase[sum->l].ncomps * sizeof(int))) == NULL )
          printf("\n\n ERROR: malloc failure\n\n" );
        if ( (lcase[sum->l].iexist = (int *)malloc( lcase[sum->l].ncomps * sizeof(int))) == NULL )
          printf("\n\n ERROR: malloc failure\n\n" );
  
        for(i=0; i<lcase[sum->l].ncomps; i++)
        {
          lcase[sum->l].ictype[i] = 1;
          lcase[sum->l].icind1[i] = i+1;
          lcase[sum->l].icind2[i] = 0;
          lcase[sum->l].iexist[i] = 0;
        }
        sprintf( lcase[sum->l].name, "ALPHA");
        strcpy( lcase[sum->l].compName[0], "alpha");
        strcpy( lcase[sum->l].compName[1], "dh   ");
        strcpy( lcase[sum->l].compName[2], "dt   ");
        strcpy( lcase[sum->l].compName[3], "dv   ");
        strcpy( lcase[sum->l].compName[4], "tau   ");
        strcpy( lcase[sum->l].compName[5], "yplus");
        strcpy( lcase[sum->l].compName[6], "wl ");
  
        for(i=0; i<lcase[sum->l].ncomps; i++) for(n=0; n<sum->n; n++) lcase[sum->l].dat[i][n]=0.;

        for(f=0; f<set[setNr].anz_f; f++)
        {
          /* calc the heigh dh of the element at the face nodes */
          e=face[set[setNr].face[f]].elem_nr;
          for(n=0; n<4; n++)
          {
            nod1=face[f].nod[n];

            /* search the opposide node in the free-stream */
            for(en=0; en<8; en++)
            {
              /* ((ni[j]==1)||(ni[j]==2)||(ni[j]==3)||(ni[j]==4)) f[0] */
              if (face[f].nr==0)
              {
                if(nod1==elem[e].nod[en])
                {
                  nod2=elem[e].nod[en+4];
                  break;
                }
              }
              /* ((ni[j]==5)||(ni[j]==8)||(ni[j]==7)||(ni[j]==6)) f[1] */
              if (face[f].nr==1)
              {
                if(nod1==elem[e].nod[en])
                {
                  nod2=elem[e].nod[en-4];
                  break;
                }
              }
              /* ((ni[j]==1)||(ni[j]==5)||(ni[j]==6)||(ni[j]==2)) f[2] */
              if (face[f].nr==2)
              {
                if(nod1==elem[e].nod[en])
                {
                  if(en==0) nod2=elem[e].nod[3];
                  if(en==1) nod2=elem[e].nod[2];
                  if(en==5) nod2=elem[e].nod[6];
                  if(en==4) nod2=elem[e].nod[7];
                  break;
                }
              }
              /* ((ni[j]==2)||(ni[j]==6)||(ni[j]==7)||(ni[j]==3)) f[3] */
              if (face[f].nr==3)
              {
                if(nod1==elem[e].nod[en])
                {
                  if(en==1) nod2=elem[e].nod[0];
                  if(en==5) nod2=elem[e].nod[4];
                  if(en==6) nod2=elem[e].nod[7];
                  if(en==2) nod2=elem[e].nod[3];
                  break;
                }
              }
              /* ((ni[j]==3)||(ni[j]==7)||(ni[j]==8)||(ni[j]==4)) f[4] */
              if (face[f].nr==4)
              {
                if(nod1==elem[e].nod[en])
                {
                  if(en==2) nod2=elem[e].nod[1];
                  if(en==6) nod2=elem[e].nod[5];
                  if(en==7) nod2=elem[e].nod[4];
                  if(en==3) nod2=elem[e].nod[0];
                  break;
                }
              }
              /* ((ni[j]==4)||(ni[j]==8)||(ni[j]==5)||(ni[j]==1)) f[5] */
              if (face[f].nr==5)
              {
                if(nod1==elem[e].nod[en])
                {
                  if(en==3) nod2=elem[e].nod[2];
                  if(en==7) nod2=elem[e].nod[6];
                  if(en==4) nod2=elem[e].nod[5];
                  if(en==0) nod2=elem[e].nod[1];
                  break;
                }
              }
            }
            v_result(&node[nod1].nx, &node[nod2].nx, p01);
            dh=v_betrag(p01);

            /* get the pres p and temps ts (stream) tf (face) and the thermal conductivity wl */
            pf=lcase[l].dat[0][nod1];
            ps=lcase[l].dat[0][nod2];
            tf=lcase[l].dat[1][nod1];
            ts=lcase[l].dat[1][nod2];
            wl=(lcase[l].dat[6][nod1]+lcase[l].dat[6][nod2])*.5;
            /* calc the heat-transfer-coefficient alpha */

            /* tangential velocities */
            vf=(lcase[l].dat[5][nod1]+lcase[l].dat[5][nod1])*.5;
            vs=(lcase[l].dat[5][nod2]+lcase[l].dat[5][nod2])*.5;
            dv=vs-vf;
            rho=(pf+ps)/R/(ts+tf);
            tau=nue*rho *(dv/dh);
            yplus=dh*sqrt(tau*rho)/(nue*rho);

            lcase[sum->l].dat[0][nod1]=wl/dh*(ts-tf)/(tref-tf);
            lcase[sum->l].dat[1][nod1]=dh;
            lcase[sum->l].dat[2][nod1]=ts-tf;
            lcase[sum->l].dat[3][nod1]=dv;
            lcase[sum->l].dat[4][nod1]=tau;
            lcase[sum->l].dat[5][nod1]=yplus;
            lcase[sum->l].dat[6][nod1]=wl;
          }
        }

        for(n=0; n<sum->n; n++)
        {
          for(i=0; i<lcase[sum->l].ncomps; i++)
          {
            if (lcase[sum->l].dat[i][node[n].nr] >  lcase[sum->l].max[i])
            {  lcase[sum->l].max[i]=lcase[sum->l].dat[i][node[n].nr]; lcase[sum->l].nmax[i]=node[n].nr; }
            if (lcase[sum->l].dat[i][node[n].nr] <  lcase[sum->l].min[i])
            {  lcase[sum->l].min[i]=lcase[sum->l].dat[i][node[n].nr]; lcase[sum->l].nmin[i]=node[n].nr; }
          }
        }
        sum->l++;
        num_olc++;
      }
    }
  }

  else if(compare(string, "lift", 4)==4)                         
  {                                                             
    sscanf(string, "%s %s", buf1, buf2);
    printf("|%s| set:|%s|\n", buf1, buf2);

    inSet=getSetNr(buf1);
    if (setNr<0)
    {
      printf (" lift: set:%s does not exist\n", buf1);
      return;
    }

    profSet=getSetNr(buf2);
    if (profSet<0)
    {
      printf (" lift: set:%s does not exist\n", buf2);
      return;
    }

    /* calculate  lift and drag */     
    for(l=0; l<sum->l; l++)                                     
    {                                                           
      /* use only duns-results */
      if (compare(lcase[l].name,"duns",4)==4)
      {
        printf(" calc lift and drag for LC[%d]: %s \n", l, lcase[l].name); 
  
        /* create a new dataset */
        if ( (lcase = (Datasets *)realloc((Datasets *)lcase, (sum->l+1) * sizeof(Datasets))) == NULL )
          printf("\n\n ERROR: malloc failure\n\n" );

        lcase[sum->l].ncomps = 7;
        lcase[sum->l].irtype = 1;
        lcase[sum->l].npheader  = 0 ;
        lcase[sum->l].value  = lcase[l].value ;
  
        if ( (lcase[sum->l].nmax = (int *)malloc( lcase[sum->l].ncomps * sizeof(int))) == NULL )
          printf("\n\n ERROR: malloc failure\n\n" );
        if ( (lcase[sum->l].nmin = (int *)malloc( lcase[sum->l].ncomps * sizeof(int))) == NULL )
          printf("\n\n ERROR: malloc failure\n\n" );
        if ( (lcase[sum->l].max = (float *)malloc( lcase[sum->l].ncomps * sizeof(float))) == NULL )
          printf("\n\n ERROR: malloc failure\n\n" );
        if ( (lcase[sum->l].min = (float *)malloc( lcase[sum->l].ncomps * sizeof(float))) == NULL )
          printf("\n\n ERROR: malloc failure\n\n" );
        if ( (lcase[sum->l].dat = (float **)malloc( lcase[sum->l].ncomps * sizeof(float *))) == NULL )
          printf("\n\n ERROR: malloc failure\n\n" );
        if ( (lcase[sum->l].compName = (unsigned char **)malloc( lcase[sum->l].ncomps * sizeof(unsigned char *))) == NULL )
          printf("\n\n ERROR: malloc failure\n\n" );
        if ( (lcase[sum->l].icname = (unsigned char **)malloc( lcase[sum->l].ncomps * sizeof(unsigned char *))) == NULL )
          printf("\n\n ERROR: malloc failure\n\n" );
        for(i=0; i<lcase[sum->l].ncomps; i++)
        {
          if ( (lcase[sum->l].dat[i] = (float *)malloc( (sum->nmax+1) * sizeof(float))) == NULL )
            printf("\n\n ERROR: malloc failure\n\n" );	               
          if ( (lcase[sum->l].compName[i] = (unsigned char *)malloc( MAX_LINE_LENGTH * sizeof(unsigned char))) == NULL )
             printf("\n\n ERROR: malloc failed\n\n" );
          if ( (lcase[sum->l].icname[i] = (unsigned char *)malloc( MAX_LINE_LENGTH * sizeof(unsigned char))) == NULL )
             printf("\n\n ERROR: malloc failed\n\n" );
          lcase[sum->l].max[i]=-MAXVALUE;
          lcase[sum->l].min[i]=MAXVALUE;
        }
        if ( (lcase[sum->l].ictype = (int *)malloc( lcase[sum->l].ncomps * sizeof(int))) == NULL )
          printf("\n\n ERROR: malloc failure\n\n" );
        if ( (lcase[sum->l].icind1 = (int *)malloc( lcase[sum->l].ncomps * sizeof(int))) == NULL )
          printf("\n\n ERROR: malloc failure\n\n" );
        if ( (lcase[sum->l].icind2 = (int *)malloc( lcase[sum->l].ncomps * sizeof(int))) == NULL )
          printf("\n\n ERROR: malloc failure\n\n" );
        if ( (lcase[sum->l].iexist = (int *)malloc( lcase[sum->l].ncomps * sizeof(int))) == NULL )
          printf("\n\n ERROR: malloc failure\n\n" );
  
        for(i=0; i<lcase[sum->l].ncomps; i++)
        {
          lcase[sum->l].ictype[i] = 1;
          lcase[sum->l].icind1[i] = i+1;
          lcase[sum->l].icind2[i] = 0;
          lcase[sum->l].iexist[i] = 0;
        }
        sprintf( lcase[sum->l].name, "LIFT");
        strcpy( lcase[sum->l].compName[0], "ax   ");
        strcpy( lcase[sum->l].compName[1], "ay   ");
        strcpy( lcase[sum->l].compName[2], "az   ");
        strcpy( lcase[sum->l].compName[3], "A    ");
        strcpy( lcase[sum->l].compName[4], "tau  ");
        strcpy( lcase[sum->l].compName[5], "     ");
        strcpy( lcase[sum->l].compName[6], "     ");
  
        for(i=0; i<lcase[sum->l].ncomps; i++) for(n=0; n<sum->n; n++) lcase[sum->l].dat[i][n]=0.;

        for(f=0; f<set[profSet].anz_f; f++)
        {
          e=face[f].elem_nr;

          /* calc the area per node in xyz, each node uses 0.25*area */
          v_result( &node[face[f].nod[0]].nx, &node[face[f].nod[1]].nx, v1);
          v_result( &node[face[f].nod[0]].nx, &node[face[f].nod[3]].nx, v2);
          v_prod( v1, v2, a1 );
          v_result( &node[face[f].nod[2]].nx, &node[face[f].nod[3]].nx, v1);
          v_result( &node[face[f].nod[2]].nx, &node[face[f].nod[1]].nx, v2);
          v_prod( v1, v2, a2 );
          lcase[sum->l].dat[0][face[f].nod[0]]=(a1[0]+a2[0])*.25;
          lcase[sum->l].dat[1][face[f].nod[0]]=(a1[1]+a2[1])*.25;
          lcase[sum->l].dat[2][face[f].nod[0]]=(a1[2]+a2[2])*.25;

          /* calc the heigh dh of the element at the face nodes */
          for(n=0; n<4; n++)
          {
            nod1=face[set[setNr].face[f]].nod[n];

            /* search the opposide node in the free-stream */
            for(en=0; en<8; en++)
            {
              /* ((ni[j]==1)||(ni[j]==2)||(ni[j]==3)||(ni[j]==4)) f[0] */
              if (face[f].nr==0)
              {
                if(nod1==elem[e].nod[en])
                {
                  nod2=elem[e].nod[en+4];
                  break;
                }
              }
              /* ((ni[j]==5)||(ni[j]==8)||(ni[j]==7)||(ni[j]==6)) f[1] */
              if (face[f].nr==1)
              {
                if(nod1==elem[e].nod[en])
                {
                  nod2=elem[e].nod[en-4];
                  break;
                }
              }
              /* ((ni[j]==1)||(ni[j]==5)||(ni[j]==6)||(ni[j]==2)) f[2] */
              if (face[f].nr==2)
              {
                if(nod1==elem[e].nod[en])
                {
                  if(en==0) nod2=elem[e].nod[3];
                  if(en==1) nod2=elem[e].nod[2];
                  if(en==5) nod2=elem[e].nod[6];
                  if(en==4) nod2=elem[e].nod[7];
                  break;
                }
              }
              /* ((ni[j]==2)||(ni[j]==6)||(ni[j]==7)||(ni[j]==3)) f[3] */
              if (face[f].nr==3)
              {
                if(nod1==elem[e].nod[en])
                {
                  if(en==1) nod2=elem[e].nod[0];
                  if(en==5) nod2=elem[e].nod[4];
                  if(en==6) nod2=elem[e].nod[7];
                  if(en==2) nod2=elem[e].nod[3];
                  break;
                }
              }
              /* ((ni[j]==3)||(ni[j]==7)||(ni[j]==8)||(ni[j]==4)) f[4] */
              if (face[f].nr==4)
              {
                if(nod1==elem[e].nod[en])
                {
                  if(en==2) nod2=elem[e].nod[1];
                  if(en==6) nod2=elem[e].nod[5];
                  if(en==7) nod2=elem[e].nod[4];
                  if(en==3) nod2=elem[e].nod[0];
                  break;
                }
              }
              /* ((ni[j]==4)||(ni[j]==8)||(ni[j]==5)||(ni[j]==1)) f[5] */
              if (face[f].nr==5)
              {
                if(nod1==elem[e].nod[en])
                {
                  if(en==3) nod2=elem[e].nod[2];
                  if(en==7) nod2=elem[e].nod[6];
                  if(en==4) nod2=elem[e].nod[5];
                  if(en==0) nod2=elem[e].nod[1];
                  break;
                }
              }
            }
            v_result(&node[nod1].nx, &node[nod2].nx, p01);
            dh=v_betrag(p01);

            /* get the pres p and temps ts (stream) tf (face) and the thermal conductivity wl */
            pf=lcase[l].dat[0][nod1];
            ps=lcase[l].dat[0][nod2];
            tf=lcase[l].dat[1][nod1];
            ts=lcase[l].dat[1][nod2];
            wl=(lcase[l].dat[6][nod1]+lcase[l].dat[6][nod2])*.5;
            /* calc the heat-transfer-coefficient alpha */

            /* tangential velocities */
            vf=(lcase[l].dat[5][nod1]+lcase[l].dat[5][nod1])*.5;
            vs=(lcase[l].dat[5][nod2]+lcase[l].dat[5][nod2])*.5;
            dv=vs-vf;
            rho=(pf+ps)/R/(ts+tf);
            tau=nue*rho *(dv/dh);
            yplus=dh*sqrt(tau*rho)/(nue*rho);

            lcase[sum->l].dat[3][nod1]+=lcase[sum->l].dat[0][nod1]*pf;
            lcase[sum->l].dat[4][nod1]+=lcase[sum->l].dat[1][nod1]*pf;
            lcase[sum->l].dat[5][nod1]+=lcase[sum->l].dat[2][nod1]*pf;
            lcase[sum->l].dat[6][nod1]=wl;
          }
        }

        for(n=0; n<sum->n; n++)
        {
          for(i=0; i<lcase[sum->l].ncomps; i++)
          {
            if (lcase[sum->l].dat[i][node[n].nr] >  lcase[sum->l].max[i])
            {  lcase[sum->l].max[i]=lcase[sum->l].dat[i][node[n].nr]; lcase[sum->l].nmax[i]=node[n].nr; }
            if (lcase[sum->l].dat[i][node[n].nr] <  lcase[sum->l].min[i])
            {  lcase[sum->l].min[i]=lcase[sum->l].dat[i][node[n].nr]; lcase[sum->l].nmin[i]=node[n].nr; }
          }
        }
        sum->l++;
        num_olc++;
      }
    }
  }

  else if(compare(string, "intpol", 5)==5)                         
  {                                                             
    sscanf(string, "%*s %s %s %d %d %d", buf2, buf1, &l, &e, &nodeOffset);
    printf("string:%s| |%s| |%s| |%d|  |%d|\n", string,buf1, buf2,  l,e);
    l--; e--;

    setNr=getSetNr(buf1);
    if (setNr<0)
    {
      printf (" intpol: set1:%s does not exist\n", buf1);
      return;
    }

    apre->n=0;
    apre->e=0;
    apre->f=0;
    apre->g=0;
    apre->emax=0;  apre->emin=MAXVALUE;
    apre->nmax=0;  apre->nmin=MAXVALUE;
    apre->l=0;
    if( readccx( buf2, apre, &npre, &epre, &lpre, &facebuf)<0) return;

    printf("add nodes:%d maxnr:%d starting with nodenr:%d\n",apre->n, apre->nmax, sum->nmax+1);  

    n=i=strlen(buf2);
    while((i>=0)&&(buf2[i]!='/')) i--;
    j=0; i++; while((i<n)&&(buf2[i]!='.')) buf2[j++]=buf2[i++];
    buf2[j]=0;
    printf("depset:|%s|\n", buf2);

    /* create the nodes */
    nodeOffset=sum->nmax;
    delSet(buf2);
    depSet=seto(buf2);
    for(i=0; i<apre->n; i++) 
    {
      nod( sum, &(*nptr), 1, npre[i].nr+nodeOffset, npre[npre[i].nr].nx, npre[npre[i].nr].ny, npre[npre[i].nr].nz, 1 );
    }
    node=*nptr;
    setc(buf2);

    if(l>=sum->l)
    {
      printf (" intpol: dataset:%d does not exist\n", l+1);
      return;
    }
    if(e>=lcase[l].ncomps)
    {
      printf (" intpol: entity:%d does not exist\n", e+1);
      return;
    }

    /* interpol of a value-field */
    sprintf(entity, "e%d", e);
    sprintf(loadcase, "l%d", l);
    sprintf(buf1, "abq");
    areampc(depSet, setNr, buf1, entity, loadcase, nodeOffset);
    zap(buf2);
  }

  else if(compare(string, "calcFres", 5)==5)                         
  {                                                             
    sscanf(string, "%*s %s %d %d %d", buf1, &l, &e, &nodeOffset);
    printf("string:%s| |%s| |%d|  |%d|\n", string,buf1, l,e);
    l--; e--;

    setNr=getSetNr(buf1);
    if (setNr<0)
    {
      printf (" calcFres: set:%s does not exist\n", buf1);
      return;
    }
    if(l>=sum->l)
    {
      printf (" calcFres: dataset:%d does not exist\n", l+1);
      return;
    }
    if(e>=lcase[l].ncomps)
    {
      printf (" calcFres: entity:%d does not exist\n", e+1);
      return;
    }

    /* go over all faces, calc area-vectors and multiply with av-pressure */
    area=0.;
    Fres=0.;
    vFres[0]=0.;
    vFres[1]=0.;
    vFres[2]=0.;
    for(i=0; i<set[setNr].anz_f; i++)
    {
      f=set[setNr].face[i];
      if(face[f].type==10)
      {
        v_result( &node[face[f].nod[8]].nx, &node[face[f].nod[0]].nx, v1);
        v_result( &node[face[f].nod[8]].nx, &node[face[f].nod[4]].nx, v2);
        v_prod( v1, v2, vn );
        v_scalf(&lcase[l].dat[e][face[f].nod[0]],vn,evF);
        v_result( &node[face[f].nod[8]].nx, &node[face[f].nod[4]].nx, v1);
        v_result( &node[face[f].nod[8]].nx, &node[face[f].nod[1]].nx, v2);
        v_prod( v1, v2, v3 );
        v_add( vn,v3,vn);
        v_scalf(&lcase[l].dat[e][face[f].nod[4]],v3,vF);
        v_add( vF,evF,evF);
        v_result( &node[face[f].nod[8]].nx, &node[face[f].nod[1]].nx, v1);
        v_result( &node[face[f].nod[8]].nx, &node[face[f].nod[5]].nx, v2);
        v_prod( v1, v2, v3 );
        v_add( vn,v3,vn);
        v_scalf(&lcase[l].dat[e][face[f].nod[1]],v3,vF);
        v_add( vF,evF,evF);
        v_result( &node[face[f].nod[8]].nx, &node[face[f].nod[5]].nx, v1);
        v_result( &node[face[f].nod[8]].nx, &node[face[f].nod[2]].nx, v2);
        v_prod( v1, v2, v3 );
        v_add( vn,v3,vn);
        v_scalf(&lcase[l].dat[e][face[f].nod[5]],v3,vF);
        v_add( vF,evF,evF);
        v_result( &node[face[f].nod[8]].nx, &node[face[f].nod[2]].nx, v1);
        v_result( &node[face[f].nod[8]].nx, &node[face[f].nod[6]].nx, v2);
        v_prod( v1, v2, v3 );
        v_add( vn,v3,vn);
        v_scalf(&lcase[l].dat[e][face[f].nod[2]],v3,vF);
        v_add( vF,evF,evF);
        v_result( &node[face[f].nod[8]].nx, &node[face[f].nod[6]].nx, v1);
        v_result( &node[face[f].nod[8]].nx, &node[face[f].nod[3]].nx, v2);
        v_prod( v1, v2, v3 );
        v_add( vn,v3,vn);
        v_scalf(&lcase[l].dat[e][face[f].nod[6]],v3,vF);
        v_add( vF,evF,evF);
        v_result( &node[face[f].nod[8]].nx, &node[face[f].nod[3]].nx, v1);
        v_result( &node[face[f].nod[8]].nx, &node[face[f].nod[7]].nx, v2);
        v_prod( v1, v2, v3 );
        v_add( vn,v3,vn);
        v_scalf(&lcase[l].dat[e][face[f].nod[3]],v3,vF);
        v_add( vF,evF,evF);
        v_result( &node[face[f].nod[8]].nx, &node[face[f].nod[7]].nx, v1);
        v_result( &node[face[f].nod[8]].nx, &node[face[f].nod[0]].nx, v2);
        v_prod( v1, v2, v3 );
        v_add( vn,v3,vn);
        v_scalf(&lcase[l].dat[e][face[f].nod[7]],v3,vF);
        v_add( vF,evF,evF);

        factor=0.5*scale->w*scale->w;
        v_scal(&factor,vn,vn);
        earea=v_betrag(vn);
        area+=earea;

        v_scal(&factor,evF,evF);
        eFres=v_betrag(evF);
        v_add(evF,vFres,vFres);
        Fres=v_betrag(vFres);

        printf("  face:%d type:%d earea:%lf eFres:%lf\n", f, face[f].type, earea, eFres);
      }
      else
      {
        printf("ERROR: face:%d.type:%d not known\n", f, face[f].type);
      }
    }
    printf("\n area:%lf Fres:%lf (%lf %lf %lf)\n",area, Fres,vFres[0],vFres[1],vFres[2]);
  }
  else printf(" ERROR userfunction:%s not known\n", string);

  *nptr=node;
  *eptr=elem;
  *lptr=lcase;
}
