/* --------------------------------------------------------------------  */
/*                          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.         */
/* --------------------------------------------------------------------  */

/* BUGS
 search for "bug:"
 */

#include <cgx.h>
#define TEST 0




extern int       neqn;                 /* offset der equations fuer ansys, bzw. MPC ID fuer Nast. */

extern int   offset, maxIndex;                            /* offset+steps-1 = maxIndex */
extern int   basCol[3];                     /* color indexes due to basic colormap */
extern int   width_ini, height_ini; /* Grafig-Fensterbreite/hoehe */
extern int   width_menu, height_menu;
extern int   w0, w1, w_index, w_rgb, activWindow;
extern int   width_w0, height_w0;
extern int   width_w1, height_w1;
extern int   MouseMode;                                   /* status maustasten */
extern double dtx, dty, dtz, drx, dry, drz, ds;                 /* Verschiebungen */
extern double vmem[4];                                     /* kor. bis auswahl eines neuen drehpkts */
extern GLdouble R[4][4];                                   /* Rotationsmatrix */
extern unsigned char  surfFlag;                /* zeichne nur Oberflaechenelemente (1), sonst (0)*/
extern unsigned char  modelEdgeFlag;                /* zeichne mit Modell-Ecken (1), sonst (0)*/
extern unsigned char  frameFlag;                   /* mit (1) oder ohne Rahmen um das Grafikfenster */
extern unsigned char  filenamFlag;                   /* mit (1) oder ohne filename im Menufenster */
extern unsigned char  textFlag;                   /* mit (1) oder ohne text im Menufenster */
extern unsigned char  printFlag;                     /* printf 1:on 0:off */
extern unsigned char  cullFlag;                     /* (1) enable Culling */
extern unsigned char  frameFlag;               /* mit (1) oder ohne Rahmen um das Grafigfenster */
extern unsigned char  scalaFlag;                 /* mit (1) oder ohne scala und wertetexte */ 
extern double dx ,dy;                                      /* Mauskoordinaten */
extern int   steps;                   /* Schrittweite der Farbscala, und NURB aufloesung */
extern double gtol;
extern unsigned char  picture_text[MAX_LINE_LENGTH], datin[MAX_LINE_LENGTH];

extern unsigned char  delPntFlag;                    /* 1: deleted points exists */
extern unsigned char  delLineFlag;                   /* 1: deleted lines exists */
extern unsigned char  delLcmbFlag;                   /* 1: deleted lcmbs exists */
extern unsigned char  delSurfFlag;                   /* 1: deleted surfs exists */
extern unsigned char  delBodyFlag;                   /* 1: deleted bodys exists */

extern int     num_onod;          /* nr-of-original-nodes (nodes from input-file) */
extern int     num_olc;          /* nr-of-original-loadcases (lc from input-file) */

extern Scale     scale[1];
extern double     *value_n;
extern Summen    anz[1];
extern Edges     *edge;
extern Nodes     *node;
extern Elements  *e_enqire;
extern Nodes     *n_anim;
extern Datasets *lcase;

extern Alias     *alias;
extern Sets      *set;
extern Psets     *pset;
extern Points    *point;
extern Lines     *line;
extern Lcmb      *lcmb;
extern Gsur      *surf;
extern Gbod      *body;
extern Nurbs     *nurbs;
extern SumGeo    anzGeo[1];
extern SumAsci   sumAsci[1];

extern int       num_olc;

extern SpecialSet specialset[1];

extern int       offset;


#define     DOFX        1
#define     DOFY        2
#define     DOFZ        3
#define     DOFT        11
#define     DPHI_TOL    0.017453      /* 1grd */

#define     N_CLOSEST_NODES 10

double   MIN_C={0.9};   /* zulaessiger flaechenfehler in calcCoefficients(), */
double   MAX_C={1.1};   /* wird durch verschieben der nodes korrigiert       */

void sendMpc( unsigned char *setname, unsigned char *format, Summen *anz, Nodes *node, Elements *e_enqire, unsigned char *rotation , double *vector)
{
  int   i,j;
  int   length, setNr;
  unsigned char prognam[MAX_LINE_LENGTH], boundary[MAX_LINE_LENGTH];

  FILE *handle, *handle_boundary;


  strcpy ( prognam, setname);
  length= strlen ( setname );
  setNr=getSetNr(setname);
  if (setNr<0)
  {
    printf (" ERROR: set:%s does not exist\n", setname);
    return;
  }

  strcpy ( prognam, setname);
  length= strlen ( setname );
  strcpy (&prognam[length], ".mpc");

  /* write the mpcs in abaqus-format */
  if (compare( format, "abq", 3)== 3)
  {
    handle = fopen (prognam, "w");
    if ( handle== NULL )
    {
      printf ("\nThe input file %s could not be opened.\n\n", prognam); 
      return;
    }

    strcpy ( boundary, setname);
    length= strlen ( setname );
    strcpy (&boundary[length], ".bou");
    handle_boundary = fopen (boundary, "w");
    if ( handle_boundary== NULL )
    {
      printf ("\nThe input file %s could not be opened.\n\n", boundary); 
      return;
    }

    fprintf(handle, "** INCLUDE THE FOLLOWING LINES IN THE MODEL-DEFINITION-SECTION:\n");
    fprintf(handle, "**   THE LOCATION OF THE INDEPENDENT NODE FOR PRETWIST\n");
    fprintf(handle, "**   IS USED TO DEFINE THE DIRECTION OF THE ROTATIONAL VECTOR\n");
    fprintf(handle, "**     AROUND X: 1.,0.,0.\n");
    fprintf(handle, "**     AROUND Y: 0.,1.,0.\n");
    fprintf(handle, "**     AROUND Z: 0.,0.,1. (DEFAULT)\n");
    fprintf(handle, "*NODE, NSET=Ntwist\n");
    fprintf(handle, "%d,%lf,%lf,%lf\n",num_onod+1,vector[0],vector[1],vector[2] );
    fprintf(handle, "*MPC, USER\n1,");
    j=0; for (i=0; i<set[setNr].anz_n; i++ )
    {
      if( j>12 )
      {
        j=0;
        fprintf(handle, "\n0,");
      }
      fprintf(handle, "%d,",set[setNr].node[i]);
      j++;
      fprintf(handle, "%d,",set[setNr].node[i]);
      j++;
      fprintf(handle, "%d,",set[setNr].node[i]);
      j++;
    }
    if(j>14) fprintf(handle, "\n0,%d\n", num_onod+1);
    else fprintf(handle, "%d\n", num_onod+1);
    fclose(handle);

    fprintf(handle_boundary, "**INCLUDE THE FOLLOWING LINES IN A STEP:\n");
    fprintf(handle_boundary, "**  Pretwist of %s degree\n*BOUNDARY\n", rotation);
    fprintf(handle_boundary, "%d, 1, 1, %lf\n", num_onod+1, atof(rotation)*pi/180.);
    fclose(handle_boundary);
  }
  else
  {
    printf(" ERROR: format %s not yet supported\a\n", format );
  }
  printf (" ready\n");
}


void cycmpc(int set1, int set2, unsigned char *format, unsigned char *value, unsigned char *corr)
{
  int i,j;
  int firstrun;
  unsigned char  datout[MAX_LINE_LENGTH], buffer[MAX_LINE_LENGTH];
  double dphi, phi_teilung, phi_vorgabe=0.;
  unsigned char  csys, axis;
  double *nx1=0, *nx2=0;
  double *nt1=0, *nt2=0;
  double *nr1=0, *nr2=0;
  double *phi=0;
  FILE  *handle;
  Nodes *node1=0;          /* dep nodes */
  Nodes *node2=0;          /* indep nodes */

  double rmin,dx,dr,R,f;
  int   node2j=0;


  if ( (compare( format, "abq", 3)!= 3)&&
       (compare( format, "ans", 3)!= 3)&&
       (compare( format, "nas", 3)!= 3) ) 
  {
    printf ("ERROR: format:%s not known\a\n\n", format);
    return;
  }

  /* ---- clear special sets ----- */
  delSet(specialset->mpc );
  delSet(specialset->nompc );


  /* Open the files and check to see that it was opened correctly */
  sprintf(datout, "%s.equ", set[set1].name);
  if(printFlag) printf ("datout:%s set1:%s nodes:%d set2:%s nodes:%d\n",datout, set[set1].name, set[set1].anz_n, set[set2].name, set[set2].anz_n);
  handle = fopen (datout, "w");
  if (handle==NULL) { printf ("\nThe output file \"%s\" could not be opened.\n\n", datout); return; }
  else  printf (" %s opened\n", datout);
  if (compare( format, "abq", 3)== 3)      fprintf(handle, "** cycmpc based on set %s %s\n",set[set1].name, set[set2].name );
  else if (compare( format, "ans", 3)== 3) fprintf(handle, "! cycmpc based on set %s %s\n",set[set1].name, set[set2].name );
  else if (compare( format, "nas", 3)== 3) fprintf(handle, "$ cycmpc based on set %s %s\n",set[set1].name, set[set2].name );

  csys=value[0];
  axis=value[1];
  i=atoi(&corr[1]);    /* startnummer der equations in abaqus, oder id in nastran */
  if(i>0) neqn=i-1;
  f=atof(&value[2]);
  if(f!=0.) phi_vorgabe=2.*pi /f;  /* teilungswinkel, berechnet aus der segmentzahl */


  /* ------- node-koordinaten berechnen und am ende wieder scalieren ------ */
  descalNodes ( anz->n, node, scale );


  /* --------- Seitenflaeche einlesen und Daten aufbereiten --------------- */

  if ( (node1 = (Nodes *)malloc( set[set1].anz_n * sizeof(Nodes))) == NULL )
  {
    printf("\nERROR: malloc failed in cycmpc() \a\n\n");
    goto end;
  }
  if ( (node2 = (Nodes *)malloc( set[set2].anz_n * sizeof(Nodes))) == NULL )
  {
    printf("\nERROR: malloc failed in cycmpc() \a\n\n");
    goto end;
  }
  if ( (nx1 = (double *)malloc( set[set1].anz_n * sizeof(double))) == NULL )
  {
    printf("\nERROR: malloc failed in cycmpc() \a\n\n");
    goto end;
  }
  if ( (nx2 = (double *)malloc( set[set2].anz_n * sizeof(double))) == NULL )
  {
    printf("\nERROR: malloc failed in cycmpc() \a\n\n");
    goto end;
  }
  if ( (nt1 = (double *)malloc( set[set1].anz_n * sizeof(double))) == NULL )
  {
    printf("\nERROR: malloc failed in cycmpc() \a\n\n");
    goto end;
  }
  if ( (nt2 = (double *)malloc( set[set2].anz_n * sizeof(double))) == NULL )
  {
    printf("\nERROR: malloc failed in cycmpc() \a\n\n");
    goto end;
  }
  if ( (nr1 = (double *)malloc( set[set1].anz_n * sizeof(double))) == NULL )
  {
    printf("\nERROR: malloc failed in cycmpc() \a\n\n");
    goto end;
  }
  if ( (nr2 = (double *)malloc( set[set2].anz_n * sizeof(double))) == NULL )
  {
    printf("\nERROR: malloc failed in cycmpc() \a\n\n");
    goto end;
  }
  if ( (phi = (double *)malloc( set[set1].anz_n * sizeof(double))) == NULL )
  {
    printf("\nERROR: malloc failed in cycmpc() \a\n\n");
    goto end;
  }

  /* nodes zuweisen */
  for (i=0; i<set[set1].anz_n; i++ ) node1[i].nr=set[set1].node[i];  
  for (i=0; i<set[set2].anz_n; i++ ) node2[i].nr=set[set2].node[i];  


  /* --------- R,Theta,x Koordinaten berechnen  */

  if (set[set1].anz_n > anz->n) {printf(" ERROR: side has more nodes than the model"); exit(-1);}


 if(axis=='x')
 {
  if(printFlag) printf(" x-axis specified\n");
  for (i=0; i<set[set1].anz_n; i++ )
  {
    nx1[i]= node[node1[i].nr].nx;
    nr1[i]= sqrt( node[node1[i].nr].nz*node[node1[i].nr].nz + node[node1[i].nr].ny*node[node1[i].nr].ny );
    if ( nr1[i] )
    {
      nt1[i]= p_angle( node[node1[i].nr].nz, node[node1[i].nr].ny ); 
    }
  }
  for (i=0; i<set[set2].anz_n; i++ )
  {
    nx2[i]= node[node2[i].nr].nx;
    nr2[i]= sqrt( node[node2[i].nr].nz*node[node2[i].nr].nz + node[node2[i].nr].ny*node[node2[i].nr].ny );
    if ( nr2[i] )
    {
      nt2[i]= p_angle( node[node2[i].nr].nz, node[node2[i].nr].ny );
    }
  }



  /* suche nodepaare, berechne differenzwinkel und schreibe EQUATION's  */
  for (i=0; i<set[set1].anz_n; i++ )
  {
   if (nr1[i]>0)
   {
    /* suche gegenueber liegenden naechsten node  */
    rmin=MAXVALUE;
    for (j=0; j<set[set2].anz_n; j++ )
    {
      if ((nr2[j]>0)&&( node2[j].nr!= node1[i].nr))
      {
        dx= nx2[j]-nx1[i];
        dr= nr2[j]-nr1[i];
        R=sqrt( dx*dx + dr*dr );
        if (R<rmin)
        {
          rmin=R;
          node2j=j;
        }
      }
    }

    /* berechne den differenzwinkel  */
    phi[i]= nt2[node2j]-nt1[i];

    /* definiere den Zielwinkel, entweder vorgabe oder wie berechnet */
    if(phi_vorgabe==0.) phi_teilung=phi[i];
    else phi_teilung=phi_vorgabe;

    firstrun=1;
   nexttryx:;
    /* kontrolliere den differenzwinkel mit der teilung */
    dphi = phi_teilung - phi[i];
    if(dphi>2*pi-DPHI_TOL) while (dphi>2*pi-DPHI_TOL) dphi-=2*pi;
    if(dphi<-2*pi+DPHI_TOL) while (dphi<-2*pi+DPHI_TOL) dphi+=2*pi;
    if ((dphi*dphi > DPHI_TOL)&&(firstrun))
    {
      firstrun=0;
      phi_teilung=-phi_vorgabe;
      goto nexttryx;
    }
    else if ((dphi*dphi > DPHI_TOL)&&(!firstrun))
    {
      printf ("ERROR: korresponding node too far away:%lf grd, see set %s\n\a",dphi*180./pi, specialset->nompc);
      sprintf( buffer, "%d", node1[i].nr); 
      pre_seta(specialset->nompc, "n", buffer);
    }
    else 
    {
    if(printFlag) printf(" theta(%d):%lf theta(%d):%lf  dtheta:%lf dtheta_corr:%lf rmin:%lf\n",
      node1[i].nr, nt1[i]*180./pi, node2[node2j].nr, nt2[node2j]*180./pi,
      phi[i]*180./pi, phi_teilung*180./pi, rmin);

    if (corr[0]=='c')
    { 
      /* versetze den gefundenen Knoten auf die korrespondierende pos. */
      /* der dependent node wird auf die pos des indep gesetzt */
      node[node1[i].nr].nx = node[node2[node2j].nr].nx;
      if ( nr1[i] )
      {
        node[node1[i].nr].ny = node[node2[node2j].nr].ny*cos(phi_teilung)-node[node2[node2j].nr].nz*sin(phi_teilung);
        node[node1[i].nr].nz = node[node2[node2j].nr].ny*sin(phi_teilung)+node[node2[node2j].nr].nz*cos(phi_teilung);
      }  
    }


   if (csys=='t')
   {
    if (compare( format, "abq", 3)== 3)
    {
      /* schreibe die EQUATIOS im Abaqusformat */
      fprintf(handle, "*EQUATION\n");
        fprintf(handle, "%d\n", 2);
        fprintf(handle, "%d,%d,%8.5f, %d,%d,%8.5f \n", node1[i].nr, DOFT, 1.,
          node2[node2j].nr, DOFT, -1. );
    }
   }
   if (csys=='r')
    {
    if (compare( format, "abq", 3)== 3)
      {
      /* schreibe die EQUATIOS im Abaqusformat */
      fprintf(handle, "*EQUATION\n");
        fprintf(handle, "%d\n", 2);
        fprintf(handle, "%d,%d,%8.5f, %d,%d,%8.5f \n", node1[i].nr, DOFX, 1.,
          node2[node2j].nr, DOFX, -1. );
      fprintf(handle, "*EQUATION\n");
        fprintf(handle, "%d\n", 3);
        fprintf(handle, "%d,%d,%8.5f, %d,%d,%8.5f, %d,%d,%8.5f\n", node1[i].nr, DOFY, 1.,
          node2[node2j].nr, DOFY, -cos(phi_teilung),  node2[node2j].nr, DOFZ, sin(phi_teilung) );
      fprintf(handle, "*EQUATION\n");
        fprintf(handle, "%d\n", 3);
        fprintf(handle, "%d,%d,%8.5f, %d,%d,%8.5f, %d,%d,%8.5f\n", node1[i].nr, DOFZ, 1.,
          node2[node2j].nr, DOFY, -sin(phi_teilung),  node2[node2j].nr, DOFZ, -cos(phi_teilung) );
      }
    else if (compare( format, "ans", 3)== 3)
      {
      /* schreibe die EQUATIOS im Ansysformat */
      neqn++;
      fprintf(handle, "CE,%d,0,%d,%s,%8.5f, %d,%s,%8.5f,  %d,%s,%8.5f\n",
        neqn, -1, "UX", 1.,
              node1[i].nr, "UX", 1., node2[node2j].nr, "UX", -1. );
      neqn++;
      fprintf(handle, "CE,%d,0,%d,%s,%8.5f, %d,%s,%8.5f,  %d,%s,%8.5f\n",
        neqn, node1[i].nr, "UY", 1.,
              node2[node2j].nr, "UY", -cos(phi_teilung), node2[node2j].nr, "UZ", sin(phi_teilung) );
      neqn++;
      fprintf(handle, "CE,%d,0,%d,%s,%8.5f, %d,%s,%8.5f,  %d,%s,%8.5f\n",
        neqn, node1[i].nr, "UZ", 1.,
              node2[node2j].nr, "UY", -sin(phi_teilung), node2[node2j].nr, "UZ", -cos(phi_teilung) );
      }
    else if (compare( format, "nas", 3)== 3)
      {
      /* schreibe die EQUATIOS im Nastranformat */
      fprintf(handle, "MPC,%8d,%8d,%8d,%8.5f,%8d,%8d,%8.5f\n", neqn+1, node1[i].nr, DOFX, 1.,
          node2[node2j].nr, DOFX, -1. );
      fprintf(handle, "MPC,%8d,%8d,%8d,%8.5f,%8d,%8d,%8.5f\n", neqn+1, node1[i].nr, DOFY, 1.,
                                                          node2[node2j].nr, DOFY, -cos(phi_teilung));
      fprintf(handle, ", ,%8d,%8d,%8.5f\n", node2[node2j].nr, DOFZ, sin(phi_teilung) );
      fprintf(handle, "MPC,%8d,%8d,%8d,%8.5f,%8d,%8d,%8.5f\n", neqn+1, node1[i].nr, DOFZ, 1.,
                                                          node2[node2j].nr, DOFY, -sin(phi_teilung));
      fprintf(handle, ", ,%8d,%8d,%8.5f\n", node2[node2j].nr, DOFZ, -cos(phi_teilung) );
      }
    }
   if (csys=='c')
    {
    if (compare( format, "abq", 3)== 3)
      {
      /* schreibe die EQUATIOS im Abaqusformat */
      fprintf(handle, "*EQUATION\n");
        fprintf(handle, "%d\n", 2);
        fprintf(handle, "%d,%d,%8.5f, %d,%d,%8.5f \n", node1[i].nr, DOFX, 1.,
          node2[node2j].nr, DOFX, -1. );
      fprintf(handle, "*EQUATION\n");
        fprintf(handle, "%d\n", 2);
        fprintf(handle, "%d,%d,%8.5f, %d,%d,%8.5f \n", node1[i].nr, DOFY, 1.,
          node2[node2j].nr, DOFY, -1. );
      fprintf(handle, "*EQUATION\n");
        fprintf(handle, "%d\n", 2);
        fprintf(handle, "%d,%d,%8.5f, %d,%d,%8.5f \n", node1[i].nr, DOFZ, 1.,
          node2[node2j].nr, DOFZ, -1. );
      }
    else if (compare( format, "ans", 3)== 3)
      {
      /* schreibe die EQUATIOS im Ansysformat */
      neqn++;
      fprintf(handle, "CE,%d,0,%d,%s,%8.5f, %d,%s,%8.5f,  %d,%s,%8.5f\n",
        neqn, -1, "UX", 1.,
              node1[i].nr, "UX", 1., node2[node2j].nr, "UX", -1. );
      neqn++;
      fprintf(handle, "CE,%d,0,%d,%s,%8.5f, %d,%s,%8.5f,  %d,%s,%8.5f\n",
        neqn, -1, "UY", 1.,
              node1[i].nr, "UY", 1., node2[node2j].nr, "UY", -1. );
      neqn++;
      fprintf(handle, "CE,%d,0,%d,%s,%8.5f, %d,%s,%8.5f,  %d,%s,%8.5f\n",
        neqn, -1, "UZ", 1.,
              node1[i].nr, "UZ", 1., node2[node2j].nr, "UZ", -1. );
      }
    else if (compare( format, "nas", 3)== 3)
      {
      /* schreibe die EQUATIOS im Nastranformat */
      fprintf(handle, "MPC,%8d,%8d,%8d,%8.5f,%8d,%8d,%8.5f\n", neqn+1, node1[i].nr, DOFX, 1.,
          node2[node2j].nr, DOFX, -1. );
      fprintf(handle, "MPC,%8d,%8d,%8d,%8.5f,%8d,%8d,%8.5f\n", neqn+1, node1[i].nr, DOFY, 1.,
          node2[node2j].nr, DOFY, -1. );
      fprintf(handle, "MPC,%8d,%8d,%8d,%8.5f,%8d,%8d,%8.5f\n", neqn+1, node1[i].nr, DOFZ, 1.,
          node2[node2j].nr, DOFZ, -1. );
      }
    }
   sprintf( buffer, "%d", node1[i].nr); 
   pre_seta(specialset->mpc, "n", buffer);
   }
   }
  }
 }
 else if(axis=='y')
 {
  if(printFlag) printf("y-axis specified\n");
  for (i=0; i<set[set1].anz_n; i++ )
  {
    nx1[i]= node[node1[i].nr].ny;
    nr1[i]= sqrt( node[node1[i].nr].nz*node[node1[i].nr].nz + node[node1[i].nr].nx*node[node1[i].nr].nx );
    if ( nr1[i] )
    {
      nt1[i]= p_angle( node[node1[i].nr].nx, node[node1[i].nr].nz ); 
    }
  }
  for (i=0; i<set[set2].anz_n; i++ )
  {
    nx2[i]= node[node2[i].nr].ny;
    nr2[i]= sqrt( node[node2[i].nr].nz*node[node2[i].nr].nz + node[node2[i].nr].nx*node[node2[i].nr].nx );
    if ( nr2[i] )
    {
      nt2[i]= p_angle( node[node2[i].nr].nx, node[node2[i].nr].nz ); 
    }
  }



  /* suche nodepaare, berechne differenzwinkel und schreibe EQUATION's  */
  for (i=0; i<set[set1].anz_n; i++ )
  {
   if (nr1[i]>0)
   {
    /* suche gegenueber liegenden naechsten node  */
    rmin=MAXVALUE;
    for (j=0; j<set[set2].anz_n; j++ )
    {
      if ((nr2[j]>0)&&( node2[j].nr!= node1[i].nr))
      {
        dx= nx2[j]-nx1[i];
        dr= nr2[j]-nr1[i];
        R=sqrt( dx*dx + dr*dr );
        if (R<rmin)
        {
          rmin=R;
          node2j=j;
        }
      }
    }

    /* berechne den differenzwinkel  */
    phi[i]= nt2[node2j]-nt1[i];

    /* definiere den Zielwinkel, entweder vorgabe oder wie berechnet */
    if(phi_vorgabe==0.) phi_teilung=phi[i];
    else phi_teilung=phi_vorgabe;

    firstrun=1;
   nexttryy:;
    /* kontrolliere den differenzwinkel mit der teilung */
    dphi = phi_teilung - phi[i];
    if(dphi>2*pi-DPHI_TOL) while (dphi>2*pi-DPHI_TOL) dphi-=2*pi;
    if(dphi<-2*pi+DPHI_TOL) while (dphi<-2*pi+DPHI_TOL) dphi+=2*pi;
    if ((dphi*dphi > DPHI_TOL)&&(firstrun))
    {
      firstrun=0;
      phi_teilung=-phi_vorgabe;
      goto nexttryy;
    }
    else if ((dphi*dphi > DPHI_TOL)&&(!firstrun))
    {
      printf ("ERROR: korresponding node too far away:%lf grd, see set %s\n\a",dphi*180./pi, specialset->nompc);
      sprintf( buffer, "%d", node1[i].nr); 
      pre_seta(specialset->nompc, "n", buffer);
    }
    else 
    {

    if(printFlag) printf(" theta(%d):%lf theta(%d):%lf  dtheta:%lf dtheta_corr:%lf rmin:%lf\n",
      node1[i].nr, nt1[i]*180./pi, node2[node2j].nr, nt2[node2j]*180./pi,
      phi[i]*180./pi, phi_teilung*180./pi, rmin);

    if (corr[0]=='c')
    { 
      /* versetze den gefundenen Knoten auf die korrespondierende pos. */
      /* der dependent node wird auf die pos des indep gesetzt */
      node[node1[i].nr].ny = node[node2[node2j].nr].ny;
      if ( nr1[i] )
      {
        node[node1[i].nr].nx = node[node2[node2j].nr].nz*sin(phi_teilung) + node[node2[node2j].nr].nx*cos(phi_teilung);
        node[node1[i].nr].nz = node[node2[node2j].nr].nz*cos(phi_teilung) - node[node2[node2j].nr].nx*sin(phi_teilung);
      }  
    }  


   if (csys=='t')
   {
    if (compare( format, "abq", 3)== 3)
    {
      /* schreibe die EQUATIOS im Abaqusformat */
      fprintf(handle, "*EQUATION\n");
        fprintf(handle, "%d\n", 2);
        fprintf(handle, "%d,%d,%8.5f, %d,%d,%8.5f \n", node1[i].nr, DOFT, 1.,
          node2[node2j].nr, DOFT, -1. );
    }
   }
   if (csys=='r')
    {
    if (compare( format, "abq", 3)== 3)
      {
      /* schreibe die EQUATIOS im Abaqusformat */
      fprintf(handle, "*EQUATION\n");
        fprintf(handle, "%d\n", 2);
        fprintf(handle, "%d,%d,%8.5f, %d,%d,%8.5f \n", node1[i].nr, DOFY, 1.,
          node2[node2j].nr, DOFY, -1. );
      fprintf(handle, "*EQUATION\n");
        fprintf(handle, "%d\n", 3);
        fprintf(handle, "%d,%d,%8.5f, %d,%d,%8.5f, %d,%d,%8.5f\n", node1[i].nr, DOFZ, 1.,
          node2[node2j].nr, DOFZ, -cos(phi_teilung),  node2[node2j].nr, DOFX, sin(phi_teilung) );
      fprintf(handle, "*EQUATION\n");
        fprintf(handle, "%d\n", 3);
        fprintf(handle, "%d,%d,%8.5f, %d,%d,%8.5f, %d,%d,%8.5f\n", node1[i].nr, DOFX, 1.,
          node2[node2j].nr, DOFZ, -sin(phi_teilung),  node2[node2j].nr, DOFX, -cos(phi_teilung) );
      }
    else if (compare( format, "ans", 3)== 3)
      {
      /* schreibe die EQUATIOS im Ansysformat */
      neqn++;
      fprintf(handle, "CE,%d,0,%d,%s,%8.5f, %d,%s,%8.5f,  %d,%s,%8.5f\n",
        neqn, -1, "UY", 1.,
              node1[i].nr, "UY", 1., node2[node2j].nr, "UY", -1. );
      neqn++;
      fprintf(handle, "CE,%d,0,%d,%s,%8.5f, %d,%s,%8.5f,  %d,%s,%8.5f\n",
        neqn, node1[i].nr, "UZ", 1.,
              node2[node2j].nr, "UZ", -cos(phi_teilung), node2[node2j].nr, "UX", sin(phi_teilung) );
      neqn++;
      fprintf(handle, "CE,%d,0,%d,%s,%8.5f, %d,%s,%8.5f,  %d,%s,%8.5f\n",
        neqn, node1[i].nr, "UX", 1.,
              node2[node2j].nr, "UZ", -sin(phi_teilung), node2[node2j].nr, "UX", -cos(phi_teilung) );
      }
    else if (compare( format, "nas", 3)== 3)
      {
      /* schreibe die EQUATIOS im Nastranformat */
      fprintf(handle, "MPC,%8d,%8d,%8d,%8.5f,%8d,%8d,%8.5f\n", neqn+1, node1[i].nr, DOFY, 1.,
          node2[node2j].nr, DOFY, -1. );
      fprintf(handle, "MPC,%8d,%8d,%8d,%8.5f,%8d,%8d,%8.5f\n", neqn+1, node1[i].nr, DOFZ, 1.,
                                                          node2[node2j].nr, DOFZ, -cos(phi_teilung));
      fprintf(handle, ", ,%8d,%8d,%8.5f\n", node2[node2j].nr, DOFX, sin(phi_teilung) );
      fprintf(handle, "MPC,%8d,%8d,%8d,%8.5f,%8d,%8d,%8.5f\n", neqn+1, node1[i].nr, DOFX, 1.,
                                                          node2[node2j].nr, DOFZ, -sin(phi_teilung));
      fprintf(handle, ", ,%8d,%8d,%8.5f\n", node2[node2j].nr, DOFX, -cos(phi_teilung) );
      }
    }
   if (csys=='c')
    {
    if (compare( format, "abq", 3)== 3)
      {
      /* schreibe die EQUATIOS im Abaqusformat */
      fprintf(handle, "*EQUATION\n");
        fprintf(handle, "%d\n", 2);
        fprintf(handle, "%d,%d,%8.5f, %d,%d,%8.5f \n", node1[i].nr, DOFX, 1.,
          node2[node2j].nr, DOFX, -1. );
      fprintf(handle, "*EQUATION\n");
        fprintf(handle, "%d\n", 2);
        fprintf(handle, "%d,%d,%8.5f, %d,%d,%8.5f \n", node1[i].nr, DOFY, 1.,
          node2[node2j].nr, DOFY, -1. );
      fprintf(handle, "*EQUATION\n");
        fprintf(handle, "%d\n", 2);
        fprintf(handle, "%d,%d,%8.5f, %d,%d,%8.5f \n", node1[i].nr, DOFZ, 1.,
          node2[node2j].nr, DOFZ, -1. );
      }
    else if (compare( format, "ans", 3)== 3)
      {
      /* schreibe die EQUATIOS im Ansysformat */
      neqn++;
      fprintf(handle, "CE,%d,0,%d,%s,%8.5f, %d,%s,%8.5f,  %d,%s,%8.5f\n",
        neqn, -1, "UX", 1.,
              node1[i].nr, "UX", 1., node2[node2j].nr, "UX", -1. );
      neqn++;
      fprintf(handle, "CE,%d,0,%d,%s,%8.5f, %d,%s,%8.5f,  %d,%s,%8.5f\n",
        neqn, -1, "UY", 1.,
              node1[i].nr, "UY", 1., node2[node2j].nr, "UY", -1. );
      neqn++;
      fprintf(handle, "CE,%d,0,%d,%s,%8.5f, %d,%s,%8.5f,  %d,%s,%8.5f\n",
        neqn, -1, "UZ", 1.,
              node1[i].nr, "UZ", 1., node2[node2j].nr, "UZ", -1. );
      }
    else if (compare( format, "nas", 3)== 3)
      {
      /* schreibe die EQUATIOS im Nastranformat */
      fprintf(handle, "MPC,%8d,%8d,%8d,%8.5f,%8d,%8d,%8.5f\n", neqn+1, node1[i].nr, DOFX, 1.,
          node2[node2j].nr, DOFX, -1. );
      fprintf(handle, "MPC,%8d,%8d,%8d,%8.5f,%8d,%8d,%8.5f\n", neqn+1, node1[i].nr, DOFY, 1.,
          node2[node2j].nr, DOFY, -1. );
      fprintf(handle, "MPC,%8d,%8d,%8d,%8.5f,%8d,%8d,%8.5f\n", neqn+1, node1[i].nr, DOFZ, 1.,
          node2[node2j].nr, DOFZ, -1. );
      }
    }
   sprintf( buffer, "%d", node1[i].nr); 
   pre_seta(specialset->mpc, "n", buffer);
   }
   }
  }
 }
 else if(axis=='z')
 {
  if(printFlag) printf("z-axis specified\n");
  for (i=0; i<set[set1].anz_n; i++ )
  {
    nx1[i]= node[node1[i].nr].nz;
    nr1[i]= sqrt( node[node1[i].nr].nx*node[node1[i].nr].nx + node[node1[i].nr].ny*node[node1[i].nr].ny );
    if ( nr1[i] )
    {
      nt1[i]= p_angle( node[node1[i].nr].ny, node[node1[i].nr].nx );
    }
  }
  for (i=0; i<set[set2].anz_n; i++ )
  {
    nx2[i]= node[node2[i].nr].nz;
    nr2[i]= sqrt( node[node2[i].nr].nx*node[node2[i].nr].nx + node[node2[i].nr].ny*node[node2[i].nr].ny );
    if ( nr2[i] )
    {
      nt2[i]= p_angle( node[node2[i].nr].ny, node[node2[i].nr].nx );
    }
  }



  /* suche nodepaare, berechne differenzwinkel und schreibe EQUATION's  */
  for (i=0; i<set[set1].anz_n; i++ )
  {
   if (nr1[i]>0)
   {
    /* suche gegenueber liegenden naechsten node  */
    rmin=MAXVALUE;
    for (j=0; j<set[set2].anz_n; j++ )
    {
      if ((nr2[j]>0)&&( node2[j].nr!= node1[i].nr))
      {
        dx= nx2[j]-nx1[i];
        dr= nr2[j]-nr1[i];
        R=sqrt( dx*dx + dr*dr );
        if (R<rmin)
        {
          rmin=R;
          node2j=j;
        }
      }
    }

    /* berechne den differenzwinkel  */
    phi[i]= nt2[node2j]-nt1[i];

    /* definiere den Zielwinkel, entweder vorgabe oder wie berechnet */
    if(phi_vorgabe==0.) phi_teilung=phi[i];
    else phi_teilung=phi_vorgabe;

    firstrun=1;
   nexttryz:;
    /* kontrolliere den differenzwinkel mit der teilung */
    dphi = phi_teilung - phi[i];
    if(dphi>2*pi-DPHI_TOL) while (dphi>2*pi-DPHI_TOL) dphi-=2*pi;
    if(dphi<-2*pi+DPHI_TOL) while (dphi<-2*pi+DPHI_TOL) dphi+=2*pi;
    if ((dphi*dphi > DPHI_TOL)&&(firstrun))
    {
      firstrun=0;
      phi_teilung=-phi_vorgabe;
      goto nexttryz;
    }
    else if ((dphi*dphi > DPHI_TOL)&&(!firstrun))
    {
      printf ("ERROR: korresponding node too far away:%lf grd, see set %s\n\a",dphi*180./pi, specialset->nompc);
      sprintf( buffer, "%d", node1[i].nr); 
      pre_seta(specialset->nompc, "n", buffer);
    }
    else 
    {
    if(printFlag) printf(" theta(%d):%lf theta(%d):%lf  dtheta:%lf dtheta_corr:%lf rmin:%lf\n",
      node1[i].nr, nt1[i]*180./pi, node2[node2j].nr, nt2[node2j]*180./pi,
      phi[i]*180./pi, phi_teilung*180./pi, rmin);

    if (corr[0]=='c')
    { 
      /* versetze den gefundenen Knoten auf die korrespondierende pos. */
      /* der dependent node wird auf die pos des indep gesetzt */
      node[node1[i].nr].nz = node[node2[node2j].nr].nz;
      if ( nr1[i] )
      {
        node[node1[i].nr].nx = node[node2[node2j].nr].nx*cos(phi_teilung)-node[node2[node2j].nr].ny*sin(phi_teilung);
        node[node1[i].nr].ny = node[node2[node2j].nr].nx*sin(phi_teilung)+node[node2[node2j].nr].ny*cos(phi_teilung);
      }  
    }  


   if (csys=='t')
   {
    if (compare( format, "abq", 3)== 3)
    {
      /* schreibe die EQUATIOS im Abaqusformat */
      fprintf(handle, "*EQUATION\n");
        fprintf(handle, "%d\n", 2);
        fprintf(handle, "%d,%d,%8.5f, %d,%d,%8.5f \n", node1[i].nr, DOFT, 1.,
          node2[node2j].nr, DOFT, -1. );
    }
   }
   if (csys=='r')
    {
    if (compare( format, "abq", 3)== 3)
      {
      /* schreibe die EQUATIOS im Abaqusformat */
      fprintf(handle, "*EQUATION\n");
        fprintf(handle, "%d\n", 2);
        fprintf(handle, "%d,%d,%8.5f, %d,%d,%8.5f \n", node1[i].nr, DOFZ, 1.,
          node2[node2j].nr, DOFZ, -1. );
      fprintf(handle, "*EQUATION\n");
        fprintf(handle, "%d\n", 3);
        fprintf(handle, "%d,%d,%8.5f, %d,%d,%8.5f, %d,%d,%8.5f\n", node1[i].nr, DOFX, 1.,
          node2[node2j].nr, DOFX, -cos(phi_teilung),  node2[node2j].nr, DOFY, sin(phi_teilung) );
      fprintf(handle, "*EQUATION\n");
        fprintf(handle, "%d\n", 3);
        fprintf(handle, "%d,%d,%8.5f, %d,%d,%8.5f, %d,%d,%8.5f\n", node1[i].nr, DOFY, 1.,
          node2[node2j].nr, DOFX, -sin(phi_teilung),  node2[node2j].nr, DOFY, -cos(phi_teilung) );
      }
    else if (compare( format, "ans", 3)== 3)
      {
      /* schreibe die EQUATIOS im Ansysformat */
      neqn++;
      fprintf(handle, "CE,%d,0,%d,%s,%8.5f, %d,%s,%8.5f,  %d,%s,%8.5f\n",
        neqn, -1, "UZ", 1.,
              node1[i].nr, "UZ", 1., node2[node2j].nr, "UZ", -1. );
      neqn++;
      fprintf(handle, "CE,%d,0,%d,%s,%8.5f, %d,%s,%8.5f,  %d,%s,%8.5f\n",
        neqn, node1[i].nr, "UX", 1.,
              node2[node2j].nr, "UX", -cos(phi_teilung), node2[node2j].nr, "UY", sin(phi_teilung) );
      neqn++;
      fprintf(handle, "CE,%d,0,%d,%s,%8.5f, %d,%s,%8.5f,  %d,%s,%8.5f\n",
        neqn, node1[i].nr, "UY", 1.,
              node2[node2j].nr, "UX", -sin(phi_teilung), node2[node2j].nr, "UY", -cos(phi_teilung) );
      }
    else if (compare( format, "nas", 3)== 3)
      {
      /* schreibe die EQUATIOS im Nastranformat */
      fprintf(handle, "MPC,%8d,%8d,%8d,%8.5f,%8d,%8d,%8.5f\n", neqn+1, node1[i].nr, DOFZ, 1.,
          node2[node2j].nr, DOFZ, -1. );
      fprintf(handle, "MPC,%8d,%8d,%8d,%8.5f,%8d,%8d,%8.5f\n", neqn+1, node1[i].nr, DOFX, 1.,
                                                          node2[node2j].nr, DOFX, -cos(phi_teilung));
      fprintf(handle, ", ,%8d,%8d,%8.5f\n", node2[node2j].nr, DOFY, sin(phi_teilung) );
      fprintf(handle, "MPC,%8d,%8d,%8d,%8.5f,%8d,%8d,%8.5f\n", neqn+1, node1[i].nr, DOFY, 1.,
                                                          node2[node2j].nr, DOFX, -sin(phi_teilung));
      fprintf(handle, ", ,%8d,%8d,%8.5f\n", node2[node2j].nr, DOFY, -cos(phi_teilung) );
      }
    }
   if (csys=='c')
    {
    if (compare( format, "abq", 3)== 3)
      {
      /* schreibe die EQUATIOS im Abaqusformat */
      fprintf(handle, "*EQUATION\n");
        fprintf(handle, "%d\n", 2);
        fprintf(handle, "%d,%d,%8.5f, %d,%d,%8.5f \n", node1[i].nr, DOFX, 1.,
          node2[node2j].nr, DOFX, -1. );
      fprintf(handle, "*EQUATION\n");
        fprintf(handle, "%d\n", 2);
        fprintf(handle, "%d,%d,%8.5f, %d,%d,%8.5f \n", node1[i].nr, DOFY, 1.,
          node2[node2j].nr, DOFY, -1. );
      fprintf(handle, "*EQUATION\n");
        fprintf(handle, "%d\n", 2);
        fprintf(handle, "%d,%d,%8.5f, %d,%d,%8.5f \n", node1[i].nr, DOFZ, 1.,
          node2[node2j].nr, DOFZ, -1. );
      }
    else if (compare( format, "ans", 3)== 3)
      {
      /* schreibe die EQUATIOS im Ansysformat */
      neqn++;
      fprintf(handle, "CE,%d,0,%d,%s,%8.5f, %d,%s,%8.5f,  %d,%s,%8.5f\n",
        neqn, -1, "UX", 1.,
              node1[i].nr, "UX", 1., node2[node2j].nr, "UX", -1. );
      neqn++;
      fprintf(handle, "CE,%d,0,%d,%s,%8.5f, %d,%s,%8.5f,  %d,%s,%8.5f\n",
        neqn, -1, "UY", 1.,
              node1[i].nr, "UY", 1., node2[node2j].nr, "UY", -1. );
      neqn++;
      fprintf(handle, "CE,%d,0,%d,%s,%8.5f, %d,%s,%8.5f,  %d,%s,%8.5f\n",
        neqn, -1, "UZ", 1.,
              node1[i].nr, "UZ", 1., node2[node2j].nr, "UZ", -1. );
      }
    else if (compare( format, "nas", 3)== 3)
      {
      /* schreibe die EQUATIOS im Nastranformat */
      fprintf(handle, "MPC,%8d,%8d,%8d,%8.5f,%8d,%8d,%8.5f\n", neqn+1, node1[i].nr, DOFX, 1.,
          node2[node2j].nr, DOFX, -1. );
      fprintf(handle, "MPC,%8d,%8d,%8d,%8.5f,%8d,%8d,%8.5f\n", neqn+1, node1[i].nr, DOFY, 1.,
          node2[node2j].nr, DOFY, -1. );
      fprintf(handle, "MPC,%8d,%8d,%8d,%8.5f,%8d,%8d,%8.5f\n", neqn+1, node1[i].nr, DOFZ, 1.,
          node2[node2j].nr, DOFZ, -1. );
      }
    }
   sprintf( buffer, "%d", node1[i].nr); 
   pre_seta(specialset->mpc, "n", buffer);
    }
   }
  }
 }
 else printf("ERROR: no axis of symmetry was specified:%c \n\n\a", (unsigned char)axis);

 end:;

  i=getSetNr(specialset->nompc);
  if (i>-1) if (set[i].anz_n>0) printf(" WARNING:%d dependent nodes could not be connected, check set:%s\n", set[i].anz_n, set[i].name);

  fclose(handle);

  if(nx1) free(nx1);
  if(nx2) free(nx2);
  if(nt1) free(nt1);
  if(nt2) free(nt2);
  if(nr1) free(nr1);
  if(nr2) free(nr2);
  if(phi) free(phi);
  if(node1) free(node1);
  if(node2) free(node2);
  scalNodes ( anz->n, node, scale );
}




/* die koeffizienten der MPCs ergeben sich aus den Flaechenanteilen */
int calcCoefficients(  Nodes *node, int n0, CTri3 *ctri3, int  e, double *c)
{
  int n1,n2,n3;
  double v01[3],v02[3],v03[3],v12[3],v13[3],vNorm012[3],vNorm023[3],vNorm031[3],vNorm123[3],eNorm012[3],eNorm023[3],eNorm031[3],eNorm123[3];
  double ag,a1,a2,a3, sum_c;

  n1=ctri3[e].nod[0];
  n2=ctri3[e].nod[1];
  n3=ctri3[e].nod[2];
  v_result( &node[n0].nx, &node[n1].nx, v01);
  v_result( &node[n0].nx, &node[n2].nx, v02);
  v_result( &node[n0].nx, &node[n3].nx, v03);
  v_result( &node[n1].nx, &node[n2].nx, v12);
  v_result( &node[n1].nx, &node[n3].nx, v13);

  /* flaeche des tri3 *2 */
  v_prod( v12, v13, vNorm123 );
  v_norm( vNorm123, eNorm123 );
  ag=v_betrag(vNorm123);

  /* teilflaechen *2 */
  v_prod( v02, v03, vNorm023 ); v_norm( vNorm023, eNorm023 );
  v_prod( v03, v01, vNorm031 ); v_norm( vNorm031, eNorm031 );
  v_prod( v01, v02, vNorm012 ); v_norm( vNorm012, eNorm012 );
  a1=v_betrag(vNorm023);
  if(v_sprod(eNorm023, eNorm123) <0.) a1*=-1;
  a2=v_betrag(vNorm031);
  if(v_sprod(eNorm031, eNorm123) <0.) a2*=-1;
  a3=v_betrag(vNorm012);
  if(v_sprod(eNorm012, eNorm123) <0.) a3*=-1;

  /* coefficienten */
  c[0]= -1;
  c[1]= a1/ag;
  c[2]= a2/ag;
  c[3]= a3/ag;
  sum_c= c[1]+c[2]+c[3];

  /*
  printf(" eNorm123:%lf %lf %lf \n", eNorm123[0],eNorm123[1],eNorm123[2] );
  printf(" eNorm023:%lf %lf %lf \n", eNorm023[0],eNorm023[1],eNorm023[2] );
  printf(" eNorm031:%lf %lf %lf \n", eNorm031[0],eNorm031[1],eNorm031[2] );
  printf(" eNorm012:%lf %lf %lf \n", eNorm012[0],eNorm012[1],eNorm012[2] );
  printf(" v_sprod(eNorm023, eNorm123):%lf\n",  v_sprod(eNorm023, eNorm123)); 
  printf(" v_sprod(eNorm031, eNorm123):%lf\n",  v_sprod(eNorm031, eNorm123));
  printf(" v_sprod(eNorm012, eNorm123):%lf\n", v_sprod(eNorm012, eNorm123));
  printf(" sum_c:%lf c:%lf %lf %lf\n", sum_c,c[1],c[2],c[3] );
  */

  if ((sum_c<MIN_C)||(sum_c>MAX_C)) return(-1);
  return(1);
}


/* liefert MAXVALUE wenn der node ausserhalb liegt, */
/* ansonsten den kuerzesten Abstand zur ebene.     */
double find_tri3( Nodes *node, int n, CTri3 *ctri3, int e)
{
   int i;
   int n0,n1,n2, inull, iplus, iminus;
   double  vN0N1[3], vN1N2[3], vN2N0[3], vN0N[3], vN1N[3],  vN2N[3],
          vprod0[3], vprod1[3], vprod2[3], vsprod[3], vnorm[3];
   double en[3], ev[3], eu[3], vNN0[3], g;

   /* der node liegt im Dreieck wenn: */
   /* - berechne die Vektorprodukte zwischen den Kantenvektoren und dem Vektor von den    */
   /*   Kantenpunkten zu dem node (v_prod= vP1P2 x vP1Pn)                                 */
   /* - berechne die Scalarprtodukte v_sprod zwischen den v_prod und dem Normalenvektor   */
   /*   des Dreiecks. Wenn alle v_sprod positiv sind, dann liegt der node innerhalb und   */
   /*   davor, wenn alle negativ sind dann dahinter. Wenn uneinheitlich, dann ausserhalb. */

   n0=ctri3[e].nod[0];
   n1=ctri3[e].nod[1];
   n2=ctri3[e].nod[2];
   v_result( &node[n0].nx, &node[n1].nx, vN0N1);
   v_result( &node[n1].nx, &node[n2].nx, vN1N2);
   v_result( &node[n2].nx, &node[n0].nx, vN2N0);
   v_result( &node[n0].nx, &node[n].nx, vN0N);
   v_result( &node[n1].nx, &node[n].nx, vN1N);
   v_result( &node[n2].nx, &node[n].nx, vN2N);

   /* berechne den Normalenvektor auf der flaeche */
   v_prod( vN0N1, vN1N2, vnorm );
   v_norm( vnorm, en );
   /* berechne die einheitsvektoren der ebenengleichung des tri3 */
   v_norm( vN0N1, eu );
   v_norm( vN1N2, ev );
   /* bestimme den Abstand zwischen den Aufpunkten der Normalen und in n verschobenen Ebene  */
   v_result( &node[n].nx, &node[n0].nx, vNN0 );

   /* berechne die Konstante g (Abstand)  pn_neu=pn-en*g  */
   g = AsplitL( vNN0, eu, ev, en );

   v_prod( vN0N1, vN0N, vprod0 );
   v_prod( vN1N2, vN1N, vprod1 );
   v_prod( vN2N0, vN2N, vprod2 );
   vsprod[0]= v_sprod( vnorm, vprod0);
   vsprod[1]= v_sprod( vnorm, vprod1);
   vsprod[2]= v_sprod( vnorm, vprod2);

   /*   kontrolle ob ein vsprod=0 ist. Dann liegt naemlich                */
   /*   der zu kontrollierende node genau ueber einer der umrandungen     */
   /*   der kontroll-flaeche (vprod ist dann senkrecht auf der normalen). */
   /*   Dann werden vsprod mit den gleichen vorzeichen zusammen-          */
   /*   gezaelt, dabei gelten die nuller als joker                        */

            inull=0;
            for (i=0; i<3; i++) if (vsprod[i] == 0.) inull++;

            iplus=inull;
            for (i=0; i<3; i++) if (vsprod[i] > 0.) iplus++;

            iminus=inull;
            for (i=0; i<3; i++) if (vsprod[i] < 0.) iminus++;
	    /*
            printf (" vsprod: %lf %lf %lf inull:%d iplus:%d iminus:%d\n",
                vsprod[0],vsprod[1],vsprod[2], inull, iplus, iminus );
	    */
   /*           * wenn alle vectorprodukte das gleiche vorzeichen haben    *   */
   /*           * dann ist der node innerhalb der flaeche                  *   */

           if (iplus == 3) return(g);
           else if (iminus == 3) return(g);
           else return(MAXVALUE);
}


/* verschiebe den node */
void corrNode(  Nodes *node, int n, CTri3 *ctri3, int  e, double g )
{
   int n0,n1,n2;
   double  vN0N1[3], vN1N2[3], vnorm[3];
   double en[3], vNNneu[3], vNneu[3], gneu ;

   n0=ctri3[e].nod[0];
   n1=ctri3[e].nod[1];
   n2=ctri3[e].nod[2];
   v_result( &node[n0].nx, &node[n1].nx, vN0N1);
   v_result( &node[n1].nx, &node[n2].nx, vN1N2);

   /* berechne den Normalenvektor auf der flaeche */
   v_prod( vN0N1, vN1N2, vnorm );
   v_norm( vnorm, en );
   /* scaliere den Normalenvektor mit dem offset */
   gneu=g*-1.;
   v_scal( &gneu, en, vNNneu );
   v_result( vNNneu, &node[n].nx, vNneu );
   /*
   printf ("x:%lf xneu:%lf dx:%lf\n",node[n].nx,vNneu[0],vNNneu[0]);
   printf ("y:%lf yneu:%lf dy:%lf\n",node[n].ny,vNneu[1],vNNneu[1]);
   printf ("z:%lf zneu:%lf dz:%lf\n",node[n].nz,vNneu[2],vNNneu[2]);
   */
   /* verschiebe den node */
   node[n].nx= vNneu[0];
   node[n].ny= vNneu[1];
   node[n].nz= vNneu[2];
}


void areampc(int set1, int set2, unsigned char *format, unsigned char *value, unsigned char *corr, int nodeOffset)
{
  register int  i, j, k, n, e;

  int    DOF[7]={0,1,1,1,0,0,0};
  unsigned char    ansy_dofs[6][5]={"UX","UY","UZ","ROTX","ROTY","ROTZ"}; /* SHORT-CUTS FOR ANSYS DOFS */

  int     sflag={0}, n_closest_nodes;      /* 0:abq, 1:ans, 2:nas equations */

  unsigned char   datout[MAX_LINE_LENGTH];
  unsigned char   buffer[MAX_LINE_LENGTH];

  Nodes     *node1=NULL;
  Nodes     *node2=NULL;
  Elements  *elem=NULL;
  CTri3     *ctri3=NULL;                   /* triangulierte indep-nodes flaeche */

  static int **tri3_index;           /* am jeweiligen node haengenden dreiecke */
  int       *ntri_nodes=NULL;        /* anzahl der anhaengenden dreiecke       */
  int       ec[21];                  /* */
  int       sum_tri3;                /* anzahl der ctri3 */
  int       puf, corrFlag, ini_corrFlag;

  FILE  *handle;

  int   ind1, ind2, ind3, elbuf=0;
  double dx,dy,dz,*dr=NULL;
  double  offset=0., min_offset,offsetbuf=0., tol;

  int   nface[8];
  double c[9],  *coords=NULL, xi_loc, et_loc;
  double dist, co_new[3], conode[3], coface[24];

  Rsort *rsort=NULL;
  double *indnodes=NULL;
  int nearNodesCallFlag, nearnodes[N_CLOSEST_NODES];



  /* ------ check and set the format ---- */
  if (compare(format,"abq", 3) == 3)  sflag=0; 
  else if (compare(format,"ans", 3) == 3)  sflag=1;
  else if (compare(format,"nas", 3) == 3)  sflag=2;
  else 
  {
    printf("ERROR, format:%s not known \n\n\a", format);
    return;
  }

  /* ---- clear special sets ----- */
  delSet(specialset->mpc );
  delSet(specialset->nompc );
  delSet(specialset->noel );

  /* Open the files and check to see that it was opened correctly */
  sprintf(datout, "%s.equ", set[set1].name);
  handle = fopen (datout, "w");
  if (handle==NULL) { printf ("\nThe output file \"%s\" could not be opened.\n\n", datout); return; }
  else  printf (" %s opened\n", datout);
  if (compare( format, "abq", 3)== 3)      fprintf(handle, "** areampc based on set %s %s\n",set[set1].name, set[set2].name );
  else if (compare( format, "ans", 3)== 3) fprintf(handle, "! areampc based on set %s %s\n",set[set1].name, set[set2].name );
  else if (compare( format, "nas", 3)== 3) fprintf(handle, "$ areampc based on set %s %s\n",set[set1].name, set[set2].name );

  /* determine the degrees of freedom */
  buffer[1]=0;
  if (atoi(value)>0)
  { 
    for (i=0;i<6;i++)  DOF[i]=0;
    for (i=0;i<6;i++)
    {
      buffer[0]=value[i];
      if (atoi(buffer)-1 >= 0) DOF[atoi(buffer)]=1;
      else if (buffer[0] == 't') DOF[0]=1;
    }  
  }
  else
  {
    /* entity is given */
    if(value[0]=='e')
    {
      if(corr[0]=='l')  DOF[0]=atoi(&value[1]); 
      else { printf(" ERROR in sequence for interpolation\n"); return; }
    }
  }

  /* set the correction flag to correct the node position */
  if (corr[0]=='c') ini_corrFlag=1;
  else ini_corrFlag=0;

  /* determine the starting nr of the equations for ansys */
  if ((corr[0]=='c')||(corr[0]=='u'))
  { if (atoi(&corr[1])>0) neqn=atoi(&corr[1])-1; }

  /* a loadcase is specified */
  if (corr[0]=='l')
  {
    DOF[1]=atoi(&corr[1]);
    if (compare(format,"abq", 3) == 3)  sflag=3;
    else 
    {
      printf("ERROR, format:%s not known \n\n\a", format);
      return;
    }
  } 


  if(printFlag) printf ("datout:%s set1:%s nodes:%d set2:%s nodes:%d\n",datout, set[set1].name, set[set1].anz_n, set[set2].name, set[set2].anz_n);

  /* ------- node-koordinaten berechnen und am ende wieder scalieren ------ */
  descalNodes ( anz->n, node, scale );

  /* ------- elem definieren ----------------------------------------------- */
  if ( (elem = (Elements *)malloc((anz->e+1) * sizeof(Elements))) == NULL )
    { printf(" ERROR: realloc ERROR in areampc, elem\n\n") ; goto end; }

  for (i=0; i<anz->e; i++)
  {
    elem[i].nr      =       set[0].elem[i];
    elem[i].type    = e_enqire[set[0].elem[i]].type;
    elem[i].group   = e_enqire[set[0].elem[i]].group;
    elem[i].mat     = e_enqire[set[0].elem[i]].mat;
    puf=0;
    if (elem[i].type == 1) puf = 8;  
    if (elem[i].type == 2) puf = 6;  
    if (elem[i].type == 3) puf = 4;  
    if (elem[i].type == 4) puf = 20; 
    if (elem[i].type == 5) puf = 15; 
    if (elem[i].type == 6) puf = 10; 
    if (elem[i].type == 7) puf = 3;  
    if (elem[i].type == 8) puf = 6;  
    if (elem[i].type == 9) puf = 4;  
    if (elem[i].type == 10) puf = 8; 
    if (elem[i].type == 11) puf = 2; 
    if (elem[i].type == 12) puf = 3; 
    if (puf==0)
    {
      if(printFlag) printf (" elem(%d) not a known type (%d)\n", elem[i].nr, elem[i].type);
    }
    else
    {
      for (j=0; j<puf; j++)
      {
        elem[i].nod[j]=e_enqire[set[0].elem[i]].nod[j];
      }
    }
  }


  if(printFlag) printf ("DOFs:"); for(i=0;i<7;i++) if(printFlag) printf("%d", DOF[i]);
  if(printFlag) printf ("\n1st Equ.Nr| ID   -e:%d\n", neqn);
  if(printFlag) printf ("Tolerance for equal node -dr:%lf\n", gtol);
  if(printFlag) printf ("Tolerance for gap        -dA:%lf\n", 1.-MIN_C);
  /* if(printFlag) printf ("Tol for mismatch   -bail:%lf\n", BAILOUT); */


  /* --------- dependent nodes --------------- */
  if ( (node1 = (Nodes *)malloc( set[set1].anz_n * sizeof(Nodes))) == NULL )
  {
    printf("\nERROR: malloc failed in areampc() \a\n\n");
    goto end;
  }

  /* --------- independent nodes  --------------- */
  if ( (node2 = (Nodes *)malloc( set[set2].anz_n * sizeof(Nodes))) == NULL )
  {
    printf("\nERROR: malloc failed in areampc() \a\n\n");
    goto end;
  }

  /* nodes zuweisen */
  for (i=0; i<set[set1].anz_n; i++ ) node1[i].nr=set[set1].node[i];  
  for (i=0; i<set[set2].anz_n; i++ ) node2[i].nr=set[set2].node[i];  


  /* hilfsdatenfeld fuer die shapefunctions anlegen */
  if((coords =(double *)malloc((anz->nmax*3+3) *sizeof(double)))==NULL)
  {
    printf("\n\n ERROR: malloc failed for coords\a\n" );
    goto end;
  }
  for (n=0;n<anz->n;n++)
  {
    coords[(node[n].nr-1)*3]=node[node[n].nr].nx; 
    coords[((node[n].nr-1)*3)+1]=node[node[n].nr].ny; 
    coords[((node[n].nr-1)*3)+2]=node[node[n].nr].nz;
    /*
    printf (" nface[%d]:%d x:%lf y:%lf z:%lf\n", n, nface[n],
      coords[node[n].nr*3], coords[node[n].nr*3+1], coords[node[n].nr*3+2] );
    */
  }


  /* hilfsfelder anlegen */
  if((tri3_index =(int **)realloc((int **)tri3_index, (anz->nmax+1) *sizeof(int *)))==NULL)
  {
    printf("\n\n ERROR: realloc failed for tri3_index\a\n" );
    goto end;
  }
  if((ntri_nodes =(int *)malloc((anz->nmax+2) *sizeof(int)))==NULL)
  {
    printf("\n\n ERROR: malloc failed for ntri_nodes\a\n" );
    goto end;
  }
  if((dr =(double *)malloc((anz->nmax+1) *sizeof(double)))==NULL)
  {
    printf("\n\n ERROR: malloc failed for dr\a\n" );
    goto end;
  }

  if ( (ctri3 = (CTri3 *)malloc( 1 * sizeof(CTri3))) == NULL )
  {
    printf("\nERROR: realloc failed in areampc() \a\n\n");
    goto end;
  }
  /* Suche die elementflaechen, die durch die independent nodes beschrieben werden,       */
  /* und zerlege diese in dreiecke. Und speichere die zu jedem node gehoerenden dreiecke. */
  /* in tri3.group wird die elementseite gespeichert (damit die randknoten bekannt sind)  */

  for (i=0; i<=anz->nmax; i++)
  {
    tri3_index[i]=NULL;
    ntri_nodes[i]=0;
  }
  sum_tri3=0;

  for (e=0; e<anz->e; e++)
  {
    j=0;

    /* ----- Tri3 --------------- */
    if (elem[e].type==7)
    {
      for (n=0; n<3; n++)
      {
        for (i=0; i<set[set2].anz_n; i++)
        {
          if (elem[e].nod[n]==node2[i].nr)
          {
            ec[j]=n;
            j++;
          }
        }
      }
      if(j==3)
      {
        /* merke dir alle am node haengenden flaechen (flaeche: sum_tri3)*/
        for (i=0; i<3; i++)
        {
         if((tri3_index[ elem[e].nod[ec[i]] ] 
          = (int *)realloc((int *)tri3_index[ elem[e].nod[ec[i]] ]
          , (ntri_nodes[elem[e].nod[ec[i]]]+1) *sizeof(int)))==NULL)
	  {
            printf("\n\n ERROR: realloc failed for tri3_index\a\n" );
            goto end;
          }

          tri3_index[ elem[e].nod[ec[i]] ][ ntri_nodes[elem[e].nod[ec[i]]] ]=sum_tri3;
          ntri_nodes[ elem[e].nod[ec[i]] ]++;
        }
        /* BUG: sum_tri3+256 chosen, because with +2 an bus error occured */
        /* its caused in relation with the last loading of ctri3[sum_tri3] */
        if ( (ctri3 = (CTri3 *)realloc( (CTri3 *)ctri3, sum_tri3+256 * sizeof(CTri3))) == NULL )
        {
          printf("\nERROR: realloc failed in areampc() \a\n\n");
          goto end;
        }
        ctri3[sum_tri3].elem_nr= e;
        ctri3[sum_tri3].group  = 1;
        ctri3[sum_tri3].mat    = elem[e].mat;
        ctri3[sum_tri3].nod[0]=elem[e].nod[0];
        ctri3[sum_tri3].nod[1]=elem[e].nod[1];
        ctri3[sum_tri3].nod[2]=elem[e].nod[2];
        sum_tri3++;
      }
    }

    /* ----- Tri6 --------------- */
    else if (elem[e].type==8)
    {
      for (n=0; n<6; n++)
      {
        for (i=0; i<set[set2].anz_n; i++)
        {
          if (elem[e].nod[n]==node2[i].nr)
          {
            ec[j]=n;
            j++;
          }
        }
      }
      if(j==6)
      {
        elem[e].group=2;

        /* merke dir alle am node haengenden flaechen (flaeche: sum_tri3, sum_tri3+1)*/
        for (n=0; n<4; n++)
        {
          for (i=0; i<6; i++)
          {
            if((tri3_index[ elem[e].nod[ec[i]] ] 
            = (int *)realloc((int *)tri3_index[ elem[e].nod[ec[i]] ]
            , (ntri_nodes[elem[e].nod[ec[i]]]+1) *sizeof(int)))==NULL)
	    {
              printf("\n\n ERROR: realloc failed for tri3_index\a\n" );
              goto end;
            }

            tri3_index[ elem[e].nod[ec[i]] ][ ntri_nodes[elem[e].nod[ec[i]]] ]=sum_tri3+n;
            ntri_nodes[ elem[e].nod[ec[i]] ]++;
          }
        }
        sum_tri3+=4;
        if ( (ctri3 = (CTri3 *)realloc( (CTri3 *)ctri3, sum_tri3 * sizeof(CTri3))) == NULL )
        {
          printf("\nERROR: realloc failed in areampc() \a\n\n");
          goto end;
        }

        ctri3[sum_tri3-4].elem_nr= e;
        ctri3[sum_tri3-4].group  = 1;
        ctri3[sum_tri3-4].mat    = elem[e].mat;
        ctri3[sum_tri3-4].nod[0]=elem[e].nod[0];
        ctri3[sum_tri3-4].nod[1]=elem[e].nod[5];
        ctri3[sum_tri3-4].nod[2]=elem[e].nod[3];

        ctri3[sum_tri3-3].elem_nr= e;
        ctri3[sum_tri3-3].group  = 1;
        ctri3[sum_tri3-3].mat    = elem[e].mat;
        ctri3[sum_tri3-3].nod[0]=elem[e].nod[3];
        ctri3[sum_tri3-3].nod[1]=elem[e].nod[5];
        ctri3[sum_tri3-3].nod[2]=elem[e].nod[4];

        ctri3[sum_tri3-2].elem_nr= e;
        ctri3[sum_tri3-2].group  = 1;
        ctri3[sum_tri3-2].mat    = elem[e].mat;
        ctri3[sum_tri3-2].nod[0]=elem[e].nod[5];
        ctri3[sum_tri3-2].nod[1]=elem[e].nod[2];
        ctri3[sum_tri3-2].nod[2]=elem[e].nod[4];

        ctri3[sum_tri3-1].elem_nr= e;
        ctri3[sum_tri3-1].group  = 1;
        ctri3[sum_tri3-1].mat    = elem[e].mat;
        ctri3[sum_tri3-1].nod[0]=elem[e].nod[3];
        ctri3[sum_tri3-1].nod[1]=elem[e].nod[4];
        ctri3[sum_tri3-1].nod[2]=elem[e].nod[1];
      }
    }

    /* ----- Qu4 --------------- */
    else if (elem[e].type==9)
    {
     for (n=0; n<4; n++)
      {
        for (i=0; i<set[set2].anz_n; i++)
        {
          if (elem[e].nod[n]==node2[i].nr)
          {
            ec[j]=n;
            j++;
          }
        }
      }
     if(j==4)
      {
       elem[e].group=2;

        /* merke dir alle am node haengenden flaechen (flaeche: sum_tri3, sum_tri3+1)*/
        for (n=0; n<2; n++)
        {
          for (i=0; i<4; i++)
          {
            if((tri3_index[ elem[e].nod[ec[i]] ] 
            = (int *)realloc((int *)tri3_index[ elem[e].nod[ec[i]] ]
            , (ntri_nodes[elem[e].nod[ec[i]]]+1) *sizeof(int)))==NULL)
	    {
              printf("\n\n ERROR: realloc failed for tri3_index\a\n" );
              goto end;
            }

            tri3_index[ elem[e].nod[ec[i]] ][ ntri_nodes[elem[e].nod[ec[i]]] ]=sum_tri3+n;
            ntri_nodes[ elem[e].nod[ec[i]] ]++;
          }
        }
        sum_tri3+=2;
        if ( (ctri3 = (CTri3 *)realloc( (CTri3 *)ctri3, sum_tri3 * sizeof(CTri3))) == NULL )
        {
          printf("\nERROR: realloc failed in areampc() \a\n\n");
          goto end;
        }

        ctri3[sum_tri3-2].elem_nr= e;
        ctri3[sum_tri3-2].group  = 1;
        ctri3[sum_tri3-2].mat    = elem[e].mat;
        ctri3[sum_tri3-2].nod[0]=elem[e].nod[0];
        ctri3[sum_tri3-2].nod[1]=elem[e].nod[1];
        ctri3[sum_tri3-2].nod[2]=elem[e].nod[2];

        ctri3[sum_tri3-1].elem_nr= e;
        ctri3[sum_tri3-1].group  = 1;
        ctri3[sum_tri3-1].mat    = elem[e].mat;
        ctri3[sum_tri3-1].nod[0]=elem[e].nod[0];
        ctri3[sum_tri3-1].nod[1]=elem[e].nod[2];
        ctri3[sum_tri3-1].nod[2]=elem[e].nod[3];
      }
    }


    /* ----- Qu8 --------------- */
    else if (elem[e].type==10)
    {
      for (n=0; n<8; n++)
      {
        for (i=0; i<set[set2].anz_n; i++)
        {
          if (elem[e].nod[n]==node2[i].nr)
          {
            ec[j]=n;
            j++;
          }
        }
      }
      if(j==8)
      {
        elem[e].group=2;

        /* merke dir alle am node haengenden flaechen (flaeche: sum_tri3, sum_tri3+1)*/
        for (n=0; n<6; n++)
        {
          for (i=0; i<8; i++)
          {
            if((tri3_index[ elem[e].nod[ec[i]] ] 
            = (int *)realloc((int *)tri3_index[ elem[e].nod[ec[i]] ]
            , (ntri_nodes[elem[e].nod[ec[i]]]+1) *sizeof(int)))==NULL)
	    {
              printf("\n\n ERROR: realloc failed for tri3_index\a\n" );
              goto end;
            }

            tri3_index[ elem[e].nod[ec[i]] ][ ntri_nodes[elem[e].nod[ec[i]]] ]=sum_tri3+n;
            ntri_nodes[ elem[e].nod[ec[i]] ]++;
          }
        }
        sum_tri3+=6;
        if ( (ctri3 = (CTri3 *)realloc( (CTri3 *)ctri3, sum_tri3 * sizeof(CTri3))) == NULL )
        {
          printf("\nERROR: realloc failed in areampc() \a\n\n");
          goto end;
        }

        ctri3[sum_tri3-6].elem_nr= e;
        ctri3[sum_tri3-6].group  = 1;
        ctri3[sum_tri3-6].mat    = elem[e].mat;
        ctri3[sum_tri3-6].nod[0]=elem[e].nod[4];
        ctri3[sum_tri3-6].nod[1]=elem[e].nod[0];
        ctri3[sum_tri3-6].nod[2]=elem[e].nod[7];

        ctri3[sum_tri3-5].elem_nr= e;
        ctri3[sum_tri3-5].group  = 1;
        ctri3[sum_tri3-5].mat    = elem[e].mat;
        ctri3[sum_tri3-5].nod[0]=elem[e].nod[7];
        ctri3[sum_tri3-5].nod[1]=elem[e].nod[3];
        ctri3[sum_tri3-5].nod[2]=elem[e].nod[6];

        ctri3[sum_tri3-4].elem_nr= e;
        ctri3[sum_tri3-4].group  = 1;
        ctri3[sum_tri3-4].mat    = elem[e].mat;
        ctri3[sum_tri3-4].nod[0]=elem[e].nod[6];
        ctri3[sum_tri3-4].nod[1]=elem[e].nod[2];
        ctri3[sum_tri3-4].nod[2]=elem[e].nod[5];

        ctri3[sum_tri3-3].elem_nr= e;
        ctri3[sum_tri3-3].group  = 1;
        ctri3[sum_tri3-3].mat    = elem[e].mat;
        ctri3[sum_tri3-3].nod[0]=elem[e].nod[5];
        ctri3[sum_tri3-3].nod[1]=elem[e].nod[1];
        ctri3[sum_tri3-3].nod[2]=elem[e].nod[4];

        ctri3[sum_tri3-2].elem_nr= e;
        ctri3[sum_tri3-2].group  = 1;
        ctri3[sum_tri3-2].mat    = elem[e].mat;
        ctri3[sum_tri3-2].nod[0]=elem[e].nod[4];
        ctri3[sum_tri3-2].nod[1]=elem[e].nod[7];
        ctri3[sum_tri3-2].nod[2]=elem[e].nod[6];

        ctri3[sum_tri3-1].elem_nr= e;
        ctri3[sum_tri3-1].group  = 1;
        ctri3[sum_tri3-1].mat    = elem[e].mat;
        ctri3[sum_tri3-1].nod[0]=elem[e].nod[6];
        ctri3[sum_tri3-1].nod[1]=elem[e].nod[5];
        ctri3[sum_tri3-1].nod[2]=elem[e].nod[4];
      }
    }

    /* ----- Te4 --------------- */
    else if (elem[e].type==3)
    {
      for (n=0; n<4; n++)
      {
        for (i=0; i<set[set2].anz_n; i++)
        {
          if (elem[e].nod[n]==node2[i].nr)
          {
            ec[j]=n;
            j++;
          }
        }
      }
      if(j==3)
      {
        /* merke dir alle am node haengenden flaechen (flaeche: sum_tri3)*/
        for (i=0; i<3; i++)
        {
          if((tri3_index[ elem[e].nod[ec[i]] ] 
          = (int *)realloc((int *)tri3_index[ elem[e].nod[ec[i]] ]
          , (ntri_nodes[elem[e].nod[ec[i]]]+1) *sizeof(int)))==NULL)
	  {
            printf("\n\n ERROR: realloc failed for tri3_index\a\n" );
            goto end;
          }

          tri3_index[ elem[e].nod[ec[i]] ][ ntri_nodes[elem[e].nod[ec[i]]] ]=sum_tri3;
          ntri_nodes[ elem[e].nod[ec[i]] ]++;
        }
        if ( (ctri3 = (CTri3 *)realloc( (CTri3 *)ctri3, (sum_tri3+2) * sizeof(CTri3))) == NULL )
        {
          printf("\nERROR: realloc failed in areampc() \a\n\n");
          goto end;
        }

        if((ec[0]==0)&&(ec[1]==1)&&(ec[2]==2))
        {
          ctri3[sum_tri3].elem_nr= e;
          ctri3[sum_tri3].group  = 1;
          ctri3[sum_tri3].mat    = elem[e].mat;
          ctri3[sum_tri3].nod[0]=elem[e].nod[0];
          ctri3[sum_tri3].nod[1]=elem[e].nod[2];
          ctri3[sum_tri3].nod[2]=elem[e].nod[1];
        }
        else if((ec[0]==0)&&(ec[1]==1)&&(ec[2]==3))
        {
          ctri3[sum_tri3].elem_nr= e;
          ctri3[sum_tri3].group  = 2;
          ctri3[sum_tri3].mat    = elem[e].mat;
          ctri3[sum_tri3].nod[0]=elem[e].nod[0];
          ctri3[sum_tri3].nod[1]=elem[e].nod[1];
          ctri3[sum_tri3].nod[2]=elem[e].nod[3];
        }
        else if((ec[0]==1)&&(ec[1]==2)&&(ec[2]==3))
        {
          ctri3[sum_tri3].elem_nr= e;
          ctri3[sum_tri3].group  = 3;
          ctri3[sum_tri3].mat    = elem[e].mat;
          ctri3[sum_tri3].nod[0]=elem[e].nod[1];
          ctri3[sum_tri3].nod[1]=elem[e].nod[2];
          ctri3[sum_tri3].nod[2]=elem[e].nod[3];
        }
        else if((ec[0]==0)&&(ec[1]==2)&&(ec[2]==3))
        {
          ctri3[sum_tri3].elem_nr= e;
          ctri3[sum_tri3].group  = 4;
          ctri3[sum_tri3].mat    = elem[e].mat;
          ctri3[sum_tri3].nod[0]=elem[e].nod[2];
          ctri3[sum_tri3].nod[1]=elem[e].nod[0];
          ctri3[sum_tri3].nod[2]=elem[e].nod[3];
        }
        else { printf(" no element side found from el:%d,  %d %d %d\n", elem[e].nr,ec[0],
		      ec[1], ec[2]); sum_tri3--; }
        sum_tri3++;
      }
    }

    /* ----- Te10 --------------- */
    else if (elem[e].type==6)
    {
      for (n=0; n<10; n++)
      {
        for (i=0; i<set[set2].anz_n; i++)
        {
          if (elem[e].nod[n]==node2[i].nr)
          {
            ec[j]=n;
            j++;
          }
        }
      }
      if(j==6)
      {
        elem[e].group=2;

        /* merke dir alle am node haengenden flaechen (flaeche: sum_tri3, sum_tri3+1)*/
        for (n=0; n<4; n++)
        {
          for (i=0; i<6; i++)
          {
            if((tri3_index[ elem[e].nod[ec[i]] ] 
            = (int *)realloc((int *)tri3_index[ elem[e].nod[ec[i]] ]
            , (ntri_nodes[elem[e].nod[ec[i]]]+1) *sizeof(int)))==NULL)
	    {
              printf("\n\n ERROR: realloc failed for tri3_index\a\n" );
              goto end;
            }

            tri3_index[ elem[e].nod[ec[i]] ][ ntri_nodes[elem[e].nod[ec[i]]] ]=sum_tri3+n;
            ntri_nodes[ elem[e].nod[ec[i]] ]++;
          }
        }
        sum_tri3+=4;
        if ( (ctri3 = (CTri3 *)realloc( (CTri3 *)ctri3, sum_tri3 * sizeof(CTri3))) == NULL )
        {
          printf("\nERROR: realloc failed in areampc() \a\n\n");
          goto end;
        }

        if((ec[0]==0)&&(ec[1]==1)&&(ec[2]==3))
        {
          ctri3[sum_tri3-4].elem_nr= e;
          ctri3[sum_tri3-4].group  = 1;
          ctri3[sum_tri3-4].mat    = elem[e].mat;
          ctri3[sum_tri3-4].nod[0]=elem[e].nod[0];
          ctri3[sum_tri3-4].nod[1]=elem[e].nod[4];
          ctri3[sum_tri3-4].nod[2]=elem[e].nod[7];

          ctri3[sum_tri3-3].elem_nr= e;
          ctri3[sum_tri3-3].group  = 1;
          ctri3[sum_tri3-3].mat    = elem[e].mat;
          ctri3[sum_tri3-3].nod[0]=elem[e].nod[7];
          ctri3[sum_tri3-3].nod[1]=elem[e].nod[4];
          ctri3[sum_tri3-3].nod[2]=elem[e].nod[8];

          ctri3[sum_tri3-2].elem_nr= e;
          ctri3[sum_tri3-2].group  = 1;
          ctri3[sum_tri3-2].mat    = elem[e].mat;
          ctri3[sum_tri3-2].nod[0]=elem[e].nod[4];
          ctri3[sum_tri3-2].nod[1]=elem[e].nod[1];
          ctri3[sum_tri3-2].nod[2]=elem[e].nod[8];

          ctri3[sum_tri3-1].elem_nr= e;
          ctri3[sum_tri3-1].group  = 1;
          ctri3[sum_tri3-1].mat    = elem[e].mat;
          ctri3[sum_tri3-1].nod[0]=elem[e].nod[7];
          ctri3[sum_tri3-1].nod[1]=elem[e].nod[8];
          ctri3[sum_tri3-1].nod[2]=elem[e].nod[3];
        }
        else if((ec[0]==1)&&(ec[1]==2)&&(ec[2]==3))
        {
          ctri3[sum_tri3-4].elem_nr= e;
          ctri3[sum_tri3-4].group  = 2;
          ctri3[sum_tri3-4].mat    = elem[e].mat;
          ctri3[sum_tri3-4].nod[0]=elem[e].nod[1];
          ctri3[sum_tri3-4].nod[1]=elem[e].nod[5];
          ctri3[sum_tri3-4].nod[2]=elem[e].nod[8];

          ctri3[sum_tri3-3].elem_nr= e;
          ctri3[sum_tri3-3].group  = 2;
          ctri3[sum_tri3-3].mat    = elem[e].mat;
          ctri3[sum_tri3-3].nod[0]=elem[e].nod[8];
          ctri3[sum_tri3-3].nod[1]=elem[e].nod[5];
          ctri3[sum_tri3-3].nod[2]=elem[e].nod[9];

          ctri3[sum_tri3-2].elem_nr= e;
          ctri3[sum_tri3-2].group  = 2;
          ctri3[sum_tri3-2].mat    = elem[e].mat;
          ctri3[sum_tri3-2].nod[0]=elem[e].nod[5];
          ctri3[sum_tri3-2].nod[1]=elem[e].nod[2];
          ctri3[sum_tri3-2].nod[2]=elem[e].nod[9];

          ctri3[sum_tri3-1].elem_nr= e;
          ctri3[sum_tri3-1].group  = 2;
          ctri3[sum_tri3-1].mat    = elem[e].mat;
          ctri3[sum_tri3-1].nod[0]=elem[e].nod[8];
          ctri3[sum_tri3-1].nod[1]=elem[e].nod[9];
          ctri3[sum_tri3-1].nod[2]=elem[e].nod[3];
        }
        else if((ec[0]==0)&&(ec[1]==2)&&(ec[2]==3))
        {
          ctri3[sum_tri3-4].elem_nr= e;
          ctri3[sum_tri3-4].group  = 3;
          ctri3[sum_tri3-4].mat    = elem[e].mat;
          ctri3[sum_tri3-4].nod[0]=elem[e].nod[2];
          ctri3[sum_tri3-4].nod[1]=elem[e].nod[6];
          ctri3[sum_tri3-4].nod[2]=elem[e].nod[9];

          ctri3[sum_tri3-3].elem_nr= e;
          ctri3[sum_tri3-3].group  = 3;
          ctri3[sum_tri3-3].mat    = elem[e].mat;
          ctri3[sum_tri3-3].nod[0]=elem[e].nod[9];
          ctri3[sum_tri3-3].nod[1]=elem[e].nod[6];
          ctri3[sum_tri3-3].nod[2]=elem[e].nod[7];

          ctri3[sum_tri3-2].elem_nr= e;
          ctri3[sum_tri3-2].group  = 3;
          ctri3[sum_tri3-2].mat    = elem[e].mat;
          ctri3[sum_tri3-2].nod[0]=elem[e].nod[6];
          ctri3[sum_tri3-2].nod[1]=elem[e].nod[0];
          ctri3[sum_tri3-2].nod[2]=elem[e].nod[7];

          ctri3[sum_tri3-1].elem_nr= e;
          ctri3[sum_tri3-1].group  = 3;
          ctri3[sum_tri3-1].mat    = elem[e].mat;
          ctri3[sum_tri3-1].nod[0]=elem[e].nod[9];
          ctri3[sum_tri3-1].nod[1]=elem[e].nod[7];
          ctri3[sum_tri3-1].nod[2]=elem[e].nod[3];
        }
        else if((ec[0]==0)&&(ec[1]==1)&&(ec[2]==2))
        {
          ctri3[sum_tri3-4].elem_nr= e;
          ctri3[sum_tri3-4].group  = 4;
          ctri3[sum_tri3-4].mat    = elem[e].mat;
          ctri3[sum_tri3-4].nod[0]=elem[e].nod[0];
          ctri3[sum_tri3-4].nod[1]=elem[e].nod[6];
          ctri3[sum_tri3-4].nod[2]=elem[e].nod[4];

          ctri3[sum_tri3-3].elem_nr= e;
          ctri3[sum_tri3-3].group  = 4;
          ctri3[sum_tri3-3].mat    = elem[e].mat;
          ctri3[sum_tri3-3].nod[0]=elem[e].nod[4];
          ctri3[sum_tri3-3].nod[1]=elem[e].nod[6];
          ctri3[sum_tri3-3].nod[2]=elem[e].nod[5];

          ctri3[sum_tri3-2].elem_nr= e;
          ctri3[sum_tri3-2].group  = 4;
          ctri3[sum_tri3-2].mat    = elem[e].mat;
          ctri3[sum_tri3-2].nod[0]=elem[e].nod[6];
          ctri3[sum_tri3-2].nod[1]=elem[e].nod[2];
          ctri3[sum_tri3-2].nod[2]=elem[e].nod[5];

          ctri3[sum_tri3-1].elem_nr= e;
          ctri3[sum_tri3-1].group  = 4;
          ctri3[sum_tri3-1].mat    = elem[e].mat;
          ctri3[sum_tri3-1].nod[0]=elem[e].nod[4];
          ctri3[sum_tri3-1].nod[1]=elem[e].nod[5];
          ctri3[sum_tri3-1].nod[2]=elem[e].nod[1];
        }
        else { printf(" no element side found from el:%d,  %d %d %d\n", elem[e].nr,ec[0],
		      ec[1], ec[2]); sum_tri3-=4; }
      }
    }

    /* ----- HE8 --------------- */
    else if (elem[e].type==1)
    {
      for (n=0; n<8; n++)
      {
        for (i=0; i<set[set2].anz_n; i++)
        {
          if (elem[e].nod[n]==node2[i].nr)
          {
            ec[j]=n;
            j++;
          }
        }
      }
      if(j==4)
      {
        elem[e].group=2;

        /* merke dir alle am node haengenden flaechen (flaeche: sum_tri3, sum_tri3+1)*/
        for (n=0; n<2; n++)
        {
          for (i=0; i<4; i++)
          {
            if((tri3_index[ elem[e].nod[ec[i]] ] 
            = (int *)realloc((int *)tri3_index[ elem[e].nod[ec[i]] ]
            , (ntri_nodes[elem[e].nod[ec[i]]]+1) *sizeof(int)))==NULL)
	    {
              printf("\n\n ERROR: realloc failed for tri3_index\a\n" );
              goto end;
            }

            tri3_index[ elem[e].nod[ec[i]] ][ ntri_nodes[elem[e].nod[ec[i]]] ]=sum_tri3+n;
            ntri_nodes[ elem[e].nod[ec[i]] ]++;
          }
        }
        sum_tri3+=2;
        if ( (ctri3 = (CTri3 *)realloc( (CTri3 *)ctri3, sum_tri3 * sizeof(CTri3))) == NULL )
        {
          printf("\nERROR: realloc failed in areampc() \a\n\n");
          goto end;
        }

        if((ec[0]==0)&&(ec[1]==1)&&(ec[2]==2)&&(ec[3]==3))
        {
          ctri3[sum_tri3-2].elem_nr= e;
          ctri3[sum_tri3-2].group  = 1;
          ctri3[sum_tri3-2].mat    = elem[e].mat;
          ctri3[sum_tri3-2].nod[0]=elem[e].nod[0];
          ctri3[sum_tri3-2].nod[1]=elem[e].nod[1];
          ctri3[sum_tri3-2].nod[2]=elem[e].nod[2];

          ctri3[sum_tri3-1].elem_nr= e;
          ctri3[sum_tri3-1].group  = 1;
          ctri3[sum_tri3-1].mat    = elem[e].mat;
          ctri3[sum_tri3-1].nod[0]=elem[e].nod[0];
          ctri3[sum_tri3-1].nod[1]=elem[e].nod[2];
          ctri3[sum_tri3-1].nod[2]=elem[e].nod[3];
        }
        else if((ec[0]==0)&&(ec[1]==1)&&(ec[2]==4)&&(ec[3]==5))
        {
          ctri3[sum_tri3-2].elem_nr= e;
          ctri3[sum_tri3-2].group  = 2;
          ctri3[sum_tri3-2].mat    = elem[e].mat;
          ctri3[sum_tri3-2].nod[0]=elem[e].nod[0];
          ctri3[sum_tri3-2].nod[1]=elem[e].nod[1];
          ctri3[sum_tri3-2].nod[2]=elem[e].nod[5];

          ctri3[sum_tri3-1].elem_nr= e;
          ctri3[sum_tri3-1].group  = 2;
          ctri3[sum_tri3-1].mat    = elem[e].mat;
          ctri3[sum_tri3-1].nod[0]=elem[e].nod[0];
          ctri3[sum_tri3-1].nod[1]=elem[e].nod[5];
          ctri3[sum_tri3-1].nod[2]=elem[e].nod[4];
        }
        else if((ec[0]==1)&&(ec[1]==2)&&(ec[2]==5)&&(ec[3]==6))
        {
          ctri3[sum_tri3-2].elem_nr= e;
          ctri3[sum_tri3-2].group  = 3;
          ctri3[sum_tri3-2].mat    = elem[e].mat;
          ctri3[sum_tri3-2].nod[0]=elem[e].nod[1];
          ctri3[sum_tri3-2].nod[1]=elem[e].nod[2];
          ctri3[sum_tri3-2].nod[2]=elem[e].nod[6];

          ctri3[sum_tri3-1].elem_nr= e;
          ctri3[sum_tri3-1].group  = 3;
          ctri3[sum_tri3-1].mat    = elem[e].mat;
          ctri3[sum_tri3-1].nod[0]=elem[e].nod[1];
          ctri3[sum_tri3-1].nod[1]=elem[e].nod[6];
          ctri3[sum_tri3-1].nod[2]=elem[e].nod[5];
        }
        else if((ec[0]==2)&&(ec[1]==3)&&(ec[2]==6)&&(ec[3]==7))
        {
          ctri3[sum_tri3-2].elem_nr= e;
          ctri3[sum_tri3-2].group  = 4;
          ctri3[sum_tri3-2].mat    = elem[e].mat;
          ctri3[sum_tri3-2].nod[0]=elem[e].nod[2];
          ctri3[sum_tri3-2].nod[1]=elem[e].nod[3];
          ctri3[sum_tri3-2].nod[2]=elem[e].nod[7];

          ctri3[sum_tri3-1].elem_nr= e;
          ctri3[sum_tri3-1].group  = 4;
          ctri3[sum_tri3-1].mat    = elem[e].mat;
          ctri3[sum_tri3-1].nod[0]=elem[e].nod[2];
          ctri3[sum_tri3-1].nod[1]=elem[e].nod[7];
          ctri3[sum_tri3-1].nod[2]=elem[e].nod[6];
        }
        else if((ec[0]==0)&&(ec[1]==3)&&(ec[2]==4)&&(ec[3]==7))
        {
          ctri3[sum_tri3-2].elem_nr= e;
          ctri3[sum_tri3-2].group  = 5;
          ctri3[sum_tri3-2].mat    = elem[e].mat;
          ctri3[sum_tri3-2].nod[0]=elem[e].nod[3];
          ctri3[sum_tri3-2].nod[1]=elem[e].nod[0];
          ctri3[sum_tri3-2].nod[2]=elem[e].nod[4];

          ctri3[sum_tri3-1].elem_nr= e;
          ctri3[sum_tri3-1].group  = 5;
          ctri3[sum_tri3-1].mat    = elem[e].mat;
          ctri3[sum_tri3-1].nod[0]=elem[e].nod[3];
          ctri3[sum_tri3-1].nod[1]=elem[e].nod[4];
          ctri3[sum_tri3-1].nod[2]=elem[e].nod[7];
        }
        else if((ec[0]==4)&&(ec[1]==5)&&(ec[2]==6)&&(ec[3]==7))
        {
          ctri3[sum_tri3-2].elem_nr= e;
          ctri3[sum_tri3-2].group  = 6;
          ctri3[sum_tri3-2].mat    = elem[e].mat;
          ctri3[sum_tri3-2].nod[0]=elem[e].nod[4];
          ctri3[sum_tri3-2].nod[1]=elem[e].nod[5];
          ctri3[sum_tri3-2].nod[2]=elem[e].nod[6];

          ctri3[sum_tri3-1].elem_nr= e;
          ctri3[sum_tri3-1].group  = 6;
          ctri3[sum_tri3-1].mat    = elem[e].mat;
          ctri3[sum_tri3-1].nod[0]=elem[e].nod[4];
          ctri3[sum_tri3-1].nod[1]=elem[e].nod[6];
          ctri3[sum_tri3-1].nod[2]=elem[e].nod[7];
        }
        else { printf(" no element side found from el:%d,  %d %d %d %d\n", elem[e].nr,ec[0],
		    ec[1], ec[2], ec[3]); sum_tri3-=2; }
      }
    }


    /* ----- HE20 --------------- */
    else if (elem[e].type==4)
    {
      for (n=0; n<20; n++)
      {
        for (i=0; i<set[set2].anz_n; i++)
        {
          if (elem[e].nod[n]==node2[i].nr)
          {
            ec[j]=n;
            j++;
          }
        }
      }
      if(j==8)
      {
        elem[e].group=2;

        /* merke dir alle am node haengenden flaechen (flaeche: sum_tri3, sum_tri3+1)*/
        for (n=0; n<6; n++)
        {
          for (i=0; i<8; i++)
          {
            if((tri3_index[ elem[e].nod[ec[i]] ] 
            = (int *)realloc((int *)tri3_index[ elem[e].nod[ec[i]] ]
            , (ntri_nodes[elem[e].nod[ec[i]]]+1) *sizeof(int)))==NULL)
	    {
              printf("\n\n ERROR: realloc failed for tri3_index\a\n" );
              goto end;
            }

            tri3_index[ elem[e].nod[ec[i]] ][ ntri_nodes[elem[e].nod[ec[i]]] ]=sum_tri3+n;
            ntri_nodes[ elem[e].nod[ec[i]] ]++;
          }
        }
        sum_tri3+=6;
        if ( (ctri3 = (CTri3 *)realloc( (CTri3 *)ctri3, sum_tri3 * sizeof(CTri3))) == NULL )
        {
          printf("\nERROR: realloc failed in areampc() \a\n\n");
          goto end;
        }

        if((ec[0]==0)&&(ec[1]==1)&&(ec[2]==2)&&(ec[3]==3))
        {
          ctri3[sum_tri3-6].elem_nr= e;
          ctri3[sum_tri3-6].group  = 1;
          ctri3[sum_tri3-6].mat    = elem[e].mat;
          ctri3[sum_tri3-6].nod[0]=elem[e].nod[8];
          ctri3[sum_tri3-6].nod[1]=elem[e].nod[0];
          ctri3[sum_tri3-6].nod[2]=elem[e].nod[11];

          ctri3[sum_tri3-5].elem_nr= e;
          ctri3[sum_tri3-5].group  = 1;
          ctri3[sum_tri3-5].mat    = elem[e].mat;
          ctri3[sum_tri3-5].nod[0]=elem[e].nod[11];
          ctri3[sum_tri3-5].nod[1]=elem[e].nod[3];
          ctri3[sum_tri3-5].nod[2]=elem[e].nod[10];

          ctri3[sum_tri3-4].elem_nr= e;
          ctri3[sum_tri3-4].group  = 1;
          ctri3[sum_tri3-4].mat    = elem[e].mat;
          ctri3[sum_tri3-4].nod[0]=elem[e].nod[10];
          ctri3[sum_tri3-4].nod[1]=elem[e].nod[2];
          ctri3[sum_tri3-4].nod[2]=elem[e].nod[9];

          ctri3[sum_tri3-3].elem_nr= e;
          ctri3[sum_tri3-3].group  = 1;
          ctri3[sum_tri3-3].mat    = elem[e].mat;
          ctri3[sum_tri3-3].nod[0]=elem[e].nod[9];
          ctri3[sum_tri3-3].nod[1]=elem[e].nod[1];
          ctri3[sum_tri3-3].nod[2]=elem[e].nod[8];

          ctri3[sum_tri3-2].elem_nr= e;
          ctri3[sum_tri3-2].group  = 1;
          ctri3[sum_tri3-2].mat    = elem[e].mat;
          ctri3[sum_tri3-2].nod[0]=elem[e].nod[8];
          ctri3[sum_tri3-2].nod[1]=elem[e].nod[11];
          ctri3[sum_tri3-2].nod[2]=elem[e].nod[10];

          ctri3[sum_tri3-1].elem_nr= e;
          ctri3[sum_tri3-1].group  = 1;
          ctri3[sum_tri3-1].mat    = elem[e].mat;
          ctri3[sum_tri3-1].nod[0]=elem[e].nod[10];
          ctri3[sum_tri3-1].nod[1]=elem[e].nod[9];
          ctri3[sum_tri3-1].nod[2]=elem[e].nod[8];
        }
        else if((ec[0]==0)&&(ec[1]==1)&&(ec[2]==4)&&(ec[3]==5))
        {
          ctri3[sum_tri3-6].elem_nr= e;
          ctri3[sum_tri3-6].group  = 2;
          ctri3[sum_tri3-6].mat    = elem[e].mat;
          ctri3[sum_tri3-6].nod[0]=elem[e].nod[8];
          ctri3[sum_tri3-6].nod[1]=elem[e].nod[1];
          ctri3[sum_tri3-6].nod[2]=elem[e].nod[13];

          ctri3[sum_tri3-5].elem_nr= e;
          ctri3[sum_tri3-5].group  = 2;
          ctri3[sum_tri3-5].mat    = elem[e].mat;
          ctri3[sum_tri3-5].nod[0]=elem[e].nod[13];
          ctri3[sum_tri3-5].nod[1]=elem[e].nod[5];
          ctri3[sum_tri3-5].nod[2]=elem[e].nod[16];

          ctri3[sum_tri3-4].elem_nr= e;
          ctri3[sum_tri3-4].group  = 2;
          ctri3[sum_tri3-4].mat    = elem[e].mat;
          ctri3[sum_tri3-4].nod[0]=elem[e].nod[16];
          ctri3[sum_tri3-4].nod[1]=elem[e].nod[4];
          ctri3[sum_tri3-4].nod[2]=elem[e].nod[12];

          ctri3[sum_tri3-3].elem_nr= e;
          ctri3[sum_tri3-3].group  = 2;
          ctri3[sum_tri3-3].mat    = elem[e].mat;
          ctri3[sum_tri3-3].nod[0]=elem[e].nod[12];
          ctri3[sum_tri3-3].nod[1]=elem[e].nod[0];
          ctri3[sum_tri3-3].nod[2]=elem[e].nod[8];

          ctri3[sum_tri3-2].elem_nr= e;
          ctri3[sum_tri3-2].group  = 2;
          ctri3[sum_tri3-2].mat    = elem[e].mat;
          ctri3[sum_tri3-2].nod[0]=elem[e].nod[8];
          ctri3[sum_tri3-2].nod[1]=elem[e].nod[13];
          ctri3[sum_tri3-2].nod[2]=elem[e].nod[16];

          ctri3[sum_tri3-1].elem_nr= e;
          ctri3[sum_tri3-1].group  = 2;
          ctri3[sum_tri3-1].mat    = elem[e].mat;
          ctri3[sum_tri3-1].nod[0]=elem[e].nod[16];
          ctri3[sum_tri3-1].nod[1]=elem[e].nod[12];
          ctri3[sum_tri3-1].nod[2]=elem[e].nod[8];
        }
        else if((ec[0]==1)&&(ec[1]==2)&&(ec[2]==5)&&(ec[3]==6))
        {
          ctri3[sum_tri3-6].elem_nr= e;
          ctri3[sum_tri3-6].group  = 3;
          ctri3[sum_tri3-6].mat    = elem[e].mat;
          ctri3[sum_tri3-6].nod[0]=elem[e].nod[9];
          ctri3[sum_tri3-6].nod[1]=elem[e].nod[2];
          ctri3[sum_tri3-6].nod[2]=elem[e].nod[14];

          ctri3[sum_tri3-5].elem_nr= e;
          ctri3[sum_tri3-5].group  = 3;
          ctri3[sum_tri3-5].mat    = elem[e].mat;
          ctri3[sum_tri3-5].nod[0]=elem[e].nod[14];
          ctri3[sum_tri3-5].nod[1]=elem[e].nod[6];
          ctri3[sum_tri3-5].nod[2]=elem[e].nod[17];

          ctri3[sum_tri3-4].elem_nr= e;
          ctri3[sum_tri3-4].group  = 3;
          ctri3[sum_tri3-4].mat    = elem[e].mat;
          ctri3[sum_tri3-4].nod[0]=elem[e].nod[17];
          ctri3[sum_tri3-4].nod[1]=elem[e].nod[5];
          ctri3[sum_tri3-4].nod[2]=elem[e].nod[13];

          ctri3[sum_tri3-3].elem_nr= e;
          ctri3[sum_tri3-3].group  = 3;
          ctri3[sum_tri3-3].mat    = elem[e].mat;
          ctri3[sum_tri3-3].nod[0]=elem[e].nod[13];
          ctri3[sum_tri3-3].nod[1]=elem[e].nod[1];
          ctri3[sum_tri3-3].nod[2]=elem[e].nod[9];

          ctri3[sum_tri3-2].elem_nr= e;
          ctri3[sum_tri3-2].group  = 3;
          ctri3[sum_tri3-2].mat    = elem[e].mat;
          ctri3[sum_tri3-2].nod[0]=elem[e].nod[9];
          ctri3[sum_tri3-2].nod[1]=elem[e].nod[14];
          ctri3[sum_tri3-2].nod[2]=elem[e].nod[17];

          ctri3[sum_tri3-1].elem_nr= e;
          ctri3[sum_tri3-1].group  = 3;
          ctri3[sum_tri3-1].mat    = elem[e].mat;
          ctri3[sum_tri3-1].nod[0]=elem[e].nod[17];
          ctri3[sum_tri3-1].nod[1]=elem[e].nod[13];
          ctri3[sum_tri3-1].nod[2]=elem[e].nod[9];
        }
        else if((ec[0]==2)&&(ec[1]==3)&&(ec[2]==6)&&(ec[3]==7))
        {
          ctri3[sum_tri3-6].elem_nr= e;
          ctri3[sum_tri3-6].group  = 4;
          ctri3[sum_tri3-6].mat    = elem[e].mat;
          ctri3[sum_tri3-6].nod[0]=elem[e].nod[10];
          ctri3[sum_tri3-6].nod[1]=elem[e].nod[3];
          ctri3[sum_tri3-6].nod[2]=elem[e].nod[15];

          ctri3[sum_tri3-5].elem_nr= e;
          ctri3[sum_tri3-5].group  = 4;
          ctri3[sum_tri3-5].mat    = elem[e].mat;
          ctri3[sum_tri3-5].nod[0]=elem[e].nod[15];
          ctri3[sum_tri3-5].nod[1]=elem[e].nod[7];
          ctri3[sum_tri3-5].nod[2]=elem[e].nod[18];

          ctri3[sum_tri3-4].elem_nr= e;
          ctri3[sum_tri3-4].group  = 4;
          ctri3[sum_tri3-4].mat    = elem[e].mat;
          ctri3[sum_tri3-4].nod[0]=elem[e].nod[18];
          ctri3[sum_tri3-4].nod[1]=elem[e].nod[6];
          ctri3[sum_tri3-4].nod[2]=elem[e].nod[14];

          ctri3[sum_tri3-3].elem_nr= e;
          ctri3[sum_tri3-3].group  = 4;
          ctri3[sum_tri3-3].mat    = elem[e].mat;
          ctri3[sum_tri3-3].nod[0]=elem[e].nod[14];
          ctri3[sum_tri3-3].nod[1]=elem[e].nod[2];
          ctri3[sum_tri3-3].nod[2]=elem[e].nod[10];

          ctri3[sum_tri3-2].elem_nr= e;
          ctri3[sum_tri3-2].group  = 4;
          ctri3[sum_tri3-2].mat    = elem[e].mat;
          ctri3[sum_tri3-2].nod[0]=elem[e].nod[10];
          ctri3[sum_tri3-2].nod[1]=elem[e].nod[15];
          ctri3[sum_tri3-2].nod[2]=elem[e].nod[18];

          ctri3[sum_tri3-1].elem_nr= e;
          ctri3[sum_tri3-1].group  = 4;
          ctri3[sum_tri3-1].mat    = elem[e].mat;
          ctri3[sum_tri3-1].nod[0]=elem[e].nod[18];
          ctri3[sum_tri3-1].nod[1]=elem[e].nod[14];
          ctri3[sum_tri3-1].nod[2]=elem[e].nod[10];
        }
        else if((ec[0]==0)&&(ec[1]==3)&&(ec[2]==4)&&(ec[3]==7))
        {
          ctri3[sum_tri3-6].elem_nr= e;
          ctri3[sum_tri3-6].group  = 5;
          ctri3[sum_tri3-6].mat    = elem[e].mat;
          ctri3[sum_tri3-6].nod[0]=elem[e].nod[11];
          ctri3[sum_tri3-6].nod[1]=elem[e].nod[0];
          ctri3[sum_tri3-6].nod[2]=elem[e].nod[12];

          ctri3[sum_tri3-5].elem_nr= e;
          ctri3[sum_tri3-5].group  = 5;
          ctri3[sum_tri3-5].mat    = elem[e].mat;
          ctri3[sum_tri3-5].nod[0]=elem[e].nod[12];
          ctri3[sum_tri3-5].nod[1]=elem[e].nod[4];
          ctri3[sum_tri3-5].nod[2]=elem[e].nod[19];

          ctri3[sum_tri3-4].elem_nr= e;
          ctri3[sum_tri3-4].group  = 5;
          ctri3[sum_tri3-4].mat    = elem[e].mat;
          ctri3[sum_tri3-4].nod[0]=elem[e].nod[19];
          ctri3[sum_tri3-4].nod[1]=elem[e].nod[7];
          ctri3[sum_tri3-4].nod[2]=elem[e].nod[15];

          ctri3[sum_tri3-3].elem_nr= e;
          ctri3[sum_tri3-3].group  = 5;
          ctri3[sum_tri3-3].mat    = elem[e].mat;
          ctri3[sum_tri3-3].nod[0]=elem[e].nod[15];
          ctri3[sum_tri3-3].nod[1]=elem[e].nod[3];
          ctri3[sum_tri3-3].nod[2]=elem[e].nod[11];

          ctri3[sum_tri3-2].elem_nr= e;
          ctri3[sum_tri3-2].group  = 5;
          ctri3[sum_tri3-2].mat    = elem[e].mat;
          ctri3[sum_tri3-2].nod[0]=elem[e].nod[11];
          ctri3[sum_tri3-2].nod[1]=elem[e].nod[12];
          ctri3[sum_tri3-2].nod[2]=elem[e].nod[19];

          ctri3[sum_tri3-1].elem_nr= e;
          ctri3[sum_tri3-1].group  = 5;
          ctri3[sum_tri3-1].mat    = elem[e].mat;
          ctri3[sum_tri3-1].nod[0]=elem[e].nod[19];
          ctri3[sum_tri3-1].nod[1]=elem[e].nod[15];
          ctri3[sum_tri3-1].nod[2]=elem[e].nod[11];
        }
        else if((ec[0]==4)&&(ec[1]==5)&&(ec[2]==6)&&(ec[3]==7))
        {
          ctri3[sum_tri3-6].elem_nr= e;
          ctri3[sum_tri3-6].group  = 6;
          ctri3[sum_tri3-6].mat    = elem[e].mat;
          ctri3[sum_tri3-6].nod[0]=elem[e].nod[16];
          ctri3[sum_tri3-6].nod[1]=elem[e].nod[5];
          ctri3[sum_tri3-6].nod[2]=elem[e].nod[17];

          ctri3[sum_tri3-5].elem_nr= e;
          ctri3[sum_tri3-5].group  = 6;
          ctri3[sum_tri3-5].mat    = elem[e].mat;
          ctri3[sum_tri3-5].nod[0]=elem[e].nod[17];
          ctri3[sum_tri3-5].nod[1]=elem[e].nod[6];
          ctri3[sum_tri3-5].nod[2]=elem[e].nod[18];

          ctri3[sum_tri3-4].elem_nr= e;
          ctri3[sum_tri3-4].group  = 6;
          ctri3[sum_tri3-4].mat    = elem[e].mat;
          ctri3[sum_tri3-4].nod[0]=elem[e].nod[18];
          ctri3[sum_tri3-4].nod[1]=elem[e].nod[7];
          ctri3[sum_tri3-4].nod[2]=elem[e].nod[19];

          ctri3[sum_tri3-3].elem_nr= e;
          ctri3[sum_tri3-3].group  = 6;
          ctri3[sum_tri3-3].mat    = elem[e].mat;
          ctri3[sum_tri3-3].nod[0]=elem[e].nod[19];
          ctri3[sum_tri3-3].nod[1]=elem[e].nod[4];
          ctri3[sum_tri3-3].nod[2]=elem[e].nod[16];

          ctri3[sum_tri3-2].elem_nr= e;
          ctri3[sum_tri3-2].group  = 6;
          ctri3[sum_tri3-2].mat    = elem[e].mat;
          ctri3[sum_tri3-2].nod[0]=elem[e].nod[16];
          ctri3[sum_tri3-2].nod[1]=elem[e].nod[17];
          ctri3[sum_tri3-2].nod[2]=elem[e].nod[18];

          ctri3[sum_tri3-1].elem_nr= e;
          ctri3[sum_tri3-1].group  = 6;
          ctri3[sum_tri3-1].mat    = elem[e].mat;
          ctri3[sum_tri3-1].nod[0]=elem[e].nod[18];
          ctri3[sum_tri3-1].nod[1]=elem[e].nod[19];
          ctri3[sum_tri3-1].nod[2]=elem[e].nod[16];
        }
        else { printf(" no element side found from el:%d,  %d %d %d %d\n", elem[e].nr,ec[0],
           ec[1], ec[2], ec[3]); sum_tri3-=6; }
      }
    }
    else
    {
      printf ("ERROR: independent element-type:%d is not supported\n\n\a",elem[e].type );
      goto end;
    }

  }
  if(printFlag) printf (" %d ctri3 created from %d elements\n\n", sum_tri3, anz->e );
  if(!sum_tri3)
  {
    printf ("ERROR: found no valid element\n\n\a" );
    goto end;
  }

  /* suche nodes, berechne und schreibe EQUATION's  */
  if((int)N_CLOSEST_NODES<set[set2].anz_n) n_closest_nodes=(int)N_CLOSEST_NODES; else n_closest_nodes=set[set2].anz_n;
  tol=gtol/scale->w;
  tol*=tol;
  if ( (rsort = (Rsort *)malloc( (set[set2].anz_n+1) * sizeof(Rsort))) == NULL )
    printf("ERROR: realloc failed: Rsort\n\n" ); 

  /* for Guidos routine nearNodes() */
  if ( (indnodes = (double *)malloc( (set[set2].anz_n*3.+1) * sizeof(double))) == NULL )
    printf("ERROR: realloc failed: indnodes\n\n" ); 
  i=j=0; do
  { 
      indnodes[i++]= node[node2[j].nr].nx;
      indnodes[i++]= node[node2[j].nr].ny;
      indnodes[i++]= node[node2[j++].nr].nz;
  }while(j<set[set2].anz_n);
  nearNodesCallFlag=0;
  /* end */

  for (i=0; i<set[set1].anz_n; i++ )
  {
    /* suche die naechst-liegenden indep-nodes  */
    nearNodes(&indnodes[0], &set[set2].anz_n, &node[node1[i].nr].nx, &nearnodes[0], &n_closest_nodes, &nearNodesCallFlag);
    nearNodesCallFlag=1;
    for (j=0; j<n_closest_nodes; j++)
    {
      dx= node[node2[nearnodes[j]].nr].nx - node[node1[i].nr].nx;
      dy= node[node2[nearnodes[j]].nr].ny - node[node1[i].nr].ny;
      dz= node[node2[nearnodes[j]].nr].nz - node[node1[i].nr].nz;      
      rsort[j].i=node2[nearnodes[j]].nr;
      rsort[j].r=dx*dx + dy*dy + dz*dz;
    }

#if TEST
    for (j=0; j<set[set2].anz_n; j++)
      printf("%d n:%d r:%lf\n", j, rsort[j].i, sqrt(rsort[j].r)); 
#endif

    if ( rsort[0].r<tol ) /* IF 2 NODES ARE EQUAL */
    {
      if(printFlag) printf("node:%d, found equal node:%d with dr:%lf\n"
      , node1[i].nr, rsort[0].i, sqrt(rsort[0].r));
      ind1=rsort[0].i;

      /* versetze den gefundenen Knoten auf die exakte korrespondierende pos. */
      if(ini_corrFlag)
      {
        node[node1[i].nr].nx = node[ind1].nx;
        node[node1[i].nr].ny = node[ind1].ny;
        node[node1[i].nr].nz = node[ind1].nz;
      }

      switch (sflag)
      {
        case 0:
        /* schreibe die EQUATIOS im Abaqusformat */
        for (e=0;e<7;e++)
        {
          if(DOF[e])
          {
            fprintf(handle, "*EQUATION\n");
            fprintf(handle, "%d\n", 2);
            if(e) fprintf(handle, "%d,%d,%8.5f,%d,%d,%8.5f \n", node1[i].nr, e, -1., ind1, e, 1. );
            else fprintf(handle, "%d,%d,%8.5f,%d,%d,%8.5f \n", node1[i].nr, DOFT, -1., ind1, DOFT, 1. );
          }
        }
        break;
        case 1:
        /* schreibe die EQUATIOS im Ansysformat */
        for (e=0;e<6;e++)
        {
          if(DOF[e+1])
          {
            neqn++;
            fprintf(handle, "CE,%d,0,%d,%s,%8.5f, %d,%s,%8.5f,  %d,%s,%8.5f\n",
            neqn, node1[i].nr, ansy_dofs[e], 1., ind1, ansy_dofs[e], -1., -1, ansy_dofs[e], 1. );
          }
        }
        break;
        case 2:
        /* schreibe die EQUATIOS im NASTRANformat */
        for (e=1;e<7;e++)
        {
          if(DOF[e])
          {
            fprintf(handle, "MPC,%8d,%8d,%8d,%8.5f,%8d,%8d,%8.5f\n"
            , neqn+1, node1[i].nr,e,-1.,ind1,e,1.);
          }
        }
        break;
        case 3:
          fprintf(handle, " %d, %f\n", node1[i].nr-nodeOffset, lcase[DOF[1]].dat[DOF[0]][ind1]);       
        break;
      }
    }
    else
    {
      if(printFlag) printf("node:%d, found non equal node:%d at dist:%lf\n", node1[i].nr, rsort[0].i, sqrt(rsort[0].r));

      /* knoten liegt zwischen den indep-nodes, suche das passende element.       */
      /* fange mit den elementen des naechstliegenden nodes an, und kontrolliere   */
      /* mit dem vectorprodukt welche elementflaeche den node umschliest          */

      min_offset=MAXVALUE;
      for (n=0; n<n_closest_nodes; n++)
      {
        for (j=0; j<ntri_nodes[ rsort[n].i ]; j++)
        {
          e=tri3_index[ rsort[n].i ][j];
	    /*
          printf("checke n:%d von e:%d  nod:%d %d %d\n",
            rsort[n].i, e+1,ctri3[e].nod[0],ctri3[e].nod[1],ctri3[e].nod[2] );
	    */
          offset=find_tri3( node, node1[i].nr, ctri3, e);
          if( offset != MAXVALUE )
          {
            /*
            printf(" found enclosing tri3:%d for node:%d, offset:%lf\n", e+1, node1[i].nr, offset);
            */
            /* merke dir das element und den offset */
            if (min_offset > offset*offset ) { min_offset=offset*offset;  elbuf=e; offsetbuf=offset;}
          }
        }
      }
      if (min_offset==MAXVALUE)
      {
        corrFlag=0;
        printf("WARNING: no enclosing element for dep-node:%d found, see set %s\n"
        , node1[i].nr, specialset->noel );
        sprintf( buffer, "%d", node1[i].nr); 
        pre_seta(specialset->noel, "n", buffer);

        /* kontrolliere welches zum naechsten node gehoerende dreieck */
        /* relativ am naechsten liegt und ob der grenzwert unterschritten ist */
        /* kriterium: flaechenfehler aller tri-node1[i].nr poligone */
        for (j=0; j<ntri_nodes[ rsort[0].i ]; j++)
        {
          e=tri3_index[ rsort[0].i ][j];
#if TEST    	    
          printf("suche fuer n:%d das naechste Tri3 e:%d  nod:%d %d %d \n",
            rsort[0].i, e+1,ctri3[e].nod[0],ctri3[e].nod[1],ctri3[e].nod[2] );
#endif	    
          if ( calcCoefficients( node, node1[i].nr, ctri3, e, c) != -1 )
          {
            offset=c[1]*c[1]+c[2]*c[2]+c[3]*c[3];
            if(offset<min_offset){ min_offset=offset; elbuf=e; }
#if TEST    
            printf(" qadsum:%lf coef:%lf %lf %lf\n",
              offset, c[3], c[1], c[2] );
#endif	    
          }    
	}
        if(min_offset==MAXVALUE)
        {
          printf("WARNING: no coefficients could be calculated, no MPC created for node:%d, see set %s\n", node1[i].nr, specialset->nompc);
          goto create_no_mpc;
        }
        else    
        {
          printf(" but found a close element\n");
        }
      }
      else
      {
        corrFlag=ini_corrFlag;
        offset=offsetbuf;
        if(printFlag) printf("closest tri3:%d (%d %d %d)for node:%d, offset:%lf\n", elbuf+1, ctri3[elbuf].nod[0],ctri3[elbuf].nod[1],ctri3[elbuf].nod[2], node1[i].nr, offset);
      }    

      /* das umschliessende Tri3 ist nun bekannt, wenn die korrekte shapefunction des */
      /* Mutterelements noch nicht eingebaut ist, haenge den node direkt an das Tri3  */
      if ( elem[ ctri3[elbuf].elem_nr ].type ==  1 )
      {
        /* berechnung der MPC-Koeffizienten fuer he8  */

        /* knoten der betroffenen elementseite filtern */
        switch(ctri3[elbuf].group)
        {
          case 1:
          nface[0]=elem[ ctri3[elbuf].elem_nr ].nod[0];
          nface[1]=elem[ ctri3[elbuf].elem_nr ].nod[1];
          nface[2]=elem[ ctri3[elbuf].elem_nr ].nod[2];
          nface[3]=elem[ ctri3[elbuf].elem_nr ].nod[3];
          break;
          case 2:
          nface[0]=elem[ ctri3[elbuf].elem_nr ].nod[0];
          nface[1]=elem[ ctri3[elbuf].elem_nr ].nod[1];
          nface[2]=elem[ ctri3[elbuf].elem_nr ].nod[5];
          nface[3]=elem[ ctri3[elbuf].elem_nr ].nod[4];
          break;
          case 3:
          nface[0]=elem[ ctri3[elbuf].elem_nr ].nod[1];
          nface[1]=elem[ ctri3[elbuf].elem_nr ].nod[2];
          nface[2]=elem[ ctri3[elbuf].elem_nr ].nod[6];
          nface[3]=elem[ ctri3[elbuf].elem_nr ].nod[5];
          break;
          case 4:
          nface[0]=elem[ ctri3[elbuf].elem_nr ].nod[2];
          nface[1]=elem[ ctri3[elbuf].elem_nr ].nod[3];
          nface[2]=elem[ ctri3[elbuf].elem_nr ].nod[7];
          nface[3]=elem[ ctri3[elbuf].elem_nr ].nod[6];
          break;
          case 5:
          nface[0]=elem[ ctri3[elbuf].elem_nr ].nod[3];
          nface[1]=elem[ ctri3[elbuf].elem_nr ].nod[0];
          nface[2]=elem[ ctri3[elbuf].elem_nr ].nod[4];
          nface[3]=elem[ ctri3[elbuf].elem_nr ].nod[7];
          break;
          case 6:
          nface[0]=elem[ ctri3[elbuf].elem_nr ].nod[4];
          nface[1]=elem[ ctri3[elbuf].elem_nr ].nod[5];
          nface[2]=elem[ ctri3[elbuf].elem_nr ].nod[6];
          nface[3]=elem[ ctri3[elbuf].elem_nr ].nod[7];
          break;
        }
        nface[4]=nface[5]=nface[6]=nface[7]=0; 
        attachhe8_( coords, &anz->n, nface, &node1[i].nr, &xi_loc, &et_loc );
        shapefhe8_( &xi_loc, &et_loc, c );         

	if(printFlag)
        {
          printf("elem:%d xi:%lf et:%lf ",elem[ ctri3[elbuf].elem_nr ].nr,xi_loc,et_loc );
          for (n=0; n<4; n++) printf("n:%d ",nface[n]); printf("\n");
	}

        /* verschiebung des dep nodes auf die elementflaeche */
        conode[0]=node[node1[i].nr].nx;
        conode[1]=node[node1[i].nr].ny;
        conode[2]=node[node1[i].nr].nz;
        for(n=0;n<4;n++)
        {
          coface[n*3]=  node[nface[n]].nx;
          coface[n*3+1]=node[nface[n]].ny;
          coface[n*3+2]=node[nface[n]].nz;
        }
        distattachhe8_( &xi_loc, &et_loc, coface, conode, &dist, co_new );
        if(printFlag) printf(" dist:%lf\n",dist);  
        /* correct the node possition if requested */
        if(ini_corrFlag)
        {
          node[node1[i].nr].nx=co_new[0];
          node[node1[i].nr].ny=co_new[1];
          node[node1[i].nr].nz=co_new[2];
        }
        k=5;
      }
      else if ( elem[ ctri3[elbuf].elem_nr ].type == 4 )
      {
        /* berechnung der MPC-Koeffizienten fuer he20 */

        /* knoten der betroffenen elementseite filtern */
        switch(ctri3[elbuf].group)
        {
          case 1:
          nface[0]=elem[ ctri3[elbuf].elem_nr ].nod[0];
          nface[1]=elem[ ctri3[elbuf].elem_nr ].nod[1];
          nface[2]=elem[ ctri3[elbuf].elem_nr ].nod[2];
          nface[3]=elem[ ctri3[elbuf].elem_nr ].nod[3];
          nface[4]=elem[ ctri3[elbuf].elem_nr ].nod[8];
          nface[5]=elem[ ctri3[elbuf].elem_nr ].nod[9];
          nface[6]=elem[ ctri3[elbuf].elem_nr ].nod[10];
          nface[7]=elem[ ctri3[elbuf].elem_nr ].nod[11];
          break;
          case 2:
          nface[0]=elem[ ctri3[elbuf].elem_nr ].nod[0];
          nface[1]=elem[ ctri3[elbuf].elem_nr ].nod[1];
          nface[2]=elem[ ctri3[elbuf].elem_nr ].nod[5];
          nface[3]=elem[ ctri3[elbuf].elem_nr ].nod[4];
          nface[4]=elem[ ctri3[elbuf].elem_nr ].nod[8];
          nface[5]=elem[ ctri3[elbuf].elem_nr ].nod[13];
          nface[6]=elem[ ctri3[elbuf].elem_nr ].nod[16];
          nface[7]=elem[ ctri3[elbuf].elem_nr ].nod[12];
          break;
          case 3:
          nface[0]=elem[ ctri3[elbuf].elem_nr ].nod[1];
          nface[1]=elem[ ctri3[elbuf].elem_nr ].nod[2];
          nface[2]=elem[ ctri3[elbuf].elem_nr ].nod[6];
          nface[3]=elem[ ctri3[elbuf].elem_nr ].nod[5];
          nface[4]=elem[ ctri3[elbuf].elem_nr ].nod[9];
          nface[5]=elem[ ctri3[elbuf].elem_nr ].nod[14];
          nface[6]=elem[ ctri3[elbuf].elem_nr ].nod[17];
          nface[7]=elem[ ctri3[elbuf].elem_nr ].nod[13];
          break;
          case 4:
          nface[0]=elem[ ctri3[elbuf].elem_nr ].nod[2];
          nface[1]=elem[ ctri3[elbuf].elem_nr ].nod[3];
          nface[2]=elem[ ctri3[elbuf].elem_nr ].nod[7];
          nface[3]=elem[ ctri3[elbuf].elem_nr ].nod[6];
          nface[4]=elem[ ctri3[elbuf].elem_nr ].nod[10];
          nface[5]=elem[ ctri3[elbuf].elem_nr ].nod[15];
          nface[6]=elem[ ctri3[elbuf].elem_nr ].nod[18];
          nface[7]=elem[ ctri3[elbuf].elem_nr ].nod[14];
          break;
          case 5:
          nface[0]=elem[ ctri3[elbuf].elem_nr ].nod[3];
          nface[1]=elem[ ctri3[elbuf].elem_nr ].nod[0];
          nface[2]=elem[ ctri3[elbuf].elem_nr ].nod[4];
          nface[3]=elem[ ctri3[elbuf].elem_nr ].nod[7];
          nface[4]=elem[ ctri3[elbuf].elem_nr ].nod[11];
          nface[5]=elem[ ctri3[elbuf].elem_nr ].nod[12];
          nface[6]=elem[ ctri3[elbuf].elem_nr ].nod[19];
          nface[7]=elem[ ctri3[elbuf].elem_nr ].nod[15];
          break;
          case 6:
          nface[0]=elem[ ctri3[elbuf].elem_nr ].nod[4];
          nface[1]=elem[ ctri3[elbuf].elem_nr ].nod[5];
          nface[2]=elem[ ctri3[elbuf].elem_nr ].nod[6];
          nface[3]=elem[ ctri3[elbuf].elem_nr ].nod[7];
          nface[4]=elem[ ctri3[elbuf].elem_nr ].nod[16];
          nface[5]=elem[ ctri3[elbuf].elem_nr ].nod[17];
          nface[6]=elem[ ctri3[elbuf].elem_nr ].nod[18];
          nface[7]=elem[ ctri3[elbuf].elem_nr ].nod[19];
          break;
        }
        attachhe20_( coords, &anz->n, nface, &node1[i].nr, &xi_loc, &et_loc );
        shapefhe20_( &xi_loc, &et_loc, c );         

	if(printFlag)
        {
          printf("elem:%d xi:%lf et:%lf ",elem[ ctri3[elbuf].elem_nr ].nr,xi_loc,et_loc );
          for (n=0; n<8; n++) printf("n:%d ",nface[n]); printf("\n");
	}

        /* verschiebung des dep nodes auf die elementflaeche */
        conode[0]=node[node1[i].nr].nx;
        conode[1]=node[node1[i].nr].ny;
        conode[2]=node[node1[i].nr].nz;
        for(n=0;n<8;n++)
        {
          coface[n*3]=  node[nface[n]].nx;
          coface[n*3+1]=node[nface[n]].ny;
          coface[n*3+2]=node[nface[n]].nz;
        }
        distattachhe20_( &xi_loc, &et_loc, coface, conode, &dist, co_new );
        if(printFlag) printf(" dist:%lf\n", dist);  
        /* correct the node possition if requested */
        if(ini_corrFlag)
        {
          node[node1[i].nr].nx=co_new[0];
          node[node1[i].nr].ny=co_new[1];
          node[node1[i].nr].nz=co_new[2];
	}
        k=9;
      }
      else
      {
        /* berechnung der MPC-Koeffizienten fuer Tri3 */

        ind1=ctri3[elbuf].nod[0];
        ind2=ctri3[elbuf].nod[1];
        ind3=ctri3[elbuf].nod[2];
        nface[0]=ind1; nface[1]=ind2; nface[2]=ind3;  
        if(printFlag) printf("   enclosing nodes:%d %d %d\n", ind1,ind2,ind3 );

        if(corrFlag)
	{
          /* verschiebung des dep nodes ins tri3-element */
          corrNode( node, node1[i].nr, ctri3, elbuf, offset );
           /* ueberpruefung der neuen position */
          if(printFlag) printf (" dist %lf\n", offset);
          offset=find_tri3( node, node1[i].nr, ctri3, elbuf);
          if(printFlag) printf (" dist after corr %lf\n", offset);
        }
        /* bestimmung der coeffizienten */
        if ( calcCoefficients( node, node1[i].nr, ctri3, elbuf, c) == -1 )
        {
          printf("WARNING: no coefficients could be calculated, no MPC created for node:%d, see set %s\n", node1[i].nr, specialset->nompc);
          goto create_no_mpc;
        }    
        k=4;
      }

      /* Die Koeffizienten c sind nun bekannt */
      /* setze den koeffizienten gleich der summe der indep-koeffizienten */
      c[0]=0.;
      for (n=1;n<k;n++) c[0]-= c[n];
      if(printFlag) printf ("sum_c=%lf (should be 1)\n", -c[0]);

#if TEST
      /* schreibe die EQUATIOS im Abaqusformat auf den Schirm */
      for (e=0;e<7;e++)
      {
        if(DOF[e])
        {
          printf( "*EQUATION\n");
          printf( "%d\n", k);
          if(e)
          {
            printf("%d,%d,%8.5f \n", node1[i].nr, e, c[0]);
            for (n=1;n<k;n++)
              printf("%d,%d,%8.5f \n", nface[n-1], e, c[n] );
          }
          else
          {
            printf("%d,%d,%8.5f \n", node1[i].nr, DOFT, c[0]);
            for (n=1;n<k;n++)
              printf("%d,%d,%8.5f \n", nface[n-1], DOFT, c[n] );
          }
        }
      }
      printf("\n");
#endif

      switch (sflag)
      {
        case 0:
        for (e=0;e<7;e++)
        {
          if(DOF[e])
          {
            fprintf(handle, "*EQUATION\n");
            fprintf(handle, "%d\n", k);
            if(e)
            {
              fprintf(handle, "%d,%d,%8.5f\n", node1[i].nr, e, c[0]);
              for (n=1;n<k;n++)
                fprintf(handle, "%d,%d,%8.5f\n", nface[n-1], e, c[n] );
            }
            else
            {
              fprintf(handle, "%d,%d,%8.5f\n", node1[i].nr, DOFT, c[0]);
              for (n=1;n<k;n++)
                fprintf(handle, "%d,%d,%8.5f\n", nface[n-1], DOFT, c[n] );
            }
          }
        }
        break;
        case 1:
        /* schreibe die EQUATIOS im Ansysformat */
        for (e=0;e<6;e++)
        {
          if(DOF[e+1])
          {
            neqn++;
            fprintf(handle, "CE,%d,0,%d,%s,%8.5f\n", neqn, node1[i].nr, ansy_dofs[e], c[0]);
            for (n=1;n<k;n++)
              fprintf(handle, "CE,%d,0,%d,%s,%8.5f\n", neqn, nface[n-1], ansy_dofs[e], c[n]);
          }
        }
        break;
        case 2:
        /* schreibe die EQUATIOS im NASTRANformat */
        for (e=1;e<7;e++)
        {
          if(DOF[e])
          {
             fprintf(handle, "MPC,%8d,%8d,%8d,%8.5f\n", neqn+1, node1[i].nr, e, c[0]);
             for (n=1;n<k;n++)
               fprintf(handle, ", ,%8d,%8d,%8.5f\n", nface[n-1], e, c[n] );
          }
        }
        break;
        case 3:
          c[0]=0.;
          for (n=1;n<k;n++) c[0]+=lcase[DOF[1]].dat[DOF[0]][nface[n-1]]*c[n];
          fprintf(handle, " %d, %f\n", node1[i].nr-nodeOffset, c[0]);       
        break;
      }
    }
    goto create_mpc;
    create_no_mpc:;
        sprintf( buffer, "%d", node1[i].nr); 
        pre_seta(specialset->nompc, "n", buffer);
    goto cont;
    create_mpc:;  
        sprintf( buffer, "%d", node1[i].nr); 
        pre_seta(specialset->mpc, "n", buffer);
    cont:;
  }
  if(rsort) free(rsort);
  if(indnodes) free(indnodes);

 end:;

  i=getSetNr(specialset->nompc);
  if (i>-1) if (set[i].anz_n>0) printf(" WARNING:%d dependent nodes could not be connected, check set:%s\n", set[i].anz_n, set[i].name);

  fclose(handle);
  if(ntri_nodes) free(ntri_nodes);
  /* if(tri3_index) free(tri3_index); do not free, otherwise subfiels must be freed as well */
  if(dr) free(dr);
  if(coords) free(coords);
  if(ctri3) free(ctri3);
  if(node1) free(node1);
  if(node2) free(node2);
  if(elem) free(elem);
  scalNodes ( anz->n, node, scale );
}


