/*
This file is part of the FElt finite element analysis package.
Copyright (C) 1993, 1994 Jason I. Gobat and Darren C. Atkinson
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; either version 2 of the License, or
(at your option) any later version.
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.
*/
/****************************************************************************
*
* File: coalesce.c
*
***************************************************************************/
# include <math.h>
# include "allocate.h"
# include "error.h"
# include "fe.h"
# include "objects.h"
# define TOLERANCE 0.001
# define DIST(a,b) (sqrt(((a) -> x - (b) -> x)*((a) -> x - (b) -> x) + \
((a) -> y - (b) -> y)*((a) -> y - (b) -> y) + \
((a) -> z - (b) -> z)*((a) -> z - (b) -> z)))
/****************************************************************************
*
* Function:
*
* Description:
*
****************************************************************************/
int CheckConnections (n1, n2, element, numelts)
Node n1, n2;
Element *element;
unsigned numelts;
{
unsigned i, j, k;
int status;
status = 0;
for (i = 1 ; i <= numelts ; i++) {
for (j = 1 ; j <= element[i] -> definition -> numnodes ; j++) {
if (element[i] -> node[j] == n1) {
for (k = 1 ; k <= element[i] -> definition -> numnodes ; k++) {
if (element[i] -> node[k] == n2) {
status = 1;
break;
}
}
}
}
if (status)
break;
}
return status;
}
void Reconnect (new, old, element, numelts)
Node new, old;
Element *element;
unsigned numelts;
{
unsigned i,j;
for (i = 1 ; i <= numelts ; i++) {
for (j = 1 ; j <= element[i] -> definition -> numnodes ; j++) {
if (element[i] -> node[j] == old) {
element[i] -> node[j] = new;
break;
}
}
}
return;
}
Node *MergeNodes (node, element, numnodes, numelts, merges, merge_count)
Node *node;
Element *element;
unsigned numnodes;
unsigned numelts;
unsigned *merges;
unsigned merge_count;
{
Node *new_nodes;
unsigned i;
unsigned count;
new_nodes = Allocate (Node, (numnodes - merge_count));
UnitOffset (new_nodes);
count = 0;
for (i = 1 ; i <= numnodes ; i++) {
if (merges [i]) {
Reconnect (node [merges[i]], node[i], element, numelts);
DestroyNode (node [i]);
}
else {
count++;
new_nodes [count] = node [i];
node [i] -> number = count;
}
}
ZeroOffset (node);
Deallocate (node);
return new_nodes;
}
Node *CoalesceNodes (node, element, nn, numelts)
Node *node;
Element *element;
unsigned *nn;
unsigned numelts;
{
double maxX, maxY, maxZ;
double minX, minY, minZ;
double tol;
unsigned i,j;
unsigned merge_count;
unsigned numnodes;
unsigned *merges;
Node *new_nodes;
int status;
numnodes = *nn;
if (numnodes == 0 || numelts == 0) {
error ("nothing to coalesce");
return NULL;
}
maxX = minX = node[1] -> x;
maxY = minY = node[1] -> y;
maxZ = minZ = node[1] -> z;
for (i = 1 ; i <= numnodes ; i++) {
if (node[i] -> x > maxX)
maxX = node[i] -> x;
else if (node[i] -> x < minX)
minX = node[i] -> x;
if (node[i] -> y > maxY)
maxY = node[i] -> y;
else if (node[i] -> y < minY)
minY = node[i] -> y;
if (node[i] -> z > maxZ)
maxZ = node[i] -> z;
else if (node[i] -> z < minZ)
minZ = node[i] -> z;
}
tol = TOLERANCE * sqrt ((maxX - minX)*(maxX - minX) +
(maxY - minY)*(maxY - minY) +
(maxZ - minZ)*(maxZ - minZ));
merges = Allocate (unsigned, numnodes);
UnitOffset (merges);
for (i = 1 ; i <= numnodes ; i++)
merges [i] = 0;
merge_count = 0;
for (i = 1 ; i <= numnodes ; i++) {
for (j = i+1 ; j <= numnodes ; j++) {
if (!merges [j]) {
if (DIST(node[i], node[j]) < tol) {
status = CheckConnections (node[i], node[j], element, numelts);
if (!status) {
merge_count++;
merges [j] = i;
}
}
}
}
}
if (merge_count) {
new_nodes = MergeNodes(node,element,numnodes,numelts,merges,merge_count);
numnodes -= merge_count;
}
else
new_nodes = node;
ZeroOffset (merges);
Deallocate (merges);
*nn = numnodes;
return new_nodes;
}
syntax highlighted by Code2HTML, v. 0.9.1