
#include <extUtil.h>

/* attach.f -- translated by f2c (version 19950110).
*/


int distattachhe20_(double *xi,double *et,double *pneigh,double *pnode,double *dist,double *p)
{
    /* System generated locals */
    double d__1, d__2, d__3;

    /* Local variables */
    static int i;

/*     calculates the global coordinates p within an 8-node 2-D element */
/*     (given by global coordinates pneigh)of a point with given local */
/*     coordinates (xi,et) and determines the distance from this point */
/*     (dist)to the point with global coordinates pnode */

    /* Parameter adjustments */
    --p;
    --pnode;
    pneigh -= 4;

    /* Function Body */
    for (i = 1; i <= 3; ++i) {
	p[i] = pneigh[i + 3] * (1. - *xi) * (1. - *et) * (-(*xi) - *et - 1.) /
		 4. + pneigh[i + 6] * (*xi + 1.) * (1. - *et) * (*xi - *et -
		1.) / 4. + pneigh[i + 9] * (*xi + 1.) * (*et + 1.) * (*xi + *
		et - 1.) / 4. + pneigh[i + 12] * (1. - *xi) * (*et + 1.) * (-(
		*xi) + *et - 1.) / 4. + pneigh[i + 15] * (1. - *xi * *xi) * (
		1. - *et) / 2. + pneigh[i + 18] * (1. - *et * *et) * (*xi +
		1.) / 2. + pneigh[i + 21] * (1. - *xi * *xi) * (*et + 1.) /
		2. + pneigh[i + 24] * (1. - *et * *et) * (1. - *xi) / 2.;
    }

/* Computing 2nd power */
    d__1 = p[1] - pnode[1];
/* Computing 2nd power */
    d__2 = p[2] - pnode[2];
/* Computing 2nd power */
    d__3 = p[3] - pnode[3];
    *dist = sqrt(d__1 * d__1 + d__2 * d__2 + d__3 * d__3);

    return 0;
} /* distattachhe20_ */



int distattachhe8_(double *xi,double * et, double *pneigh, double *pnode, double *dist, double *p)
{
    /* System generated locals */
    double d__1, d__2, d__3;


    /* Local variables */
    static int i;

/*     calculates the global coordinates p within an 8-node 2-D element */
/*     (given by global coordinates pneigh)of a point with given local */
/*     coordinates (xi,et) and determines the distance from this point */
/*     (dist)to the point with global coordinates pnode */

    /* Parameter adjustments */
    --p;
    --pnode;
    pneigh -= 4;

    /* Function Body */
    for (i = 1; i <= 3; ++i) {
	p[i] = pneigh[i + 3] * (1. - *xi) * (1. - *et) / 4. +
               pneigh[i + 6] * (*xi + 1.) * (1. - *et) / 4. +
               pneigh[i + 9] * (*xi + 1.) * (*et + 1.) / 4. + 
               pneigh[i + 12] * (1. - *xi) * (*et + 1.) / 4.;
    }

/* Computing 2nd power */
    d__1 = p[1] - pnode[1];
/* Computing 2nd power */
    d__2 = p[2] - pnode[2];
/* Computing 2nd power */
    d__3 = p[3] - pnode[3];
    *dist = sqrt(d__1 * d__1 + d__2 * d__2 + d__3 * d__3);

    return 0;
} /* distattachhe8_ */



int shapefhe20_(double *xi, double *et, double *coef)
{

/*     calculates the shape function at (xi,et) */

    /* Parameter adjustments */
    --coef;

    /* Function Body */
    coef[1] = -1.;
    coef[2] = (1. - *xi) * (1. - *et) * (-(*xi) - *et - 1.) / 4.;
    coef[3] = (*xi + 1.) * (1. - *et) * (*xi - *et - 1.) / 4.;
    coef[4] = (*xi + 1.) * (*et + 1.) * (*xi + *et - 1.) / 4.;
    coef[5] = (1. - *xi) * (*et + 1.) * (-(*xi) + *et - 1.) / 4.;
    coef[6] = (1. - *xi * *xi) * (1. - *et) / 2.;
    coef[7] = (1. - *et * *et) * (*xi + 1.) / 2.;
    coef[8] = (1. - *xi * *xi) * (*et + 1.) / 2.;
    coef[9] = (1. - *et * *et) * (1. - *xi) / 2.;

    return 0;
} /* shapef_ */


int shapefhe8_(double *xi, double *et, double *coef)
{

/*     calculates the shape function at (xi,et) */

    /* Parameter adjustments */
    --coef;

    /* Function Body */
    coef[1] = -1.;
    coef[2] = (1. - *xi) * (1. - *et) / 4.;
    coef[3] = (*xi + 1.) * (1. - *et) / 4.;
    coef[4] = (*xi + 1.) * (*et + 1.) / 4.;
    coef[5] = (1. - *xi) * (*et + 1.) / 4.;

    return 0;
} /* shapef_ */

int attachhe20_(double *co, int *nk, int *neigh, int *node, double *xi_loc__,double *et_loc__)
{
    /* System generated locals */
    double d__1;

    /* Local variables */
    static double aold[9]	/* was [3][3] */;
    static int imin, jmin;
    static double a[9]	/* was [3][3] */;
    static int i, j;
    static double p[3], pnode[3], etold[9]	/* was [3][3] */, xiold[9]	
	    /* was [3][3] */;
    static int ii;
    static double et[9]	/* was [3][3] */, xi[9]	/* was [3][3] */,
	    pneigh[24]	/* was [3][8] */;
    static double distmin;


/*     projects a node ('node') on the face of a twenty-node element. The
*/
/*     eight face nodes are contained in neigh. */

    /* Parameter adjustments */
    --neigh;
    co -= 4;

    /* Function Body */
    for (i = 1; i <= 8; ++i) {
	for (j = 1; j <= 3; ++j) {
	    pneigh[j + i * 3 - 4] = co[j + neigh[i] * 3];
	}
    }

    for (j = 1; j <= 3; ++j) {
	pnode[j - 1] = co[j + *node * 3];
    }

/*     initialisation */

    for (i = -1; i <= 1; ++i) {
	for (j = -1; j <= 1; ++j) {
	    xi[i + j * 3 + 4] = i * .01;
	    et[i + j * 3 + 4] = j * .01;
	    distattachhe20_(&xi[i + j * 3 + 4], &et[i + j * 3 + 4], pneigh, pnode,
		     &a[i + j * 3 + 4], p);
	}
    }

/*     minimizing the distance from the face to the node */

    for (ii = 1; ii <= 1000000; ++ii) {
	distmin = a[4];
	imin = 0;
	jmin = 0;
	for (i = -1; i <= 1; ++i) {
	    for (j = -1; j <= 1; ++j) {
		if (a[i + j * 3 + 4] < distmin) {
		    distmin = a[i + j * 3 + 4];
		    imin = i;
		    jmin = j;
		}
	    }
	}

/*       exit if minimum found */

	if (imin == 0 && jmin == 0) {
	    goto L10;
	}

	for (i = -1; i <= 1; ++i) {
	    for (j = -1; j <= 1; ++j) {
		aold[i + j * 3 + 4] = a[i + j * 3 + 4];
		xiold[i + j * 3 + 4] = xi[i + j * 3 + 4];
		etold[i + j * 3 + 4] = et[i + j * 3 + 4];
	    }
	}

	for (i = -1; i <= 1; ++i) {
	    for (j = -1; j <= 1; ++j) {
		if (i + imin >= -1 && i + imin <= 1 && j + jmin >= -1 && j +
			jmin <= 1) {
		    a[i + j * 3 + 4] = aold[i + imin + (j + jmin) * 3 + 4];
		    xi[i + j * 3 + 4] = xiold[i + imin + (j + jmin) * 3 + 4];
		    et[i + j * 3 + 4] = etold[i + imin + (j + jmin) * 3 + 4];
		} else {
		    xi[i + j * 3 + 4] += imin * .01;
		    et[i + j * 3 + 4] += jmin * .01;

/* Computing MIN */
		    d__1 = xi[i + j * 3 + 4];
		    xi[i + j * 3 + 4] = smin(d__1,1.);
/* Computing MAX */
		    d__1 = xi[i + j * 3 + 4];
		    xi[i + j * 3 + 4] = smax(d__1,-1.);
/* Computing MIN */
		    d__1 = et[i + j * 3 + 4];
		    et[i + j * 3 + 4] = smin(d__1,1.);
/* Computing MAX */
		    d__1 = et[i + j * 3 + 4];
		    et[i + j * 3 + 4] = smax(d__1,-1.);

		    distattachhe20_(&xi[i + j * 3 + 4], &et[i + j * 3 + 4],
			    pneigh, pnode, &a[i + j * 3 + 4], p);
		}
	    }
	}
    }
L10:

    distattachhe20_(&xi[4], &et[4], pneigh, pnode, &a[4], p);
    for (i = 1; i <= 3; ++i) {
	co[i + *node * 3] = p[i - 1];
    }

    *xi_loc__ = xi[4];
    *et_loc__ = et[4];

    return 0;
} /* attach_ */



int attachhe8_(double *co, int *nk, int *neigh, int *node,double *xi_loc__,double *et_loc__)
{
    /* System generated locals */
    double d__1;

    /* Local variables */
    static double aold[9]	/* was [3][3] */;
    static int imin, jmin;
    static double a[9]	/* was [3][3] */;
    static int i, j;
    static double p[3], pnode[3], etold[9]	/* was [3][3] */, xiold[9]	
	    /* was [3][3] */;
    static int ii;
    static double et[9]	/* was [3][3] */, xi[9]	/* was [3][3] */,
	    pneigh[24]	/* was [3][8] */;
    static double distmin;


/*     projects a node ('node') on the face of a twenty-node element. The
*/
/*     eight face nodes are contained in neigh. */

    /* Parameter adjustments */
    --neigh;
    co -= 4;

    /* Function Body */
    for (i = 1; i <= 8; ++i) {
	for (j = 1; j <= 3; ++j) {
	    pneigh[j + i * 3 - 4] = co[j + neigh[i] * 3];
	}
    }

    for (j = 1; j <= 3; ++j) {
	pnode[j - 1] = co[j + *node * 3];
    }

/*     initialisation */

    for (i = -1; i <= 1; ++i) {
	for (j = -1; j <= 1; ++j) {
	    xi[i + j * 3 + 4] = i * .01;
	    et[i + j * 3 + 4] = j * .01;
	    distattachhe8_(&xi[i + j * 3 + 4], &et[i + j * 3 + 4], pneigh, pnode,
		     &a[i + j * 3 + 4], p);
	}
    }

/*     minimizing the distance from the face to the node */

    for (ii = 1; ii <= 1000000; ++ii) {
	distmin = a[4];
	imin = 0;
	jmin = 0;
	for (i = -1; i <= 1; ++i) {
	    for (j = -1; j <= 1; ++j) {
		if (a[i + j * 3 + 4] < distmin) {
		    distmin = a[i + j * 3 + 4];
		    imin = i;
		    jmin = j;
		}
	    }
	}

/*       exit if minimum found */

	if (imin == 0 && jmin == 0) {
	    goto L10;
	}

	for (i = -1; i <= 1; ++i) {
	    for (j = -1; j <= 1; ++j) {
		aold[i + j * 3 + 4] = a[i + j * 3 + 4];
		xiold[i + j * 3 + 4] = xi[i + j * 3 + 4];
		etold[i + j * 3 + 4] = et[i + j * 3 + 4];
	    }
	}

	for (i = -1; i <= 1; ++i) {
	    for (j = -1; j <= 1; ++j) {
		if (i + imin >= -1 && i + imin <= 1 && j + jmin >= -1 && j +
			jmin <= 1) {
		    a[i + j * 3 + 4] = aold[i + imin + (j + jmin) * 3 + 4];
		    xi[i + j * 3 + 4] = xiold[i + imin + (j + jmin) * 3 + 4];
		    et[i + j * 3 + 4] = etold[i + imin + (j + jmin) * 3 + 4];
		} else {
		    xi[i + j * 3 + 4] += imin * .01;
		    et[i + j * 3 + 4] += jmin * .01;

/* Computing MIN */
		    d__1 = xi[i + j * 3 + 4];
		    xi[i + j * 3 + 4] = smin(d__1,1.);
/* Computing MAX */
		    d__1 = xi[i + j * 3 + 4];
		    xi[i + j * 3 + 4] = smax(d__1,-1.);
/* Computing MIN */
		    d__1 = et[i + j * 3 + 4];
		    et[i + j * 3 + 4] = smin(d__1,1.);
/* Computing MAX */
		    d__1 = et[i + j * 3 + 4];
		    et[i + j * 3 + 4] = smax(d__1,-1.);

		    distattachhe8_(&xi[i + j * 3 + 4], &et[i + j * 3 + 4],
			    pneigh, pnode, &a[i + j * 3 + 4], p);
		}
	    }
	}
    }
L10:

    distattachhe8_(&xi[4], &et[4], pneigh, pnode, &a[4], p);
    for (i = 1; i <= 3; ++i) {
	co[i + *node * 3] = p[i - 1];
    }

    *xi_loc__ = xi[4];
    *et_loc__ = et[4];

    return 0;
} /* attach_ */



/* neue attach funktionen (ccx_1.5) */
/* attach.f -- translated by f2c (version 20000121).
   You must link the resulting object file with the libraries:
	-lf2c -lm   (in that order)
*/



/*     CalculiX - A 3-dimensional finite element program */
/*              Copyright (C) 1998-2005 Guido Dhondt */

/*     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); */


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

/* Subroutine */ int attach_new(pneigh, pnode, nterms, ratio, dist)
double *pneigh, *pnode;
int *nterms;
double *ratio, *dist;
{
    /* System generated locals */
    double d__1;

    /* Local variables */
    static double aold[9]	/* was [3][3] */;
    static int imin, jmin;
    static double a[9]	/* was [3][3] */;
    static int i__, j;
    static double p[3], etold[9]	/* was [3][3] */, xiold[9]	/* 
	    was [3][3] */, d1, d2, d3, d4, etopt, xiopt;
    static int ii;
    static double et[9]	/* was [3][3] */, xi[9]	/* was [3][3] */;
    extern /* Subroutine */ int distattach_new();
    static double distmin;


/*     ataches node with coordinates in "pnode" to the face containing */
/*     "nterms" nodes with coordinates in field "pneigh" (nterms < 9). */




    /* Parameter adjustments */
    --ratio;
    --pnode;
    pneigh -= 4;

    /* Function Body */
    d1 = .25;
    d2 = .03125;
    d3 = .0039063;
    d4 = .001;

/*     initialisation */

    for (i__ = -1; i__ <= 1; ++i__) {
	for (j = -1; j <= 1; ++j) {
	    xi[i__ + j * 3 + 4] = i__ * d1;
	    et[i__ + j * 3 + 4] = j * d1;
	    distattach_new(&xi[i__ + j * 3 + 4], &et[i__ + j * 3 + 4], &pneigh[4]
		    , &pnode[1], &a[i__ + j * 3 + 4], p, &ratio[1], nterms);
	}
    }

/*     minimizing the distance from the face to the node */

    for (ii = 1; ii <= 1000000; ++ii) {
	distmin = a[4];
	imin = 0;
	jmin = 0;
	for (i__ = -1; i__ <= 1; ++i__) {
	    for (j = -1; j <= 1; ++j) {
		if (a[i__ + j * 3 + 4] < distmin) {
		    distmin = a[i__ + j * 3 + 4];
		    imin = i__;
		    jmin = j;
		}
	    }
	}

/*       exit if minimum found */

	if (imin == 0 && jmin == 0) {
	    goto L100;
	}

	for (i__ = -1; i__ <= 1; ++i__) {
	    for (j = -1; j <= 1; ++j) {
		aold[i__ + j * 3 + 4] = a[i__ + j * 3 + 4];
		xiold[i__ + j * 3 + 4] = xi[i__ + j * 3 + 4];
		etold[i__ + j * 3 + 4] = et[i__ + j * 3 + 4];
	    }
	}

	for (i__ = -1; i__ <= 1; ++i__) {
	    for (j = -1; j <= 1; ++j) {
		if (i__ + imin >= -1 && i__ + imin <= 1 && j + jmin >= -1 && 
			j + jmin <= 1) {
		    a[i__ + j * 3 + 4] = aold[i__ + imin + (j + jmin) * 3 + 4]
			    ;
		    xi[i__ + j * 3 + 4] = xiold[i__ + imin + (j + jmin) * 3 + 
			    4];
		    et[i__ + j * 3 + 4] = etold[i__ + imin + (j + jmin) * 3 + 
			    4];
		} else {
		    xi[i__ + j * 3 + 4] += imin * d1;
		    et[i__ + j * 3 + 4] += jmin * d1;

/* Computing MIN */
		    d__1 = xi[i__ + j * 3 + 4];
		    xi[i__ + j * 3 + 4] = min(d__1,1.);
/* Computing MAX */
		    d__1 = xi[i__ + j * 3 + 4];
		    xi[i__ + j * 3 + 4] = max(d__1,-1.);
/* Computing MIN */
		    d__1 = et[i__ + j * 3 + 4];
		    et[i__ + j * 3 + 4] = min(d__1,1.);
/* Computing MAX */
		    d__1 = et[i__ + j * 3 + 4];
		    et[i__ + j * 3 + 4] = max(d__1,-1.);

		    distattach_new(&xi[i__ + j * 3 + 4], &et[i__ + j * 3 + 4], &
			    pneigh[4], &pnode[1], &a[i__ + j * 3 + 4], p, &
			    ratio[1], nterms);
/*              write(*,*) a(i,j) */
		}
	    }
	}
    }
L100:

/*     2nd run */
/*     initialisation */

    xiopt = xi[4];
    etopt = et[4];
    for (i__ = -1; i__ <= 1; ++i__) {
	for (j = -1; j <= 1; ++j) {
	    xi[i__ + j * 3 + 4] = xiopt + i__ * d2;
	    et[i__ + j * 3 + 4] = etopt + j * d2;
/* Computing MIN */
	    d__1 = xi[i__ + j * 3 + 4];
	    xi[i__ + j * 3 + 4] = min(d__1,1.);
/* Computing MAX */
	    d__1 = xi[i__ + j * 3 + 4];
	    xi[i__ + j * 3 + 4] = max(d__1,-1.);
/* Computing MIN */
	    d__1 = et[i__ + j * 3 + 4];
	    et[i__ + j * 3 + 4] = min(d__1,1.);
/* Computing MAX */
	    d__1 = et[i__ + j * 3 + 4];
	    et[i__ + j * 3 + 4] = max(d__1,-1.);
	    distattach_new(&xi[i__ + j * 3 + 4], &et[i__ + j * 3 + 4], &pneigh[4]
		    , &pnode[1], &a[i__ + j * 3 + 4], p, &ratio[1], nterms);
	}
    }

/*     minimizing the distance from the face to the node */

    for (ii = 1; ii <= 1000000; ++ii) {
	distmin = a[4];
	imin = 0;
	jmin = 0;
	for (i__ = -1; i__ <= 1; ++i__) {
	    for (j = -1; j <= 1; ++j) {
		if (a[i__ + j * 3 + 4] < distmin) {
		    distmin = a[i__ + j * 3 + 4];
		    imin = i__;
		    jmin = j;
		}
	    }
	}

/*       exit if minimum found */

	if (imin == 0 && jmin == 0) {
	    goto L200;
	}

	for (i__ = -1; i__ <= 1; ++i__) {
	    for (j = -1; j <= 1; ++j) {
		aold[i__ + j * 3 + 4] = a[i__ + j * 3 + 4];
		xiold[i__ + j * 3 + 4] = xi[i__ + j * 3 + 4];
		etold[i__ + j * 3 + 4] = et[i__ + j * 3 + 4];
	    }
	}

	for (i__ = -1; i__ <= 1; ++i__) {
	    for (j = -1; j <= 1; ++j) {
		if (i__ + imin >= -1 && i__ + imin <= 1 && j + jmin >= -1 && 
			j + jmin <= 1) {
		    a[i__ + j * 3 + 4] = aold[i__ + imin + (j + jmin) * 3 + 4]
			    ;
		    xi[i__ + j * 3 + 4] = xiold[i__ + imin + (j + jmin) * 3 + 
			    4];
		    et[i__ + j * 3 + 4] = etold[i__ + imin + (j + jmin) * 3 + 
			    4];
		} else {
		    xi[i__ + j * 3 + 4] += imin * d2;
		    et[i__ + j * 3 + 4] += jmin * d2;

/* Computing MIN */
		    d__1 = xi[i__ + j * 3 + 4];
		    xi[i__ + j * 3 + 4] = min(d__1,1.);
/* Computing MAX */
		    d__1 = xi[i__ + j * 3 + 4];
		    xi[i__ + j * 3 + 4] = max(d__1,-1.);
/* Computing MIN */
		    d__1 = et[i__ + j * 3 + 4];
		    et[i__ + j * 3 + 4] = min(d__1,1.);
/* Computing MAX */
		    d__1 = et[i__ + j * 3 + 4];
		    et[i__ + j * 3 + 4] = max(d__1,-1.);

		    distattach_new(&xi[i__ + j * 3 + 4], &et[i__ + j * 3 + 4], &
			    pneigh[4], &pnode[1], &a[i__ + j * 3 + 4], p, &
			    ratio[1], nterms);
/*              write(*,*) a(i,j) */
		}
	    }
	}
    }
L200:

/*     3rd run */
/*     initialisation */

    xiopt = xi[4];
    etopt = et[4];
    for (i__ = -1; i__ <= 1; ++i__) {
	for (j = -1; j <= 1; ++j) {
	    xi[i__ + j * 3 + 4] = xiopt + i__ * d3;
	    et[i__ + j * 3 + 4] = etopt + j * d3;
/* Computing MIN */
	    d__1 = xi[i__ + j * 3 + 4];
	    xi[i__ + j * 3 + 4] = min(d__1,1.);
/* Computing MAX */
	    d__1 = xi[i__ + j * 3 + 4];
	    xi[i__ + j * 3 + 4] = max(d__1,-1.);
/* Computing MIN */
	    d__1 = et[i__ + j * 3 + 4];
	    et[i__ + j * 3 + 4] = min(d__1,1.);
/* Computing MAX */
	    d__1 = et[i__ + j * 3 + 4];
	    et[i__ + j * 3 + 4] = max(d__1,-1.);
	    distattach_new(&xi[i__ + j * 3 + 4], &et[i__ + j * 3 + 4], &pneigh[4]
		    , &pnode[1], &a[i__ + j * 3 + 4], p, &ratio[1], nterms);
	}
    }

/*     minimizing the distance from the face to the node */

    for (ii = 1; ii <= 1000000; ++ii) {
	distmin = a[4];
	imin = 0;
	jmin = 0;
	for (i__ = -1; i__ <= 1; ++i__) {
	    for (j = -1; j <= 1; ++j) {
		if (a[i__ + j * 3 + 4] < distmin) {
		    distmin = a[i__ + j * 3 + 4];
		    imin = i__;
		    jmin = j;
		}
	    }
	}

/*       exit if minimum found */

	if (imin == 0 && jmin == 0) {
	    goto L400;
	}

	for (i__ = -1; i__ <= 1; ++i__) {
	    for (j = -1; j <= 1; ++j) {
		aold[i__ + j * 3 + 4] = a[i__ + j * 3 + 4];
		xiold[i__ + j * 3 + 4] = xi[i__ + j * 3 + 4];
		etold[i__ + j * 3 + 4] = et[i__ + j * 3 + 4];
	    }
	}

	for (i__ = -1; i__ <= 1; ++i__) {
	    for (j = -1; j <= 1; ++j) {
		if (i__ + imin >= -1 && i__ + imin <= 1 && j + jmin >= -1 && 
			j + jmin <= 1) {
		    a[i__ + j * 3 + 4] = aold[i__ + imin + (j + jmin) * 3 + 4]
			    ;
		    xi[i__ + j * 3 + 4] = xiold[i__ + imin + (j + jmin) * 3 + 
			    4];
		    et[i__ + j * 3 + 4] = etold[i__ + imin + (j + jmin) * 3 + 
			    4];
		} else {
		    xi[i__ + j * 3 + 4] += imin * d3;
		    et[i__ + j * 3 + 4] += jmin * d3;

/* Computing MIN */
		    d__1 = xi[i__ + j * 3 + 4];
		    xi[i__ + j * 3 + 4] = min(d__1,1.);
/* Computing MAX */
		    d__1 = xi[i__ + j * 3 + 4];
		    xi[i__ + j * 3 + 4] = max(d__1,-1.);
/* Computing MIN */
		    d__1 = et[i__ + j * 3 + 4];
		    et[i__ + j * 3 + 4] = min(d__1,1.);
/* Computing MAX */
		    d__1 = et[i__ + j * 3 + 4];
		    et[i__ + j * 3 + 4] = max(d__1,-1.);

		    distattach_new(&xi[i__ + j * 3 + 4], &et[i__ + j * 3 + 4], &
			    pneigh[4], &pnode[1], &a[i__ + j * 3 + 4], p, &
			    ratio[1], nterms);
/*              write(*,*) a(i,j) */
		}
	    }
	}
    }
L400:

/*     4th run */
/*     initialisation */

    xiopt = xi[4];
    etopt = et[4];
    for (i__ = -1; i__ <= 1; ++i__) {
	for (j = -1; j <= 1; ++j) {
	    xi[i__ + j * 3 + 4] = xiopt + i__ * d4;
	    et[i__ + j * 3 + 4] = etopt + j * d4;
/* Computing MIN */
	    d__1 = xi[i__ + j * 3 + 4];
	    xi[i__ + j * 3 + 4] = min(d__1,1.);
/* Computing MAX */
	    d__1 = xi[i__ + j * 3 + 4];
	    xi[i__ + j * 3 + 4] = max(d__1,-1.);
/* Computing MIN */
	    d__1 = et[i__ + j * 3 + 4];
	    et[i__ + j * 3 + 4] = min(d__1,1.);
/* Computing MAX */
	    d__1 = et[i__ + j * 3 + 4];
	    et[i__ + j * 3 + 4] = max(d__1,-1.);
	    distattach_new(&xi[i__ + j * 3 + 4], &et[i__ + j * 3 + 4], &pneigh[4]
		    , &pnode[1], &a[i__ + j * 3 + 4], p, &ratio[1], nterms);
	}
    }

/*     minimizing the distance from the face to the node */

    for (ii = 1; ii <= 1000000; ++ii) {
	distmin = a[4];
	imin = 0;
	jmin = 0;
	for (i__ = -1; i__ <= 1; ++i__) {
	    for (j = -1; j <= 1; ++j) {
		if (a[i__ + j * 3 + 4] < distmin) {
		    distmin = a[i__ + j * 3 + 4];
		    imin = i__;
		    jmin = j;
		}
	    }
	}

/*       exit if minimum found */

	if (imin == 0 && jmin == 0) {
	    goto L300;
	}

	for (i__ = -1; i__ <= 1; ++i__) {
	    for (j = -1; j <= 1; ++j) {
		aold[i__ + j * 3 + 4] = a[i__ + j * 3 + 4];
		xiold[i__ + j * 3 + 4] = xi[i__ + j * 3 + 4];
		etold[i__ + j * 3 + 4] = et[i__ + j * 3 + 4];
	    }
	}

	for (i__ = -1; i__ <= 1; ++i__) {
	    for (j = -1; j <= 1; ++j) {
		if (i__ + imin >= -1 && i__ + imin <= 1 && j + jmin >= -1 && 
			j + jmin <= 1) {
		    a[i__ + j * 3 + 4] = aold[i__ + imin + (j + jmin) * 3 + 4]
			    ;
		    xi[i__ + j * 3 + 4] = xiold[i__ + imin + (j + jmin) * 3 + 
			    4];
		    et[i__ + j * 3 + 4] = etold[i__ + imin + (j + jmin) * 3 + 
			    4];
		} else {
		    xi[i__ + j * 3 + 4] += imin * d4;
		    et[i__ + j * 3 + 4] += jmin * d4;

/* Computing MIN */
		    d__1 = xi[i__ + j * 3 + 4];
		    xi[i__ + j * 3 + 4] = min(d__1,1.);
/* Computing MAX */
		    d__1 = xi[i__ + j * 3 + 4];
		    xi[i__ + j * 3 + 4] = max(d__1,-1.);
/* Computing MIN */
		    d__1 = et[i__ + j * 3 + 4];
		    et[i__ + j * 3 + 4] = min(d__1,1.);
/* Computing MAX */
		    d__1 = et[i__ + j * 3 + 4];
		    et[i__ + j * 3 + 4] = max(d__1,-1.);

		    distattach_new(&xi[i__ + j * 3 + 4], &et[i__ + j * 3 + 4], &
			    pneigh[4], &pnode[1], &a[i__ + j * 3 + 4], p, &
			    ratio[1], nterms);
/*              write(*,*) a(i,j) */
		}
	    }
	}
    }
L300:

    distattach_new(&xi[4], &et[4], &pneigh[4], &pnode[1], &a[4], p, &ratio[1], 
	    nterms);

    for (i__ = 1; i__ <= 3; ++i__) {
	pnode[i__] = p[i__ - 1];
    }

    *dist = a[4];

    return 0;
} /* attach_ */




/* distattach.f -- translated by f2c (version 20000121).
   You must link the resulting object file with the libraries:
	-lf2c -lm   (in that order)
*/




/*     CalculiX - A 3-dimensional finite element program */
/*              Copyright (C) 1998-2005 Guido Dhondt */

/*     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); */


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

/* Subroutine */ int distattach_new(xig, etg, pneigh, pnode, a, p, ratio, nterms)
double *xig, *etg, *pneigh, *pnode, *a, *p, *ratio;
int *nterms;
{
    /* System generated locals */
    int i__1;
    double d__1, d__2, d__3;

    /* Builtin functions */
    int s_wsle(), do_lio(), e_wsle();
    /* Subroutine */ int s_stop();

    /* Local variables */
    static int i__, j;
    static double dummy, et, xi;



/*     calculates the distance between the node with coordinates */
/*     in "pnode" and the node with local coordinates xig and etg */
/*     in a face described by "nterms" nodes with coordinates */
/*     in pneigh */




    /* Parameter adjustments */
    --ratio;
    --p;
    --pnode;
    pneigh -= 4;

    /* Function Body */
    if (*nterms == 3) {
	xi = (*xig + 1.) / 2.;
	et = (*etg + 1.) / 2.;
	if (xi + et > 1.) {
	    dummy = xi;
	    xi = 1. - et;
	    et = 1. - dummy;
	}
	ratio[1] = 1. - xi - et;
	ratio[2] = xi;
	ratio[3] = et;
    } else if (*nterms == 4) {
	xi = *xig;
	et = *etg;
	ratio[1] = (1. - xi) * (1. - et) / 4.;
	ratio[2] = (xi + 1.) * (1. - et) / 4.;
	ratio[3] = (xi + 1.) * (et + 1.) / 4.;
	ratio[4] = (1. - xi) * (et + 1.) / 4.;
    } else if (*nterms == 6) {
	xi = (*xig + 1.) / 2.;
	et = (*etg + 1.) / 2.;
	if (xi + et > 1.) {
	    dummy = xi;
	    xi = 1. - et;
	    et = 1. - dummy;
	}
	ratio[1] = (.5 - xi - et) * 2. * (1. - xi - et);
	ratio[2] = xi * (xi * 2. - 1.);
	ratio[3] = et * (et * 2. - 1.);
	ratio[4] = xi * 4. * (1. - xi - et);
	ratio[5] = xi * 4. * et;
	ratio[6] = et * 4. * (1. - xi - et);
    } else if (*nterms == 8) {
	xi = *xig;
	et = *etg;
	ratio[1] = (1. - xi) * (1. - et) * (-xi - et - 1.) / 4.;
	ratio[2] = (xi + 1.) * (1. - et) * (xi - et - 1.) / 4.;
	ratio[3] = (xi + 1.) * (et + 1.) * (xi + et - 1.) / 4.;
	ratio[4] = (1. - xi) * (et + 1.) * (-xi + et - 1.) / 4.;
	ratio[5] = (1. - xi * xi) * (1. - et) / 2.;
	ratio[6] = (xi + 1.) * (1. - et * et) / 2.;
	ratio[7] = (1. - xi * xi) * (et + 1.) / 2.;
	ratio[8] = (1. - xi) * (1. - et * et) / 2.;
    } else {
	printf ("ERROR in distattach\n");
    }

/*     calculating the position in the face */

    for (i__ = 1; i__ <= 3; ++i__) {
	p[i__] = 0.;
	i__1 = *nterms;
	for (j = 1; j <= i__1; ++j) {
	    p[i__] += ratio[j] * pneigh[i__ + j * 3];
	}
    }

/*     calculating the distance */

/* Computing 2nd power */
    d__1 = pnode[1] - p[1];
/* Computing 2nd power */
    d__2 = pnode[2] - p[2];
/* Computing 2nd power */
    d__3 = pnode[3] - p[3];
    *a = d__1 * d__1 + d__2 * d__2 + d__3 * d__3;

    return 0;
} /* distattach_new */

