/* --------------------------------------------------------------------  */
/*                          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) */
                                                                 
                                                                
void userFunction(unsigned char *string, Summen *sum, Nodes **nptr, Elements **eptr, Datasets **lptr, Faces **fptr, Sets **sptr)
{                                                               
  int i,j,l,n, setNr;                                                    
  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 v1[3], v2[3], a1[3], a2[3];

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



  if(strlen(string)==0)                         
  {
    printf("  average <common-DATASET-name> l<nr> l<nr>\n");
    printf("  maxVals <common-DATASET-name>\n");                                          
    printf("  hydro\n");
    printf("  alpha <set> tref\n");
    printf("  intpol <abqnodefile(target)> <set> l(oadcase)<nr> e(ntity)<nr>\n");
    printf("  lift <setin> <setprofil>\n");
    printf("  mksets l<nr> e<nr>\n");
  }                                          


  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].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].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].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].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 printf(" ERROR userfunction:%s not known\n", string);

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