[cig-commits] r5621 - in long/3D/Gale/trunk/src/StGermain: . Discretisation/Mesh/src Discretisation/Mesh/tests

walter at geodynamics.org walter at geodynamics.org
Fri Dec 22 06:06:33 PST 2006


Author: walter
Date: 2006-12-22 06:06:32 -0800 (Fri, 22 Dec 2006)
New Revision: 5621

Modified:
   long/3D/Gale/trunk/src/StGermain/
   long/3D/Gale/trunk/src/StGermain/Discretisation/Mesh/src/CartesianGenerator.c
   long/3D/Gale/trunk/src/StGermain/Discretisation/Mesh/src/CartesianGenerator.h
   long/3D/Gale/trunk/src/StGermain/Discretisation/Mesh/src/MeshAdaptor.c
   long/3D/Gale/trunk/src/StGermain/Discretisation/Mesh/src/MeshAdaptor.h
   long/3D/Gale/trunk/src/StGermain/Discretisation/Mesh/src/MeshClass.c
   long/3D/Gale/trunk/src/StGermain/Discretisation/Mesh/src/MeshGenerator.c
   long/3D/Gale/trunk/src/StGermain/Discretisation/Mesh/src/MeshGenerator.h
   long/3D/Gale/trunk/src/StGermain/Discretisation/Mesh/src/MeshTopology.c
   long/3D/Gale/trunk/src/StGermain/Discretisation/Mesh/src/Mesh_Algorithms.c
   long/3D/Gale/trunk/src/StGermain/Discretisation/Mesh/src/Mesh_Algorithms.h
   long/3D/Gale/trunk/src/StGermain/Discretisation/Mesh/tests/testCartesianGenerator.c
   long/3D/Gale/trunk/src/StGermain/Discretisation/Mesh/tests/testMesh.c
   long/3D/Gale/trunk/src/StGermain/Discretisation/Mesh/tests/testMeshTopology.c
Log:
 r3209 at earth (orig r3911):  LukeHodkinson | 2006-12-21 17:37:13 -0800
 Adding the capacity to enable/disable various
 mesh incidence relations. We need this to ensure
 we can reduce memory requirements for the mesh
 when desired. Involved modifying how 'point in
 element' search algorithms are chosen.
 



Property changes on: long/3D/Gale/trunk/src/StGermain
___________________________________________________________________
Name: svk:merge
   - 1ef209d2-b310-0410-a72d-e20c9eb0015c:/cig:3196
afb6c753-b9d0-0310-b4e7-dbd8d91cdd35:/branches/decomp3d/StGermain:3910
afb6c753-b9d0-0310-b4e7-dbd8d91cdd35:/trunk/StGermain:3899
   + 1ef209d2-b310-0410-a72d-e20c9eb0015c:/cig:3196
afb6c753-b9d0-0310-b4e7-dbd8d91cdd35:/branches/decomp3d/StGermain:3911
afb6c753-b9d0-0310-b4e7-dbd8d91cdd35:/trunk/StGermain:3899

Modified: long/3D/Gale/trunk/src/StGermain/Discretisation/Mesh/src/CartesianGenerator.c
===================================================================
--- long/3D/Gale/trunk/src/StGermain/Discretisation/Mesh/src/CartesianGenerator.c	2006-12-22 14:06:28 UTC (rev 5620)
+++ long/3D/Gale/trunk/src/StGermain/Discretisation/Mesh/src/CartesianGenerator.c	2006-12-22 14:06:32 UTC (rev 5621)
@@ -74,6 +74,7 @@
 					_CartesianGenerator_Destroy, 
 					name, 
 					NON_GLOBAL, 
+					CartesianGenerator_SetDimSize, 
 					CartesianGenerator_Generate );
 }
 
@@ -93,6 +94,8 @@
 }
 
 void _CartesianGenerator_Init( CartesianGenerator* self ) {
+	assert( self && Stg_CheckType( self, CartesianGenerator ) );
+
 	self->shadowDepth = 1;
 	self->maxDecompDims = 0;
 	self->minDecomp = NULL;
@@ -112,8 +115,8 @@
 ** Virtual functions
 */
 
-void _CartesianGenerator_Delete( void* generator ) {
-	CartesianGenerator*	self = (CartesianGenerator*)generator;
+void _CartesianGenerator_Delete( void* meshGenerator ) {
+	CartesianGenerator*	self = (CartesianGenerator*)meshGenerator;
 
 	CartesianGenerator_Destruct( self );
 
@@ -121,32 +124,33 @@
 	_MeshGenerator_Delete( self );
 }
 
-void _CartesianGenerator_Print( void* generator, Stream* stream ) {
-	CartesianGenerator*	self = (CartesianGenerator*)generator;
+void _CartesianGenerator_Print( void* meshGenerator, Stream* stream ) {
+	CartesianGenerator*	self = (CartesianGenerator*)meshGenerator;
 	
 	/* Set the Journal for printing informations */
-	Stream* generatorStream;
-	generatorStream = Journal_Register( InfoStream_Type, "CartesianGeneratorStream" );
+	Stream* meshGeneratorStream;
+	meshGeneratorStream = Journal_Register( InfoStream_Type, "CartesianGeneratorStream" );
 
+	assert( self && Stg_CheckType( self, CartesianGenerator ) );
+
 	/* Print parent */
 	Journal_Printf( stream, "CartesianGenerator (ptr): (%p)\n", self );
 	_MeshGenerator_Print( self, stream );
 }
 
-void _CartesianGenerator_Construct( void* generator, Stg_ComponentFactory* cf, void* data ) {
-	CartesianGenerator*	self = (CartesianGenerator*)generator;
+void _CartesianGenerator_Construct( void* meshGenerator, Stg_ComponentFactory* cf, void* data ) {
+	CartesianGenerator*	self = (CartesianGenerator*)meshGenerator;
 	Dictionary*		dict;
 	Dictionary_Entry_Value*	tmp;
 	char*			rootKey;
 	Dictionary_Entry_Value*	sizeList;
 	Dictionary_Entry_Value	*minList, *maxList;
-	unsigned		nDims;
 	double			*crdMin, *crdMax;
 	unsigned*		size;
 	unsigned		shadowDepth;
 	unsigned		d_i;
 
-	assert( self );
+	assert( self && Stg_CheckType( self, CartesianGenerator ) );
 	assert( cf );
 
 	/* Call parent construct. */
@@ -155,16 +159,12 @@
 	/* Rip out the components structure as a dictionary. */
 	dict = Dictionary_Entry_Value_AsDictionary( Dictionary_Get( cf->componentDict, self->name ) );
 
-	/* Read the desired number of dimensions. */
-	nDims = Stg_ComponentFactory_GetUnsignedInt( cf, self->name, "dim", 0 );
-	assert( nDims );
-
 	/* Read the sizes. */
 	sizeList = Dictionary_Get( dict, "size" );
 	assert( sizeList );
-	assert( Dictionary_Entry_Value_GetCount( sizeList ) >= nDims );
-	size = Memory_Alloc_Array_Unnamed( unsigned, nDims );
-	for( d_i = 0; d_i < nDims; d_i++ ) {
+	assert( Dictionary_Entry_Value_GetCount( sizeList ) >= self->nDims );
+	size = Memory_Alloc_Array_Unnamed( unsigned, self->nDims );
+	for( d_i = 0; d_i < self->nDims; d_i++ ) {
 		tmp = Dictionary_Entry_Value_GetElement( sizeList, d_i );
 		rootKey = Dictionary_Entry_Value_AsString( tmp );
 
@@ -174,17 +174,17 @@
 	}
 
 	/* Initial setup. */
-	CartesianGenerator_SetTopologyParams( self, nDims, size, 0, NULL, NULL );
+	CartesianGenerator_SetTopologyParams( self, size, 0, NULL, NULL );
 
 	/* Read geometry. */
 	minList = Dictionary_Get( dict, "minCoord" );
 	maxList = Dictionary_Get( dict, "maxCoord" );
 	if( minList && maxList ) {
-		assert( Dictionary_Entry_Value_GetCount( minList ) >= nDims );
-		assert( Dictionary_Entry_Value_GetCount( maxList ) >= nDims );
-		crdMin = Memory_Alloc_Array_Unnamed( double, nDims );
-		crdMax = Memory_Alloc_Array_Unnamed( double, nDims );
-		for( d_i = 0; d_i < nDims; d_i++ ) {
+		assert( Dictionary_Entry_Value_GetCount( minList ) >= self->nDims );
+		assert( Dictionary_Entry_Value_GetCount( maxList ) >= self->nDims );
+		crdMin = Memory_Alloc_Array_Unnamed( double, self->nDims );
+		crdMax = Memory_Alloc_Array_Unnamed( double, self->nDims );
+		for( d_i = 0; d_i < self->nDims; d_i++ ) {
 			tmp = Dictionary_Entry_Value_GetElement( minList, d_i );
 			rootKey = Dictionary_Entry_Value_AsString( tmp );
 
@@ -219,76 +219,79 @@
 	FreeArray( size );
 }
 
-void _CartesianGenerator_Build( void* generator, void* data ) {
-	_MeshGenerator_Build( generator, data );
+void _CartesianGenerator_Build( void* meshGenerator, void* data ) {
+	_MeshGenerator_Build( meshGenerator, data );
 }
 
-void _CartesianGenerator_Initialise( void* generator, void* data ) {
+void _CartesianGenerator_Initialise( void* meshGenerator, void* data ) {
 }
 
-void _CartesianGenerator_Execute( void* generator, void* data ) {
+void _CartesianGenerator_Execute( void* meshGenerator, void* data ) {
 }
 
-void _CartesianGenerator_Destroy( void* generator, void* data ) {
+void _CartesianGenerator_Destroy( void* meshGenerator, void* data ) {
 }
 
+void CartesianGenerator_SetDimSize( void* meshGenerator, unsigned nDims ) {
+	CartesianGenerator*	self = (CartesianGenerator*)meshGenerator;
+
+	assert( self && Stg_CheckType( self, CartesianGenerator ) );
+
+	_MeshGenerator_SetDimSize( self, nDims );
+
+	self->minDecomp = AllocArray( unsigned, self->nDims );
+	memset( self->minDecomp, 0, nDims * sizeof(unsigned) );
+	self->maxDecomp = AllocArray( unsigned, self->nDims );
+	memset( self->maxDecomp, 0, nDims * sizeof(unsigned) );
+}
+
 /*--------------------------------------------------------------------------------------------------------------------------
 ** Public Functions
 */
 
-void CartesianGenerator_SetTopologyParams( void* generator, unsigned nDims, unsigned* sizes, 
+void CartesianGenerator_SetTopologyParams( void* meshGenerator, unsigned* sizes, 
 					   unsigned maxDecompDims, unsigned* minDecomp, unsigned* maxDecomp )
 {
-	CartesianGenerator*	self = (CartesianGenerator*)generator;
+	CartesianGenerator*	self = (CartesianGenerator*)meshGenerator;
 	unsigned		d_i;
 
 	/* Sanity check. */
-	assert( self );
-	assert( !nDims || sizes );
-	assert( nDims <= 3 );
+	assert( self && Stg_CheckType( self, CartesianGenerator ) );
+	assert( !self->nDims || sizes );
+	assert( self->nDims <= 3 );
 
 	/* Kill everything we have, topologically. */
 	CartesianGenerator_DestructTopology( self );
 
 	/* Don't continue if we have nothing. */
-	if( !nDims )
+	if( !self->nDims )
 		return;
 
 	/* Set the parameters. */
 	self->elGrid = Grid_New();
-	Grid_SetNDims( self->elGrid, nDims );
+	Grid_SetNDims( self->elGrid, self->nDims );
 	Grid_SetSizes( self->elGrid, sizes );
 
 	self->vertGrid = Grid_New();
-	Grid_SetNDims( self->vertGrid, nDims );
-	for( d_i = 0; d_i < nDims; d_i++ )
+	Grid_SetNDims( self->vertGrid, self->nDims );
+	for( d_i = 0; d_i < self->nDims; d_i++ )
 		sizes[d_i]++;
 	Grid_SetSizes( self->vertGrid, sizes );
-	for( d_i = 0; d_i < nDims; d_i++ )
+	for( d_i = 0; d_i < self->nDims; d_i++ )
 		sizes[d_i]--;
 
-	/* Allocate and set restrictions. */
-	self->minDecomp = Memory_Alloc_Array( unsigned, nDims, "CartesianGenerator::minDecomp" );
-	self->maxDecomp = Memory_Alloc_Array( unsigned, nDims, "CartesianGenerator::maxDecomp" );
-
 	if( minDecomp )
-		memcpy( self->minDecomp, minDecomp, nDims * sizeof(unsigned) );
-	else
-		memset( self->minDecomp, 0, nDims * sizeof(unsigned) );
-
+		memcpy( self->minDecomp, minDecomp, self->nDims * sizeof(unsigned) );
 	if( maxDecomp )
-		memcpy( self->maxDecomp, maxDecomp, nDims * sizeof(unsigned) );
-	else
-		memset( self->maxDecomp, 0, nDims * sizeof(unsigned) );
-
+		memcpy( self->maxDecomp, maxDecomp, self->nDims * sizeof(unsigned) );
 	self->maxDecompDims = maxDecompDims;
 
 	/* As soon as we know the topology, we can decompose. */
 	CartesianGenerator_BuildDecomp( self );
 }
 
-void CartesianGenerator_SetGeometryParams( void* generator, double* min, double* max ) {
-	CartesianGenerator*	self = (CartesianGenerator*)generator;
+void CartesianGenerator_SetGeometryParams( void* meshGenerator, double* min, double* max ) {
+	CartesianGenerator*	self = (CartesianGenerator*)meshGenerator;
 
 	/* Sanity check. */
 	assert( self );
@@ -307,8 +310,8 @@
 	}
 }
 
-void CartesianGenerator_SetShadowDepth( void* generator, unsigned depth ) {
-	CartesianGenerator*	self = (CartesianGenerator*)generator;
+void CartesianGenerator_SetShadowDepth( void* meshGenerator, unsigned depth ) {
+	CartesianGenerator*	self = (CartesianGenerator*)meshGenerator;
 
 	/* Sanity check. */
 	assert( self );
@@ -316,8 +319,8 @@
 	self->shadowDepth = depth;
 }
 
-void CartesianGenerator_Generate( void* generator, void* _mesh ) {
-	CartesianGenerator*	self = (CartesianGenerator*)generator;
+void CartesianGenerator_Generate( void* meshGenerator, void* _mesh ) {
+	CartesianGenerator*	self = (CartesianGenerator*)meshGenerator;
 	Mesh*			mesh = (Mesh*)_mesh;
 	Grid**			grid;
 	unsigned		*localRange, *localOrigin;
@@ -531,7 +534,7 @@
 void CartesianGenerator_GenTopo( CartesianGenerator* self, MeshTopology* topo ) {
 	Grid***		grids;
 	CommTopology*	commTopo;
-	unsigned	d_i;
+	unsigned	d_i, d_j;
 
 	assert( self );
 	assert( topo );
@@ -600,21 +603,35 @@
 	}
 
 	/* Generate topological elements. */
-	CartesianGenerator_GenVertices( self, topo, grids );
-	CartesianGenerator_GenElements( self, topo, grids );
+	if( self->enabledDims[0] )
+		CartesianGenerator_GenVertices( self, topo, grids );
+	if( self->enabledDims[self->nDims] )
+		CartesianGenerator_GenElements( self, topo, grids );
 	if( topo->nDims >= 2 ) {
-		CartesianGenerator_GenEdges( self, topo, grids );
-		if( topo->nDims >= 3 )
-			CartesianGenerator_GenFaces( self, topo, grids );
+		if( self->enabledDims[1] )
+			CartesianGenerator_GenEdges( self, topo, grids );
+		if( topo->nDims >= 3 ) {
+			if( self->enabledDims[2] )
+				CartesianGenerator_GenFaces( self, topo, grids );
+		}
 	}
 
 	/* Generate topological incidence. */
-	CartesianGenerator_GenElementVertexInc( self, topo, grids );
+	if( self->enabledInc[self->nDims][0] )
+		CartesianGenerator_GenElementVertexInc( self, topo, grids );
 	if( topo->nDims >= 2 ) {
-		CartesianGenerator_GenEdgeVertexInc( self, topo, grids );
-		CartesianGenerator_GenFaceEdgeInc( self, topo, grids );
-		if( topo->nDims >= 3 )
-			CartesianGenerator_GenVolumeFaceInc( self, topo, grids );
+		if( self->enabledInc[2][1] )
+			CartesianGenerator_GenFaceEdgeInc( self, topo, grids );
+		if( self->enabledInc[1][0] )
+			CartesianGenerator_GenEdgeVertexInc( self, topo, grids );
+		if( topo->nDims >= 3 ) {
+			if( self->enabledInc[2][0] )
+				CartesianGenerator_GenFaceVertexInc( self, topo, grids );
+			if( self->enabledInc[3][1] )
+				CartesianGenerator_GenVolumeEdgeInc( self, topo, grids );
+			if( self->enabledInc[3][2] )
+				CartesianGenerator_GenVolumeFaceInc( self, topo, grids );
+		}
 	}
 
 	/* Set the shadow depth and correct incidence. */
@@ -624,6 +641,7 @@
 		MeshTopology_Invert( topo, MT_VERTEX, topo->nDims );
 		MeshTopology_Neighbourhood( topo, topo->nDims );
 
+		/* Set the shadow depth. */
 		MeshTopology_SetShadowDepth( topo, self->shadowDepth );
 
 		/* Kill up relations and neighbours. */
@@ -633,9 +651,19 @@
 		KillArray2D( topo->domains[MT_VERTEX]->nDomains, topo->incEls[MT_VERTEX][topo->nDims] );
 	}
 
-	/* Complete all relations. */
-	MeshTopology_Complete( topo );
+	/* Complete all required relations. */
+	for( d_i = 0; d_i < self->nDims; d_i++ ) {
+		for( d_j = d_i + 1; d_j <= self->nDims; d_j++ ) {
+			if( !self->enabledInc[d_i][d_j] )
+				continue;
 
+			MeshTopology_Invert( topo, d_i, d_j );
+		}
+
+		if( self->enabledInc[d_i][d_i] )
+			MeshTopology_Neighbourhood( topo, d_i );
+	}
+
 	/* Free allocated grids. */
 	grids[topo->nDims][0] = NULL;
 	for( d_i = 0; d_i < topo->nDims; d_i++ ) {
@@ -1111,6 +1139,75 @@
 	FreeArray( dimInds );
 }
 
+void CartesianGenerator_GenVolumeEdgeInc( CartesianGenerator* self, MeshTopology* topo, Grid*** grids ) {
+	unsigned*	nIncEls;
+	unsigned**	incEls;
+	unsigned*	dimInds;
+	unsigned	e_i;
+
+	assert( self );
+	assert( topo );
+	assert( grids );
+	assert( topo->nDims >= 3 );
+
+	nIncEls = Memory_Alloc_Array_Unnamed( unsigned, topo->domains[topo->nDims]->nDomains );
+	incEls = Memory_Alloc_2DArray_Unnamed( unsigned, topo->domains[topo->nDims]->nDomains, 12 );
+	dimInds = Memory_Alloc_Array_Unnamed( unsigned, topo->nDims );
+	for( e_i = 0; e_i < topo->domains[MT_VOLUME]->nDomains; e_i++ ) {
+		unsigned	gInd = Decomp_Sync_DomainToGlobal( topo->domains[MT_VOLUME], e_i );
+
+		nIncEls[e_i] = 12;
+		Grid_Lift( grids[topo->nDims][0], gInd, dimInds );
+
+		incEls[e_i][0] = Grid_Project( grids[1][0], dimInds );
+
+		dimInds[1]++;
+		incEls[e_i][1] = Grid_Project( grids[1][0], dimInds );
+		dimInds[1]--;
+
+		incEls[e_i][2] = Grid_Project( grids[1][1], dimInds ) + grids[1][0]->nPoints;
+
+		dimInds[0]++;
+		incEls[e_i][3] = Grid_Project( grids[1][1], dimInds ) + grids[1][0]->nPoints;
+		dimInds[0]--;
+
+		dimInds[2]++;
+		incEls[e_i][4] = Grid_Project( grids[1][0], dimInds );
+
+		dimInds[1]++;
+		incEls[e_i][5] = Grid_Project( grids[1][0], dimInds );
+		dimInds[1]--;
+
+		incEls[e_i][6] = Grid_Project( grids[1][1], dimInds ) + grids[1][0]->nPoints;
+
+		dimInds[0]++;
+		incEls[e_i][7] = Grid_Project( grids[1][1], dimInds ) + grids[1][0]->nPoints;
+		dimInds[0]--;
+		dimInds[2]--;
+
+		incEls[e_i][8] = Grid_Project( grids[1][2], dimInds ) + grids[1][0]->nPoints + grids[1][1]->nPoints;
+
+		dimInds[0]++;
+		incEls[e_i][9] = Grid_Project( grids[1][2], dimInds ) + grids[1][0]->nPoints + grids[1][1]->nPoints;
+		dimInds[0]--;
+
+		dimInds[1]++;
+		incEls[e_i][10] = Grid_Project( grids[1][2], dimInds ) + grids[1][0]->nPoints + grids[1][1]->nPoints;
+
+		dimInds[0]++;
+		incEls[e_i][11] = Grid_Project( grids[1][2], dimInds ) + grids[1][0]->nPoints + grids[1][1]->nPoints;
+		dimInds[0]--;
+		dimInds[1]--;
+	}
+
+	CartesianGenerator_MapToDomain( self, topo->domains[MT_EDGE], topo->domains[MT_VOLUME]->nDomains, 
+					nIncEls, incEls );
+	MeshTopology_SetIncidence( topo, MT_VOLUME, MT_EDGE, nIncEls, incEls );
+	FreeArray( nIncEls );
+	FreeArray( incEls );
+	FreeArray( dimInds );
+}
+
 void CartesianGenerator_GenVolumeFaceInc( CartesianGenerator* self, MeshTopology* topo, Grid*** grids ) {
 	unsigned*	nIncEls;
 	unsigned**	incEls;
@@ -1158,6 +1255,91 @@
 	FreeArray( dimInds );
 }
 
+void CartesianGenerator_GenFaceVertexInc( CartesianGenerator* self, MeshTopology* topo, Grid*** grids ) {
+	unsigned*	nIncEls;
+	unsigned**	incEls;
+	unsigned*	dimInds;
+	unsigned	e_i;
+
+	assert( self );
+	assert( topo );
+	assert( grids );
+	assert( topo->nDims >= 2 );
+
+	nIncEls = Memory_Alloc_Array_Unnamed( unsigned, topo->domains[MT_FACE]->nDomains );
+	incEls = Memory_Alloc_2DArray_Unnamed( unsigned, topo->domains[MT_FACE]->nDomains, 4 );
+	dimInds = Memory_Alloc_Array_Unnamed( unsigned, topo->nDims );
+	for( e_i = 0; e_i < topo->domains[MT_FACE]->nDomains; e_i++ ) {
+		unsigned	gInd = Decomp_Sync_DomainToGlobal( topo->domains[MT_FACE], e_i );
+
+		nIncEls[e_i] = 4;
+
+		if( gInd < grids[2][0]->nPoints ) {
+			Grid_Lift( grids[2][0], gInd, dimInds );
+
+			incEls[e_i][0] = Grid_Project( grids[0][0], dimInds );
+
+			dimInds[0]++;
+			incEls[e_i][1] = Grid_Project( grids[0][0], dimInds );
+			dimInds[0]--;
+
+			dimInds[1]++;
+			incEls[e_i][2] = Grid_Project( grids[0][0], dimInds );
+
+			dimInds[0]++;
+			incEls[e_i][3] = Grid_Project( grids[0][0], dimInds );
+			dimInds[0]--;
+			dimInds[1]--;
+		}
+		else if( gInd < grids[2][0]->nPoints + grids[2][1]->nPoints ) {
+			assert( topo->nDims >= 3 );
+
+			Grid_Lift( grids[2][1], gInd - grids[2][0]->nPoints, dimInds );
+
+			incEls[e_i][0] = Grid_Project( grids[0][0], dimInds );
+
+			dimInds[0]++;
+			incEls[e_i][1] = Grid_Project( grids[0][0], dimInds );
+			dimInds[0]--;
+
+			dimInds[2]++;
+			incEls[e_i][2] = Grid_Project( grids[0][0], dimInds );
+
+			dimInds[0]++;
+			incEls[e_i][3] = Grid_Project( grids[0][0], dimInds );
+			dimInds[0]--;
+			dimInds[2]--;
+		}
+		else {
+			assert( gInd < grids[2][0]->nPoints + grids[2][1]->nPoints + grids[2][2]->nPoints );
+			assert( topo->nDims >= 3 );
+
+			Grid_Lift( grids[2][2], gInd - grids[2][0]->nPoints - grids[2][1]->nPoints, dimInds );
+
+			incEls[e_i][0] = Grid_Project( grids[0][0], dimInds );
+
+			dimInds[1]++;
+			incEls[e_i][1] = Grid_Project( grids[0][0], dimInds );
+			dimInds[1]--;
+
+			dimInds[2]++;
+			incEls[e_i][2] = Grid_Project( grids[0][0], dimInds );
+
+			dimInds[1]++;
+			incEls[e_i][3] = Grid_Project( grids[0][0], dimInds );
+			dimInds[1]--;
+			dimInds[2]--;
+		}
+	}
+
+	CartesianGenerator_MapToDomain( self, topo->domains[MT_VERTEX], topo->domains[MT_FACE]->nDomains, 
+					nIncEls, incEls );
+	MeshTopology_SetIncidence( topo, MT_FACE, MT_VERTEX, nIncEls, incEls );
+	FreeArray( nIncEls );
+	FreeArray( incEls );
+	FreeArray( dimInds );
+}
+
 void CartesianGenerator_GenFaceEdgeInc( CartesianGenerator* self, MeshTopology* topo, Grid*** grids ) {
 	unsigned*	nIncEls;
 	unsigned**	incEls;
@@ -1392,8 +1574,8 @@
 	assert( self );
 
 	self->maxDecompDims = 0;
-	KillArray( self->minDecomp );
-	KillArray( self->maxDecomp );
+	memset( self->minDecomp, 0, self->nDims * sizeof(unsigned) );
+	memset( self->maxDecomp, 0, self->nDims * sizeof(unsigned) );
 	KillObject( self->vertGrid );
 	KillObject( self->elGrid );
 	KillObject( self->procGrid );

Modified: long/3D/Gale/trunk/src/StGermain/Discretisation/Mesh/src/CartesianGenerator.h
===================================================================
--- long/3D/Gale/trunk/src/StGermain/Discretisation/Mesh/src/CartesianGenerator.h	2006-12-22 14:06:28 UTC (rev 5620)
+++ long/3D/Gale/trunk/src/StGermain/Discretisation/Mesh/src/CartesianGenerator.h	2006-12-22 14:06:32 UTC (rev 5621)
@@ -88,24 +88,25 @@
 	** Virtual functions
 	*/
 
-	void _CartesianGenerator_Delete( void* generator );
-	void _CartesianGenerator_Print( void* generator, Stream* stream );
-	void _CartesianGenerator_Construct( void* generator, Stg_ComponentFactory* cf, void* data );
-	void _CartesianGenerator_Build( void* generator, void* data );
-	void _CartesianGenerator_Initialise( void* generator, void* data );
-	void _CartesianGenerator_Execute( void* generator, void* data );
-	void _CartesianGenerator_Destroy( void* generator, void* data );
+	void _CartesianGenerator_Delete( void* meshGenerator );
+	void _CartesianGenerator_Print( void* meshGenerator, Stream* stream );
+	void _CartesianGenerator_Construct( void* meshGenerator, Stg_ComponentFactory* cf, void* data );
+	void _CartesianGenerator_Build( void* meshGenerator, void* data );
+	void _CartesianGenerator_Initialise( void* meshGenerator, void* data );
+	void _CartesianGenerator_Execute( void* meshGenerator, void* data );
+	void _CartesianGenerator_Destroy( void* meshGenerator, void* data );
 
-	void CartesianGenerator_Generate( void* generator, void* _mesh );
+	void CartesianGenerator_SetDimSize( void* meshGenerator, unsigned nDims );
+	void CartesianGenerator_Generate( void* meshGenerator, void* mesh );
 
 	/*--------------------------------------------------------------------------------------------------------------------------
 	** Public functions
 	*/
 
-	void CartesianGenerator_SetTopologyParams( void* generator, unsigned nDims, unsigned* sizes, 
+	void CartesianGenerator_SetTopologyParams( void* meshGenerator, unsigned* sizes, 
 						   unsigned maxDecompDims, unsigned* minDecomp, unsigned* maxDecomp );
-	void CartesianGenerator_SetGeometryParams( void* generator, double* min, double* max );
-	void CartesianGenerator_SetShadowDepth( void* generator, unsigned depth );
+	void CartesianGenerator_SetGeometryParams( void* meshGenerator, double* min, double* max );
+	void CartesianGenerator_SetShadowDepth( void* meshGenerator, unsigned depth );
 
 	/*--------------------------------------------------------------------------------------------------------------------------
 	** Private Member functions
@@ -124,7 +125,9 @@
 	void CartesianGenerator_GenEdges3D( CartesianGenerator* self, MeshTopology* topo, Grid*** grids );
 	void CartesianGenerator_GenFaces( CartesianGenerator* self, MeshTopology* topo, Grid*** grids );
 	void CartesianGenerator_GenElementVertexInc( CartesianGenerator* self, MeshTopology* topo, Grid*** grids );
+	void CartesianGenerator_GenVolumeEdgeInc( CartesianGenerator* self, MeshTopology* topo, Grid*** grids );
 	void CartesianGenerator_GenVolumeFaceInc( CartesianGenerator* self, MeshTopology* topo, Grid*** grids );
+	void CartesianGenerator_GenFaceVertexInc( CartesianGenerator* self, MeshTopology* topo, Grid*** grids );
 	void CartesianGenerator_GenFaceEdgeInc( CartesianGenerator* self, MeshTopology* topo, Grid*** grids );
 	void CartesianGenerator_GenEdgeVertexInc( CartesianGenerator* self, MeshTopology* topo, Grid*** grids );
 	void CartesianGenerator_MapToDomain( CartesianGenerator* self, Decomp_Sync* sync, 

Modified: long/3D/Gale/trunk/src/StGermain/Discretisation/Mesh/src/MeshAdaptor.c
===================================================================
--- long/3D/Gale/trunk/src/StGermain/Discretisation/Mesh/src/MeshAdaptor.c	2006-12-22 14:06:28 UTC (rev 5620)
+++ long/3D/Gale/trunk/src/StGermain/Discretisation/Mesh/src/MeshAdaptor.c	2006-12-22 14:06:32 UTC (rev 5621)
@@ -61,7 +61,7 @@
 	
 	/* Allocate memory */
 	assert( sizeOfSelf >= sizeof(MeshAdaptor) );
-	self = (MeshAdaptor*)_MeshGenerator_New( MESHGENERATOR_PASSARGS );
+	self = (MeshAdaptor*)_MeshGenerator_New( STG_COMPONENT_PASSARGS, NULL, generateFunc );
 
 	/* Virtual info */
 

Modified: long/3D/Gale/trunk/src/StGermain/Discretisation/Mesh/src/MeshAdaptor.h
===================================================================
--- long/3D/Gale/trunk/src/StGermain/Discretisation/Mesh/src/MeshAdaptor.h	2006-12-22 14:06:28 UTC (rev 5620)
+++ long/3D/Gale/trunk/src/StGermain/Discretisation/Mesh/src/MeshAdaptor.h	2006-12-22 14:06:32 UTC (rev 5621)
@@ -64,10 +64,13 @@
 	*/
 
 	#define MESHADAPTOR_DEFARGS	\
-		MESHGENERATOR_DEFARGS
+		STG_COMPONENT_DEFARGS,				\
+		MeshGenerator_GenerateFunc*	generateFunc
 
-	#define MESHADAPTOR_PASSARGS	\
-		MESHGENERATOR_PASSARGS
+	#define MESHADAPTOR_PASSARGS		\
+		STG_COMPONENT_PASSARGS,		\
+		NULL,				\
+		generateFunc
 
 	MeshAdaptor* _MeshAdaptor_New( MESHADAPTOR_DEFARGS );
 	void _MeshAdaptor_Init( MeshAdaptor* self );

Modified: long/3D/Gale/trunk/src/StGermain/Discretisation/Mesh/src/MeshClass.c
===================================================================
--- long/3D/Gale/trunk/src/StGermain/Discretisation/Mesh/src/MeshClass.c	2006-12-22 14:06:28 UTC (rev 5620)
+++ long/3D/Gale/trunk/src/StGermain/Discretisation/Mesh/src/MeshClass.c	2006-12-22 14:06:32 UTC (rev 5621)
@@ -154,6 +154,7 @@
 		return;
 
 	MeshGenerator_Generate( self->generator, self );
+	Mesh_Algorithms_SetMesh( self->algorithms, self );
 
 	nDims = Mesh_GetDimSize( self );
 	if( !nDims )
@@ -421,60 +422,12 @@
 	MeshTopology_GetIncidence( self->topo, fromDim, fromInd, toDim, nInc, inc );
 }
 
-#define Vec_Sep( nDims, v0, v1 )		    				\
-	(((v0)[0] - (v1)[0]) * ((v0)[0] - (v1)[0]) + 				\
-	((v0)[1] - (v1)[1]) * ((v0)[1] - (v1)[1]) + 				\
-	(((nDims) == 3) ? (((v0)[2] - (v1)[2]) * ((v0)[2] - (v1)[2])) : 0))
-
 unsigned Mesh_NearestVertex( void* mesh, double* point ) {
-	Mesh*		self = (Mesh*)mesh;
-	unsigned	nDims;
-	unsigned	curVert;
-	double		sep;
-	Bool		done;
+	Mesh*	self = (Mesh*)mesh;
 
 	assert( self );
-	assert( Mesh_HasIncidence( self, MT_VERTEX, MT_VERTEX ) );
 
-	/* Get dimensionality. */
-	nDims = Mesh_GetDimSize( self );
-
-	/* Begin somewhere in the middle. */
-	curVert = Mesh_GetDomainSize( self, MT_VERTEX ) / 2;
-
-	/* Calc distance squared to current node. */
-	sep = Vec_Sep( nDims, Mesh_GetVertex( self, curVert ), point );
-
-	/* Loop until we've found closest local node. */
-	do {
-		unsigned	nNbrs;
-		unsigned*	nbrs;
-		unsigned	nbr_i;
-
-		/* Get neighbouring vertices. */
-		Mesh_GetIncidence( self, MT_VERTEX, curVert, MT_VERTEX, &nNbrs, &nbrs );
-
-		/* Assume we'll be done after this loop. */
-		done = True;
-
-		/* Compare to neighbours. */
-		for( nbr_i = 0; nbr_i < nNbrs; nbr_i++ ) {
-			double	nbrSep;
-
-			/* Calculate neighbour separation. */
-			nbrSep = Vec_Sep( nDims, Mesh_GetVertex( self, nbrs[nbr_i] ), point );
-
-			/* Closer? */
-			if( nbrSep < sep ) {
-				curVert = nbrs[nbr_i];
-				sep = nbrSep;
-				done = False;
-			}
-		}
-	}
-	while( !done );
-
-	return curVert;
+	return Mesh_Algorithms_NearestVertex( self->algorithms, point );
 }
 
 Bool Mesh_Search( void* mesh, double* point, 
@@ -484,7 +437,7 @@
 
 	assert( self );
 
-	return Mesh_Algorithms_Search( self->algorithms, self, point, dim, ind );
+	return Mesh_Algorithms_Search( self->algorithms, point, dim, ind );
 }
 
 Bool Mesh_ElementHasPoint( void* mesh, unsigned element, double* point, 
@@ -589,10 +542,12 @@
 
 	assert( self );
 
-	self->minSep = Mesh_Algorithms_GetMinimumSeparation( self->algorithms, self, self->minAxialSep );
-	Mesh_Algorithms_GetLocalCoordRange( self->algorithms, self, self->minLocalCrd, self->maxLocalCrd );
-	Mesh_Algorithms_GetDomainCoordRange( self->algorithms, self, self->minDomainCrd, self->maxDomainCrd );
-	Mesh_Algorithms_GetGlobalCoordRange( self->algorithms, self, self->minGlobalCrd, self->maxGlobalCrd );
+	Mesh_Algorithms_Update( self->algorithms );
+
+	self->minSep = Mesh_Algorithms_GetMinimumSeparation( self->algorithms, self->minAxialSep );
+	Mesh_Algorithms_GetLocalCoordRange( self->algorithms, self->minLocalCrd, self->maxLocalCrd );
+	Mesh_Algorithms_GetDomainCoordRange( self->algorithms, self->minDomainCrd, self->maxDomainCrd );
+	Mesh_Algorithms_GetGlobalCoordRange( self->algorithms, self->minGlobalCrd, self->maxGlobalCrd );
 }
 
 void Mesh_Sync( void* mesh ) {

Modified: long/3D/Gale/trunk/src/StGermain/Discretisation/Mesh/src/MeshGenerator.c
===================================================================
--- long/3D/Gale/trunk/src/StGermain/Discretisation/Mesh/src/MeshGenerator.c	2006-12-22 14:06:28 UTC (rev 5620)
+++ long/3D/Gale/trunk/src/StGermain/Discretisation/Mesh/src/MeshGenerator.c	2006-12-22 14:06:32 UTC (rev 5621)
@@ -55,13 +55,14 @@
 */
 
 MeshGenerator* _MeshGenerator_New( MESHGENERATOR_DEFARGS ) {
-	MeshGenerator* self;
-	
+	MeshGenerator*	self;
+
 	/* Allocate memory */
 	assert( sizeOfSelf >= sizeof(MeshGenerator) );
 	self = (MeshGenerator*)_Stg_Component_New( STG_COMPONENT_PASSARGS );
 
 	/* Virtual info */
+	self->setDimSizeFunc = setDimSizeFunc;
 	self->generateFunc = generateFunc;
 
 	/* MeshGenerator info */
@@ -74,6 +75,9 @@
 	self->comm = MPI_COMM_WORLD;
 	self->nMeshes = 0;
 	self->meshes = NULL;
+	self->nDims = 0;
+	self->enabledDims = NULL;
+	self->enabledInc = NULL;
 }
 
 
@@ -84,7 +88,7 @@
 void _MeshGenerator_Delete( void* meshGenerator ) {
 	MeshGenerator*	self = (MeshGenerator*)meshGenerator;
 
-	FreeArray( self->meshes );
+	MeshGenerator_Destruct( self );
 
 	/* Delete the parent. */
 	_Stg_Component_Delete( self );
@@ -105,7 +109,9 @@
 void _MeshGenerator_Construct( void* meshGenerator, Stg_ComponentFactory* cf, void* data ) {
 	MeshGenerator*		self = (MeshGenerator*)meshGenerator;
 	Dictionary*		dict;
+	unsigned		nDims;
 	Dictionary_Entry_Value*	meshList;
+	Dictionary_Entry_Value	*enabledDimsList, *enabledIncList;
 	Mesh*			mesh;
 
 	assert( self );
@@ -139,6 +145,40 @@
 		}
 	}
 
+	/* Read dimensions and state. */
+	nDims = Stg_ComponentFactory_GetUnsignedInt( cf, self->name, "dims", 2 );
+	MeshGenerator_SetDimSize( self, nDims );
+	enabledDimsList = Dictionary_Get( dict, "enabledDims" );
+	enabledIncList = Dictionary_Get( dict, "enabledIncidence" );
+	if( enabledDimsList || enabledIncList ) {
+		memset( self->enabledDims, 0, nDims * sizeof(Bool) );
+		memset( self->enabledInc, 0, nDims * nDims * sizeof(Bool) );
+	}
+	if( enabledDimsList ) {
+		unsigned	nEnabledDims;
+		unsigned	dim;
+		unsigned	d_i;
+
+		nEnabledDims = Dictionary_Entry_Value_GetCount( enabledDimsList );
+		for( d_i = 0; d_i < nEnabledDims; d_i++ ) {
+			dim = Dictionary_Entry_Value_AsUnsignedInt( Dictionary_Entry_Value_GetElement( enabledDimsList, d_i ) );
+			MeshGenerator_SetDimState( self, dim, True );
+		}
+	}
+	if( enabledIncList ) {
+		unsigned	nEnabledInc;
+		unsigned	fromDim, toDim;
+		unsigned	d_i;
+
+		nEnabledInc = Dictionary_Entry_Value_GetCount( enabledIncList );
+		assert( nEnabledInc % 2 == 0 );
+		for( d_i = 0; d_i < nEnabledInc; d_i += 2 ) {
+			fromDim = Dictionary_Entry_Value_AsUnsignedInt( Dictionary_Entry_Value_GetElement( enabledDimsList, d_i ) );
+			toDim = Dictionary_Entry_Value_AsUnsignedInt( Dictionary_Entry_Value_GetElement( enabledDimsList, d_i + 1 ) );
+			MeshGenerator_SetIncidenceState( self, fromDim, toDim, True );
+		}
+	}
+
 	/* Add to live component register. */
 	LiveComponentRegister_Add( cf->LCRegister, (Stg_Component*)self );
 }
@@ -155,6 +195,22 @@
 void _MeshGenerator_Destroy( void* meshGenerator, void* data ) {
 }
 
+void _MeshGenerator_SetDimSize( void* meshGenerator, unsigned nDims ) {
+	MeshGenerator*	self = (MeshGenerator*)meshGenerator;
+	unsigned	d_i, d_j;
+
+	assert( self && Stg_CheckType( self, MeshGenerator ) );
+
+	self->nDims = nDims;
+	self->enabledDims = ReallocArray( self->enabledDims, Bool, nDims + 1 );
+	self->enabledInc = ReallocArray2D( self->enabledInc, Bool, nDims + 1, nDims + 1 );
+	for( d_i = 0; d_i <= nDims; d_i++ ) {
+		self->enabledDims[d_i] = True;
+		for( d_j = 0; d_j <= nDims; d_j++ )
+			self->enabledInc[d_i][d_j] = True;
+	}
+}
+
 /*--------------------------------------------------------------------------------------------------------------------------
 ** Public Functions
 */
@@ -191,6 +247,37 @@
 	((Mesh*)mesh)->generator = self;
 }
 
+void MeshGenerator_SetDimState( void* meshGenerator, unsigned dim, Bool state ) {
+	MeshGenerator*	self = (MeshGenerator*)meshGenerator;
+
+	assert( self && Stg_CheckType( self, MeshGenerator ) );
+	assert( dim <= self->nDims );
+	assert( self->enabledDims );
+
+	self->enabledDims[dim] = state;
+}
+
+void MeshGenerator_SetIncidenceState( void* meshGenerator, unsigned fromDim, unsigned toDim, Bool state ) {
+	MeshGenerator*	self = (MeshGenerator*)meshGenerator;
+
+	assert( self && Stg_CheckType( self, MeshGenerator ) );
+	assert( fromDim <= self->nDims );
+	assert( toDim <= self->nDims );
+	assert( self->enabledInc );
+
+	self->enabledInc[fromDim][toDim] = state;
+}
+
 /*----------------------------------------------------------------------------------------------------------------------------------
 ** Private Functions
 */
+
+void MeshGenerator_Destruct( MeshGenerator* self ) {
+	assert( self && Stg_CheckType( self, MeshGenerator ) );
+
+	KillArray( self->enabledDims );
+	KillArray( self->enabledInc );
+	KillArray( self->meshes );
+	self->nMeshes = 0;
+	self->nDims = 0;
+}

Modified: long/3D/Gale/trunk/src/StGermain/Discretisation/Mesh/src/MeshGenerator.h
===================================================================
--- long/3D/Gale/trunk/src/StGermain/Discretisation/Mesh/src/MeshGenerator.h	2006-12-22 14:06:28 UTC (rev 5620)
+++ long/3D/Gale/trunk/src/StGermain/Discretisation/Mesh/src/MeshGenerator.h	2006-12-22 14:06:32 UTC (rev 5621)
@@ -45,6 +45,7 @@
 	extern const Type MeshGenerator_Type;
 
 	/** Virtual function types */
+	typedef void (MeshGenerator_SetDimSizeFunc)( void* meshGenerator, unsigned nDims );
 	typedef void (MeshGenerator_GenerateFunc)( void* meshGenerator, void* _mesh );
 
 	/** MeshGenerator class contents */
@@ -53,12 +54,17 @@
 		__Stg_Component					\
 								\
 		/* Virtual info */				\
+		MeshGenerator_SetDimSizeFunc*	setDimSizeFunc;	\
 		MeshGenerator_GenerateFunc*	generateFunc;	\
 								\
 		/* MeshGenerator info */			\
-		MPI_Comm			comm;		\
-		unsigned			nMeshes;	\
-		Mesh**				meshes;
+		MPI_Comm		comm;			\
+		unsigned		nMeshes;		\
+		Mesh**			meshes;			\
+								\
+		unsigned		nDims;			\
+		Bool*			enabledDims;		\
+		Bool**			enabledInc;
 
 	struct MeshGenerator { __MeshGenerator };
 
@@ -68,10 +74,13 @@
 
 	#define MESHGENERATOR_DEFARGS				\
 		STG_COMPONENT_DEFARGS,				\
+		MeshGenerator_SetDimSizeFunc*	setDimSizeFunc,	\
 		MeshGenerator_GenerateFunc*	generateFunc
 
-	#define MESHGENERATOR_PASSARGS			\
-		STG_COMPONENT_PASSARGS, generateFunc
+	#define MESHGENERATOR_PASSARGS		\
+		STG_COMPONENT_PASSARGS,		\
+		setDimSizeFunc,			\
+		generateFunc
 
 	MeshGenerator* _MeshGenerator_New( MESHGENERATOR_DEFARGS );
 	void _MeshGenerator_Init( MeshGenerator* self );
@@ -95,13 +104,13 @@
 	void _MeshGenerator_Execute( void* meshGenerator, void* data );
 	void _MeshGenerator_Destroy( void* meshGenerator, void* data );
 
-#ifndef NDEBUG
+	void _MeshGenerator_SetDimSize( void* meshGenerator, unsigned nDims );
+
+	#define MeshGenerator_SetDimSize( self, nDims )			\
+		VirtualCall( self, setDimSizeFunc, self, nDims )
+
 	#define MeshGenerator_Generate( self, mesh )			\
-		(assert( self ), (self)->generateFunc( self, mesh ))
-#else
-	#define MeshGenerator_Generate( self, mesh )	\
-		(self)->generateFunc( self, mesh )
-#endif
+		VirtualCall( self, generateFunc, self, mesh )
 
 	/*--------------------------------------------------------------------------------------------------------------------------
 	** Public functions
@@ -109,9 +118,13 @@
 
 	void MeshGenerator_SetComm( void* meshGenerator, MPI_Comm comm );
 	void MeshGenerator_AddMesh( void* meshGenerator, void* mesh );
+	void MeshGenerator_SetDimState( void* meshGenerator, unsigned dim, Bool state );
+	void MeshGenerator_SetIncidenceState( void* meshGenerator, unsigned fromDim, unsigned toDim, Bool state );
 
 	/*--------------------------------------------------------------------------------------------------------------------------
 	** Private Member functions
 	*/
 
+	void MeshGenerator_Destruct( MeshGenerator* self );
+
 #endif /* __Discretisaton_Mesh_MeshGenerator_h__ */

Modified: long/3D/Gale/trunk/src/StGermain/Discretisation/Mesh/src/MeshTopology.c
===================================================================
--- long/3D/Gale/trunk/src/StGermain/Discretisation/Mesh/src/MeshTopology.c	2006-12-22 14:06:28 UTC (rev 5620)
+++ long/3D/Gale/trunk/src/StGermain/Discretisation/Mesh/src/MeshTopology.c	2006-12-22 14:06:32 UTC (rev 5621)
@@ -316,6 +316,7 @@
 }
 
 void MeshTopology_Invert( void* topo, MeshTopology_Dim fromDim, MeshTopology_Dim toDim ) {
+	Stream*		errorStream = Journal_Register( ErrorStream_Type, "MeshTopology::Invert" );
 	MeshTopology*	self = (MeshTopology*)topo;
 	unsigned	fromSize, toSize;
 	unsigned*	invNIncEls;
@@ -328,11 +329,17 @@
 	assert( self );
 	assert( fromDim < self->nTDims );
 	assert( toDim < self->nTDims );
-	assert( Decomp_Sync_GetDomainSize( self->domains[fromDim] ) );
-	assert( Decomp_Sync_GetDomainSize( self->domains[toDim] ) );
-	assert( !self->nIncEls[fromDim][toDim] && !self->incEls[fromDim][toDim] );
-	assert( self->nIncEls[toDim][fromDim] && self->incEls[toDim][fromDim] );
 
+	Journal_Firewall( self->domains[fromDim] && self->domains[toDim] && 
+			  MeshTopology_HasIncidence( self, toDim, fromDim ), 
+			  errorStream, 
+			  "\n" \
+			  "*******************************************************\n" \
+			  "* Error: Cannot invert a topological relation without *\n" \
+			  "*        pre-existing relation.                       *\n" \
+			  "*******************************************************\n" \
+			  "\n" );
+
 	/* Shortcuts. */
 	fromSize = Decomp_Sync_GetDomainSize( self->domains[fromDim] );
 	toSize = Decomp_Sync_GetDomainSize( self->domains[toDim] );
@@ -589,7 +596,7 @@
 	assert( dim < self->nTDims );
 	assert( self->domains );
 
-	return Decomp_Sync_GetCommTopology( self->domains[dim] );
+	return self->domains[dim] ? Decomp_Sync_GetCommTopology( self->domains[dim] ) : NULL;
 }
 
 Decomp_Sync* MeshTopology_GetSync( void* meshTopology, MeshTopology_Dim dim ) {
@@ -767,6 +774,8 @@
 	allSet = RangeSet_New();
 	for( d_i = 0; d_i < self->nTDims; d_i++ ) {
 		commTopo = MeshTopology_GetCommTopology( self, d_i );
+		if( !commTopo )
+			continue;
 		CommTopology_GetIncidence( commTopo, &nIncRanks, &incRanks );
 		RangeSet_AddIndices( allSet, nIncRanks, incRanks );
 	}
@@ -774,9 +783,11 @@
 	curSet = RangeSet_New();
 	tmpSet = RangeSet_New();
 	for( d_i = 0; d_i < self->nTDims; d_i++ ) {
+		sync = MeshTopology_GetSync( self, d_i );
+		if( !sync )
+			continue;
 		RangeSet_Clear( tmpSet );
 		RangeSet_Union( tmpSet, allSet );
-		sync = MeshTopology_GetSync( self, d_i );
 		commTopo = MeshTopology_GetCommTopology( self, d_i );
 		CommTopology_GetIncidence( commTopo, &nIncRanks, &incRanks );
 		RangeSet_SetIndices( curSet, nIncRanks, incRanks );
@@ -834,11 +845,17 @@
 	nOldIncRanks = AllocArray( unsigned, self->nTDims );
 	for( d_i = 0; d_i < self->nTDims; d_i++ ) {
 		commTopo = MeshTopology_GetCommTopology( self, d_i );
+		if( !commTopo )
+			continue;
+
 		nOldIncRanks[d_i] = CommTopology_GetIncidenceSize( commTopo );
 	}
 	MeshTopology_CommUnion( self );
 	for( d_i = 0; d_i < self->nTDims; d_i++ ) {
 		commTopo = MeshTopology_GetCommTopology( self, d_i );
+		if( !commTopo )
+			continue;
+
 		nIncRanks = CommTopology_GetIncidenceSize( commTopo );
 		if( nIncRanks != nOldIncRanks[d_i] ) {
 			nShdEls[d_i] = ReallocArray( nShdEls[d_i], unsigned, nIncRanks );
@@ -1021,26 +1038,26 @@
 	unsigned	nIncRanks;
 	unsigned	nLocals;
 	unsigned	prevDim, prevRank;
-	unsigned	p_i;
+	IndexSet	*iSet, *extSet;
+	RangeSet*	remSet;
+	unsigned	p_i, e_i;
 
 	assert( self );
 	assert( dim < self->nTDims );
 	assert( nShadowedEls && shadowedEls );
 	assert( nShadowedEls[dim] && shadowedEls[dim] );
 
+	if( !self->domains[dim] )
+		return;
+
 	sync = MeshTopology_GetSync( self, dim );
 	commTopo = MeshTopology_GetCommTopology( self, dim );
 	nLocals = MeshTopology_GetLocalSize( self, dim );
 	nIncRanks = CommTopology_GetIncidenceSize( commTopo );
-
-	prevDim = dim + 1;
+	prevDim = self->nDims;
 	prevCommTopo = MeshTopology_GetCommTopology( self, prevDim );
 
 	for( p_i = 0; p_i < nIncRanks; p_i++ ) {
-		IndexSet	*iSet, *extSet;
-		RangeSet*	remSet;
-		unsigned	e_i;
-
 		/* Map to previous dimension. */
 		prevRank = CommTopology_LocalToGlobal( commTopo, p_i );
 		insist( CommTopology_GlobalToLocal( prevCommTopo, prevRank, &prevRank ) );
@@ -1110,6 +1127,9 @@
 	assert( nShadowedEls && shadowedEls );
 	assert( nShadowedInc && shadowedInc );
 
+	if( !self->domains[dim] )
+		return;
+
 	commTopo = MeshTopology_GetCommTopology( self, dim );
 	nIncRanks = CommTopology_GetIncidenceSize( commTopo );
 
@@ -1147,6 +1167,9 @@
 	assert( dim < self->nTDims );
 	assert( nShadowedEls && shadowedEls );
 
+	if( !self->domains[dim] )
+		return;
+
 	sync = MeshTopology_GetSync( self, dim );
 	commTopo = MeshTopology_GetCommTopology( self, dim );
 	CommTopology_GetIncidence( commTopo, &nIncRanks, &incRanks );
@@ -1220,6 +1243,9 @@
 	assert( dim < self->nTDims );
 	assert( nExternalEls && externalEls );
 
+	if( !self->domains[dim] )
+		return;
+
 	sync = MeshTopology_GetSync( self, dim );
 	decomp = Decomp_Sync_GetDecomp( sync );
 	commTopo = MeshTopology_GetCommTopology( self, dim );
@@ -1429,6 +1455,9 @@
 	assert( dim < self->nTDims );
 	assert( nShadowedInc && shadowedInc );
 
+	if( !self->domains[dim] )
+		return;
+
 	commTopo = MeshTopology_GetCommTopology( self, dim );
 	nIncRanks = CommTopology_GetIncidenceSize( commTopo );
 

Modified: long/3D/Gale/trunk/src/StGermain/Discretisation/Mesh/src/Mesh_Algorithms.c
===================================================================
--- long/3D/Gale/trunk/src/StGermain/Discretisation/Mesh/src/Mesh_Algorithms.c	2006-12-22 14:06:28 UTC (rev 5620)
+++ long/3D/Gale/trunk/src/StGermain/Discretisation/Mesh/src/Mesh_Algorithms.c	2006-12-22 14:06:32 UTC (rev 5621)
@@ -61,6 +61,9 @@
 				     _Mesh_Algorithms_Destroy, 
 				     name, 
 				     NON_GLOBAL, 
+				     _Mesh_Algorithms_SetMesh, 
+				     _Mesh_Algorithms_Update, 
+				     _Mesh_Algorithms_NearestVertex, 
 				     _Mesh_Algorithms_Search, 
 				     _Mesh_Algorithms_SearchElements, 
 				     _Mesh_Algorithms_GetMinimumSeparation, 
@@ -77,6 +80,9 @@
 	self = (Mesh_Algorithms*)_Stg_Component_New( STG_COMPONENT_PASSARGS );
 
 	/* Virtual info */
+	self->setMeshFunc = setMeshFunc;
+	self->updateFunc = updateFunc;
+	self->nearestVertexFunc = nearestVertexFunc;
 	self->searchFunc = searchFunc;
 	self->searchElementsFunc = searchElementsFunc;
 	self->getMinimumSeparationFunc = getMinimumSeparationFunc;
@@ -91,6 +97,9 @@
 }
 
 void _Mesh_Algorithms_Init( Mesh_Algorithms* self ) {
+	self->nearestVertex = NULL;
+	self->search = NULL;
+	self->mesh = NULL;
 }
 
 
@@ -132,75 +141,68 @@
 void _Mesh_Algorithms_Destroy( void* algorithms, void* data ) {
 }
 
-Bool _Mesh_Algorithms_Search( void* algorithms, void* _mesh, double* point, 
-			      MeshTopology_Dim* dim, unsigned* ind )
-{
+void _Mesh_Algorithms_SetMesh( void* algorithms, void* mesh ) {
 	Mesh_Algorithms*	self = (Mesh_Algorithms*)algorithms;
-	Mesh*			mesh = (Mesh*)_mesh;
-	double			maxCrd[3], minCrd[3];
-	unsigned		nDims;
-	unsigned		nEls;
-	unsigned		e_i, d_i;
 
-	assert( self );
-	assert( mesh );
-	assert( dim );
-	assert( ind );
+	assert( self && Stg_CheckType( self, Mesh_Algorithms ) );
+	assert( !mesh || Stg_CheckType( mesh, Mesh ) );
 
-	/* Get dimensionality. */
-	nDims = Mesh_GetDimSize( mesh );
+	self->mesh = (Mesh*)mesh;
+	Mesh_Algorithms_Update( self );
+}
 
-	/* If outside local range, immediately return false. */
-	Mesh_GetDomainCoordRange( mesh, minCrd, maxCrd );
-	for( d_i = 0; d_i < nDims; d_i++ ) {
-		if( point[d_i] < minCrd[d_i] || point[d_i] > maxCrd[d_i] )
-			return False;
-	}
+void _Mesh_Algorithms_Update( void* algorithms ) {
+	Mesh_Algorithms*	self = (Mesh_Algorithms*)algorithms;
 
-	/* Do we have enough information to reduce search time? */
-	if( Mesh_HasIncidence( mesh, MT_VERTEX, MT_VERTEX ) && 
-	    Mesh_HasIncidence( mesh, MT_VERTEX, nDims ) )
-	{
-		unsigned	nearVert;
-		unsigned	nInc;
-		unsigned*	inc;
-		unsigned	inc_i;
+	assert( self && Stg_CheckType( self, Mesh_Algorithms ) );
 
-		/* Start by locating the closest vertex. */
-		nearVert = Mesh_NearestVertex( mesh, point );
+	if( !self->mesh )
+		return;
 
-		/* Get vertex/element incidence. */
-		Mesh_GetIncidence( mesh, MT_VERTEX, nearVert, nDims, 
-				   &nInc, &inc );
+	if( Mesh_HasIncidence( self->mesh, MT_VERTEX, MT_VERTEX ) )
+		self->nearestVertex = Mesh_Algorithms_NearestVertexWithNeighbours;
+	else
+		self->nearestVertex = Mesh_Algorithms_NearestVertexGeneral;
 
-		/* Search each of these incident elements in turn. */
-		for( inc_i = 0; inc_i < nInc; inc_i++ ) {
-			if( Mesh_ElementHasPoint( mesh, inc[inc_i], point, dim, ind ) )
-				return True;
-		}
-	}
+	if( Mesh_HasIncidence( self->mesh, MT_VERTEX, Mesh_GetDimSize( self->mesh ) ) )
+		self->search = Mesh_Algorithms_SearchWithIncidence;
+	else
+		self->search = Mesh_Algorithms_SearchGeneral;
+}
 
-	/* Brute force, search every element in turn. */
-	nEls = Mesh_GetDomainSize( mesh, nDims );
-	for( e_i = 0; e_i < nEls; e_i++ ) {
-		if( Mesh_ElementHasPoint( mesh, e_i, point, dim, ind ) )
-			return True;
-	}
+unsigned _Mesh_Algorithms_NearestVertex( void* algorithms, double* point ) {
+	Mesh_Algorithms*	self = (Mesh_Algorithms*)algorithms;
 
-	return False;
+	assert( self && Stg_CheckType( self, Mesh_Algorithms ) );
+	assert( self->nearestVertex );
+
+	self->nearestVertex( self, point );
 }
 
-Bool _Mesh_Algorithms_SearchElements( void* algorithms, void* _mesh, double* point, 
+Bool _Mesh_Algorithms_Search( void* algorithms, double* point, 
+			      MeshTopology_Dim* dim, unsigned* ind )
+{
+	Mesh_Algorithms*	self = (Mesh_Algorithms*)algorithms;
+
+	assert( self && Stg_CheckType( self, Mesh_Algorithms ) );
+	assert( self->search );
+
+	self->search( self, point, dim, ind );
+}
+
+Bool _Mesh_Algorithms_SearchElements( void* algorithms, double* point, 
 				      unsigned* elInd )
 {
 	Mesh_Algorithms*	self = (Mesh_Algorithms*)algorithms;
-	Mesh*			mesh = (Mesh*)_mesh;
+	Mesh*			mesh;
 	unsigned		dim, ind;
 
 	assert( self );
+	assert( self->mesh );
 	assert( elInd );
 
-	if( Mesh_Algorithms_Search( self, mesh, point, &dim, &ind ) ) {
+	mesh = self->mesh;
+	if( Mesh_Algorithms_Search( self, point, &dim, &ind ) ) {
 		unsigned	nDims;
 
 		nDims = Mesh_GetDimSize( mesh );
@@ -211,6 +213,9 @@
 			unsigned	global;
 			unsigned	inc_i;
 
+			/* Must have required incidence for this to work. */
+			assert( Mesh_HasIncidence( mesh, dim, nDims ) );
+
 			nLocalEls = Mesh_GetLocalSize( mesh, nDims );
 			Mesh_GetIncidence( mesh, dim, ind, nDims, &nInc, &inc );
 
@@ -254,13 +259,18 @@
 	return False;
 }
 
-double _Mesh_Algorithms_GetMinimumSeparation( void* algorithms, void* _mesh, double* perDim ) {
-	Mesh*			mesh = (Mesh*)_mesh;
+double _Mesh_Algorithms_GetMinimumSeparation( void* algorithms, double* perDim ) {
+	Mesh_Algorithms*	self = (Mesh_Algorithms*)algorithms;
+	Mesh*			mesh;
 	unsigned		nDomainEls;
 	double			minSep;
 	double*			dimSep;
 	unsigned		e_i;
 
+	assert( self );
+	assert( self->mesh );
+
+	mesh = self->mesh;
 	if( perDim )
 		dimSep = Memory_Alloc_Array_Unnamed( double, Mesh_GetDimSize( mesh ) );
 	else
@@ -284,19 +294,20 @@
 	return minSep;
 }
 
-void _Mesh_Algorithms_GetLocalCoordRange( void* algorithms, void* _mesh, double* min, double* max ) {
+void _Mesh_Algorithms_GetLocalCoordRange( void* algorithms, double* min, double* max ) {
 	Mesh_Algorithms*	self = (Mesh_Algorithms*)algorithms;
-	Mesh*			mesh = (Mesh*)_mesh;
+	Mesh*			mesh;
 	unsigned		nVerts;
 	double*			vert;
 	unsigned		nDims;
 	unsigned		v_i, d_i;
 
 	assert( self );
-	assert( mesh );
+	assert( self->mesh );
 	assert( min );
 	assert( max );
 
+	mesh = self->mesh;
 	nDims = Mesh_GetDimSize( mesh );
 	nVerts = Mesh_GetLocalSize( mesh, MT_VERTEX );
 	memcpy( min, Mesh_GetVertex( mesh, 0 ), nDims * sizeof(double) );
@@ -312,19 +323,20 @@
 	}
 }
 
-void _Mesh_Algorithms_GetDomainCoordRange( void* algorithms, void* _mesh, double* min, double* max ) {
+void _Mesh_Algorithms_GetDomainCoordRange( void* algorithms, double* min, double* max ) {
 	Mesh_Algorithms*	self = (Mesh_Algorithms*)algorithms;
-	Mesh*			mesh = (Mesh*)_mesh;
+	Mesh*			mesh;
 	unsigned		nVerts;
 	double*			vert;
 	unsigned		nDims;
 	unsigned		v_i, d_i;
 
 	assert( self );
-	assert( mesh );
+	assert( self->mesh );
 	assert( min );
 	assert( max );
 
+	mesh = self->mesh;
 	nDims = Mesh_GetDimSize( mesh );
 	nVerts = Mesh_GetDomainSize( mesh, MT_VERTEX );
 	memcpy( min, Mesh_GetVertex( mesh, 0 ), nDims * sizeof(double) );
@@ -340,25 +352,26 @@
 	}
 }
 
-void _Mesh_Algorithms_GetGlobalCoordRange( void* algorithms, void* _mesh, double* min, double* max ) {
+void _Mesh_Algorithms_GetGlobalCoordRange( void* algorithms, double* min, double* max ) {
 	Mesh_Algorithms*	self = (Mesh_Algorithms*)algorithms;
-	Mesh*			mesh = (Mesh*)_mesh;
+	Mesh*			mesh;
 	unsigned		nDims;
 	double			*localMin, *localMax;
 	MPI_Comm		comm;
 	unsigned		d_i;
 
 	assert( self );
-	assert( mesh );
+	assert( self->mesh );
 	assert( min );
 	assert( max );
 
+	mesh = self->mesh;
 	nDims = Mesh_GetDimSize( mesh );
 	localMin = Memory_Alloc_Array_Unnamed( double, nDims );
 	localMax = Memory_Alloc_Array_Unnamed( double, nDims );
 
 	comm = CommTopology_GetComm( Mesh_GetCommTopology( mesh, MT_VERTEX ) );
-	Mesh_Algorithms_GetLocalCoordRange( self, mesh, localMin, localMax );
+	Mesh_Algorithms_GetLocalCoordRange( self, localMin, localMax );
 	for( d_i = 0; d_i < Mesh_GetDimSize( mesh ); d_i++ ) {
 		MPI_Allreduce( localMin + d_i, min + d_i, 1, MPI_DOUBLE, MPI_MIN, comm );
 		MPI_Allreduce( localMax + d_i, max + d_i, 1, MPI_DOUBLE, MPI_MAX, comm );
@@ -373,7 +386,188 @@
 ** Public Functions
 */
 
+#define Vec_Sep( nDims, v0, v1 )					\
+	(((v0)[0] - (v1)[0]) * ((v0)[0] - (v1)[0]) +			\
+	 ((v0)[1] - (v1)[1]) * ((v0)[1] - (v1)[1]) +			\
+	 (((nDims) == 3) ? (((v0)[2] - (v1)[2]) * ((v0)[2] - (v1)[2])) : 0))
 
+unsigned Mesh_Algorithms_NearestVertexWithNeighbours( void* algorithms, double* point ) {
+	Mesh_Algorithms*	self = (Mesh_Algorithms*)algorithms;
+	Mesh*			mesh;
+	unsigned		nDims;
+	unsigned		curVert;
+	double			sep;
+	Bool			done;
+	unsigned		nNbrs;
+	unsigned*		nbrs;
+	double			nbrSep;
+	unsigned		nbr_i;
+
+	assert( self );
+	assert( self->mesh );
+	assert( Mesh_HasIncidence( self->mesh, MT_VERTEX, MT_VERTEX ) );
+
+	/* Get dimensionality. */
+	mesh = self->mesh;
+	nDims = Mesh_GetDimSize( mesh );
+
+	/* Begin somewhere in the middle. */
+	curVert = Mesh_GetDomainSize( mesh, MT_VERTEX ) / 2;
+
+	/* Calc distance squared to current node. */
+	sep = Vec_Sep( nDims, Mesh_GetVertex( mesh, curVert ), point );
+
+	/* Loop until we've found closest local node. */
+	do {
+		/* Get neighbouring vertices. */
+		Mesh_GetIncidence( mesh, MT_VERTEX, curVert, MT_VERTEX, &nNbrs, &nbrs );
+
+		/* Assume we'll be done after this loop. */
+		done = True;
+
+		/* Compare to neighbours. */
+		for( nbr_i = 0; nbr_i < nNbrs; nbr_i++ ) {
+			/* Calculate neighbour separation. */
+			nbrSep = Vec_Sep( nDims, Mesh_GetVertex( mesh, nbrs[nbr_i] ), point );
+
+			/* Closer? */
+			if( nbrSep < sep ) {
+				curVert = nbrs[nbr_i];
+				sep = nbrSep;
+				done = False;
+			}
+		}
+	}
+	while( !done );
+
+	return curVert;
+}
+
+unsigned Mesh_Algorithms_NearestVertexGeneral( void* algorithms, double* point ) {
+	Mesh_Algorithms*	self = (Mesh_Algorithms*)algorithms;
+	Mesh*			mesh;
+	unsigned		nDims;
+	unsigned		nDomainVerts;
+	double*			vert;
+	unsigned		minVertInd;
+	double			curSep, minSep;
+	unsigned		v_i;
+
+	assert( self && Stg_CheckType( self, Mesh_Algorithms ) );
+	assert( self->mesh && Stg_CheckType( self->mesh, Mesh ) );
+	assert( Mesh_GetDomainSize( self->mesh, MT_VERTEX ) );
+
+	/* TODO: This is going to be hella slow, need to use some kind of spatial partitioning scheme. */
+
+	mesh = self->mesh;
+	nDims = Mesh_GetDimSize( mesh );
+	nDomainVerts = Mesh_GetDomainSize( mesh, MT_VERTEX );
+
+	vert = Mesh_GetVertex( mesh, 0 );
+	minSep = Vec_Sep( nDims, vert, point );
+	minVertInd = 0;
+
+	for( v_i = 1; v_i < nDomainVerts; v_i++ ) {
+		vert = Mesh_GetVertex( mesh, v_i );
+		curSep = Vec_Sep( nDims, vert, point );
+		if( curSep < minSep ) {
+			minSep = curSep;
+			minVertInd = v_i;
+		}
+	}
+
+	return minVertInd;
+}
+
+Bool Mesh_Algorithms_SearchWithIncidence( void* algorithms, double* point, 
+					  MeshTopology_Dim* dim, unsigned* ind )
+{
+	Mesh_Algorithms*	self = (Mesh_Algorithms*)algorithms;
+	Mesh*			mesh;
+	double			maxCrd[3], minCrd[3];
+	unsigned		nDims;
+	unsigned		nEls;
+	unsigned		nearVert;
+	unsigned		nInc, *inc;
+	unsigned		e_i, d_i, inc_i;
+
+	assert( self );
+	assert( self->mesh );
+	assert( Mesh_HasIncidence( self->mesh, MT_VERTEX, Mesh_GetDimSize( self->mesh ) ) );
+	assert( dim );
+	assert( ind );
+
+	/* Get dimensionality. */
+	mesh = self->mesh;
+	nDims = Mesh_GetDimSize( mesh );
+
+	/* If outside local range, immediately return false. */
+	Mesh_GetDomainCoordRange( mesh, minCrd, maxCrd );
+	for( d_i = 0; d_i < nDims; d_i++ ) {
+		if( point[d_i] < minCrd[d_i] || point[d_i] > maxCrd[d_i] )
+			return False;
+	}
+
+	/* Start by locating the closest vertex. */
+	nearVert = Mesh_NearestVertex( mesh, point );
+
+	/* Get vertex/element incidence. */
+	Mesh_GetIncidence( mesh, MT_VERTEX, nearVert, nDims, 
+			   &nInc, &inc );
+
+	/* Search each of these incident elements in turn. */
+	for( inc_i = 0; inc_i < nInc; inc_i++ ) {
+		if( Mesh_ElementHasPoint( mesh, inc[inc_i], point, dim, ind ) )
+			return True;
+
+		/* Brute force, search every element in turn (last resort). */
+		nEls = Mesh_GetDomainSize( mesh, nDims );
+		for( e_i = 0; e_i < nEls; e_i++ ) {
+			if( Mesh_ElementHasPoint( mesh, e_i, point, dim, ind ) )
+				return True;
+		}
+	}
+
+	return False;
+}
+
+Bool Mesh_Algorithms_SearchGeneral( void* algorithms, double* point, 
+				    MeshTopology_Dim* dim, unsigned* ind )
+{
+	Mesh_Algorithms*	self = (Mesh_Algorithms*)algorithms;
+	Mesh*			mesh;
+	double			maxCrd[3], minCrd[3];
+	unsigned		nDims;
+	unsigned		nEls;
+	unsigned		e_i, d_i;
+
+	assert( self );
+	assert( self->mesh );
+	assert( dim );
+	assert( ind );
+
+	/* Get dimensionality. */
+	mesh = self->mesh;
+	nDims = Mesh_GetDimSize( mesh );
+
+	/* If outside local range, immediately return false. */
+	Mesh_GetDomainCoordRange( mesh, minCrd, maxCrd );
+	for( d_i = 0; d_i < nDims; d_i++ ) {
+		if( point[d_i] < minCrd[d_i] || point[d_i] > maxCrd[d_i] )
+			return False;
+	}
+
+	/* Brute force, search every element in turn. */
+	nEls = Mesh_GetDomainSize( mesh, nDims );
+	for( e_i = 0; e_i < nEls; e_i++ ) {
+		if( Mesh_ElementHasPoint( mesh, e_i, point, dim, ind ) )
+			return True;
+	}
+
+	return False;
+}
+
+
 /*----------------------------------------------------------------------------------------------------------------------------------
 ** Private Functions
 */

Modified: long/3D/Gale/trunk/src/StGermain/Discretisation/Mesh/src/Mesh_Algorithms.h
===================================================================
--- long/3D/Gale/trunk/src/StGermain/Discretisation/Mesh/src/Mesh_Algorithms.h	2006-12-22 14:06:28 UTC (rev 5620)
+++ long/3D/Gale/trunk/src/StGermain/Discretisation/Mesh/src/Mesh_Algorithms.h	2006-12-22 14:06:32 UTC (rev 5621)
@@ -45,14 +45,17 @@
 	extern const Type Mesh_Algorithms_Type;
 
 	/** Virtual function types */
-	typedef Bool (Mesh_Algorithms_SearchFunc)( void* algorithms, void* mesh, double* point, 
+	typedef void (Mesh_Algorithms_SetMeshFunc)( void* algorithms, void* mesh );
+	typedef void (Mesh_Algorithms_UpdateFunc)( void* algorithms );
+	typedef unsigned (Mesh_Algorithms_NearestVertexFunc)( void* algorithms, double* point );
+	typedef Bool (Mesh_Algorithms_SearchFunc)( void* algorithms, double* point, 
 						   MeshTopology_Dim* dim, unsigned* ind );
-	typedef Bool (Mesh_Algorithms_SearchElementsFunc)( void* algorithms, void* _mesh, double* point, 
+	typedef Bool (Mesh_Algorithms_SearchElementsFunc)( void* algorithms, double* point, 
 							   unsigned* elInd );
-	typedef double (Mesh_Algorithms_GetMinimumSeparationFunc)( void* algorithms, void* mesh, double* perDim );
-	typedef void (Mesh_Algorithms_GetLocalCoordRangeFunc)( void* algorithms, void* mesh, double* min, double* max );
-	typedef void (Mesh_Algorithms_GetDomainCoordRangeFunc)( void* algorithms, void* mesh, double* min, double* max );
-	typedef void (Mesh_Algorithms_GetGlobalCoordRangeFunc)( void* algorithms, void* mesh, double* min, double* max );
+	typedef double (Mesh_Algorithms_GetMinimumSeparationFunc)( void* algorithms, double* perDim );
+	typedef void (Mesh_Algorithms_GetLocalCoordRangeFunc)( void* algorithms, double* min, double* max );
+	typedef void (Mesh_Algorithms_GetDomainCoordRangeFunc)( void* algorithms, double* min, double* max );
+	typedef void (Mesh_Algorithms_GetGlobalCoordRangeFunc)( void* algorithms, double* min, double* max );
 
 	/** Class contents */
 	#define __Mesh_Algorithms								\
@@ -60,6 +63,9 @@
 		__Stg_Component									\
 												\
 		/* Virtual info */								\
+		Mesh_Algorithms_SetMeshFunc*			setMeshFunc;			\
+		Mesh_Algorithms_UpdateFunc*			updateFunc;			\
+		Mesh_Algorithms_NearestVertexFunc*		nearestVertexFunc;		\
 		Mesh_Algorithms_SearchFunc*			searchFunc;			\
 		Mesh_Algorithms_SearchElementsFunc*		searchElementsFunc;		\
 		Mesh_Algorithms_GetMinimumSeparationFunc*	getMinimumSeparationFunc;	\
@@ -67,7 +73,10 @@
 		Mesh_Algorithms_GetDomainCoordRangeFunc*	getDomainCoordRangeFunc;	\
 		Mesh_Algorithms_GetGlobalCoordRangeFunc*	getGlobalCoordRangeFunc;	\
 												\
-		/* Mesh_Algorithms info */
+		/* Mesh_Algorithms info */							\
+		Mesh_Algorithms_NearestVertexFunc*	nearestVertex;				\
+		Mesh_Algorithms_SearchFunc*		search;					\
+		Mesh*					mesh;
 
 	struct Mesh_Algorithms { __Mesh_Algorithms };
 
@@ -77,6 +86,9 @@
 
 	#define MESH_ALGORITHMS_DEFARGS								\
 		STG_COMPONENT_DEFARGS,								\
+		Mesh_Algorithms_SetMeshFunc*			setMeshFunc,			\
+		Mesh_Algorithms_UpdateFunc*			updateFunc,			\
+		Mesh_Algorithms_NearestVertexFunc*		nearestVertexFunc, 		\
 		Mesh_Algorithms_SearchFunc*			searchFunc, 			\
 		Mesh_Algorithms_SearchElementsFunc*		searchElementsFunc, 		\
 		Mesh_Algorithms_GetMinimumSeparationFunc*	getMinimumSeparationFunc, 	\
@@ -84,10 +96,17 @@
 		Mesh_Algorithms_GetDomainCoordRangeFunc*	getDomainCoordRangeFunc,	\
 		Mesh_Algorithms_GetGlobalCoordRangeFunc*	getGlobalCoordRangeFunc
 
-	#define MESH_ALGORITHMS_PASSARGS							\
-		STG_COMPONENT_PASSARGS, searchFunc, searchElementsFunc, 			\
-		getMinimumSeparationFunc, 							\
-		getLocalCoordRangeFunc, getDomainCoordRangeFunc, getGlobalCoordRangeFunc
+	#define MESH_ALGORITHMS_PASSARGS	\
+		STG_COMPONENT_PASSARGS, 	\
+		setMeshFunc, 			\
+		updateFunc, 			\
+		nearestVertexFunc,		\
+		searchFunc, 			\
+		searchElementsFunc,		\
+		getMinimumSeparationFunc,	\
+		getLocalCoordRangeFunc, 	\
+		getDomainCoordRangeFunc, 	\
+		getGlobalCoordRangeFunc
 
 	Mesh_Algorithms* Mesh_Algorithms_New( Name name );
 	Mesh_Algorithms* _Mesh_Algorithms_New( MESH_ALGORITHMS_DEFARGS );
@@ -105,43 +124,62 @@
 	void _Mesh_Algorithms_Execute( void* algorithms, void* data );
 	void _Mesh_Algorithms_Destroy( void* algorithms, void* data );
 
-	Bool _Mesh_Algorithms_Search( void* algorithms, void* mesh, double* point, 
-					 MeshTopology_Dim* dim, unsigned* ind );
-	Bool _Mesh_Algorithms_SearchElements( void* algorithms, void* _mesh, double* point, 
+	void _Mesh_Algorithms_SetMesh( void* algorithms, void* mesh );
+	void _Mesh_Algorithms_Update( void* algorithms );
+	unsigned _Mesh_Algorithms_NearestVertex( void* algorithms, double* point );
+	Bool _Mesh_Algorithms_Search( void* algorithms, double* point, 
+				      MeshTopology_Dim* dim, unsigned* ind );
+	Bool _Mesh_Algorithms_SearchElements( void* algorithms, double* point, 
 					      unsigned* elInd );
-	double _Mesh_Algorithms_GetMinimumSeparation( void* algorithms, void* mesh, double* perDim );
-	void _Mesh_Algorithms_GetLocalCoordRange( void* algorithms, void* mesh, double* min, double* max );
-	void _Mesh_Algorithms_GetDomainCoordRange( void* algorithms, void* mesh, double* min, double* max );
-	void _Mesh_Algorithms_GetGlobalCoordRange( void* algorithms, void* mesh, double* min, double* max );
+	double _Mesh_Algorithms_GetMinimumSeparation( void* algorithms, double* perDim );
+	void _Mesh_Algorithms_GetLocalCoordRange( void* algorithms, double* min, double* max );
+	void _Mesh_Algorithms_GetDomainCoordRange( void* algorithms, double* min, double* max );
+	void _Mesh_Algorithms_GetGlobalCoordRange( void* algorithms, double* min, double* max );
 
 	/*--------------------------------------------------------------------------------------------------------------------------
 	** Public functions
 	*/
 
-	#define Mesh_Algorithms_Search( algorithms, mesh, point, dim, ind )				\
+	#define Mesh_Algorithms_SetMesh( self, mesh )							\
+		VirtualCall( self, setMeshFunc, self, mesh )
+
+	#define Mesh_Algorithms_Update( self )								\
+		VirtualCall( self, updateFunc, self )
+
+	#define Mesh_Algorithms_NearestVertex( self, point )					\
+		VirtualCall( self, nearestVertexFunc, self, point )
+
+	#define Mesh_Algorithms_Search( algorithms, point, dim, ind )				\
 		(assert( (algorithms) && ((Mesh_Algorithms*)algorithms)->searchFunc ),			\
-		 ((Mesh_Algorithms*)algorithms)->searchFunc( algorithms, mesh, point, dim, ind ))
+		 ((Mesh_Algorithms*)algorithms)->searchFunc( algorithms, point, dim, ind ))
 
-	#define Mesh_Algorithms_SearchElements( algorithms, mesh, point, elInd )			\
+	#define Mesh_Algorithms_SearchElements( algorithms, point, elInd )			\
 		(assert( (algorithms) && ((Mesh_Algorithms*)algorithms)->searchElementsFunc ),		\
-		 ((Mesh_Algorithms*)algorithms)->searchElementsFunc( algorithms, mesh, point, elInd ))
+		 ((Mesh_Algorithms*)algorithms)->searchElementsFunc( algorithms, point, elInd ))
 
-	#define Mesh_Algorithms_GetMinimumSeparation( algorithms, mesh, perDim )			\
+	#define Mesh_Algorithms_GetMinimumSeparation( algorithms, perDim )			\
 		(assert( (algorithms) && ((Mesh_Algorithms*)algorithms)->getMinimumSeparationFunc ),	\
-		 ((Mesh_Algorithms*)algorithms)->getMinimumSeparationFunc( algorithms, mesh, perDim ))
+		 ((Mesh_Algorithms*)algorithms)->getMinimumSeparationFunc( algorithms, perDim ))
 
-	#define Mesh_Algorithms_GetLocalCoordRange( algorithms, mesh, min, max )			\
+	#define Mesh_Algorithms_GetLocalCoordRange( algorithms, min, max )			\
 		(assert( (algorithms) && ((Mesh_Algorithms*)algorithms)->getLocalCoordRangeFunc ),	\
-		 ((Mesh_Algorithms*)algorithms)->getLocalCoordRangeFunc( algorithms, mesh, min, max ))
+		 ((Mesh_Algorithms*)algorithms)->getLocalCoordRangeFunc( algorithms, min, max ))
 
-	#define Mesh_Algorithms_GetDomainCoordRange( algorithms, mesh, min, max )			\
+	#define Mesh_Algorithms_GetDomainCoordRange( algorithms, min, max )			\
 		(assert( (algorithms) && ((Mesh_Algorithms*)algorithms)->getDomainCoordRangeFunc ),	\
-		 ((Mesh_Algorithms*)algorithms)->getDomainCoordRangeFunc( algorithms, mesh, min, max ))
+		 ((Mesh_Algorithms*)algorithms)->getDomainCoordRangeFunc( algorithms, min, max ))
 
-	#define Mesh_Algorithms_GetGlobalCoordRange( algorithms, mesh, min, max )			\
+	#define Mesh_Algorithms_GetGlobalCoordRange( algorithms, min, max )			\
 		(assert( (algorithms) && ((Mesh_Algorithms*)algorithms)->getGlobalCoordRangeFunc ),	\
-		 ((Mesh_Algorithms*)algorithms)->getGlobalCoordRangeFunc( algorithms, mesh, min, max ))
+		 ((Mesh_Algorithms*)algorithms)->getGlobalCoordRangeFunc( algorithms, min, max ))
 
+	unsigned Mesh_Algorithms_NearestVertexWithNeighbours( void* algorithms, double* point );
+	unsigned Mesh_Algorithms_NearestVertexGeneral( void* algorithms, double* point );
+	Bool Mesh_Algorithms_SearchWithIncidence( void* algorithms, double* point, 
+						  MeshTopology_Dim* dim, unsigned* ind );
+	Bool Mesh_Algorithms_SearchGeneral( void* algorithms, double* point, 
+					    MeshTopology_Dim* dim, unsigned* ind );
+
 	/*--------------------------------------------------------------------------------------------------------------------------
 	** Private Member functions
 	*/

Modified: long/3D/Gale/trunk/src/StGermain/Discretisation/Mesh/tests/testCartesianGenerator.c
===================================================================
--- long/3D/Gale/trunk/src/StGermain/Discretisation/Mesh/tests/testCartesianGenerator.c	2006-12-22 14:06:28 UTC (rev 5620)
+++ long/3D/Gale/trunk/src/StGermain/Discretisation/Mesh/tests/testCartesianGenerator.c	2006-12-22 14:06:32 UTC (rev 5621)
@@ -56,8 +56,9 @@
 	maxCrd[0] = (double)nProcs;
 
 	gen = CartesianGenerator_New( "" );
+	MeshGenerator_SetDimSize( gen, 1 );
 	CartesianGenerator_SetShadowDepth( gen, 0 );
-	CartesianGenerator_SetTopologyParams( gen, 1, sizes, 0, NULL, NULL );
+	CartesianGenerator_SetTopologyParams( gen, sizes, 0, NULL, NULL );
 	CartesianGenerator_SetGeometryParams( gen, minCrd, maxCrd );
 
 	mesh = Mesh_New( "" );
@@ -156,8 +157,9 @@
 	maxCrd[0] = (double)nProcs;
 
 	gen = CartesianGenerator_New( "" );
+	MeshGenerator_SetDimSize( gen, 1 );
 	CartesianGenerator_SetShadowDepth( gen, 1 );
-	CartesianGenerator_SetTopologyParams( gen, 1, sizes, 0, NULL, NULL );
+	CartesianGenerator_SetTopologyParams( gen, sizes, 0, NULL, NULL );
 	CartesianGenerator_SetGeometryParams( gen, minCrd, maxCrd );
 
 	mesh = Mesh_New( "" );
@@ -253,9 +255,8 @@
 	MPI_Init( &argc, &argv );
 
 	/* Initialise StGermain. */
-	BaseFoundation_Init( &argc, &argv );
-	BaseIO_Init( &argc, &argv );
-	BaseContainer_Init( &argc, &argv );
+	Base_Init( &argc, &argv );
+	DiscretisationMesh_Init( &argc, &argv );
 
 	/* Create the test suite. */
 	suite = TestSuite_New();
@@ -269,9 +270,8 @@
 	FreeObject( suite );
 
 	/* Finalise StGermain. */
-	BaseContainer_Finalise();
-	BaseIO_Finalise();
-	BaseFoundation_Finalise();
+	DiscretisationMesh_Finalise();
+	Base_Finalise();
 
 	/* Close off MPI */
 	MPI_Finalize();

Modified: long/3D/Gale/trunk/src/StGermain/Discretisation/Mesh/tests/testMesh.c
===================================================================
--- long/3D/Gale/trunk/src/StGermain/Discretisation/Mesh/tests/testMesh.c	2006-12-22 14:06:28 UTC (rev 5620)
+++ long/3D/Gale/trunk/src/StGermain/Discretisation/Mesh/tests/testMesh.c	2006-12-22 14:06:32 UTC (rev 5621)
@@ -31,6 +31,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <assert.h>
 #include <mpi.h>
 #include <mpi.h>
 
@@ -53,7 +54,8 @@
 	maxCrd[0] = maxCrd[1] = maxCrd[2] = (double)nProcs;
 
 	gen = CartesianGenerator_New( "" );
-	CartesianGenerator_SetTopologyParams( gen, 3, sizes, 0, NULL, NULL );
+	MeshGenerator_SetDimSize( gen, 3 );
+	CartesianGenerator_SetTopologyParams( gen, sizes, 0, NULL, NULL );
 	CartesianGenerator_SetGeometryParams( gen, minCrd, maxCrd );
 
 	mesh = Mesh_New( "" );
@@ -100,7 +102,8 @@
 	maxCrd[0] = (double)nProcs;
 
 	gen = CartesianGenerator_New( "" );
-	CartesianGenerator_SetTopologyParams( gen, 1, sizes, 0, NULL, NULL );
+	MeshGenerator_SetDimSize( gen, 1 );
+	CartesianGenerator_SetTopologyParams( gen, sizes, 0, NULL, NULL );
 	CartesianGenerator_SetGeometryParams( gen, minCrd, maxCrd );
 
 	mesh = Mesh_New( "" );
@@ -165,7 +168,8 @@
 	maxCrd[0] = maxCrd[1] = (double)nProcs;
 
 	gen = CartesianGenerator_New( "" );
-	CartesianGenerator_SetTopologyParams( gen, 2, sizes, 0, NULL, NULL );
+	MeshGenerator_SetDimSize( gen, 2 );
+	CartesianGenerator_SetTopologyParams( gen, sizes, 0, NULL, NULL );
 	CartesianGenerator_SetGeometryParams( gen, minCrd, maxCrd );
 
 	mesh = Mesh_New( "" );
@@ -255,7 +259,8 @@
 	maxCrd[0] = maxCrd[1] = maxCrd[2] = (double)nProcs;
 
 	gen = CartesianGenerator_New( "" );
-	CartesianGenerator_SetTopologyParams( gen, 3, sizes, 0, NULL, NULL );
+	MeshGenerator_SetDimSize( gen, 3 );
+	CartesianGenerator_SetTopologyParams( gen, sizes, 0, NULL, NULL );
 	CartesianGenerator_SetGeometryParams( gen, minCrd, maxCrd );
 
 	mesh = Mesh_New( "" );
@@ -360,13 +365,153 @@
 	return result;
 }
 
+Bool testMinElSearch3D( unsigned rank, unsigned nProcs, unsigned watch ) {
+	Bool			result = True;
+	CartesianGenerator*	gen;
+	Mesh*			mesh;
+	unsigned		sizes[3];
+	double			minCrd[3];
+	double			maxCrd[3];
 
-#define nTests	4
+	sizes[0] = sizes[1] = sizes[2] = nProcs * 64;
+	minCrd[0] = minCrd[1] = minCrd[2] = 0.0;
+	maxCrd[0] = maxCrd[1] = maxCrd[2] = (double)nProcs;
 
+	gen = CartesianGenerator_New( "" );
+	MeshGenerator_SetDimSize( gen, 3 );
+	MeshGenerator_SetDimState( gen, 2, False );
+	MeshGenerator_SetDimState( gen, 1, True );
+	MeshGenerator_SetIncidenceState( gen, 3, 3, False );
+	MeshGenerator_SetIncidenceState( gen, 3, 2, False );
+	MeshGenerator_SetIncidenceState( gen, 3, 1, False );
+	MeshGenerator_SetIncidenceState( gen, 3, 0, True );
+	MeshGenerator_SetIncidenceState( gen, 2, 3, False );
+	MeshGenerator_SetIncidenceState( gen, 2, 2, False );
+	MeshGenerator_SetIncidenceState( gen, 2, 1, False );
+	MeshGenerator_SetIncidenceState( gen, 2, 0, False );
+	MeshGenerator_SetIncidenceState( gen, 1, 3, False );
+	MeshGenerator_SetIncidenceState( gen, 1, 2, False );
+	MeshGenerator_SetIncidenceState( gen, 1, 1, False );
+	MeshGenerator_SetIncidenceState( gen, 1, 0, True );
+	MeshGenerator_SetIncidenceState( gen, 0, 3, True );
+	MeshGenerator_SetIncidenceState( gen, 0, 2, False );
+	MeshGenerator_SetIncidenceState( gen, 0, 1, True );
+	MeshGenerator_SetIncidenceState( gen, 0, 0, True );
+	CartesianGenerator_SetTopologyParams( gen, sizes, 0, NULL, NULL );
+	CartesianGenerator_SetGeometryParams( gen, minCrd, maxCrd );
+
+	mesh = Mesh_New( "" );
+	Mesh_SetGenerator( mesh, gen );
+	Build( mesh, NULL, False );
+
+#if 0
+	if( rank == watch ) {
+		unsigned	e_i;
+
+		for( e_i = 0; e_i < Mesh_GetDomainSize( mesh, MT_VOLUME ); e_i++ ) {
+			unsigned	nInc, *inc;
+			double		point[3];
+			unsigned	elDim, elInd;
+			unsigned	inc_i;
+
+			Mesh_GetIncidence( mesh, MT_VOLUME, e_i, MT_VERTEX, &nInc, &inc );
+			for( inc_i = 0; inc_i < nInc; inc_i++ ) {
+				double*	vert;
+
+				vert = Mesh_GetVertex( mesh, inc[inc_i] );
+				if( !Mesh_Search( mesh, vert, &elDim, &elInd ) || 
+				    elDim != MT_VERTEX || 
+				    elInd != inc[inc_i] )
+				{
+					result = False;
+					goto done;
+				}
+			}
+
+			Mesh_GetIncidence( mesh, MT_VOLUME, e_i, MT_EDGE, &nInc, &inc );
+			for( inc_i = 0; inc_i < nInc; inc_i++ ) {
+				unsigned	nEdgeInc, *edgeInc;
+				unsigned	inc_j;
+
+				Mesh_GetIncidence( mesh, MT_EDGE, inc[inc_i], MT_VERTEX, &nEdgeInc, &edgeInc );
+				point[0] = point[1] = point[2] = 0.0;
+				for( inc_j = 0; inc_j < nEdgeInc; inc_j++ ) {
+					point[0] += Mesh_GetVertex( mesh, edgeInc[inc_j] )[0];
+					point[1] += Mesh_GetVertex( mesh, edgeInc[inc_j] )[1];
+					point[2] += Mesh_GetVertex( mesh, edgeInc[inc_j] )[2];
+				}
+				point[0] /= (double)nEdgeInc;
+				point[1] /= (double)nEdgeInc;
+				point[2] /= (double)nEdgeInc;
+				if( !Mesh_Search( mesh, point, &elDim, &elInd ) || 
+				    elDim != MT_EDGE || 
+				    elInd != inc[inc_i] )
+				{
+					result = False;
+					goto done;
+				}
+			}
+
+			Mesh_GetIncidence( mesh, MT_VOLUME, e_i, MT_FACE, &nInc, &inc );
+			for( inc_i = 0; inc_i < nInc; inc_i++ ) {
+				unsigned	nFaceInc, *faceInc;
+				unsigned	inc_j;
+
+				Mesh_GetIncidence( mesh, MT_FACE, inc[inc_i], MT_VERTEX, &nFaceInc, &faceInc );
+				point[0] = point[1] = point[2] = 0.0;
+				for( inc_j = 0; inc_j < nFaceInc; inc_j++ ) {
+					point[0] += Mesh_GetVertex( mesh, faceInc[inc_j] )[0];
+					point[1] += Mesh_GetVertex( mesh, faceInc[inc_j] )[1];
+					point[2] += Mesh_GetVertex( mesh, faceInc[inc_j] )[2];
+				}
+				point[0] /= (double)nFaceInc;
+				point[1] /= (double)nFaceInc;
+				point[2] /= (double)nFaceInc;
+				if( !Mesh_Search( mesh, point, &elDim, &elInd ) || 
+				    elDim != MT_FACE || 
+				    elInd != inc[inc_i] )
+				{
+					result = False;
+					goto done;
+				}
+			}
+
+			Mesh_GetIncidence( mesh, MT_VOLUME, e_i, MT_VERTEX, &nInc, &inc );
+			point[0] = point[1] = point[2] = 0.0;
+			for( inc_i = 0; inc_i < nInc; inc_i++ ) {
+				point[0] += Mesh_GetVertex( mesh, inc[inc_i] )[0];
+				point[1] += Mesh_GetVertex( mesh, inc[inc_i] )[1];
+				point[2] += Mesh_GetVertex( mesh, inc[inc_i] )[2];
+			}
+			point[0] /= (double)nInc;
+			point[1] /= (double)nInc;
+			point[2] /= (double)nInc;
+			if( !Mesh_Search( mesh, point, &elDim, &elInd ) || 
+			    elDim != MT_VOLUME || 
+			    elInd != e_i )
+			{
+				result = False;
+				goto done;
+			}
+		}
+	}
+#endif
+
+done:
+	FreeObject( gen );
+	FreeObject( mesh );
+
+	return result;
+}
+
+
+#define nTests	5
+
 TestSuite_Test	tests[nTests] = {{"test nearest vertex", testNearVert, 1}, 
 				 {"test element search (1D)", testElSearch1D, 1}, 
 				 {"test element search (2D)", testElSearch2D, 1}, 
-				 {"test element search (3D)", testElSearch3D, 1}};
+				 {"test element search (3D)", testElSearch3D, 1}, 
+				 {"test minimum element search (3D)", testMinElSearch3D, 1}};
 
 
 int main( int argc, char* argv[] ) {
@@ -376,9 +521,8 @@
 	MPI_Init( &argc, &argv );
 
 	/* Initialise StGermain. */
-	BaseFoundation_Init( &argc, &argv );
-	BaseIO_Init( &argc, &argv );
-	BaseContainer_Init( &argc, &argv );
+	Base_Init( &argc, &argv );
+	DiscretisationMesh_Init( &argc, &argv );
 
 	/* Create the test suite. */
 	suite = TestSuite_New();
@@ -392,9 +536,8 @@
 	FreeObject( suite );
 
 	/* Finalise StGermain. */
-	BaseContainer_Finalise();
-	BaseIO_Finalise();
-	BaseFoundation_Finalise();
+	DiscretisationMesh_Finalise();
+	Base_Finalise();
 
 	/* Close off MPI */
 	MPI_Finalize();

Modified: long/3D/Gale/trunk/src/StGermain/Discretisation/Mesh/tests/testMeshTopology.c
===================================================================
--- long/3D/Gale/trunk/src/StGermain/Discretisation/Mesh/tests/testMeshTopology.c	2006-12-22 14:06:28 UTC (rev 5620)
+++ long/3D/Gale/trunk/src/StGermain/Discretisation/Mesh/tests/testMeshTopology.c	2006-12-22 14:06:32 UTC (rev 5621)
@@ -120,9 +120,7 @@
 	MPI_Init( &argc, &argv );
 
 	/* Initialise StGermain. */
-	BaseFoundation_Init( &argc, &argv );
-	BaseIO_Init( &argc, &argv );
-	BaseContainer_Init( &argc, &argv );
+	Base_Init( &argc, &argv );
 
 	/* Create the test suite. */
 	suite = TestSuite_New();
@@ -136,9 +134,7 @@
 	FreeObject( suite );
 
 	/* Finalise StGermain. */
-	BaseContainer_Finalise();
-	BaseIO_Finalise();
-	BaseFoundation_Finalise();
+	Base_Finalise();
 
 	/* Close off MPI */
 	MPI_Finalize();



More information about the cig-commits mailing list