[cig-commits] r5533 - in long/3D/Gale/trunk/src/StgFEM: . Apps/EnergySolver Apps/EnergySolver/tests Apps/EnergySolver/tests/AdvDiffSteadyState1D Apps/EnergySolver/tests/HomogeneousNaturalBCs Apps/StgFEM_Components Apps/StokesMomentumUzawa Apps/StokesMomentumUzawa/tests/LidDrivenIsoviscousAnalytic Apps/TempDiffusion Apps/TempDiffusion/tests/LinearTemperatureField Apps/ThermalConvection Apps/ThermalConvection/tests/ColumnViscosityAnalytic Assembly/src Discretisation/src Discretisation/tests Discretisation/tests/data SLE/MultiGrid/src SLE/ProvidedSystems/AdvectionDiffusion/src SLE/ProvidedSystems/AdvectionDiffusion/tests SLE/ProvidedSystems/Energy/src SLE/ProvidedSystems/StokesFlow/src SLE/SystemSetup/src SLE/SystemSetup/tests SLE/SystemSetup/tests/data SLE/src plugins/CompareFeVariableAgainstReferenceSolution plugins/FeVariableImportExporters/FeVariable_ImportExport_ABAQUS plugins/StandardConditionFunctions plugins/VelicAnalyticSolutions/Velic_solA src

walter at geodynamics.org walter at geodynamics.org
Thu Dec 7 15:29:45 PST 2006


Author: walter
Date: 2006-12-07 15:29:43 -0800 (Thu, 07 Dec 2006)
New Revision: 5533

Added:
   long/3D/Gale/trunk/src/StgFEM/Discretisation/src/C0Generator.c
   long/3D/Gale/trunk/src/StgFEM/Discretisation/src/C0Generator.h
   long/3D/Gale/trunk/src/StgFEM/Discretisation/src/C0Generator.meta
   long/3D/Gale/trunk/src/StgFEM/Discretisation/src/FeMesh.c
   long/3D/Gale/trunk/src/StgFEM/Discretisation/src/FeMesh.h
   long/3D/Gale/trunk/src/StgFEM/Discretisation/src/FeMesh.meta
   long/3D/Gale/trunk/src/StgFEM/Discretisation/src/FeMesh_Algorithms.c
   long/3D/Gale/trunk/src/StgFEM/Discretisation/src/FeMesh_Algorithms.h
   long/3D/Gale/trunk/src/StgFEM/Discretisation/src/FeMesh_Algorithms.meta
   long/3D/Gale/trunk/src/StgFEM/Discretisation/src/FeMesh_ElementType.c
   long/3D/Gale/trunk/src/StgFEM/Discretisation/src/FeMesh_ElementType.h
   long/3D/Gale/trunk/src/StgFEM/Discretisation/src/FeMesh_ElementType.meta
   long/3D/Gale/trunk/src/StgFEM/Discretisation/tests/data/wallVC.xml
   long/3D/Gale/trunk/src/StgFEM/Discretisation/tests/testFeEquationNumber.c
   long/3D/Gale/trunk/src/StgFEM/SLE/SystemSetup/tests/data/
   long/3D/Gale/trunk/src/StgFEM/SLE/SystemSetup/tests/data/wallVC.xml
   long/3D/Gale/trunk/src/StgFEM/SLE/SystemSetup/tests/testStiffnessMatrix.c
Removed:
   long/3D/Gale/trunk/src/StgFEM/Discretisation/src/Mesh.c
   long/3D/Gale/trunk/src/StgFEM/Discretisation/src/Mesh.h
   long/3D/Gale/trunk/src/StgFEM/Discretisation/src/Mesh.meta
   long/3D/Gale/trunk/src/StgFEM/Discretisation/tests/testFeEquationNumber-LM.c
   long/3D/Gale/trunk/src/StgFEM/SLE/src/StiffRemesher.c
   long/3D/Gale/trunk/src/StgFEM/SLE/src/StiffRemesher.h
   long/3D/Gale/trunk/src/StgFEM/SLE/src/StiffRemesher.meta
Modified:
   long/3D/Gale/trunk/src/StgFEM/
   long/3D/Gale/trunk/src/StgFEM/Apps/EnergySolver/EnergySolver2D.xml
   long/3D/Gale/trunk/src/StgFEM/Apps/EnergySolver/tests/AdvDiffSteadyState1D/AdvDiffSteadyState1D.c
   long/3D/Gale/trunk/src/StgFEM/Apps/EnergySolver/tests/HomogeneousNaturalBCs/HomogeneousNaturalBCs.c
   long/3D/Gale/trunk/src/StgFEM/Apps/EnergySolver/tests/homogeneousNaturalBCs.xml
   long/3D/Gale/trunk/src/StgFEM/Apps/StgFEM_Components/ConstantMesh.xml
   long/3D/Gale/trunk/src/StgFEM/Apps/StgFEM_Components/LinearMesh.xml
   long/3D/Gale/trunk/src/StgFEM/Apps/StgFEM_Components/PressureField.xml
   long/3D/Gale/trunk/src/StgFEM/Apps/StgFEM_Components/StokesFlowUzawa.xml
   long/3D/Gale/trunk/src/StgFEM/Apps/StgFEM_Components/TemperatureField.xml
   long/3D/Gale/trunk/src/StgFEM/Apps/StgFEM_Components/VelocityField.xml
   long/3D/Gale/trunk/src/StgFEM/Apps/StokesMomentumUzawa/LidDrivenConvection.xml
   long/3D/Gale/trunk/src/StgFEM/Apps/StokesMomentumUzawa/tests/LidDrivenIsoviscousAnalytic/LidDrivenIsoviscousAnalytic.c
   long/3D/Gale/trunk/src/StgFEM/Apps/TempDiffusion/TempDiffusion.xml
   long/3D/Gale/trunk/src/StgFEM/Apps/TempDiffusion/analyticTemperature.xml
   long/3D/Gale/trunk/src/StgFEM/Apps/TempDiffusion/tests/LinearTemperatureField/LinearTemperatureField.c
   long/3D/Gale/trunk/src/StgFEM/Apps/ThermalConvection/ThermalConvection.xml
   long/3D/Gale/trunk/src/StgFEM/Apps/ThermalConvection/tests/ColumnViscosityAnalytic/ColumnViscosityAnalytic.c
   long/3D/Gale/trunk/src/StgFEM/Assembly/src/GradientStiffnessMatrixTerm.c
   long/3D/Gale/trunk/src/StgFEM/Assembly/src/IsoviscousStressTensorTerm.c
   long/3D/Gale/trunk/src/StgFEM/Assembly/src/LaplacianStiffnessMatrixTerm.c
   long/3D/Gale/trunk/src/StgFEM/Assembly/src/ThermalBuoyancyForceTerm.c
   long/3D/Gale/trunk/src/StgFEM/Discretisation/src/AnalyticSolution.c
   long/3D/Gale/trunk/src/StgFEM/Discretisation/src/BilinearElementType.c
   long/3D/Gale/trunk/src/StgFEM/Discretisation/src/BilinearElementType.h
   long/3D/Gale/trunk/src/StgFEM/Discretisation/src/ConstantElementType.c
   long/3D/Gale/trunk/src/StgFEM/Discretisation/src/ConstantElementType.h
   long/3D/Gale/trunk/src/StgFEM/Discretisation/src/Discretisation.h
   long/3D/Gale/trunk/src/StgFEM/Discretisation/src/ElementType.c
   long/3D/Gale/trunk/src/StgFEM/Discretisation/src/ElementType.h
   long/3D/Gale/trunk/src/StgFEM/Discretisation/src/FeEquationNumber.c
   long/3D/Gale/trunk/src/StgFEM/Discretisation/src/FeEquationNumber.h
   long/3D/Gale/trunk/src/StgFEM/Discretisation/src/FeVariable.c
   long/3D/Gale/trunk/src/StgFEM/Discretisation/src/FeVariable.h
   long/3D/Gale/trunk/src/StgFEM/Discretisation/src/Init.c
   long/3D/Gale/trunk/src/StgFEM/Discretisation/src/LinkedDofInfo.c
   long/3D/Gale/trunk/src/StgFEM/Discretisation/src/OperatorFeVariable.c
   long/3D/Gale/trunk/src/StgFEM/Discretisation/src/OperatorFeVariable.h
   long/3D/Gale/trunk/src/StgFEM/Discretisation/src/ShapeFeVariable.c
   long/3D/Gale/trunk/src/StgFEM/Discretisation/src/TrilinearElementType.c
   long/3D/Gale/trunk/src/StgFEM/Discretisation/src/TrilinearElementType.h
   long/3D/Gale/trunk/src/StgFEM/Discretisation/src/types.h
   long/3D/Gale/trunk/src/StgFEM/Discretisation/tests/testElementType.c
   long/3D/Gale/trunk/src/StgFEM/Discretisation/tests/testFeEquationNumber-LinkedDofs.c
   long/3D/Gale/trunk/src/StgFEM/Discretisation/tests/testFeEquationNumber-LinkedDofs2.c
   long/3D/Gale/trunk/src/StgFEM/Discretisation/tests/testFeVariable-saveAndLoad.c
   long/3D/Gale/trunk/src/StgFEM/Discretisation/tests/testFeVariable-shadowing.c
   long/3D/Gale/trunk/src/StgFEM/Discretisation/tests/testFeVariable.c
   long/3D/Gale/trunk/src/StgFEM/Discretisation/tests/testIntegration.c
   long/3D/Gale/trunk/src/StgFEM/Discretisation/tests/testTrilinearShapeFunc.c
   long/3D/Gale/trunk/src/StgFEM/Discretisation/tests/testTrilinearShapeFuncLocalDerivs.c
   long/3D/Gale/trunk/src/StgFEM/SLE/MultiGrid/src/MGCoarsener_RegCartesian.c
   long/3D/Gale/trunk/src/StgFEM/SLE/ProvidedSystems/AdvectionDiffusion/src/AdvectionDiffusionSLE.c
   long/3D/Gale/trunk/src/StgFEM/SLE/ProvidedSystems/AdvectionDiffusion/src/AdvectionDiffusionSLE.h
   long/3D/Gale/trunk/src/StgFEM/SLE/ProvidedSystems/AdvectionDiffusion/src/LumpedMassMatrixForceTerm.c
   long/3D/Gale/trunk/src/StgFEM/SLE/ProvidedSystems/AdvectionDiffusion/src/Residual.c
   long/3D/Gale/trunk/src/StgFEM/SLE/ProvidedSystems/AdvectionDiffusion/src/ShapeFunctions.c
   long/3D/Gale/trunk/src/StgFEM/SLE/ProvidedSystems/AdvectionDiffusion/src/Timestep.c
   long/3D/Gale/trunk/src/StgFEM/SLE/ProvidedSystems/AdvectionDiffusion/src/UpwindParameter.c
   long/3D/Gale/trunk/src/StgFEM/SLE/ProvidedSystems/AdvectionDiffusion/tests/testLumpedMassMatrix.c
   long/3D/Gale/trunk/src/StgFEM/SLE/ProvidedSystems/AdvectionDiffusion/tests/testSUPGShapeFunc.c
   long/3D/Gale/trunk/src/StgFEM/SLE/ProvidedSystems/Energy/src/Energy_SLE_Solver.c
   long/3D/Gale/trunk/src/StgFEM/SLE/ProvidedSystems/StokesFlow/src/Stokes_SLE_UzawaSolver.c
   long/3D/Gale/trunk/src/StgFEM/SLE/ProvidedSystems/StokesFlow/src/UzawaPreconditionerTerm.c
   long/3D/Gale/trunk/src/StgFEM/SLE/SystemSetup/src/ForceVector.c
   long/3D/Gale/trunk/src/StgFEM/SLE/SystemSetup/src/SolutionVector.c
   long/3D/Gale/trunk/src/StgFEM/SLE/SystemSetup/src/StiffnessMatrix.c
   long/3D/Gale/trunk/src/StgFEM/SLE/SystemSetup/tests/testSolutionVector.c
   long/3D/Gale/trunk/src/StgFEM/SLE/SystemSetup/tests/testStiffnessMatrix-nonZeroCalculation-linkedDofs.c
   long/3D/Gale/trunk/src/StgFEM/SLE/SystemSetup/tests/testStiffnessMatrix-nonZeroCalculation.c
   long/3D/Gale/trunk/src/StgFEM/SLE/src/Init.c
   long/3D/Gale/trunk/src/StgFEM/SLE/src/SLE.h
   long/3D/Gale/trunk/src/StgFEM/plugins/CompareFeVariableAgainstReferenceSolution/CompareFeVariableAgainstReferenceSolution.c
   long/3D/Gale/trunk/src/StgFEM/plugins/FeVariableImportExporters/FeVariable_ImportExport_ABAQUS/FeVariable_ImportExport_ABAQUS.c
   long/3D/Gale/trunk/src/StgFEM/plugins/StandardConditionFunctions/StandardConditionFunctions.c
   long/3D/Gale/trunk/src/StgFEM/plugins/VelicAnalyticSolutions/Velic_solA/solA.c
   long/3D/Gale/trunk/src/StgFEM/plugins/VelicAnalyticSolutions/Velic_solA/solA.h
   long/3D/Gale/trunk/src/StgFEM/src/main.c
Log:
Merge in parallel changes from Luke


Property changes on: long/3D/Gale/trunk/src/StgFEM
___________________________________________________________________
Name: svk:merge
   - 38867592-cf10-0410-9e16-a142ea72ac34:/cig:880
db209038-57f2-0310-97fa-b160e0ae9d04:/trunk:669
   + 38867592-cf10-0410-9e16-a142ea72ac34:/cig:880
db209038-57f2-0310-97fa-b160e0ae9d04:/branches/decomp3d:671
db209038-57f2-0310-97fa-b160e0ae9d04:/trunk:669

Modified: long/3D/Gale/trunk/src/StgFEM/Apps/EnergySolver/EnergySolver2D.xml
===================================================================
--- long/3D/Gale/trunk/src/StgFEM/Apps/EnergySolver/EnergySolver2D.xml	2006-12-07 23:26:14 UTC (rev 5532)
+++ long/3D/Gale/trunk/src/StgFEM/Apps/EnergySolver/EnergySolver2D.xml	2006-12-07 23:29:43 UTC (rev 5533)
@@ -32,14 +32,12 @@
 	<param name="elementResI"> 10 </param>
 	<param name="elementResJ"> 10 </param>
 	<param name="elementResK"> 10 </param>
-	<param name="allowUnbalancing"> True </param>
 	
 	<!-- Integration Scheme configuration -->
 	<param name="gaussParticlesX"> 2 </param>
 	<param name="gaussParticlesY"> 2 </param>
 	<param name="gaussParticlesZ"> 2 </param>
 	
-	<include>../StgFEM_Components/ElementLayout.xml</include>
 	<include>../StgFEM_Components/LinearMesh.xml</include>
 	<include>../StgFEM_Components/VelocityField.xml</include>
 	<include>../StgFEM_Components/TemperatureField.xml</include>

Modified: long/3D/Gale/trunk/src/StgFEM/Apps/EnergySolver/tests/AdvDiffSteadyState1D/AdvDiffSteadyState1D.c
===================================================================
--- long/3D/Gale/trunk/src/StgFEM/Apps/EnergySolver/tests/AdvDiffSteadyState1D/AdvDiffSteadyState1D.c	2006-12-07 23:26:14 UTC (rev 5532)
+++ long/3D/Gale/trunk/src/StgFEM/Apps/EnergySolver/tests/AdvDiffSteadyState1D/AdvDiffSteadyState1D.c	2006-12-07 23:29:43 UTC (rev 5533)
@@ -53,6 +53,7 @@
 	double                    A;
 	double                    B;
 	double                    c;
+	FeVariable*		  temperatureField;
 } AdvDiffSteadyState1D;
 
 void AdvDiffSteadyState1D_TemperatureFunction( void* analyticSolution, FeVariable* analyticFeVariable, double* coord, double* temperature ) {
@@ -68,12 +69,12 @@
 	DiscretisationContext*	context    = (DiscretisationContext*)_context;
 	AdvDiffSteadyState1D*   self       = Stg_ComponentFactory_ConstructByName( context->CF, AdvDiffSteadyState1D_Type, AdvDiffSteadyState1D, True, 0 /* dummy */ );
 	FeVariable*             feVariable = NULL;
-	FiniteElement_Mesh*     mesh       = NULL;
+	FeMesh*     mesh       = NULL;
 	double*                 coord;
 	
 	feVariable = (FeVariable*)FieldVariable_Register_GetByName( context->fieldVariable_Register, "TemperatureField" );
 	mesh       = feVariable->feMesh;
-	coord      = Mesh_CoordAt( mesh, node_lI );
+	coord      = Mesh_GetVertex( mesh, node_lI );
 
 	AdvDiffSteadyState1D_TemperatureFunction( self, NULL, coord, temperature );
 }
@@ -87,6 +88,8 @@
 	AllNodesVC*           allNodesVC;
 	AllNodesVC_Entry*     vcEntry;
 
+	AnalyticSolution_CreateAnalyticField( self, self->temperatureField, AdvDiffSteadyState1D_TemperatureFunction );
+
 	_AnalyticSolution_Build( self, data );
 
 	/* Get AllNodes Variable Condition */
@@ -119,14 +122,12 @@
 
 void _AdvDiffSteadyState1D_Construct( void* analyticSolution, Stg_ComponentFactory* cf, void* data ) {
 	AdvDiffSteadyState1D*  self = (AdvDiffSteadyState1D*)analyticSolution;
-	FeVariable*            temperatureField;
 	AbstractContext*       context;
 	ConditionFunction*     condFunc;
 
 	_AnalyticSolution_Construct( self, cf, data );
 
-	temperatureField = Stg_ComponentFactory_ConstructByName( cf, "TemperatureField", FeVariable, True, data );
-	AnalyticSolution_CreateAnalyticField( self, temperatureField, AdvDiffSteadyState1D_TemperatureFunction );
+	self->temperatureField = Stg_ComponentFactory_ConstructByName( cf, "TemperatureField", FeVariable, True, data );
 
 	self->residual = Stg_ComponentFactory_ConstructByName( cf, "defaultResidualForceTerm", AdvDiffResidualForceTerm, True, data );
 

Modified: long/3D/Gale/trunk/src/StgFEM/Apps/EnergySolver/tests/HomogeneousNaturalBCs/HomogeneousNaturalBCs.c
===================================================================
--- long/3D/Gale/trunk/src/StgFEM/Apps/EnergySolver/tests/HomogeneousNaturalBCs/HomogeneousNaturalBCs.c	2006-12-07 23:26:14 UTC (rev 5532)
+++ long/3D/Gale/trunk/src/StgFEM/Apps/EnergySolver/tests/HomogeneousNaturalBCs/HomogeneousNaturalBCs.c	2006-12-07 23:29:43 UTC (rev 5533)
@@ -47,6 +47,7 @@
 typedef struct { 
 	__AnalyticSolution
 	double angle;
+	FeVariable* temperatureField;
 } HomogeneousNaturalBCs;
 
 
@@ -83,29 +84,26 @@
 		True,
 		0 );
 	FeVariable*             feVariable = NULL;
-	FiniteElement_Mesh*     mesh       = NULL;
+	FeMesh*			mesh       = NULL;
 	double*                 result     = (double*) _result;
 	double*                 coord;
 	
 	feVariable = (FeVariable*)FieldVariable_Register_GetByName( context->fieldVariable_Register, "TemperatureField" );
 	mesh       = feVariable->feMesh;
-	coord = Mesh_CoordAt( mesh, node_lI );
+	coord = Mesh_GetVertex( mesh, node_lI );
 
 	HomogeneousNaturalBCs_TemperatureFunction( self, feVariable, coord, result );
 }
 
 void _HomogeneousNaturalBCs_Construct( void* analyticSolution, Stg_ComponentFactory* cf, void* data ) {
 	HomogeneousNaturalBCs* self = (HomogeneousNaturalBCs*)analyticSolution;
-	FeVariable*            temperatureField;
 	AbstractContext*       context;
 	ConditionFunction*     condFunc;
 
 	_AnalyticSolution_Construct( self, cf, data );
 
-	temperatureField = Stg_ComponentFactory_ConstructByName( cf, "TemperatureField", FeVariable, True, data ); 
+	self->temperatureField = Stg_ComponentFactory_ConstructByName( cf, "TemperatureField", FeVariable, True, data ); 
 
-	AnalyticSolution_CreateAnalyticField( self, temperatureField, HomogeneousNaturalBCs_TemperatureFunction );
-
 	/* Create Condition Functions */
 	context = Stg_ComponentFactory_ConstructByName( cf, "context", AbstractContext, True, data ); 
 	condFunc = ConditionFunction_New( HomogeneousNaturalBCs_Velocity_SkewToMesh, "Velocity_SkewToMesh" );
@@ -114,6 +112,14 @@
 	ConditionFunction_Register_Add( context->condFunc_Register, condFunc );
 }
 
+void _HomogeneousNaturalBCs_Build( void* analyticSolution, void* data ) {
+	HomogeneousNaturalBCs* self = (HomogeneousNaturalBCs*)analyticSolution;	
+
+	AnalyticSolution_CreateAnalyticField( self, self->temperatureField, HomogeneousNaturalBCs_TemperatureFunction );
+
+	_AnalyticSolution_Build( self, data );
+}
+
 void* _HomogeneousNaturalBCs_DefaultNew( Name name ) {
 	return (void*) _AnalyticSolution_New( 
 			sizeof(HomogeneousNaturalBCs),
@@ -123,7 +129,7 @@
 			_AnalyticSolution_Copy,
 			_HomogeneousNaturalBCs_DefaultNew,
 			_HomogeneousNaturalBCs_Construct,
-			_AnalyticSolution_Build,
+			_HomogeneousNaturalBCs_Build,
 			_AnalyticSolution_Initialise,
 			_AnalyticSolution_Execute,
 			_AnalyticSolution_Destroy,

Modified: long/3D/Gale/trunk/src/StgFEM/Apps/EnergySolver/tests/homogeneousNaturalBCs.xml
===================================================================
--- long/3D/Gale/trunk/src/StgFEM/Apps/EnergySolver/tests/homogeneousNaturalBCs.xml	2006-12-07 23:26:14 UTC (rev 5532)
+++ long/3D/Gale/trunk/src/StgFEM/Apps/EnergySolver/tests/homogeneousNaturalBCs.xml	2006-12-07 23:29:43 UTC (rev 5533)
@@ -38,7 +38,7 @@
 				</list>
 			</struct>			
 		</list>
-	</struct>			
+	</struct>
 	<struct name="temperatureBCs" mergeType="replace">
 		<param name="type">CompositeVC</param>
 		<list name="vcList">

Modified: long/3D/Gale/trunk/src/StgFEM/Apps/StgFEM_Components/ConstantMesh.xml
===================================================================
--- long/3D/Gale/trunk/src/StgFEM/Apps/StgFEM_Components/ConstantMesh.xml	2006-12-07 23:26:14 UTC (rev 5532)
+++ long/3D/Gale/trunk/src/StgFEM/Apps/StgFEM_Components/ConstantMesh.xml	2006-12-07 23:29:43 UTC (rev 5533)
@@ -4,37 +4,18 @@
 <!-- DTD to validate against -->
 <StGermainData xmlns="http://www.vpac.org/StGermain/XML_IO_Handler/Jun2003">
 
-	<!-- Constant Mesh Stuff -->
-	<struct name="components" mergeType="merge">
-		<struct name="bodyNodeTopology">
-			<param name="Type">IJK6Topology</param>
-			<param name="sizeI">elementResI</param>
-			<param name="sizeJ">elementResJ</param>
-			<param name="sizeK">elementResK</param>
-		</struct>	
-		<struct name="bodyNodeLayout">
-			<param name="Type">BodyNL</param>
-			<param name="ElementLayout">elementLayout</param>
-			<param name="Topology">bodyNodeTopology</param>
-		</struct>
-		<struct name="decomp-constant">
-			<param name="Type">HexaMD</param>
-			<param name="ElementLayout">elementLayout</param>
-			<param name="NodeLayout">bodyNodeLayout</param>
-			<param name="numPartitionedDims">numPartitionedDims</param>
-		</struct>
-		<struct name="meshLayout-constant">
-			<param name="Type">MeshLayout</param>
-			<param name="ElementLayout">elementLayout</param>
-			<param name="NodeLayout">bodyNodeLayout</param>
-			<param name="MeshDecomp">decomp-constant</param>
-		</struct>		
-		<struct name="mesh-constant">
-			<param name="Type">FiniteElement_Mesh</param>
-			<param name="MeshLayout">meshLayout-constant</param>
-			<param name="ElementSize">8</param>
-			<param name="NodeSize">0</param>
-		</struct>
-	</struct>
+  <!-- Constant Mesh Stuff -->
+  <struct name="components" mergeType="merge">
+    <struct name="mesh-constant">
+      <param name="Type"> FeMesh </param>
+      <param name="elementType"> constant </param>
+      <param name="elementMesh"> mesh-linear </param>
+    </struct>
 
+    <struct name="constantMesh-generator">
+      <param name="Type"> C0Generator </param>
+      <param name="mesh"> mesh-constant </param>
+    </struct>
+  </struct>
+
 </StGermainData>

Modified: long/3D/Gale/trunk/src/StgFEM/Apps/StgFEM_Components/LinearMesh.xml
===================================================================
--- long/3D/Gale/trunk/src/StgFEM/Apps/StgFEM_Components/LinearMesh.xml	2006-12-07 23:26:14 UTC (rev 5532)
+++ long/3D/Gale/trunk/src/StgFEM/Apps/StgFEM_Components/LinearMesh.xml	2006-12-07 23:29:43 UTC (rev 5533)
@@ -3,39 +3,35 @@
 <!-- A StGermain input file -->
 <!-- DTD to validate against -->
 <StGermainData xmlns="http://www.vpac.org/StGermain/XML_IO_Handler/Jun2003">
-	
-	<!-- Linear Mesh Stuff -->
-	<struct name="components" mergeType="merge">
-		<struct name="cornerNodeTopology">
-			<param name="Type">IJK6Topology</param>
-			<param name="sizeI">elementResI</param>
-			<param name="sizeJ">elementResJ</param>
-			<param name="sizeK">elementResK</param>
-			<param name="sizeShift">1</param>
-		</struct>	
-		<struct name="cornerNodeLayout">
-			<param name="Type">CornerNL</param>
-			<param name="ElementLayout">elementLayout</param>
-			<param name="Topology">cornerNodeTopology</param>
-		</struct>
-		<struct name="decomp-linear">
-			<param name="Type">HexaMD</param>
-			<param name="ElementLayout">elementLayout</param>
-			<param name="NodeLayout">cornerNodeLayout</param>
-			<param name="numPartitionedDims">numPartitionedDims</param>
-		</struct>
-		<struct name="meshLayout-linear">
-			<param name="Type">MeshLayout</param>
-			<param name="ElementLayout">elementLayout</param>
-			<param name="NodeLayout">cornerNodeLayout</param>
-			<param name="MeshDecomp">decomp-linear</param>
-		</struct>		
-		<struct name="mesh-linear">
-			<param name="Type">FiniteElement_Mesh</param>
-			<param name="MeshLayout">meshLayout-linear</param>
-			<param name="ElementSize">8</param>
-			<param name="NodeSize">0</param>
-		</struct>
-	</struct>
 
+  <!-- Linear Mesh Stuff -->
+  <struct name="components" mergeType="merge">
+    <struct name="mesh-linear">
+      <param name="Type"> FeMesh </param>
+      <param name="elementType"> linear </param>
+    </struct>
+
+    <struct name="linearMesh-generator">
+      <param name="Type"> CartesianGenerator </param>
+      <param name="mesh"> mesh-linear </param>
+      <param name="dim"> dim </param>
+      <param name="shadowDepth"> shadowDepth </param>
+      <list name="size">
+	<param> elementResI </param>
+	<param> elementResJ </param>
+	<param> elementResK </param>
+      </list>
+      <list name="minCoord">
+	<param> minX </param>
+	<param> minY </param>
+	<param> minZ </param>
+      </list>
+      <list name="maxCoord">
+	<param> maxX </param>
+	<param> maxY </param>
+	<param> maxZ </param>
+      </list>
+    </struct>
+  </struct>
+
 </StGermainData>

Modified: long/3D/Gale/trunk/src/StgFEM/Apps/StgFEM_Components/PressureField.xml
===================================================================
--- long/3D/Gale/trunk/src/StgFEM/Apps/StgFEM_Components/PressureField.xml	2006-12-07 23:26:14 UTC (rev 5532)
+++ long/3D/Gale/trunk/src/StgFEM/Apps/StgFEM_Components/PressureField.xml	2006-12-07 23:29:43 UTC (rev 5533)
@@ -7,15 +7,14 @@
 	<!-- PressureField Stuff -->
 	<struct name="components" mergeType="merge">
 		<struct name="pressure">
-			<param name="Type">Variable</param>
+			<param name="Type">MeshVariable</param>
+			<param name="mesh">mesh-constant</param>
 			<param name="Rank">Scalar</param>
-			<param name="Dependency">decomp-constant</param>
 			<param name="DataType">Double</param>
-			<param name="Count">decomp-constant-nodeDomainCount</param>
 		</struct>
 		<struct name="pressureDofLayout">
 			<param name="Type">DofLayout</param>
-			<param name="Count">decomp-constant-nodeDomainCount</param>
+			<param name="mesh">mesh-constant</param>
 			<list name="BaseVariables">
 				<param>pressure</param>
 			</list>
@@ -23,7 +22,6 @@
 		<struct name="PressureField">
 			<param name="Type">FeVariable</param>
 			<param name="FEMesh">mesh-constant</param>
-			<param name="GeometryMesh">mesh-linear</param>
 			<param name="DofLayout">pressureDofLayout</param>
 			<param name="LinkedDofInfo">pressureLinkedDofs</param>
 		</struct>

Modified: long/3D/Gale/trunk/src/StgFEM/Apps/StgFEM_Components/StokesFlowUzawa.xml
===================================================================
--- long/3D/Gale/trunk/src/StgFEM/Apps/StgFEM_Components/StokesFlowUzawa.xml	2006-12-07 23:26:14 UTC (rev 5532)
+++ long/3D/Gale/trunk/src/StgFEM/Apps/StgFEM_Components/StokesFlowUzawa.xml	2006-12-07 23:29:43 UTC (rev 5533)
@@ -32,7 +32,7 @@
 		<struct name="k_matrix">
 			<param name="Type">StiffnessMatrix</param>
 			<param name="RowVariable">VelocityField</param>
-			<param name="ColumnVariable">VelocityField</param>	
+			<param name="ColumnVariable">VelocityField</param>
 			<param name="RHS">mom_force</param>
 			<param name="allowZeroElementContributions">False</param>
 		</struct>

Modified: long/3D/Gale/trunk/src/StgFEM/Apps/StgFEM_Components/TemperatureField.xml
===================================================================
--- long/3D/Gale/trunk/src/StgFEM/Apps/StgFEM_Components/TemperatureField.xml	2006-12-07 23:26:14 UTC (rev 5532)
+++ long/3D/Gale/trunk/src/StgFEM/Apps/StgFEM_Components/TemperatureField.xml	2006-12-07 23:29:43 UTC (rev 5533)
@@ -7,41 +7,40 @@
 	<!-- TemperatureField Stuff -->
 	<struct name="components" mergeType="merge">
 		<struct name="temperature">
-			<param name="Type">Variable</param>
-			<param name="Rank">Scalar</param>
-			<param name="Dependency">decomp-linear</param>
-			<param name="DataType">Double</param>
-			<param name="Count">decomp-linear-nodeDomainCount</param>
+			<param name="Type"> MeshVariable </param>
+			<param name="Rank"> Scalar </param>
+			<param name="DataType"> Double </param>
+			<param name="mesh"> mesh-linear </param>
 		</struct>
 		<struct name="temperatureBCs">
-			<param name="Type">CompositeVC</param>
-			<param name="Data">mesh-linear</param>
+			<param name="Type"> CompositeVC </param>
+			<param name="Data"> mesh-linear </param>
 		</struct>
 		<struct name="temperatureICs">
-			<param name="Type">CompositeVC</param>
-			<param name="Data">mesh-linear</param>
-		</struct>		
+			<param name="Type"> CompositeVC </param>
+			<param name="Data"> mesh-linear </param>
+		</struct>
 		<struct name="temperatureDofLayout">
-			<param name="Type">DofLayout</param>
-			<param name="Count">decomp-linear-nodeDomainCount</param>
+			<param name="Type"> DofLayout </param>
+			<param name="mesh"> mesh-linear </param>
 			<list name="BaseVariables">
 				<param>temperature</param>
 			</list>
-		</struct>		
+		</struct>
 		<struct name="TemperatureField">
-			<param name="Type">FeVariable</param>
-			<param name="FEMesh">mesh-linear</param>
-			<param name="DofLayout">temperatureDofLayout</param>
-			<param name="BC">temperatureBCs</param>
-			<param name="IC">temperatureICs</param>
-			<param name="LinkedDofInfo">temperatureLinkedDofs</param>
+			<param name="Type"> FeVariable </param>
+			<param name="FEMesh"> mesh-linear </param>
+			<param name="DofLayout"> temperatureDofLayout </param>
+			<param name="BC"> temperatureBCs </param>
+			<param name="IC"> temperatureICs </param>
+			<param name="LinkedDofInfo"> temperatureLinkedDofs </param>
 		</struct>
 
 		<!-- Standard Operators on velocity field -->
 		<struct name="TemperatureGradientsField"> 
-			<param name="Type">OperatorFeVariable</param>
-			<param name="Operator">Gradient</param>
-			<param name="FeVariable">TemperatureField</param>
+			<param name="Type"> OperatorFeVariable </param>
+			<param name="Operator"> Gradient </param>
+			<param name="FeVariable"> TemperatureField </param>
 		</struct>	
 	</struct>
 

Modified: long/3D/Gale/trunk/src/StgFEM/Apps/StgFEM_Components/VelocityField.xml
===================================================================
--- long/3D/Gale/trunk/src/StgFEM/Apps/StgFEM_Components/VelocityField.xml	2006-12-07 23:26:14 UTC (rev 5532)
+++ long/3D/Gale/trunk/src/StgFEM/Apps/StgFEM_Components/VelocityField.xml	2006-12-07 23:29:43 UTC (rev 5533)
@@ -7,11 +7,10 @@
 	<!-- VelocityField Stuff -->
 	<struct name="components" mergeType="merge">
 		<struct name="velocity">
-			<param name="Type">Variable</param>
+			<param name="Type">MeshVariable</param>
+			<param name="mesh">mesh-linear</param>
 			<param name="Rank">Vector</param>
-			<param name="Dependency">decomp-linear</param>
 			<param name="DataType">Double</param>
-			<param name="Count">decomp-linear-nodeDomainCount</param>
 			<param name="VectorComponentCount">dim</param>
 			<list name="names">
 				<param>vx</param>
@@ -29,14 +28,14 @@
 		</struct>		
 		<struct name="velocityDofLayout">
 			<param name="Type">DofLayout</param>
-			<param name="Count">decomp-linear-nodeDomainCount</param>
+			<param name="mesh">mesh-linear</param>
 			<param name="BaseVariableCount">dim</param>
 			<list name="BaseVariables">
 				<param>vx</param>
 				<param>vy</param>
 				<param>vz</param>
 			</list>
-		</struct>		
+		</struct>
 		<struct name="VelocityField">
 			<param name="Type">FeVariable</param>
 			<param name="FEMesh">mesh-linear</param>
@@ -56,7 +55,7 @@
 			<param name="Type">OperatorFeVariable</param>
 			<param name="Operator">Gradient</param>
 			<param name="FeVariable">VelocityField</param>
-		</struct>		
+		</struct>
 		<struct name="VelocityGradientsInvariantField"> 
 			<param name="Type">OperatorFeVariable</param>
 			<param name="Operator">TensorInvariant</param>
@@ -85,7 +84,7 @@
 			<param name="Type">OperatorFeVariable</param>
 			<param name="Operator">TensorSymmetricPart</param>
 			<param name="FeVariable">VelocityGradientsField</param>
-		</struct>		
+		</struct>
 		<struct name="VorticityField"> 
 			<param name="Type">OperatorFeVariable</param>
 			<param name="Operator">TensorAntisymmetricPart</param>
@@ -100,19 +99,19 @@
 			<param name="Type">OperatorFeVariable</param>
 			<param name="Operator">TakeFirstComponent</param>
 			<param name="FeVariable">StrainRateField</param>
-		</struct>			
+		</struct>
 		<struct name="StrainRateYYField"> 
 			<param name="Type">OperatorFeVariable</param>
 			<param name="Operator">TakeSecondComponent</param>
 			<param name="FeVariable">StrainRateField</param>
-		</struct>		
+		</struct>
 		<!--
 		<struct name="StrainRateZZField"> 
 			<param name="Type">OperatorFeVariable</param>
 			<param name="Operator">TakeThirdComponent</param>
 			<param name="FeVariable">StrainRateField</param>
-		</struct>		
-		-->	
+		</struct>
+		-->
 	</struct>
 	
 </StGermainData>

Modified: long/3D/Gale/trunk/src/StgFEM/Apps/StokesMomentumUzawa/LidDrivenConvection.xml
===================================================================
--- long/3D/Gale/trunk/src/StgFEM/Apps/StokesMomentumUzawa/LidDrivenConvection.xml	2006-12-07 23:26:14 UTC (rev 5532)
+++ long/3D/Gale/trunk/src/StgFEM/Apps/StokesMomentumUzawa/LidDrivenConvection.xml	2006-12-07 23:29:43 UTC (rev 5533)
@@ -31,17 +31,15 @@
 	<param name="maxX"> 1.0f </param>
 	<param name="maxY"> 1.0f </param>
 	<param name="maxZ"> 1.0f </param>
-	<param name="elementResI"> 9 </param>
-	<param name="elementResJ"> 9 </param>
+	<param name="elementResI"> 12 </param>
+	<param name="elementResJ"> 12 </param>
 	<param name="elementResK"> 2 </param>
-	<param name="allowUnbalancing"> True </param>
 
 	<!-- Integration Scheme configuration -->
 	<!--param name="gaussParticlesX"> 2 </param>
 	<param name="gaussParticlesY"> 2 </param>
 	<param name="gaussParticlesZ"> 2 </param-->
 	
-	<include>../StgFEM_Components/ElementLayout.xml          </include>
 	<include>../StgFEM_Components/ConstantMesh.xml           </include>
 	<include>../StgFEM_Components/LinearMesh.xml             </include>
 	<include>../StgFEM_Components/VelocityField.xml          </include>

Modified: long/3D/Gale/trunk/src/StgFEM/Apps/StokesMomentumUzawa/tests/LidDrivenIsoviscousAnalytic/LidDrivenIsoviscousAnalytic.c
===================================================================
--- long/3D/Gale/trunk/src/StgFEM/Apps/StokesMomentumUzawa/tests/LidDrivenIsoviscousAnalytic/LidDrivenIsoviscousAnalytic.c	2006-12-07 23:26:14 UTC (rev 5532)
+++ long/3D/Gale/trunk/src/StgFEM/Apps/StokesMomentumUzawa/tests/LidDrivenIsoviscousAnalytic/LidDrivenIsoviscousAnalytic.c	2006-12-07 23:29:43 UTC (rev 5533)
@@ -50,6 +50,8 @@
 	__AnalyticSolution 
 	unsigned int wavenumber;
 	double A, B, C, D;
+	FeVariable* velocityField;
+	FeVariable* pressureField;
 } LidDrivenIsoviscousAnalytic;
 
 
@@ -123,22 +125,29 @@
 
 void _LidDrivenIsoviscousAnalytic_Construct( void* analyticSolution, Stg_ComponentFactory* cf, void* data ) {
 	LidDrivenIsoviscousAnalytic *self = (LidDrivenIsoviscousAnalytic*)analyticSolution;
-	FeVariable*       velocityField;
-	FeVariable*       pressureField;
 
 	_AnalyticSolution_Construct( self, cf, data );
 
-	velocityField = Stg_ComponentFactory_ConstructByName( cf, "VelocityField", FeVariable, True, data ); 
-	AnalyticSolution_CreateAnalyticVectorField( self, velocityField, LidDrivenIsoviscousAnalytic_VelocityFunction );
+	self->velocityField = Stg_ComponentFactory_ConstructByName( cf, "VelocityField", FeVariable, True, data ); 
+	self->pressureField = Stg_ComponentFactory_ConstructByName( cf, "PressureField", FeVariable, True, data ); 
 
-	pressureField = Stg_ComponentFactory_ConstructByName( cf, "PressureField", FeVariable, True, data ); 
-	AnalyticSolution_CreateAnalyticField( self, pressureField, LidDrivenIsoviscousAnalytic_PressureFunction );
-
 	/* Set constants */
 	self->wavenumber = Stg_ComponentFactory_GetRootDictUnsignedInt( cf, "sinusoidalLidWavenumber", 1 );
 	LidDrivenIsoviscousAnalytic_CalculateConstants( self );
 }
 
+void _LidDrivenIsoviscousAnalytic_Build( void* analyticSolution, void* data ) {
+	LidDrivenIsoviscousAnalytic *self = (LidDrivenIsoviscousAnalytic*)analyticSolution;
+
+	Build( self->velocityField, data, False );
+	Build( self->velocityField, data, False );
+
+	AnalyticSolution_CreateAnalyticVectorField( self, self->velocityField, LidDrivenIsoviscousAnalytic_VelocityFunction );
+	AnalyticSolution_CreateAnalyticField( self, self->pressureField, LidDrivenIsoviscousAnalytic_PressureFunction );
+
+	_AnalyticSolution_Build( self, data );
+}
+
 void* _LidDrivenIsoviscousAnalytic_DefaultNew( Name name ) {
 	return (void*) _AnalyticSolution_New( 
 			sizeof(LidDrivenIsoviscousAnalytic),
@@ -148,7 +157,7 @@
 			_AnalyticSolution_Copy,
 			_LidDrivenIsoviscousAnalytic_DefaultNew,
 			_LidDrivenIsoviscousAnalytic_Construct,
-			_AnalyticSolution_Build,
+			_LidDrivenIsoviscousAnalytic_Build, 
 			_AnalyticSolution_Initialise,
 			_AnalyticSolution_Execute,
 			_AnalyticSolution_Destroy,

Modified: long/3D/Gale/trunk/src/StgFEM/Apps/TempDiffusion/TempDiffusion.xml
===================================================================
--- long/3D/Gale/trunk/src/StgFEM/Apps/TempDiffusion/TempDiffusion.xml	2006-12-07 23:26:14 UTC (rev 5532)
+++ long/3D/Gale/trunk/src/StgFEM/Apps/TempDiffusion/TempDiffusion.xml	2006-12-07 23:29:43 UTC (rev 5533)
@@ -23,7 +23,7 @@
 	<param name="journal-level-branch.debug.StgFEM"> 1 </param>
 	
 	<!-- Geometry & Mesh setup -->
-	<param name="dim"> 2 </param>
+	<param name="dim"> 3 </param>
 	<param name="shadowDepth"> 1 </param>
 	<param name="minX"> 0.0f </param>
 	<param name="minY"> 0.0f </param>
@@ -34,7 +34,6 @@
 	<param name="elementResI"> 5 </param>
 	<param name="elementResJ"> 5 </param>
 	<param name="elementResK"> 5 </param>
-	<param name="allowUnbalancing"> True </param>
 	
 	<!-- Set up BCs -->
 	<include>standardTempBCs.xml</include>
@@ -48,7 +47,6 @@
 		<param>TemperatureField</param>
 	</list>
 	
-	<include>../StgFEM_Components/ElementLayout.xml       </include>
 	<include>../StgFEM_Components/LinearMesh.xml          </include>
 	<include>../StgFEM_Components/TemperatureField.xml    </include>
 	<include>../StgFEM_Components/GaussSwarm.xml          </include>

Modified: long/3D/Gale/trunk/src/StgFEM/Apps/TempDiffusion/analyticTemperature.xml
===================================================================
--- long/3D/Gale/trunk/src/StgFEM/Apps/TempDiffusion/analyticTemperature.xml	2006-12-07 23:26:14 UTC (rev 5532)
+++ long/3D/Gale/trunk/src/StgFEM/Apps/TempDiffusion/analyticTemperature.xml	2006-12-07 23:29:43 UTC (rev 5533)
@@ -4,11 +4,10 @@
 <!-- DTD to validate against -->
 <StGermainData xmlns="http://www.vpac.org/StGermain/XML_IO_Handler/Jun2003">
 
-
 	<list name="plugins" mergeType="merge">
-		<param>StgFEM_LinearTemperatureField</param>
+		<param> StgFEM_LinearTemperatureField </param>
 	</list>
 
-	<param name="TemperatureField-Tolerance">1.0e-4</param>
+	<param name="TemperatureField-Tolerance"> 1.0e-4 </param>
 
 </StGermainData>

Modified: long/3D/Gale/trunk/src/StgFEM/Apps/TempDiffusion/tests/LinearTemperatureField/LinearTemperatureField.c
===================================================================
--- long/3D/Gale/trunk/src/StgFEM/Apps/TempDiffusion/tests/LinearTemperatureField/LinearTemperatureField.c	2006-12-07 23:26:14 UTC (rev 5532)
+++ long/3D/Gale/trunk/src/StgFEM/Apps/TempDiffusion/tests/LinearTemperatureField/LinearTemperatureField.c	2006-12-07 23:29:43 UTC (rev 5533)
@@ -44,7 +44,7 @@
 
 const Type LinearTemperatureField_Type = "LinearTemperatureField";
 
-typedef struct { __AnalyticSolution } LinearTemperatureField;
+typedef struct { __AnalyticSolution FeVariable* temperatureField; } LinearTemperatureField;
 
 void LinearTemperatureField_TemperatureFunction( void* analyticSolution, FeVariable* analyticFeVariable, double* coord, double* value ) {
 	*value = 1.0 - coord[ J_AXIS ];
@@ -53,13 +53,18 @@
 
 void _LinearTemperatureField_Construct( void* analyticSolution, Stg_ComponentFactory* cf, void* data ) {
 	LinearTemperatureField *self = (LinearTemperatureField*)analyticSolution;
-	FeVariable*       temperatureField;
 
 	_AnalyticSolution_Construct( self, cf, data );
 
-	temperatureField = Stg_ComponentFactory_ConstructByName( cf, "TemperatureField", FeVariable, True, data ); 
+	self->temperatureField = Stg_ComponentFactory_ConstructByName( cf, "TemperatureField", FeVariable, True, data ); 
+}
 
-	AnalyticSolution_CreateAnalyticField( self, temperatureField, LinearTemperatureField_TemperatureFunction );
+void _LinearTemperatureField_Build( void* analyticSolution, void* data ) {
+	LinearTemperatureField *self = (LinearTemperatureField*)analyticSolution;
+
+	AnalyticSolution_CreateAnalyticField( self, self->temperatureField, LinearTemperatureField_TemperatureFunction );
+
+	_AnalyticSolution_Build( self, data );
 }
 
 void* _LinearTemperatureField_DefaultNew( Name name ) {
@@ -71,7 +76,7 @@
 			_AnalyticSolution_Copy,
 			_LinearTemperatureField_DefaultNew,
 			_LinearTemperatureField_Construct,
-			_AnalyticSolution_Build,
+			_LinearTemperatureField_Build,
 			_AnalyticSolution_Initialise,
 			_AnalyticSolution_Execute,
 			_AnalyticSolution_Destroy,

Modified: long/3D/Gale/trunk/src/StgFEM/Apps/ThermalConvection/ThermalConvection.xml
===================================================================
--- long/3D/Gale/trunk/src/StgFEM/Apps/ThermalConvection/ThermalConvection.xml	2006-12-07 23:26:14 UTC (rev 5532)
+++ long/3D/Gale/trunk/src/StgFEM/Apps/ThermalConvection/ThermalConvection.xml	2006-12-07 23:29:43 UTC (rev 5533)
@@ -11,7 +11,6 @@
 	</list>
 
 	<!-- Include Components that define the basic model -->
-	<include>../StgFEM_Components/ElementLayout.xml          </include>
 	<include>../StgFEM_Components/ConstantMesh.xml           </include>
 	<include>../StgFEM_Components/LinearMesh.xml             </include>
 	<include>../StgFEM_Components/VelocityField.xml          </include>

Modified: long/3D/Gale/trunk/src/StgFEM/Apps/ThermalConvection/tests/ColumnViscosityAnalytic/ColumnViscosityAnalytic.c
===================================================================
--- long/3D/Gale/trunk/src/StgFEM/Apps/ThermalConvection/tests/ColumnViscosityAnalytic/ColumnViscosityAnalytic.c	2006-12-07 23:26:14 UTC (rev 5532)
+++ long/3D/Gale/trunk/src/StgFEM/Apps/ThermalConvection/tests/ColumnViscosityAnalytic/ColumnViscosityAnalytic.c	2006-12-07 23:29:43 UTC (rev 5533)
@@ -54,6 +54,9 @@
 	double ZB;
 	double xc;
 	double C1A,C2A,C3A,C4A,C1B,C2B,C3B,C4B;
+	FeVariable* velocityField;
+	FeVariable* pressureField;
+	FeVariable* stressField;
 } ColumnViscosityAnalytic;
 
 #define SMALL 1.0e-5
@@ -67,8 +70,7 @@
 void ColumnViscosityAnalytic_TemperatureIC( Node_LocalIndex node_lI, Variable_Index var_I, void* _context, void* _result ) {
 	DiscretisationContext*  context            = (DiscretisationContext*)_context;
 	FeVariable*             temperatureField   = (FeVariable*) FieldVariable_Register_GetByName( context->fieldVariable_Register, "TemperatureField" );
-	FiniteElement_Mesh*     mesh               = temperatureField->feMesh;
-	BlockGeometry*          geometry           = (BlockGeometry*) mesh->layout->elementLayout->geometry;
+	FeMesh*     mesh               = temperatureField->feMesh;
 	Dictionary*             dictionary         = context->dictionary;
 	double*                 result             = (double*) _result;
 	double*                 coord;
@@ -79,16 +81,18 @@
 	int                     wavenumberX;
 	int                     wavenumberY;
 	double                  L;
+	double			min[3], max[3];
 	
 	/* Find coordinate of node */
-	coord = Mesh_CoordAt( mesh, node_lI );
+	coord = Mesh_GetVertex( mesh, node_lI );
 
 	/* Make sure that the box has right dimensions */
-	assert( ( geometry->max[ J_AXIS ] - geometry->min[ J_AXIS ] - 1.0 ) < SMALL );
-	L = geometry->max[ I_AXIS ] - geometry->min[ I_AXIS ];
+	Mesh_GetGlobalCoordRange( mesh, min, max );
+	assert( ( max[ J_AXIS ] - min[ J_AXIS ] - 1.0 ) < SMALL );
+	L = max[ I_AXIS ] - min[ I_AXIS ];
 
-	x = coord[ I_AXIS ] - geometry->min[ I_AXIS ];
-	y = coord[ J_AXIS ] - geometry->min[ J_AXIS ];
+	x = coord[ I_AXIS ] - min[ I_AXIS ];
+	y = coord[ J_AXIS ] - min[ J_AXIS ];
 
 	wavenumberX = Dictionary_GetInt_WithDefault( dictionary, "wavenumberX", 1 );
 	wavenumberY = Dictionary_GetInt_WithDefault( dictionary, "wavenumberY", 1 );
@@ -2565,9 +2569,6 @@
 	ColumnViscosityAnalytic* self = (ColumnViscosityAnalytic*)analyticSolution;
 	AbstractContext*         context;
 	ConditionFunction*       condFunc;
-	FeVariable*              velocityField;
-	FeVariable*              pressureField;
-	FeVariable*              stressField;
 
 	/* Construct Parent */
 	_AnalyticSolution_Construct( self, cf, data );
@@ -2575,16 +2576,10 @@
 	context = Stg_ComponentFactory_ConstructByName( cf, "context", AbstractContext, True, data ); 
 	
 	/* Create Analytic Fields */
-	velocityField = Stg_ComponentFactory_ConstructByName( cf, "VelocityField", FeVariable, True, data ); 
-	AnalyticSolution_CreateAnalyticField( self, velocityField, ColumnViscosityAnalytic_VelocityFunction );
+	self->velocityField = Stg_ComponentFactory_ConstructByName( cf, "VelocityField", FeVariable, True, data ); 
+	self->pressureField = Stg_ComponentFactory_ConstructByName( cf, "PressureField", FeVariable, True, data ); 
+	self->stressField = Stg_ComponentFactory_ConstructByName( cf, "StressField", FeVariable, False, data ); 
 
-	pressureField = Stg_ComponentFactory_ConstructByName( cf, "PressureField", FeVariable, True, data ); 
-	AnalyticSolution_CreateAnalyticField( self, pressureField, ColumnViscosityAnalytic_PressureFunction );
-
-	stressField = Stg_ComponentFactory_ConstructByName( cf, "StressField", FeVariable, False, data ); 
-	if ( stressField ) 
-		AnalyticSolution_CreateAnalyticField( self, stressField, ColumnViscosityAnalytic_StressFunction );
-
 	/* Add condition function for temperature */
 	condFunc = ConditionFunction_New( ColumnViscosityAnalytic_TemperatureIC, "ColumnViscosityAnalytic_TemperatureIC" );
 	ConditionFunction_Register_Add( context->condFunc_Register, condFunc );
@@ -2598,6 +2593,22 @@
 	ColumnViscosityAnalytic_Constants( self );
 }
 
+void _ColumnViscosityAnalytic_Build( void* analyticSolution, void* data ) {
+	ColumnViscosityAnalytic* self = (ColumnViscosityAnalytic*)analyticSolution;
+
+	Build( self->velocityField, data, False );
+	Build( self->pressureField, data, False );
+	if( self->stressField )
+		Build( self->stressField, data, False );
+
+	AnalyticSolution_CreateAnalyticField( self, self->velocityField, ColumnViscosityAnalytic_VelocityFunction );
+	AnalyticSolution_CreateAnalyticField( self, self->pressureField, ColumnViscosityAnalytic_PressureFunction );
+	if( self->stressField ) 
+		AnalyticSolution_CreateAnalyticField( self, self->stressField, ColumnViscosityAnalytic_StressFunction );
+
+	_AnalyticSolution_Build( self, data );
+}
+
 void* _ColumnViscosityAnalytic_DefaultNew( Name name ) {
 	return _AnalyticSolution_New(
 			sizeof(ColumnViscosityAnalytic),
@@ -2607,7 +2618,7 @@
 			_AnalyticSolution_Copy,
 			_ColumnViscosityAnalytic_DefaultNew,
 			_ColumnViscosityAnalytic_Construct,
-			_AnalyticSolution_Build,
+			_ColumnViscosityAnalytic_Build, 
 			_AnalyticSolution_Initialise,
 			_AnalyticSolution_Execute,
 			_AnalyticSolution_Destroy,

Modified: long/3D/Gale/trunk/src/StgFEM/Assembly/src/GradientStiffnessMatrixTerm.c
===================================================================
--- long/3D/Gale/trunk/src/StgFEM/Assembly/src/GradientStiffnessMatrixTerm.c	2006-12-07 23:26:14 UTC (rev 5532)
+++ long/3D/Gale/trunk/src/StgFEM/Assembly/src/GradientStiffnessMatrixTerm.c	2006-12-07 23:29:43 UTC (rev 5533)
@@ -220,10 +220,10 @@
 	ElementType*                        elementType_col;
 	
 	/* Set the element type */
-	elementType_row = FeMesh_ElementTypeAt( variable_row->feMesh, lElement_I );
+	elementType_row = FeMesh_GetElementType( variable_row->feMesh, lElement_I );
 	nodesPerEl_row = elementType_row->nodeCount;
 	
-	elementType_col = FeMesh_ElementTypeAt( variable_col->feMesh, lElement_I );
+	elementType_col = FeMesh_GetElementType( variable_col->feMesh, lElement_I );
 	nodesPerEl_col = elementType_col->nodeCount;
 		
 	dofPerNode_row = dim;	/* velocity */

Modified: long/3D/Gale/trunk/src/StgFEM/Assembly/src/IsoviscousStressTensorTerm.c
===================================================================
--- long/3D/Gale/trunk/src/StgFEM/Assembly/src/IsoviscousStressTensorTerm.c	2006-12-07 23:26:14 UTC (rev 5532)
+++ long/3D/Gale/trunk/src/StgFEM/Assembly/src/IsoviscousStressTensorTerm.c	2006-12-07 23:29:43 UTC (rev 5533)
@@ -227,7 +227,7 @@
 	Index                               colIndex;
 	
 	/* Set the element type */
-	elementType = FeMesh_ElementTypeAt( variable1->feMesh, lElement_I );
+	elementType = FeMesh_GetElementType( variable1->feMesh, lElement_I );
 	nodesPerEl = elementType->nodeCount;
 
 	/* assumes constant number of dofs per element */

Modified: long/3D/Gale/trunk/src/StgFEM/Assembly/src/LaplacianStiffnessMatrixTerm.c
===================================================================
--- long/3D/Gale/trunk/src/StgFEM/Assembly/src/LaplacianStiffnessMatrixTerm.c	2006-12-07 23:26:14 UTC (rev 5532)
+++ long/3D/Gale/trunk/src/StgFEM/Assembly/src/LaplacianStiffnessMatrixTerm.c	2006-12-07 23:29:43 UTC (rev 5533)
@@ -211,7 +211,7 @@
 	ElementType*                        elementType;
 	
 	/* Set the element type */
-	elementType = FeMesh_ElementTypeAt( variable1->feMesh, lElement_I );
+	elementType = FeMesh_GetElementType( variable1->feMesh, lElement_I );
 	nodesPerEl = elementType->nodeCount;
 	
 	/* allocate */

Modified: long/3D/Gale/trunk/src/StgFEM/Assembly/src/ThermalBuoyancyForceTerm.c
===================================================================
--- long/3D/Gale/trunk/src/StgFEM/Assembly/src/ThermalBuoyancyForceTerm.c	2006-12-07 23:26:14 UTC (rev 5532)
+++ long/3D/Gale/trunk/src/StgFEM/Assembly/src/ThermalBuoyancyForceTerm.c	2006-12-07 23:29:43 UTC (rev 5533)
@@ -213,7 +213,7 @@
 	Dimension_Index         dim                = forceVector->dim;
 	IntegrationPoint*       particle;
 	FeVariable*             temperatureField;
-	FiniteElement_Mesh*     mesh;
+	FeMesh*			mesh;
 	double*                 xi;
 	Particle_InCellIndex    cParticle_I;
 	Particle_InCellIndex    cellParticleCount;
@@ -235,7 +235,7 @@
 	mesh             = temperatureField->feMesh;
 	
 	/* Set the element type */
-	elementType      = FeMesh_ElementTypeAt( temperatureField->feMesh, lElement_I );
+	elementType      = FeMesh_GetElementType( temperatureField->feMesh, lElement_I );
 	elementNodeCount = elementType->nodeCount;
 
 	/* assumes constant number of dofs per element */

Modified: long/3D/Gale/trunk/src/StgFEM/Discretisation/src/AnalyticSolution.c
===================================================================
--- long/3D/Gale/trunk/src/StgFEM/Discretisation/src/AnalyticSolution.c	2006-12-07 23:26:14 UTC (rev 5532)
+++ long/3D/Gale/trunk/src/StgFEM/Discretisation/src/AnalyticSolution.c	2006-12-07 23:29:43 UTC (rev 5533)
@@ -45,7 +45,7 @@
 #include "AnalyticSolution.h"
 #include "FeVariable.h"
 #include "OperatorFeVariable.h"
-#include "Mesh.h"
+#include "FeMesh.h"
 
 #include <stdio.h>
 #include <stdlib.h>
@@ -232,6 +232,7 @@
 	double*                                      value;
 	Stream*                                      infoStream = Journal_MyStream( Info_Type, self );
 	FeVariable*                                  feVariable;
+	FeMesh*						mesh;
 
 	/* Do some error checking */
 	assert( Stg_ObjectList_Count( self->analyticFeVariableList ) >= analyticFeVariable_I );
@@ -239,6 +240,7 @@
 	/* Grab pointers */
 	analyticFeVariable = 
 		Stg_CheckType( Stg_ObjectList_At( self->analyticFeVariableList, analyticFeVariable_I ), FeVariable );
+	mesh = analyticFeVariable->feMesh;
 	solutionFunction   = (AnalyticSolution_FeVariableSolutionFunction*) 
 		Stg_ObjectList_ObjectAt( self->analyticFeVariableFuncList, analyticFeVariable_I );
 	feVariable = AnalyticSolution_GetFeVariableFromAnalyticFeVariable( self, analyticFeVariable );
@@ -248,8 +250,8 @@
 	value = Memory_Alloc_Array( double, dofAtEachNodeCount, "value" );
 
 	/* Loop over all the nodes - applying the analytic solution */
-	for ( dNode_I = 0 ; dNode_I < analyticFeVariable->feMesh->nodeDomainCount ; dNode_I++ ) {
-		coord = Mesh_CoordAt( analyticFeVariable->feMesh, dNode_I );
+	for ( dNode_I = 0 ; dNode_I < Mesh_GetDomainSize( mesh, MT_VERTEX ); dNode_I++ ) {
+		coord = Mesh_GetVertex( mesh, dNode_I );
 
 		/* Calculate value at node */
 		memset( value, 0, dofAtEachNodeCount * sizeof(double) );
@@ -352,17 +354,27 @@
 	Stream*                                      stream;
 	Index                                        count;
 
+	Build( feVariable->feMesh, NULL, False );
+
 	/* Create new data Variable */
 	tmpName = Stg_Object_AppendSuffix( feVariable, "Analytic-DataVariable" );
 	if ( scalar ) {
+		Decomp_Sync*	sync;
+
+		sync = Mesh_GetSync( feVariable->feMesh, MT_VERTEX );
 		dataVariable = Variable_NewScalar( 	
 			tmpName,
 			Variable_DataType_Double, 
-			&feVariable->feMesh->nodeDomainCount, 
+			&sync->nDomains, 
 			(void**)NULL, 
 			variable_Register );
 	}
 	else {
+		Decomp_Sync*	sync;
+		unsigned	c_i;
+
+		sync = Mesh_GetSync( feVariable->feMesh, MT_VERTEX );
+
 		/* Create names of variables */
 		assert( componentsCount <= 9 );
 		for ( variable_I = 0 ; variable_I < componentsCount ; variable_I++ ) {
@@ -372,7 +384,7 @@
 				tmpName,
 				Variable_DataType_Double, 
 				componentsCount,
-				&feVariable->feMesh->nodeDomainCount, 
+				&sync->nDomains, 
 				(void**)NULL, 
 				variable_Register,
 				variableName[0],
@@ -384,13 +396,15 @@
 				variableName[6],
 				variableName[7],
 				variableName[8] );
+		for( c_i = 0; c_i < dataVariable->dataTypeCounts[0]; c_i++ )
+			dataVariable->components[c_i]->allocateSelf = True;
 	}
 	Memory_Free( tmpName );
 	dataVariable->allocateSelf = True;
 	
 	/* Create new dof layout */
 	tmpName = Stg_Object_AppendSuffix( feVariable, "Analytic-DofLayout" );
-	dofLayout = DofLayout_New( tmpName, variable_Register, feVariable->feMesh->layout->decomp->nodeDomainCount );
+	dofLayout = DofLayout_New( tmpName, variable_Register, Mesh_GetDomainSize( feVariable->feMesh, MT_VERTEX ), NULL );
 	if ( scalar ) {
 		DofLayout_AddAllFromVariableArray( dofLayout, 1, &dataVariable );
 	}
@@ -402,7 +416,7 @@
 			variable->arrayPtrPtr = &dataVariable->arrayPtr;
 
 			/* Assign variable to each node */
-			for( node_I = 0; node_I < feVariable->feMesh->layout->decomp->nodeDomainCount ; node_I++ ) {
+			for( node_I = 0; node_I < Mesh_GetDomainSize( feVariable->feMesh, MT_VERTEX ); node_I++ ) {
 				DofLayout_AddDof_ByVarName( dofLayout, variableName[variable_I], node_I );
 			}
 			/* Free Name */

Modified: long/3D/Gale/trunk/src/StgFEM/Discretisation/src/BilinearElementType.c
===================================================================
--- long/3D/Gale/trunk/src/StgFEM/Discretisation/src/BilinearElementType.c	2006-12-07 23:26:14 UTC (rev 5532)
+++ long/3D/Gale/trunk/src/StgFEM/Discretisation/src/BilinearElementType.c	2006-12-07 23:29:43 UTC (rev 5533)
@@ -127,8 +127,6 @@
 	return self;
 }
 
-
-
 void _BilinearElementType_Init( BilinearElementType* self ) {
 	Dimension_Index dim_I=0;
 	/* General and Virtual info should already be set */
@@ -140,10 +138,16 @@
 		self->maxElLocalCoord[dim_I] = 1;
 		self->elLocalLength[dim_I] = self->maxElLocalCoord[dim_I] - self->minElLocalCoord[dim_I];
 	}
+
+	self->triInds = Memory_Alloc_2DArray( unsigned, 2, 3, "BilinearElementType::triInds" );
+	self->triInds[0][0] = 0; self->triInds[0][1] = 1; self->triInds[0][2] = 2;
+	self->triInds[1][0] = 1; self->triInds[1][1] = 3; self->triInds[1][2] = 2;
 }
 
 void _BilinearElementType_Delete( void* elementType ) {
 	BilinearElementType* self = (BilinearElementType*)elementType;
+
+	FreeArray( self->triInds );
 	
 	Journal_DPrintf( self->debug, "In %s\n", __func__ );
 	/* Stg_Class_Delete parent*/
@@ -223,8 +227,8 @@
 	
 	evaluatedValues[0] = 0.25*( 1.0-xi )*( 1.0-eta );
 	evaluatedValues[1] = 0.25*( 1.0+xi )*( 1.0-eta );
-	evaluatedValues[2] = 0.25*( 1.0+xi )*( 1.0+eta );
-	evaluatedValues[3] = 0.25*( 1.0-xi )*( 1.0+eta );
+	evaluatedValues[3] = 0.25*( 1.0+xi )*( 1.0+eta );
+	evaluatedValues[2] = 0.25*( 1.0-xi )*( 1.0+eta );
 }
 
 
@@ -239,14 +243,14 @@
 	/* derivatives wrt xi */
 	evaluatedDerivatives[0][0] = - 0.25*( 1.0 - eta );
 	evaluatedDerivatives[0][1] =   0.25*( 1.0 - eta );
-	evaluatedDerivatives[0][2] =   0.25*( 1.0 + eta );
-	evaluatedDerivatives[0][3] = - 0.25*( 1.0 + eta );
+	evaluatedDerivatives[0][3] =   0.25*( 1.0 + eta );
+	evaluatedDerivatives[0][2] = - 0.25*( 1.0 + eta );
 	
 	/* derivatives wrt eta */
 	evaluatedDerivatives[1][0] = - 0.25*( 1.0 - xi );
 	evaluatedDerivatives[1][1] = - 0.25*( 1.0 + xi );
-	evaluatedDerivatives[1][2] =   0.25*( 1.0 + xi );
-	evaluatedDerivatives[1][3] =   0.25*( 1.0 - xi );
+	evaluatedDerivatives[1][3] =   0.25*( 1.0 + xi );
+	evaluatedDerivatives[1][2] =   0.25*( 1.0 - xi );
 }
 
 
@@ -254,84 +258,31 @@
 ** Calculates the barycenter of a triangle with respect to some point.
 */
 
-#if 0
-void _BilinearElementType_TriBarycenter( Coord tri[3], const Coord pnt, Coord dst ) {
-	double	a = tri[1][0] - tri[0][0];
-	double	b = tri[2][0] - tri[0][0];
-	double	c = tri[1][1] - tri[0][1];
-	double	d = tri[2][1] - tri[0][1];
-	double	e = pnt[0] - tri[0][0];
-	double	f = pnt[1] - tri[0][1];
-	double	aInv = 1.0 / a;
-
-	dst[2] = (f - (c * e * aInv)) / (d - (c * b * aInv));
-	dst[1] = (e - b * dst[1]) * aInv;
-	dst[0] = 1.0 - dst[1] - dst[2];
-}
-#endif
-
 void _BilinearElementType_ConvertGlobalCoordToElLocal(
 		void*		elementType,
-		ElementLayout*	elementLayout,
-		const Coord**	globalNodeCoordPtrsInElement,
-		const Coord	globalCoord,
-		Coord		elLocalCoord )
+		void*		_mesh, 
+		unsigned	element, 
+		const double*	globalCoord,
+		double*		elLocalCoord )
 {
 	BilinearElementType*	self = (BilinearElementType*)elementType;
-	Dimension_Index		dim_I = 0;
-	double			globalToElLocalScaling[2] = {0.0,0.0};
-	Coord			relToBottomLeftGlobalCoord = {0.0,0.0,0.0};
+	Mesh*			mesh = (Mesh*)_mesh;
+	unsigned		inside;
+	double			bc[3];
+	static double		lCrds[4][3] = {{-1.0, -1.0, 0.0}, {1.0, -1.0, 0.0}, 
+					       {-1.0, 1.0, 0.0}, {1.0, 1.0, 0.0}};
+	unsigned		nInc, *inc;
+	unsigned		bc_i;
 
-	if ( elementLayout->type == ParallelPipedHexaEL_Type ) {
-		double	elLen[2];
-		elLen[0] = (*(globalNodeCoordPtrsInElement[1]))[0] - (*(globalNodeCoordPtrsInElement[0]))[0];
-		elLen[1] = (*(globalNodeCoordPtrsInElement[3]))[1] - (*(globalNodeCoordPtrsInElement[0]))[1];
-		
-		/* Initially set elLocalCoord to (0,0,0) */
-		memset( elLocalCoord, 0, sizeof( Coord ) );
-	
-		for( dim_I=0; dim_I < 2; dim_I++ ) {
-			globalToElLocalScaling[dim_I] = self->elLocalLength[dim_I] / elLen[dim_I];
+	Mesh_GetIncidence( mesh, MT_FACE, element, MT_VERTEX, &nInc, &inc );
+	assert( nInc == 4 );
 
-			/* The bottom left node is always at index zero */
-			relToBottomLeftGlobalCoord[dim_I] = globalCoord[dim_I] - (*(globalNodeCoordPtrsInElement[0]))[dim_I];
-			
-			elLocalCoord[dim_I] =  
-				self->minElLocalCoord[dim_I] + relToBottomLeftGlobalCoord[dim_I] * globalToElLocalScaling[dim_I];
-			assert( elLocalCoord[dim_I] >= -1.0 || elLocalCoord[dim_I] <= 1.0 );
-		}
-	}
-	else if( elementLayout->type == HexaEL_Type ) {
-		Coord		crds[4];
-		Coord		bc;
-		unsigned	inds[3];
-		Coord		lCrds[4] = {{-1.0, -1.0, 0.0}, {1.0, -1.0, 0.0}, 
-					    {-1.0, 1.0, 0.0}, {1.0, 1.0, 0.0}};
-		/*unsigned	gElInd;*/
-		unsigned	bc_i;
+	insist( Simplex_Search2D( mesh->verts, inc, 2, self->triInds, (double*)globalCoord, bc, &inside ) );
 
-		/* Check first triangle. */
-		memcpy( crds[0], *(globalNodeCoordPtrsInElement[0]), sizeof(Coord) );
-		memcpy( crds[1], *(globalNodeCoordPtrsInElement[1]), sizeof(Coord) );
-		memcpy( crds[2], *(globalNodeCoordPtrsInElement[3]), sizeof(Coord) );
-		memcpy( crds[3], *(globalNodeCoordPtrsInElement[2]), sizeof(Coord) );
-#ifndef NDEBUG
-		if( !_HexaEL_FindTriBarycenter( (const Coord*)crds, globalCoord, bc, inds, INCLUSIVE_UPPER_BOUNDARY, NULL, 0 ) )
-			assert( 0 );
-#else
-		_HexaEL_FindTriBarycenter( crds, globalCoord, bc, inds, INCLUSIVE_UPPER_BOUNDARY, NULL, 0 );
-#endif
-
-		/* Interpolate. */
-		memset( elLocalCoord, 0, sizeof(Coord) );
-		for( bc_i = 0; bc_i < 3; bc_i++ ) {
-			elLocalCoord[0] += bc[bc_i] * lCrds[inds[bc_i]][0];
-			elLocalCoord[1] += bc[bc_i] * lCrds[inds[bc_i]][1];
-		}
+	elLocalCoord[0] = bc[0] * lCrds[self->triInds[inside][0]][0];
+	elLocalCoord[1] = bc[0] * lCrds[self->triInds[inside][0]][1];
+	for( bc_i = 1; bc_i < 3; bc_i++ ) {
+		elLocalCoord[0] += bc[bc_i] * lCrds[self->triInds[inside][bc_i]][0];
+		elLocalCoord[1] += bc[bc_i] * lCrds[self->triInds[inside][bc_i]][1];
 	}
-	else {
-		/* Not a rectangular element -> Just use the general version */
-		_ElementType_ConvertGlobalCoordToElLocal( self, elementLayout, globalNodeCoordPtrsInElement,
-			globalCoord, elLocalCoord );
-	}
 }

Modified: long/3D/Gale/trunk/src/StgFEM/Discretisation/src/BilinearElementType.h
===================================================================
--- long/3D/Gale/trunk/src/StgFEM/Discretisation/src/BilinearElementType.h	2006-12-07 23:26:14 UTC (rev 5532)
+++ long/3D/Gale/trunk/src/StgFEM/Discretisation/src/BilinearElementType.h	2006-12-07 23:29:43 UTC (rev 5533)
@@ -65,6 +65,8 @@
 		double	minElLocalCoord[2]; /** Bottom corner in elLocal mathematical space */ \
 		double	maxElLocalCoord[2]; /** Top corner in elLocal mathematical space */ \
 		double	elLocalLength[2]; /** Length of element in elLocal space */ \
+		\
+		unsigned**		triInds;
 		
 	struct BilinearElementType { __BilinearElementType };
 	
@@ -124,8 +126,9 @@
 		then calculates this using a faster shortcut. */
 	void _BilinearElementType_ConvertGlobalCoordToElLocal(
 		void*		elementType,
-		ElementLayout*	elementLayout,
-		const Coord**	globalNodeCoordPtrsInElement,
-		const Coord	globalCoord,
-		Coord		elLocalCoord );
+		void*		mesh, 
+		unsigned	element, 
+		const double*	globalCoord,
+		double*		elLocalCoord );
+
 #endif /* __StgFEM_Discretisation_BilinearElementType_h__ */

Added: long/3D/Gale/trunk/src/StgFEM/Discretisation/src/C0Generator.c
===================================================================
--- long/3D/Gale/trunk/src/StgFEM/Discretisation/src/C0Generator.c	2006-12-07 23:26:14 UTC (rev 5532)
+++ long/3D/Gale/trunk/src/StgFEM/Discretisation/src/C0Generator.c	2006-12-07 23:29:43 UTC (rev 5533)
@@ -0,0 +1,242 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+**
+** Copyright (C), 2003, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street, Melbourne, 3053, Australia.
+**
+** Authors:
+**	Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
+**	Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
+**	Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
+**	Siew-Ching Tan, Software Engineer, VPAC. (siew at vpac.org)
+**	Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
+**	Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
+**
+**  This library is free software; you can redistribute it and/or
+**  modify it under the terms of the GNU Lesser General Public
+**  License as published by the Free Software Foundation; either
+**  version 2.1 of the License, or (at your option) any later version.
+**
+**  This library 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
+**  Lesser General Public License for more details.
+**
+**  You should have received a copy of the GNU Lesser General Public
+**  License along with this library; if not, write to the Free Software
+**  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+**
+** $Id: C0Generator.c 3584 2006-05-16 11:11:07Z PatrickSunter $
+**
+**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include <mpi.h>
+
+#include "StGermain/StGermain.h"
+#include "Discretisation.h"
+
+
+/* Textual name of this class */
+const Type C0Generator_Type = "C0Generator";
+
+
+/*----------------------------------------------------------------------------------------------------------------------------------
+** Constructors
+*/
+
+C0Generator* C0Generator_New( Name name ) {
+	return _C0Generator_New( sizeof(C0Generator), 
+				 C0Generator_Type, 
+				 _C0Generator_Delete, 
+				 _C0Generator_Print, 
+				 NULL, 
+				 (void* (*)(Name))_C0Generator_New, 
+				 _C0Generator_Construct, 
+				 _C0Generator_Build, 
+				 _C0Generator_Initialise, 
+				 _C0Generator_Execute, 
+				 _C0Generator_Destroy, 
+				 name, 
+				 NON_GLOBAL, 
+				 C0Generator_Generate );
+}
+
+C0Generator* _C0Generator_New( C0GENERATOR_DEFARGS ) {
+	C0Generator*	self;
+
+	/* Allocate memory */
+	assert( sizeOfSelf >= sizeof(C0Generator) );
+	self = (C0Generator*)_MeshGenerator_New( MESHGENERATOR_PASSARGS );
+
+	/* Virtual info */
+
+	/* C0Generator info */
+	_C0Generator_Init( self );
+
+	return self;
+}
+
+void _C0Generator_Init( C0Generator* self ) {
+}
+
+
+/*----------------------------------------------------------------------------------------------------------------------------------
+** Virtual functions
+*/
+
+void _C0Generator_Delete( void* generator ) {
+	C0Generator*	self = (C0Generator*)generator;
+
+	/* Delete the parent. */
+	_MeshGenerator_Delete( self );
+}
+
+void _C0Generator_Print( void* generator, Stream* stream ) {
+	C0Generator*	self = (C0Generator*)generator;
+	
+	/* Set the Journal for printing informations */
+	Stream* generatorStream;
+	generatorStream = Journal_Register( InfoStream_Type, "C0GeneratorStream" );
+
+	/* Print parent */
+	Journal_Printf( stream, "C0Generator (ptr): (%p)\n", self );
+	_MeshGenerator_Print( self, stream );
+}
+
+void _C0Generator_Construct( void* generator, Stg_ComponentFactory* cf, void* data ) {
+	C0Generator*	self = (C0Generator*)generator;
+
+	assert( self );
+	assert( cf );
+
+	_MeshGenerator_Construct( self, cf, data );
+}
+
+void _C0Generator_Build( void* generator, void* data ) {
+	_MeshGenerator_Build( generator, data );
+}
+
+void _C0Generator_Initialise( void* generator, void* data ) {
+	_MeshGenerator_Initialise( generator, data );
+}
+
+void _C0Generator_Execute( void* generator, void* data ) {
+}
+
+void _C0Generator_Destroy( void* generator, void* data ) {
+}
+
+
+/*--------------------------------------------------------------------------------------------------------------------------
+** Public Functions
+*/
+
+void C0Generator_Generate( void* generator, void* _mesh ) {
+	Stream*		errorStream = Journal_Register( ErrorStream_Type, "C0Generator::Generate" );
+	C0Generator*	self = (C0Generator*)generator;
+	FeMesh*		mesh = (FeMesh*)_mesh;
+	Mesh*		elMesh;
+
+	assert( self && Stg_CheckType( self, C0Generator ) );
+	assert( mesh && Stg_CheckType( mesh, FeMesh ) );
+
+	elMesh = FeMesh_GetElementMesh( mesh );
+	Journal_Firewall( (FeMesh*)elMesh != mesh, errorStream, 
+			  "\n" \
+			  "******************************************************\n" \
+			  "* Error: Cannot generate a C0 finite element mesh    *\n" \
+			  "*        without an independant discretisation mesh. *\n" \
+			  "******************************************************\n" \
+			  "\n" );
+	Build( elMesh, NULL, False );
+
+	C0Generator_BuildTopology( self, mesh, elMesh );
+	C0Generator_BuildGeometry( self, mesh, elMesh );
+	C0Generator_BuildElementTypes( self, mesh, elMesh );
+}
+
+
+/*----------------------------------------------------------------------------------------------------------------------------------
+** Private Functions
+*/
+
+void C0Generator_BuildTopology( C0Generator* self, FeMesh* mesh, Mesh* elMesh ) {
+	MeshTopology	*topo, *elTopo;
+	Decomp_Sync*	elSync;
+	unsigned	nDims;
+	unsigned	*nIncEls, **incEls;
+	unsigned	nDomainEls;
+	unsigned	e_i;
+
+	assert( self );
+	assert( mesh );
+	assert( elMesh );
+
+	nDims = Mesh_GetDimSize( elMesh );
+	elTopo = Mesh_GetTopology( elMesh );
+	elSync = MeshTopology_GetSync( elTopo, nDims );
+
+	topo = Mesh_GetTopology( mesh );
+	MeshTopology_SetDimSize( topo, nDims );
+	MeshTopology_SetSync( topo, nDims, elSync );
+	MeshTopology_SetSync( topo, MT_VERTEX, elSync );
+	topo->shadowDepth = elTopo->shadowDepth;
+
+	nDomainEls = Mesh_GetDomainSize( elMesh, nDims );
+	nIncEls = AllocArray( unsigned, nDomainEls );
+	incEls = AllocArray2D( unsigned, nDomainEls, 1 );
+	for( e_i = 0; e_i < nDomainEls; e_i++ ) {
+		nIncEls[e_i] = 1;
+		incEls[e_i][0] = e_i;
+	}
+	MeshTopology_SetIncidence( topo, nDims, MT_VERTEX, nIncEls, incEls );
+	FreeArray( nIncEls );
+	FreeArray( incEls );
+
+	MeshTopology_Invert( topo, MT_VERTEX, nDims );
+}
+
+void C0Generator_BuildGeometry( C0Generator* self, FeMesh* mesh, Mesh* elMesh ) {
+	double			*centroid, *vert;
+	unsigned		nDims;
+	unsigned		nDomainEls;
+	Mesh_ElementType*	elType;
+	unsigned		e_i;
+
+	assert( self );
+	assert( mesh );
+	assert( elMesh );
+
+	nDims = Mesh_GetDimSize( elMesh );
+	nDomainEls = Mesh_GetDomainSize( elMesh, nDims );
+	mesh->verts = AllocArray2D( double, nDomainEls, nDims );
+	centroid = AllocArray( double, nDims );
+	for( e_i = 0; e_i < nDomainEls; e_i++ ) {
+		elType = Mesh_GetElementType( elMesh, e_i );
+		Mesh_ElementType_GetCentroid( elType, elMesh, e_i, centroid );
+		vert = Mesh_GetVertex( mesh, e_i );
+		memcpy( vert, centroid, nDims * sizeof(double) );
+	}
+	FreeArray( centroid );
+}
+
+void C0Generator_BuildElementTypes( C0Generator* self, FeMesh* mesh, Mesh* elMesh ) {
+	unsigned	nDomainEls;
+	unsigned	e_i;
+
+	assert( self );
+	assert( mesh );
+	assert( elMesh );
+
+	mesh->nElTypes = 1;
+	mesh->elTypes = AllocNamedArray( Mesh_ElementType*, mesh->nElTypes, "Mesh::elTypes" );
+	mesh->elTypes[0] = (Mesh_ElementType*)FeMesh_ElementType_New();
+	nDomainEls = Mesh_GetDomainSize( mesh, Mesh_GetDimSize( mesh ) );
+	mesh->elTypeMap = AllocNamedArray( unsigned, nDomainEls, "Mesh::elTypeMap" );
+	for( e_i = 0; e_i < nDomainEls; e_i++ )
+		mesh->elTypeMap[e_i] = 0;
+
+	Mesh_SetAlgorithms( mesh, FeMesh_Algorithms_New( "" ) );
+}

Added: long/3D/Gale/trunk/src/StgFEM/Discretisation/src/C0Generator.h
===================================================================
--- long/3D/Gale/trunk/src/StgFEM/Discretisation/src/C0Generator.h	2006-12-07 23:26:14 UTC (rev 5532)
+++ long/3D/Gale/trunk/src/StgFEM/Discretisation/src/C0Generator.h	2006-12-07 23:29:43 UTC (rev 5533)
@@ -0,0 +1,100 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+**
+** Copyright (C), 2003, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street, Melbourne, 3053, Australia.
+**
+** Authors:
+**	Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
+**	Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
+**	Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
+**	Siew-Ching Tan, Software Engineer, VPAC. (siew at vpac.org)
+**	Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
+**	Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
+**
+**  This library is free software; you can redistribute it and/or
+**  modify it under the terms of the GNU Lesser General Public
+**  License as published by the Free Software Foundation; either
+**  version 2.1 of the License, or (at your option) any later version.
+**
+**  This library 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
+**  Lesser General Public License for more details.
+**
+**  You should have received a copy of the GNU Lesser General Public
+**  License along with this library; if not, write to the Free Software
+**  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+**
+*/
+/** \file
+**  Role:
+**
+** Assumptions:
+**
+** Invariants:
+**
+** Comments:
+**
+** $Id: C0Generator.h 3584 2006-05-16 11:11:07Z PatrickSunter $
+**
+**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#ifndef __Discretisaton_Mesh_C0Generator_h__
+#define __Discretisaton_Mesh_C0Generator_h__
+
+	/** Textual name of this class */
+	extern const Type C0Generator_Type;
+
+	/** Virtual function types */
+
+	/** C0Generator class contents */
+	#define __C0Generator		\
+		/* General info */		\
+		__MeshGenerator			\
+						\
+		/* Virtual info */		\
+						\
+		/* C0Generator info */
+
+	struct C0Generator { __C0Generator };
+
+	/*--------------------------------------------------------------------------------------------------------------------------
+	** Constructors
+	*/
+
+	#define C0GENERATOR_DEFARGS	\
+		MESHGENERATOR_DEFARGS
+
+	#define C0GENERATOR_PASSARGS	\
+		MESHGENERATOR_PASSARGS
+
+	C0Generator* C0Generator_New( Name name );
+	C0Generator* _C0Generator_New( C0GENERATOR_DEFARGS );
+	void _C0Generator_Init( C0Generator* self );
+
+	/*--------------------------------------------------------------------------------------------------------------------------
+	** Virtual functions
+	*/
+
+	void _C0Generator_Delete( void* generator );
+	void _C0Generator_Print( void* generator, Stream* stream );
+	void _C0Generator_Construct( void* generator, Stg_ComponentFactory* cf, void* data );
+	void _C0Generator_Build( void* generator, void* data );
+	void _C0Generator_Initialise( void* generator, void* data );
+	void _C0Generator_Execute( void* generator, void* data );
+	void _C0Generator_Destroy( void* generator, void* data );
+
+	void C0Generator_Generate( void* generator, void* _mesh );
+
+	/*--------------------------------------------------------------------------------------------------------------------------
+	** Public functions
+	*/
+
+	/*--------------------------------------------------------------------------------------------------------------------------
+	** Private Member functions
+	*/
+
+	void C0Generator_BuildTopology( C0Generator* self, FeMesh* mesh, Mesh* elMesh );
+	void C0Generator_BuildGeometry( C0Generator* self, FeMesh* mesh, Mesh* elMesh );
+	void C0Generator_BuildElementTypes( C0Generator* self, FeMesh* mesh, Mesh* elMesh );
+
+#endif /* __Discretisaton_Mesh_C0Generator_h__ */

Added: long/3D/Gale/trunk/src/StgFEM/Discretisation/src/C0Generator.meta
===================================================================
--- long/3D/Gale/trunk/src/StgFEM/Discretisation/src/C0Generator.meta	2006-12-07 23:26:14 UTC (rev 5532)
+++ long/3D/Gale/trunk/src/StgFEM/Discretisation/src/C0Generator.meta	2006-12-07 23:29:43 UTC (rev 5533)
@@ -0,0 +1,28 @@
+<?xml version="1.0"?>
+<!DOCTYPE StGermainData SYSTEM "stgermain.dtd">
+<StGermainData xmlns="http://www.vpac.org/StGermain/XML_IO_Handler/Jun2003">
+
+<param name="Name">C0Generator</param>
+<param name="Organisation">VPAC</param>
+<param name="Project">StgFEM</param>
+<param name="Location">./StgFEM/Discretisation/src/</param>
+<param name="Project Web">https://csd.vpac.org/twiki/bin/view/Stgfem/WebHome</param>
+<param name="Copyright">Copyright (C) 2004-2005 VPAC.</param>
+<param name="License">https://csd.vpac.org/twiki/bin/view/Stgermain/SoftwareLicense</param>
+<param name="Parent">ElementType</param>
+<param name="Description">...</param>
+
+<!--Now the interesting stuff-->
+
+
+<list name="Params">
+
+</list>
+
+<list name="Dependencies">
+
+</list>
+<!-- Add an exmaple XML if possible -->
+<param name="Example">...</param>
+
+</StGermainData>

Modified: long/3D/Gale/trunk/src/StgFEM/Discretisation/src/ConstantElementType.c
===================================================================
--- long/3D/Gale/trunk/src/StgFEM/Discretisation/src/ConstantElementType.c	2006-12-07 23:26:14 UTC (rev 5532)
+++ long/3D/Gale/trunk/src/StgFEM/Discretisation/src/ConstantElementType.c	2006-12-07 23:29:43 UTC (rev 5533)
@@ -222,10 +222,10 @@
 
 void _ConstantElementType_ConvertGlobalCoordToElLocal(
 		void*		elementType,
-		ElementLayout*	elementLayout,
-		const Coord**	globalNodeCoordPtrsInElement,
-		const Coord	globalCoord,
-		Coord		elLocalCoord ) 
+		Mesh*		mesh, 
+		unsigned	element, 
+		const double*	globalCoord,
+		double*		elLocalCoord )
 {
 	/* See header file function introduction for explanation... */
 	elLocalCoord[0] = elLocalCoord[1] = elLocalCoord[2] = 0;

Modified: long/3D/Gale/trunk/src/StgFEM/Discretisation/src/ConstantElementType.h
===================================================================
--- long/3D/Gale/trunk/src/StgFEM/Discretisation/src/ConstantElementType.h	2006-12-07 23:26:14 UTC (rev 5532)
+++ long/3D/Gale/trunk/src/StgFEM/Discretisation/src/ConstantElementType.h	2006-12-07 23:29:43 UTC (rev 5533)
@@ -126,8 +126,9 @@
 	*/
 	void _ConstantElementType_ConvertGlobalCoordToElLocal(
 		void*		elementType,
-		ElementLayout*	elementLayout,
-		const Coord**	globalNodeCoordPtrsInElement,
-		const Coord	globalCoord,
-		Coord		elLocalCoord );
+		Mesh*		mesh, 
+		unsigned	element, 
+		const double*	globalCoord,
+		double*		elLocalCoord );
+
 #endif /* __StgFEM_Discretisation_ConstantElementType_h__ */

Modified: long/3D/Gale/trunk/src/StgFEM/Discretisation/src/Discretisation.h
===================================================================
--- long/3D/Gale/trunk/src/StgFEM/Discretisation/src/Discretisation.h	2006-12-07 23:26:14 UTC (rev 5532)
+++ long/3D/Gale/trunk/src/StgFEM/Discretisation/src/Discretisation.h	2006-12-07 23:29:43 UTC (rev 5533)
@@ -55,8 +55,7 @@
 	
 	#include "units.h"
 	#include "types.h"
-	#include "shortcuts.h"
-		
+
 	#include "ElementType.h"
 	#include "ElementType_Register.h"
 	#include "ConstantElementType.h"
@@ -65,10 +64,14 @@
 	#include "LinearTriangleElementType.h"
 
 	#include "Element.h"
-	#include "Mesh.h"
+	#include "FeMesh.h"
+	#include "FeMesh_ElementType.h"
+	#include "FeMesh_Algorithms.h"
+	#include "C0Generator.h"
 	#include "LinkedDofInfo.h"
 	#include "FeEquationNumber.h"
 	#include "FeVariable.h"
+	#include "ShapeFeVariable.h"
 	#include "OperatorFeVariable.h"
 	#include "FeSwarmVariable.h"
 	#include "AnalyticSolution.h"

Modified: long/3D/Gale/trunk/src/StgFEM/Discretisation/src/ElementType.c
===================================================================
--- long/3D/Gale/trunk/src/StgFEM/Discretisation/src/ElementType.c	2006-12-07 23:26:14 UTC (rev 5532)
+++ long/3D/Gale/trunk/src/StgFEM/Discretisation/src/ElementType.c	2006-12-07 23:29:43 UTC (rev 5533)
@@ -150,7 +150,6 @@
 	self->_build( self, data );
 }
 
-
 void ElementType_EvaluateShapeFunctionsAt( void* elementType, const double localCoord[], double* const evaluatedValues ) {
 	ElementType* self = (ElementType*)elementType;
 	
@@ -166,27 +165,28 @@
 
 void ElementType_ConvertGlobalCoordToElLocal(
 		void*		elementType,
-		ElementLayout*	elementLayout,
-		const Coord**	globalNodeCoordPtrsInElement,
-		const Coord	globalCoord,
-		Coord		elLocalCoord ) 
+		void*		mesh, 
+		unsigned	element, 
+		const double*	globalCoord,
+		double*		elLocalCoord )
 {
-	ElementType*		self = (ElementType*)elementType;
+	ElementType*	self = (ElementType*)elementType;
 
-	self->_convertGlobalCoordToElLocal( self, elementLayout, globalNodeCoordPtrsInElement, globalCoord, elLocalCoord );
+	self->_convertGlobalCoordToElLocal( self, mesh, element, globalCoord, elLocalCoord );
 }
 
 
 /* +++ Virtual Function Implementations +++ */
 
 void _ElementType_ConvertGlobalCoordToElLocal(
-		void*           elementType,
-		ElementLayout*  elementLayout,
-		const Coord**   globalNodeCoordPtrsInElement,
-		const Coord     globalCoord,
-		Coord           elLocalCoord ) 
+		void*		elementType,
+		void*		_mesh, 
+		unsigned	element, 
+		const double*	globalCoord,
+		double*		elLocalCoord )
 {		
 	ElementType*		self            = (ElementType*)elementType;
+	Mesh*			mesh = (Mesh*)_mesh;
 	TensorArray         jacobiMatrix;
 	double              tolerance       = 0.0001; // TODO put on class
 	double              maxResidual;
@@ -198,9 +198,10 @@
 	XYZ                 rightHandSide;
 	XYZ                 xiIncrement;
 	double              shapeFunc;
-	const double*       nodeCoord;
+	double*       	    nodeCoord;
 	double**            GNi;
-	Dimension_Index     dim             = ((HexaEL*) elementLayout)->dim;
+	unsigned	    nInc, *inc;
+	Dimension_Index     dim             = Mesh_GetDimSize( mesh );
 
 	/* This function uses a Newton-Raphson iterative method to find the local coordinate from the global coordinate 
 	 * the equations are ( see FEM/BEM nodes p. 9 )
@@ -224,6 +225,8 @@
 	evaluatedShapeFuncs = Memory_Alloc_Array( double, nodeCount, "evaluatedShapeFuncs" );
 	GNi = Memory_Alloc_2DArray( double, dim, nodeCount, "localShapeFuncDerivitives" );
 
+	Mesh_GetIncidence( mesh, Mesh_GetDimSize( mesh ), element, MT_VERTEX, &nInc, &inc );
+
 	/* Initial guess for element local coordinate is in the centre of the element - ( 0.0, 0.0, 0.0 ) */
 	memset( elLocalCoord, 0, sizeof( Coord ) );
 
@@ -240,7 +243,7 @@
 
 		for ( node_I = 0 ; node_I < nodeCount ; node_I++ ) {
 			shapeFunc = evaluatedShapeFuncs[node_I];
-			nodeCoord = *(globalNodeCoordPtrsInElement[ node_I ]);
+			nodeCoord = Mesh_GetVertex( mesh, inc[node_I] );
 
 			/* Form jacobi matrix */
 			jacobiMatrix[ MAP_TENSOR( 0, 0, dim ) ] += GNi[0][node_I] * nodeCoord[ I_AXIS ];
@@ -320,12 +323,15 @@
 	int dx, dxi;
 	double tmp, D = 0.0;
 	double cof[3][3];	/* cofactors */
+	unsigned nInc, *inc;
 	Index nodesPerEl;
 	
 	
 	GNi = Memory_Alloc_2DArray( double, rows, cols, "GNi" );
 
 	nodesPerEl = self->nodeCount;
+
+	Mesh_GetIncidence( mesh, Mesh_GetDimSize( mesh ), elId, MT_VERTEX, &nInc, &inc );
 	
 	/*
 	If constant shape function gets passed in here, getLocalDeriv will
@@ -344,7 +350,7 @@
 	if( dim == 2 ) {
 		jac[0][0] = jac[0][1] = jac[1][0] = jac[1][1] = 0.0;
 		for( n=0; n<nodesPerEl; n++){	
-			nodeCoord = Mesh_CoordAt( mesh, mesh->elementNodeTbl[elId][n] );
+			nodeCoord = Mesh_GetVertex( mesh, inc[n] );
 			jac[0][0] = jac[0][0] + GNi[0][n] * nodeCoord[0];
 			jac[0][1] = jac[0][1] + GNi[0][n] * nodeCoord[1];
 			
@@ -358,7 +364,7 @@
 		jac[1][0] = jac[1][1] = jac[1][2] = 0.0;
 		jac[2][0] = jac[2][1] = jac[2][2] = 0.0;
 		for( n=0; n<nodesPerEl; n++){	
-			nodeCoord = Mesh_CoordAt( mesh, mesh->elementNodeTbl[elId][n] );
+			nodeCoord = Mesh_GetVertex( mesh, inc[n] );
 			jac[0][0] = jac[0][0] + GNi[0][n] * nodeCoord[0];
 			jac[0][1] = jac[0][1] + GNi[0][n] * nodeCoord[1];
 			jac[0][2] = jac[0][2] + GNi[0][n] * nodeCoord[2];
@@ -454,6 +460,9 @@
 	double**     GNi;
 	Node_Index   nodesPerEl  = self->nodeCount;
 	Node_Index   node_I;
+	unsigned	nInc, *inc;
+
+	Mesh_GetIncidence( mesh, Mesh_GetDimSize( mesh ), elId, MT_VERTEX, &nInc, &inc );
 	
 	/* If GNi isn't passed in - then evaluate them for you */
 	if (_GNi == NULL) {
@@ -472,14 +481,14 @@
 		case 1: 			
 			jacobian[A_axis][A_axis] = 0.0;
 			for( node_I = 0 ; node_I < nodesPerEl; node_I++){
-				nodeCoord = Mesh_CoordAt( mesh, mesh->elementNodeTbl[elId][node_I] );
+				nodeCoord = Mesh_GetVertex( mesh, inc[node_I] );
 				jacobian[A_axis][A_axis] += GNi[A_axis][node_I] * nodeCoord[A_axis];
 			}
 			break;
 		case 2:
 			jacobian[A_axis][A_axis] = jacobian[A_axis][B_axis] = jacobian[B_axis][A_axis] = jacobian[B_axis][B_axis] = 0.0;
 			for( node_I = 0 ; node_I < nodesPerEl; node_I++){
-				nodeCoord = Mesh_CoordAt( mesh, mesh->elementNodeTbl[elId][node_I] );
+				nodeCoord = Mesh_GetVertex( mesh, inc[node_I] );
 				jacobian[A_axis][A_axis] += GNi[A_axis][node_I] * nodeCoord[A_axis];
 				jacobian[A_axis][B_axis] += GNi[A_axis][node_I] * nodeCoord[B_axis];
 
@@ -492,7 +501,7 @@
 			jacobian[B_axis][A_axis] = jacobian[B_axis][B_axis] = jacobian[B_axis][C_axis] = 0.0;
 			jacobian[C_axis][A_axis] = jacobian[C_axis][B_axis] = jacobian[C_axis][C_axis] = 0.0;
 			for( node_I = 0 ; node_I < nodesPerEl; node_I++){
-				nodeCoord = Mesh_CoordAt( mesh, mesh->elementNodeTbl[elId][node_I] );
+				nodeCoord = Mesh_GetVertex( mesh, inc[node_I] );
 
 				jacobian[A_axis][A_axis] += GNi[A_axis][node_I] * nodeCoord[A_axis];
 				jacobian[A_axis][B_axis] += GNi[A_axis][node_I] * nodeCoord[B_axis];
@@ -518,7 +527,7 @@
 
 					/* Calculate */
 					for( node_I = 0 ; node_I < nodesPerEl; node_I++){
-						nodeCoord = Mesh_CoordAt( mesh, mesh->elementNodeTbl[elId][node_I] );
+						nodeCoord = Mesh_GetVertex( mesh, inc[node_I] );
 				
 						jacobian[row_I][column_I] += GNi[row_I][node_I] * nodeCoord[column_I];
 					}

Modified: long/3D/Gale/trunk/src/StgFEM/Discretisation/src/ElementType.h
===================================================================
--- long/3D/Gale/trunk/src/StgFEM/Discretisation/src/ElementType.h	2006-12-07 23:26:14 UTC (rev 5532)
+++ long/3D/Gale/trunk/src/StgFEM/Discretisation/src/ElementType.h	2006-12-07 23:29:43 UTC (rev 5533)
@@ -65,8 +65,10 @@
 		double** const evaluatedDerivatives );
 
 	typedef void	(ElementType_ConvertGlobalCoordToElLocalFunction)		( void* elementType,
-		ElementLayout* elementLayout, const Coord** globalNodeCoordPtrsInElement, const Coord globalCoord,
-		Coord elLocalCoord );
+		Mesh*		mesh, 
+		unsigned	element, 
+		const double*	globalCoord,
+		double*		elLocalCoord );
 
 	typedef void	(ElementType_BuildFunction)					( void* elementType, void *arg );
 	
@@ -123,7 +125,7 @@
 	
 	/** Build the element type */
 	void ElementType_Build( void* elementType, void *data );
-	
+
 	/** Evaluate the value of the shape functions at a local coordinate.
 	Note that in Hughes FEM notation, localCoord -> Xi, and evaluatedValues -> Ni */
 	void ElementType_EvaluateShapeFunctionsAt( void* elementType, const double localCoord[], double* const evaluatedValues );
@@ -137,19 +139,19 @@
 	(eg if its a "brick" element). */
 	void ElementType_ConvertGlobalCoordToElLocal(
 		void*		elementType,
-		ElementLayout*	elementLayout,
-		const Coord**	globalNodeCoordPtrsInElement,
-		const Coord	globalCoord,
-		Coord		elLocalCoord );
+		void*		mesh, 
+		unsigned	element, 
+		const double*	globalCoord,
+		double*		elLocalCoord );
 	
 	/** General implementation of ElementType_ConvertGlobalCoordToElLocal(). Solves the system of FE elLocal->global
 	coordinate equations. */
 	void _ElementType_ConvertGlobalCoordToElLocal(
 		void*		elementType,
-		ElementLayout*	elementLayout,
-		const Coord**	globalNodeCoordPtrsInElement,
-		const Coord	globalCoord,
-		Coord		elLocalCoord );
+		void*		mesh, 
+		unsigned	element, 
+		const double*	globalCoord,
+		double*		elLocalCoord );
 	
 	/** Calculate the shape function global derivatives for all degrees of freedom for all nodes */
 	void ElementType_ShapeFunctionsGlobalDerivs( 

Modified: long/3D/Gale/trunk/src/StgFEM/Discretisation/src/FeEquationNumber.c
===================================================================
--- long/3D/Gale/trunk/src/StgFEM/Discretisation/src/FeEquationNumber.c	2006-12-07 23:26:14 UTC (rev 5532)
+++ long/3D/Gale/trunk/src/StgFEM/Discretisation/src/FeEquationNumber.c	2006-12-07 23:29:43 UTC (rev 5533)
@@ -47,7 +47,7 @@
 #include "ElementType.h"
 #include "ElementType_Register.h"
 #include "Element.h"
-#include "Mesh.h"
+#include "FeMesh.h"
 #include "FeEquationNumber.h"
 #include "LinkedDofInfo.h"
 #include <stdio.h>
@@ -89,6 +89,7 @@
 
 /*###### Private Function Declarations ######*/
 
+#if 0
 static void _FeEquationNumber_BuildRemappedNodeInfoTable( void* feEquationNumber );
 
 static void _FeEquationNumber_CalculateDomainKnownCriticalPoints( FeEquationNumber* self, Node_DomainIndex nodeDomainCount,
@@ -131,7 +132,7 @@
 						   Index maxSubTotalsPerProc );
 
 Node_RemappedGlobalIndex _FeEquationNumber_RemapNode( 
-	HexaMD* hexaMD,
+	Mesh* mesh, 
 	Index newDimOrder[3],
 	Node_GlobalIndex gNode_I );
 
@@ -140,6 +141,7 @@
 static Bool _FeEquationNumber_IHaveCritPoint(
 	FeEquationNumber* self,
 	Node_RemappedGlobalIndex critPoint );
+#endif
 
 /*###### Function Definitions ######*/
 
@@ -260,7 +262,7 @@
 	
 	/* FinteElementMesh info */
 	self->isConstructed = True;
-	self->feMesh = (FiniteElement_Mesh*)feMesh;
+	self->feMesh = (FeMesh*)feMesh;
 	self->globalSumUnconstrainedDofs = 0;
 	self->isBuilt = False;
 	self->locationMatrixBuilt = False;
@@ -300,14 +302,14 @@
 	Journal_DPrintfL( self->debug, 1, "In %s\n",  __func__ );
 	Stream_IndentBranch( StgFEM_Debug );
 
-	Memory_Free( self->remappedNodeInfos );
+	FreeArray( self->remappedNodeInfos );
 	/* free destination array memory */
 	Journal_DPrintfL( self->debug, 2, "Freeing I.D. Array\n" );
-	Memory_Free( self->destinationArray );
+	FreeArray( self->destinationArray );
 	
 	if (self->locationMatrix) {
 		Journal_DPrintfL( self->debug, 2, "Freeing Full L.M. Array\n" );
-		Memory_Free( self->locationMatrix );
+		FreeArray( self->locationMatrix );
 	}
 
 	if( self->bcEqNums ) {
@@ -349,10 +351,14 @@
 
 
 void* _FeEquationNumber_Copy( void* feEquationNumber, void* dest, Bool deep, Name nameExt, PtrMap* ptrMap ) {
+#if 0
 	FeEquationNumber*	self = (FeEquationNumber*)feEquationNumber;
+	Mesh*			mesh;
 	FeEquationNumber*	newFeEquationNumber;
 	PtrMap*			map = ptrMap;
 	Bool			ownMap = False;
+
+	mesh = (Mesh*)self->feMesh;
 	
 	if( !map ) {
 		map = PtrMap_New( 10 );
@@ -381,14 +387,15 @@
 		newFeEquationNumber->debug = (Stream*)Stg_Class_Copy( self->debug, NULL, deep, nameExt, map );
 		newFeEquationNumber->debugLM = (Stream*)Stg_Class_Copy( self->debugLM, NULL, deep, nameExt, map );
 		newFeEquationNumber->warning = (Stream*)Stg_Class_Copy( self->warning, NULL, deep, nameExt, map );
-		newFeEquationNumber->feMesh = (FiniteElement_Mesh*)Stg_Class_Copy( self->feMesh, NULL, deep, nameExt, map );
+		newFeEquationNumber->feMesh = (FeMesh*)Stg_Class_Copy( self->feMesh, NULL, deep, nameExt, map );
 		newFeEquationNumber->dofLayout = (DofLayout*)Stg_Class_Copy( self->dofLayout, NULL, deep, nameExt, map );
 		newFeEquationNumber->bcs = (VariableCondition*)Stg_Class_Copy( self->bcs, NULL, deep, nameExt, map );
 		newFeEquationNumber->linkedDofInfo = (LinkedDofInfo*)Stg_Class_Copy( self->linkedDofInfo, NULL, deep, nameExt, map );
 		
 		if( (newFeEquationNumber->remappedNodeInfos = PtrMap_Find( map, self->remappedNodeInfos )) == NULL && self->remappedNodeInfos ) {
-			MeshDecomp*		meshDecomp = self->feMesh->layout->decomp;
-			Node_DomainIndex	nodeDomainCount = meshDecomp->nodeDomainCount;
+			Node_DomainIndex	nodeDomainCount;
+
+			nodeDomainCount = Mesh_GetDomainSize( mesh, MT_VERTEX );
 			
 			newFeEquationNumber->remappedNodeInfos = Memory_Alloc_Array( RemappedNodeInfo, nodeDomainCount, "FeEquationNumber->remappedNodeInfos" );
 			memcpy( newFeEquationNumber->remappedNodeInfos, self->remappedNodeInfos, sizeof(RemappedNodeInfo) * nodeDomainCount );
@@ -396,9 +403,10 @@
 		}
 		
 		if( (newFeEquationNumber->destinationArray = PtrMap_Find( map, self->destinationArray )) == NULL && self->destinationArray ) {
-			MeshDecomp*		meshDecomp = self->feMesh->layout->decomp;
-			Node_DomainIndex	nodeDomainCount = meshDecomp->nodeDomainCount;
+			Node_DomainIndex	nodeDomainCount;
 			Node_DomainIndex	node_dI;
+
+			nodeDomainCount = Mesh_GetDomainSize( mesh, MT_VERTEX );
 			
 			newFeEquationNumber->destinationArray = Memory_Alloc_2DComplex( Dof_EquationNumber, nodeDomainCount, self->dofLayout->dofCounts, "FeEquationNumber->destinationArray" );
 			for( node_dI = 0; node_dI < nodeDomainCount; node_dI++ ) {
@@ -408,8 +416,9 @@
 		}
 		
 		if( (newFeEquationNumber->_lowestGlobalEqNums = PtrMap_Find( map, self->_lowestGlobalEqNums )) == NULL && self->_lowestGlobalEqNums ) {
-			MeshDecomp*		meshDecomp = self->feMesh->layout->decomp;
-			Partition_Index		nProc = meshDecomp->nproc;
+			Partition_Index		nProc;
+
+			nProc = Mesh_GetCommTopology( mesh, MT_VERTEX )->nProcs;
 			
 			newFeEquationNumber->_lowestGlobalEqNums = Memory_Alloc_Array( Dof_EquationNumber, nProc, "FeEquationNumber->_lowestGlobalEqNums" );
 			memcpy( newFeEquationNumber->_lowestGlobalEqNums, self->_lowestGlobalEqNums, sizeof(Dof_EquationNumber) * nProc );
@@ -417,7 +426,7 @@
 		}
 		
 		if( (newFeEquationNumber->locationMatrix = PtrMap_Find( map, self->locationMatrix )) == NULL && self->locationMatrix ) {
-			FiniteElement_Mesh*	mesh = self->feMesh;
+			FeMesh*	mesh = self->feMesh;
 			Element_LocalIndex	lElement_I;
 			Node_LocalIndex		numNodesThisElement;
 			Node_LocalIndex		elLocalNode_I;
@@ -467,6 +476,8 @@
 	}
 	
 	return (void*)newFeEquationNumber;
+#endif
+	abort();
 }
 
 
@@ -482,16 +493,18 @@
 
 void _FeEquationNumber_Build( void* feEquationNumber ) {
 	FeEquationNumber* self = (FeEquationNumber*) feEquationNumber;
-#if DEBUG
+
 	assert(self);
-#endif
 	
 	Journal_DPrintf( self->debug, "In %s:\n",  __func__ );
 	Stream_IndentBranch( StgFEM_Debug );
 
+#if 0
 	/* If we have new mesh topology information, do this differently. */
 	if( self->feMesh->topo->domains && self->feMesh->topo->domains[MT_VERTEX] ) {
+#endif
 		FeEquationNumber_BuildWithTopology( self );
+#if 0
 	}
 	else {
 		_FeEquationNumber_BuildRemappedNodeInfoTable( self );
@@ -499,13 +512,12 @@
 		_FeEquationNumber_CalculateGlobalUnconstrainedDofTotal( self );
 		_FeEquationNumber_CalculateEqNumsDecomposition( self );
 	}
+#endif
 
-#if DEBUG
 	if ( Stream_IsPrintableLevel( self->debug, 3 ) ) {
 		FeEquationNumber_PrintDestinationArray( self, self->debug );
 	}
-#endif
-	
+
 	Stream_UnIndentBranch( StgFEM_Debug );
 }
 
@@ -526,6 +538,7 @@
 }
 
 
+#if 0
 Node_RemappedGlobalIndex _FeEquationNumber_RemapNode( 
 	HexaMD* hexaMD,
 	Index newDimOrder[3],
@@ -554,14 +567,14 @@
 
 static void _FeEquationNumber_BuildRemappedNodeInfoTable( void* feEquationNumber ) {
 	FeEquationNumber* self = (FeEquationNumber*) feEquationNumber;
-	FiniteElement_Mesh* mesh = self->feMesh;
-	MeshDecomp* meshDecomp = self->feMesh->layout->decomp;
-	Node_DomainIndex nodeDomainCount = meshDecomp->nodeDomainCount;
+	FeMesh* mesh = self->feMesh;
+	Node_DomainIndex nodeDomainCount = Mesh_GetDomainSize( mesh, MT_VERTEX );
+	CommTopology*	commTopo = Mesh_GetCommTopology( mesh, MT_VERTEX );
 	Node_GlobalIndex gNode_I = 0;
 	Node_DomainIndex dNode_I = 0;
-#if DEBUG
+/*#if DEBUG*/
 	RemappedNodeInfo_Index rNodeInfo_I;
-#endif
+/*#endif*/
 	
 	Journal_DPrintfL( self->debug, 1, "In %s:\n",  __func__ );
 	Stream_IndentBranch( StgFEM_Debug );
@@ -569,7 +582,7 @@
 	self->remappedNodeInfos = Memory_Alloc_Array( RemappedNodeInfo, nodeDomainCount, 
 						      "FeEquationNumber->remappedNodeInfos" );
 	
-	if ( 1 == meshDecomp->procsInUse ) {
+	if ( 1 == commTopo->nProcs ) {
 		Journal_DPrintfL( self->debug, 1, "Serial code: No remapping required...filling remapping table with normal values.\n" );
 		for (dNode_I = 0; dNode_I < nodeDomainCount; dNode_I++ ) {
 			gNode_I = mesh->nodeD2G[dNode_I];
@@ -723,7 +736,7 @@
 		Stream_UnIndentBranch( StgFEM_Debug );
 	}
 
-#if DEBUG
+/*#if DEBUG*/
 	if ( Stream_IsPrintableLevel( self->debug, 3 ) ) {
 		Journal_DPrintf( self->debug, "Calculated remapped node info table as:\n{\n" );
 		for (rNodeInfo_I = 0; rNodeInfo_I < nodeDomainCount; rNodeInfo_I++ ) {
@@ -733,7 +746,7 @@
 		}
 		Journal_DPrintf( self->debug, "}\n");
 	}
-#endif
+/*#endif*/
 	Stream_UnIndentBranch( StgFEM_Debug );
 }	
 
@@ -831,7 +844,7 @@
 
 	/* If not removing BCs, construct a table of which equation numbers are actually BCs. */
 	if( !self->removeBCs ) {
-		FiniteElement_Mesh*	feMesh = self->feMesh;
+		FeMesh*	feMesh = self->feMesh;
 		DofLayout*		dofLayout = self->dofLayout;
 		VariableCondition*	bcs = self->bcs;
 		unsigned		lNode_i;
@@ -930,7 +943,7 @@
 		}
 	}
 
-#if DEBUG
+/*#if DEBUG*/
 	if ( Stream_IsPrintableLevel( self->debug, 2 ) ) {
 		Index cPoint_I;
 
@@ -946,7 +959,7 @@
 		}
 		Journal_DPrintf( self->debug, "]\n" );
 	}
-#endif
+/*#endif*/
 	Stream_UnIndentBranch( StgFEM_Debug );
 }
 
@@ -1055,7 +1068,7 @@
 			}	
 		}		
 	}			
-#if DEBUG
+/*#if DEBUG*/
 	if ( Stream_IsPrintableLevel( self->debug, 2 ) ) {
 		Journal_DPrintf( self->debug, "Calculated crit points I Have:\n[" );
 		for ( myCritPoint_I = 0; myCritPoint_I < (*critPointsIHaveTotal); myCritPoint_I++ ) {
@@ -1067,7 +1080,7 @@
 		}
 		Journal_DPrintf( self->debug, "]\n");
 	}	
-#endif
+/*#endif*/
 	
 	Memory_Free( allWantedCriticalPoints );
 	Memory_Free( procWantedCritPointsTotals );
@@ -1124,16 +1137,16 @@
 {
 	MeshDecomp* meshDecomp = self->feMesh->layout->decomp;
 	Partition_Index proc_I; 
-#if DEBUG
+/*#if DEBUG*/
 	Index point_I = 0;
-#endif
+/*#endif*/
 
 	Journal_DPrintf( self->debug, "In %s\n", __func__ );
 	Stream_IndentBranch( StgFEM_Debug );
 	
 	(*maxCritPointsPerProc) = 0;
 	
-#if DEBUG
+/*#if DEBUG*/
 	if ( Stream_IsPrintableLevel( self->debug, 2 ) ) {
 		Journal_DPrintf( self->debug, "myCriticalPointsTotal=%u\n",  myCriticalPointsTotal);
 		Journal_DPrintf( self->debug, "myCritPoints:(" );
@@ -1143,7 +1156,7 @@
 		}	
 		Journal_DPrintf( self->debug, ")\n");
 	}	
-#endif
+/*#endif*/
 
 	/* First, we allocate and calculate how many critical points are on each node (this way, we don't have to guess
 	   how much memory to allocate in the main array.) */
@@ -1159,14 +1172,14 @@
 			(*maxCritPointsPerProc) = (*procCritPointsTotals)[proc_I];
 	}
 
-#if DEBUG
+/*#if DEBUG*/
 	Journal_DPrintfL( self->debug, 2, "procCritPoints totals:(");
 	for (proc_I = 0; proc_I < meshDecomp->nproc; proc_I++) {
 		Journal_DPrintfL( self->debug, 2, "%d, ", (*procCritPointsTotals)[proc_I]);
 	}
 	Journal_DPrintfL( self->debug, 2, ")\n");
 	Journal_DPrintfL( self->debug, 2, "MaxCritPointsPerProc = %d\n", (*maxCritPointsPerProc));
-#endif
+/*#endif*/
 
 	/* Now share the actual point values */
 	(*myCriticalPoints) = Memory_Realloc_Array( (*myCriticalPoints), Node_GlobalIndex, *maxCritPointsPerProc );
@@ -1177,7 +1190,7 @@
 		       (*allCriticalPoints), (*maxCritPointsPerProc), MPI_UNSIGNED,
 		       meshDecomp->communicator );
 
-#if DEBUG
+/*#if DEBUG*/
 	Journal_DPrintfL( self->debug, 2, "procCritPoints:(" );
 	for (proc_I = 0; proc_I < meshDecomp->nproc; proc_I++) {
 		for ( point_I = 0; point_I < (*procCritPointsTotals)[proc_I]; point_I++)
@@ -1187,7 +1200,7 @@
 		}	
 	}
 	Journal_DPrintfL( self->debug, 2, ")\n");
-#endif
+/*#endif*/
 	Stream_UnIndentBranch( StgFEM_Debug );
 }
 
@@ -1207,9 +1220,9 @@
 {
 	MeshDecomp* meshDecomp = self->feMesh->layout->decomp;
 	Partition_Index proc_I; 
-#if DEBUG
+/*#if DEBUG*/
 	Index point_I = 0;
-#endif
+/*#endif*/
 
 	Journal_DPrintfL( self->debug, 1, "In %s\n",  __func__ );
 	Stream_IndentBranch( StgFEM_Debug );
@@ -1226,7 +1239,7 @@
 			(*maxCritPointInfoPerProc) = (*procCritPointInfoTotals)[proc_I];
 	}
 
-#if DEBUG
+/*#if DEBUG*/
 	if ( Stream_IsPrintableLevel( self->debug, 2 ) ) {
 		Journal_DPrintf( self->debug, "procCritPointInfo totals:(" );
 		for (proc_I = 0; proc_I < meshDecomp->nproc; proc_I++) {
@@ -1235,7 +1248,7 @@
 		Journal_DPrintf( self->debug, ")\n");
 		Journal_DPrintf( self->debug, "MaxCritPointInfoPerProc = %d\n", (*maxCritPointInfoPerProc));
 	}	
-#endif
+/*#endif*/
 
 	/* Now share the actual critPointInfo arrays */
 	(*allCritPointInfo) = Memory_Alloc_Array( CritPointInfo, meshDecomp->nproc * (*maxCritPointInfoPerProc), 
@@ -1246,7 +1259,7 @@
 		       (*allCritPointInfo), (*maxCritPointInfoPerProc), MPI_critPointInfoType,
 		       meshDecomp->communicator );
 	
-#if DEBUG
+/*#if DEBUG*/
 	if ( Stream_IsPrintableLevel( self->debug, 2 ) ) {	
 		Journal_DPrintf( self->debug, "procCritPointInfos" );
 		if ( DONT_PRINT_VALUES == printValuesFlag ) {
@@ -1266,7 +1279,7 @@
 		}
 		Journal_DPrintf( self->debug, ")\n");
 	}	
-#endif
+/*#endif*/
 	Stream_UnIndentBranch( StgFEM_Debug );
 }
 
@@ -1317,7 +1330,7 @@
 		rNodeInfo_I++;
 	}
 
-#if DEBUG
+/*#if DEBUG*/
 	if ( Stream_IsPrintableLevel( self->debug, 2 ) ) {
 		Journal_DPrintf( self->debug, "Totals I have:[ " );
 		haveCritPoint_I = 0;
@@ -1334,7 +1347,7 @@
 		}	
 		Journal_Printf( self->debug, "]\n" );
 	}
-#endif
+/*#endif*/
 	Stream_UnIndentBranch( StgFEM_Debug );
 }
 
@@ -1346,7 +1359,7 @@
 						   Index maxSubTotalsPerProc )
 {	
 	Partition_Index proc_I;
-	FiniteElement_Mesh* mesh = self->feMesh;
+	FeMesh* mesh = self->feMesh;
 	MeshDecomp* meshDecomp = self->feMesh->layout->decomp;
 	Index myRank = meshDecomp->rank;
 	Node_GlobalIndex nodeDomainCount = meshDecomp->nodeDomainCount;
@@ -1568,16 +1581,16 @@
 {
 	Dof_Index	currNodeNumDofs;
 	Dof_Index	nodeLocalDof_I;
-#if DEBUG
+/*#if DEBUG*/
 	Stream*		error;
-#endif
+/*#endif*/
 	
 	Journal_DPrintfL( self->debug, 3, "In %s:",  __func__ );
-#if DEBUG
+/*#if DEBUG*/
 	error = Journal_Register( Error_Type, self->type );
 	Journal_Firewall( (dNode_I < self->feMesh->nodeDomainCount), error, "Stuffup: %s() asked to operate on node %d, bigger "
 			  "than domain count %d. Exiting.\n", __func__, dNode_I, self->feMesh->nodeDomainCount );
-#endif
+/*#endif*/
 	
 	/* get the number of dofs */
 	currNodeNumDofs = self->dofLayout->dofCounts[ dNode_I ];
@@ -1754,6 +1767,7 @@
 
 	Memory_Free( adjustDueToNonLocalLinkedDofsTbl );
 }
+#endif
 
 
 Index FeEquationNumber_CalculateActiveEqCountAtNode(
@@ -1781,15 +1795,70 @@
 	return activeEqsAtCurrRowNode;
 }
 
+
+void FeEquationNumber_BuildLocationMatrix( void* feEquationNumber ) {
+	FeEquationNumber*	self = (FeEquationNumber*)feEquationNumber;
+	FeMesh*			feMesh;
+	unsigned		nDims;
+	unsigned		nDomainEls;
+	unsigned		nLocalNodes;
+	unsigned*		nNodalDofs;
+	unsigned		nElNodes;
+	unsigned*		elNodes;
+	int**			dstArray;
+	int***			locMat;
+	unsigned		e_i, n_i, dof_i;
+
+	assert( self );
+
+	/* Don't build if already done. */
+	if( self->locationMatrixBuilt ) {
+		Journal_DPrintf( self->debugLM, "In %s: LM already built, so just returning.\n",  __func__ );
+		Stream_UnIndentBranch( StgFEM_Debug );
+		return;
+	}
+
+	/* Shortcuts. */
+	feMesh = self->feMesh;
+	nDims = Mesh_GetDimSize( feMesh );
+	nDomainEls = FeMesh_GetElementDomainSize( feMesh );
+	nLocalNodes = FeMesh_GetNodeLocalSize( feMesh );
+	nNodalDofs = self->dofLayout->dofCounts;
+	dstArray = self->destinationArray;
+
+	/* Allocate for the location matrix. */
+	locMat = AllocArray( int**, nDomainEls );
+	for( e_i = 0; e_i < nDomainEls; e_i++ ) {
+		FeMesh_GetElementNodes( feMesh, e_i, &nElNodes, &elNodes );
+		locMat[e_i] = AllocArray( int*, nElNodes );
+		for( n_i = 0; n_i < nElNodes; n_i++ )
+			locMat[e_i][n_i] = AllocArray( int, nNodalDofs[elNodes[n_i]] );
+	}
+
+	/* Build location matrix. */
+	for( e_i = 0; e_i < nDomainEls; e_i++ ) {
+		FeMesh_GetElementNodes( feMesh, e_i, &nElNodes, &elNodes );
+		for( n_i = 0; n_i < nElNodes; n_i++ ) {
+			for( dof_i = 0; dof_i < nNodalDofs[elNodes[n_i]]; dof_i++ )
+				locMat[e_i][n_i][dof_i] = dstArray[elNodes[n_i]][dof_i];
+		}
+	}
+
+	/* Store result. */
+	self->locationMatrix = locMat;
+}
+
+
+#if 0
 /** build the element location matrix mapping elements, element node, dof -> eq num */
 void FeEquationNumber_BuildLocationMatrix( FeEquationNumber* self ) {
-	FiniteElement_Mesh* mesh = self->feMesh;
+	FeMesh* mesh = self->feMesh;
 	Element_LocalIndex lElement_I;
 	Node_LocalIndex numNodesThisElement = 0;
 	Node_LocalIndex elLocalNode_I = 0;
 	Dof_Index numDofsThisNode = 0;
 	Dof_Index** dofCountsAtElementNodesArray = NULL;
-	Element_LocalIndex elementLocalCount = self->feMesh->elementLocalCount;
+	Element_LocalIndex elementLocalCount = Mesh_GetLocalSize( mesh, Mesh_GetDimSize( mesh ) );
 
 	Journal_DPrintf( self->debug, "In %s():\n", __func__ );
 	Stream_IndentBranch( StgFEM_Debug );
@@ -1799,11 +1868,12 @@
 		Stream_UnIndentBranch( StgFEM_Debug );
 		return;
 	}
-		
+
 	Journal_DPrintf( self->debugLM, "In %s: building over %d elements.\n",  __func__, elementLocalCount );
 
 	/* Allocate the LM 3D array using the Memory module, in 2 stage process */
-	dofCountsAtElementNodesArray = Memory_Alloc_3DSetup( elementLocalCount, mesh->elementNodeCountTbl );
+	dofCountsAtElementNodesArray = Memory_Alloc_3DSetup( elementLocalCount, 
+							     mesh->topo->nIncEls[nDims][MT_VERTEX] );
 
 	for ( lElement_I = 0; lElement_I < elementLocalCount; lElement_I++ ) {
 		numNodesThisElement = mesh->elementNodeCountTbl[lElement_I];
@@ -1828,25 +1898,32 @@
 	self->locationMatrixBuilt = True;
 	Stream_UnIndentBranch( StgFEM_Debug );
 }
+#endif
 
 
 /** Build an element's local location matrix */
 Dof_EquationNumber** FeEquationNumber_BuildOneElementLocationMatrix( void* feEquationNumber, Element_LocalIndex lElement_I ) {
 	FeEquationNumber* self = (FeEquationNumber*)feEquationNumber;
 	Node_DomainIndex elLocalNode_I;
-	Node_DomainIndex numNodesThisElement;
+	Node_DomainIndex numNodesThisElement, *elInc;
 	Dof_EquationNumber** localLocationMatrix = NULL;
-	FiniteElement_Mesh* mesh = self->feMesh;
+	FeMesh* feMesh = self->feMesh;
 	Dof_Index numDofsThisNode = 0;
 
-	numNodesThisElement = mesh->elementNodeCountTbl[lElement_I];
+	FeMesh_GetElementNodes( feMesh, lElement_I, &numNodesThisElement, &elInc );
 
+	/* HACK: Make sure global element location matrix is built. */
+	if( !self->locationMatrixBuilt )
+		abort();
+
 	/* if ( big LM allocated ) set pointer into it correctly */
 	if ( self->locationMatrix ) {
 		/* set ptr to correct set of local nodes ptrs */
 		localLocationMatrix = self->locationMatrix[lElement_I];
 		Journal_DPrintfL( self->debugLM, 3, "set localLocationMatrix to pt. to big LM[%d] = %p\n",  lElement_I, self->locationMatrix[lElement_I] ) ;
 	}
+
+#if 0
 	else {
 		Dof_Index* numDofsEachNode = NULL;
 
@@ -1862,7 +1939,9 @@
 							      "localLocationMatrix (set of ptrs to dof lists, indexed by element-local node)" );
 		Memory_Free( numDofsEachNode );
 	}
+#endif
 
+#if 0
 	/* If we haven't yet built full LM, copy ID values across */
 	if ( False == self->locationMatrixBuilt ) {
 		/* for (each el-local node) */
@@ -1878,6 +1957,7 @@
 				self->destinationArray[procDomainNode], numDofsThisNode * sizeof(Dof_EquationNumber) );
 		}
 	}
+#endif
 
 	return localLocationMatrix;
 }
@@ -1885,18 +1965,20 @@
 
 void FeEquationNumber_PrintDestinationArray( void* feFeEquationNumber, Stream* stream ) {
 	FeEquationNumber* self = (FeEquationNumber*) feFeEquationNumber;
+	FeMesh*		feMesh = self->feMesh;
+	MPI_Comm comm = CommTopology_GetComm( Mesh_GetCommTopology( feMesh, MT_VERTEX ) );
+	unsigned rank;
+	Node_GlobalIndex gNode_I;
+	Node_GlobalIndex nodeGlobalCount = FeMesh_GetNodeGlobalSize( feMesh );
 
-	FiniteElement_Mesh* mesh = self->feMesh;
-	MeshDecomp* meshDecomp = self->feMesh->layout->decomp;
-	Node_GlobalIndex gNode_I; 
-	Node_GlobalIndex nodeGlobalCount = meshDecomp->nodeGlobalCount;
+	Journal_Printf( stream, "%d: *** Printing destination array ***\n", rank );
 
-	Journal_Printf( stream, "%d: *** Printing destination array ***\n", mesh->layout->decomp->rank );
+	MPI_Comm_rank( comm, (int*)&rank );
 
 	for (gNode_I =0; gNode_I < nodeGlobalCount; gNode_I++) {
-		Node_DomainIndex dNode_I = Mesh_NodeMapGlobalToDomain( mesh, gNode_I );
+		Node_DomainIndex dNode_I;
 
-		if ( nodeGlobalCount == dNode_I ) {
+		if ( !Mesh_GlobalToDomain( feMesh, MT_VERTEX, gNode_I, &dNode_I ) ) {
 			Journal_Printf( stream, "\tdestinationArray[(gnode)%2d]: on another proc\n", gNode_I);
 		}
 		else {
@@ -1915,28 +1997,36 @@
 
 void FeEquationNumber_PrintLocationMatrix( void* feFeEquationNumber, Stream* stream ) {
 	FeEquationNumber* self = (FeEquationNumber*) feFeEquationNumber;
-	FiniteElement_Mesh* mesh = self->feMesh;
-	MeshDecomp* meshDecomp = self->feMesh->layout->decomp;
+	FeMesh*		feMesh = self->feMesh;
+	MPI_Comm comm = CommTopology_GetComm( Mesh_GetCommTopology( feMesh, MT_VERTEX ) );
+	unsigned rank;
 	Element_GlobalIndex gEl_I;
-	Element_GlobalIndex elementGlobalCount = meshDecomp->elementGlobalCount;
+	unsigned nDims = Mesh_GetDimSize( feMesh );
+	Element_GlobalIndex elementGlobalCount = FeMesh_GetElementGlobalSize( feMesh );
+	unsigned nLocalEls = FeMesh_GetElementLocalSize( feMesh );
 
-	Journal_Printf( stream, "%d: *** Printing location matrix ***\n", mesh->layout->decomp->rank  );
+	Journal_Printf( stream, "%d: *** Printing location matrix ***\n", rank  );
+
+	MPI_Comm_rank( comm, (int*)&rank );
 	
 	for (gEl_I =0; gEl_I < elementGlobalCount; gEl_I++ ) {
-		Element_LocalIndex lEl_I = Mesh_ElementMapGlobalToLocal( mesh, gEl_I );
+		Element_LocalIndex lEl_I;
 
-		if ( elementGlobalCount == lEl_I ) {
+		if ( !Mesh_GlobalToDomain( feMesh, nDims, gEl_I, &lEl_I ) || lEl_I >= nLocalEls ) {
 			Journal_Printf( stream, "\tLM[(g/l el)%2d/XXX]: on another proc\n", gEl_I);
 		}
 		else {
-			Node_LocalIndex numNodesAtElement = self->feMesh->elementNodeCountTbl[lEl_I];
+			Node_LocalIndex numNodesAtElement;
 			Node_LocalIndex elLocalNode_I;
+			unsigned*	incNodes;
 
+			FeMesh_GetElementNodes( self->feMesh, lEl_I, &numNodesAtElement, &incNodes );
+
 			Journal_Printf( stream, "\tLM[(g/l el)%2d/%2d][(enodes)0-%d]", gEl_I, lEl_I, numNodesAtElement);	
 			/* print the nodes and dofs */
 			for ( elLocalNode_I = 0; elLocalNode_I < numNodesAtElement; elLocalNode_I++ ) {
 				/* look up processor local node number. */
-				Element_LocalIndex currNode = self->feMesh->elementNodeTbl[lEl_I][elLocalNode_I];
+				Element_LocalIndex currNode = incNodes[elLocalNode_I];
 				/* get the number of dofs at current node */
 				Dof_Index currNodeNumDofs = self->dofLayout->dofCounts[ currNode ];
 				Dof_Index nodeLocalDof_I;
@@ -1955,6 +2045,7 @@
 }
 
 
+#if 0
 void FeEquationNumber_PrintElementLocationMatrix(
 	void*			feEquationNumber,
 	Dof_EquationNumber**	elementLM,
@@ -2070,26 +2161,26 @@
 
 	Stream_UnIndentBranch( StgFEM_Debug );
 }
+#endif
 
 
 Partition_Index FeEquationNumber_CalculateOwningProcessorOfEqNum( void* feEquationNumber, Dof_EquationNumber eqNum ) {
 	FeEquationNumber* self = (FeEquationNumber*)feEquationNumber;
-
 	Partition_Index ownerProc = (unsigned int)-1;
+	CommTopology*	commTopo = Mesh_GetCommTopology( self->feMesh, MT_VERTEX );
+	MPI_Comm	comm = CommTopology_GetComm( commTopo );
+	unsigned	nProcs;
+	unsigned	p_i;
 
-	/* If we used the new mesh topology junk, do something a little different. */
-	if( self->feMesh->topo->domains && self->feMesh->topo->domains[MT_VERTEX] ) {
-		CommTopology*	commTopo = self->feMesh->topo->domains[0]->commTopo;
-		unsigned	p_i;
+	MPI_Comm_size( comm, (int*)&nProcs );
+	for( p_i = 1; p_i < nProcs; p_i++ ) {
+		if( eqNum < self->_lowestGlobalEqNums[p_i] )
+			break;
+	}
 
-		for( p_i = 1; p_i < commTopo->nProcs; p_i++ ) {
-			if( eqNum < self->_lowestGlobalEqNums[p_i] )
-				break;
-		}
+	return p_i - 1;
 
-		return p_i - 1;
-	}
-	else {
+#if 0
 		if ( (self->remappingActivated) && ( (self->linkedDofInfo == NULL) || (self->linkedDofInfo->linkedDofSetsCount == 0 ) ) ) {
 			MeshDecomp*		meshDecomp = self->feMesh->layout->decomp;
 			Partition_Index		myRank = meshDecomp->rank;
@@ -2131,9 +2222,11 @@
 	}
 
 	return ownerProc;
+#endif
 }	
 
 
+#if 0
 void FeEquationNumber_Create_CritPointInfo_MPI_Datatype( void ) {
 #define CRIT_POINT_INFO_NBLOCKS 2
 	MPI_Aint indexExtent = 0;
@@ -2150,19 +2243,22 @@
 	
 	MPI_Type_commit( &MPI_critPointInfoType );
 }
+#endif
 
 
 void FeEquationNumber_BuildWithTopology( FeEquationNumber* self ) {
-	MeshTopology*		topo;
+	FeMesh*			feMesh;
+	Decomp_Sync*		sync;
 	CommTopology*		commTopo;
+	MPI_Comm		comm;
+	unsigned		rank, nProcs;
+	unsigned		nDims;
 	unsigned		nDomainNodes, nDomainEls;
 	unsigned		nLocalNodes;
 	unsigned*		nNodalDofs;
-	unsigned*		nElNodes;
-	unsigned**		elNodes;
+	unsigned		nElNodes, *elNodes;
 	int**			dstArray;
-	unsigned**		nLocMatDofs;
-	int***			locMat;
+	int			*nLocMatDofs, ***locMat;
 	unsigned		varInd;
 	unsigned		curEqNum;
 	unsigned		base;
@@ -2176,96 +2272,88 @@
 	assert( self );
 
 	/* Shortcuts. */
-	topo = self->feMesh->topo;
-	commTopo = topo->domains[MT_VERTEX]->commTopo;
-	nDomainNodes = self->feMesh->nodeDomainCount;
-	nDomainEls = self->feMesh->elementDomainCount;
-	nLocalNodes = MeshTopology_GetLocalSize( topo, MT_VERTEX );
+	feMesh = self->feMesh;
+	commTopo = Mesh_GetCommTopology( feMesh, MT_VERTEX );
+	comm = CommTopology_GetComm( commTopo );
+	MPI_Comm_size( comm, (int*)&nProcs );
+	MPI_Comm_rank( comm, (int*)&rank );
+	nDims = Mesh_GetDimSize( feMesh );
+	nDomainNodes = FeMesh_GetNodeDomainSize( feMesh );
+	nDomainEls = FeMesh_GetElementDomainSize( feMesh );
+	nLocalNodes = FeMesh_GetNodeLocalSize( feMesh );
 	nNodalDofs = self->dofLayout->dofCounts;
-	nElNodes = self->feMesh->elementNodeCountTbl;
-	elNodes = self->feMesh->elementNodeTbl;
 
 	/* Allocate for destination array. */
 	dstArray = Memory_Alloc_2DComplex( int, nDomainNodes, nNodalDofs, 
 					   "FeEquationNumber::destinationArray" );
 
 	/* Allocate for the location matrix. */
-	nLocMatDofs = Memory_Alloc_2DComplex_Unnamed( unsigned, nDomainEls, nElNodes );
+	nLocMatDofs = NULL;
+	locMat = AllocArray( int**, nDomainEls );
 	for( e_i = 0; e_i < nDomainEls; e_i++ ) {
-		for( n_i = 0; n_i < nElNodes[e_i]; n_i++ )
-			nLocMatDofs[e_i][n_i] = nNodalDofs[elNodes[e_i][n_i]];
+		FeMesh_GetElementNodes( feMesh, e_i, &nElNodes, &elNodes );
+		nLocMatDofs = ReallocArray( nLocMatDofs, int, nElNodes );
+		for( n_i = 0; n_i < nElNodes; n_i++ )
+			nLocMatDofs[n_i] = nNodalDofs[elNodes[n_i]];
+		locMat[e_i] = AllocComplex2D( int, nElNodes, nLocMatDofs );
 	}
-	locMat = Memory_Alloc_3DComplex( int, nDomainEls, nElNodes, nLocMatDofs, 
-					 "FeEquationNumber::locationMatrix" );
 	FreeArray( nLocMatDofs );
 
 	/* Build initial destination array and store max dofs. */
 	curEqNum = 0;
 	maxDofs = 0;
 	for( n_i = 0; n_i < nLocalNodes; n_i++ ) {
-		unsigned	lInd;
+		if( nNodalDofs[n_i] > maxDofs )
+			maxDofs = nNodalDofs[n_i];
 
-		lInd = MeshTopology_DomainToGlobal( topo, MT_VERTEX, n_i );
-		lInd = Mesh_NodeMapGlobalToDomain( self->feMesh, lInd );
-
-		if( nNodalDofs[lInd] > maxDofs )
-			maxDofs = nNodalDofs[lInd];
-
-		for( dof_i = 0; dof_i < nNodalDofs[lInd]; dof_i++ ) {
-			varInd = self->dofLayout->varIndices[lInd][dof_i];
-			if( !self->bcs || !VariableCondition_IsCondition( self->bcs, lInd, varInd ) )
-				dstArray[lInd][dof_i] = curEqNum++;
+		for( dof_i = 0; dof_i < nNodalDofs[n_i]; dof_i++ ) {
+			varInd = self->dofLayout->varIndices[n_i][dof_i];
+			if( !self->bcs || !VariableCondition_IsCondition( self->bcs, n_i, varInd ) )
+				dstArray[n_i][dof_i] = curEqNum++;
 			else
-				dstArray[lInd][dof_i] = -1;
+				dstArray[n_i][dof_i] = -1;
 		}
 	}
 
 	/* Order the equation numbers based on processor rank; cascade counts forward. */
 	base = 0;
 	subTotal = curEqNum;
-	if( commTopo->rank > 0 ) {
-		MPI_Recv( &base, 1, MPI_UNSIGNED, commTopo->rank - 1, 6669, commTopo->comm, &status );
+	if( rank > 0 ) {
+		MPI_Recv( &base, 1, MPI_UNSIGNED, rank - 1, 6669, comm, &status );
 		subTotal = base + curEqNum;
 	}
-	if( commTopo->rank < commTopo->nProcs - 1 )
-		MPI_Send( &subTotal, 1, MPI_UNSIGNED, commTopo->rank + 1, 6669, commTopo->comm );
+	if( rank < nProcs - 1 )
+		MPI_Send( &subTotal, 1, MPI_UNSIGNED, rank + 1, 6669, comm );
 
 	/* Modify existing destination array and dump to a tuple array. */
-	tuples = Memory_Alloc_Array_Unnamed( unsigned, nDomainNodes * maxDofs );
+	tuples = AllocArray( unsigned, nDomainNodes * maxDofs );
 	for( n_i = 0; n_i < nLocalNodes; n_i++ ) {
-		unsigned	lInd;
-
-		lInd = MeshTopology_DomainToGlobal( topo, MT_VERTEX, n_i );
-		lInd = Mesh_NodeMapGlobalToDomain( self->feMesh, lInd );
-
-		for( dof_i = 0; dof_i < nNodalDofs[lInd]; dof_i++ ) {
-			varInd = self->dofLayout->varIndices[lInd][dof_i];
-			if( !self->bcs || !VariableCondition_IsCondition( self->bcs, lInd, varInd ) )
-				dstArray[lInd][dof_i] += base;
-			tuples[n_i * maxDofs + dof_i] = dstArray[lInd][dof_i];
+		for( dof_i = 0; dof_i < nNodalDofs[n_i]; dof_i++ ) {
+			varInd = self->dofLayout->varIndices[n_i][dof_i];
+			if( !self->bcs || !VariableCondition_IsCondition( self->bcs, n_i, varInd ) )
+				dstArray[n_i][dof_i] += base;
+			tuples[n_i * maxDofs + dof_i] = dstArray[n_i][dof_i];
 		}
 	}
 
 	/* Update all other procs. */
-	array = Decomp_Sync_AddArray( topo->domains[MT_VERTEX], tuples, tuples + nLocalNodes * maxDofs, 
-				      maxDofs * sizeof(unsigned), maxDofs * sizeof(unsigned), 
-				      maxDofs * sizeof(unsigned) );
-	Decomp_Sync_SyncArray( topo->domains[MT_VERTEX], array );
-	Decomp_Sync_RemoveArray( topo->domains[MT_VERTEX], array );
+	sync = Mesh_GetSync( feMesh, MT_VERTEX );
+	array = Decomp_Sync_Array_New();
+	Decomp_Sync_Array_SetSync( array, sync );
+	Decomp_Sync_Array_SetMemory( array, tuples, tuples + nLocalNodes * maxDofs, 
+				     maxDofs * sizeof(unsigned), maxDofs * sizeof(unsigned), 
+				     maxDofs * sizeof(unsigned) );
+	Decomp_Sync_Array_Sync( array );
+	FreeObject( array );
 
 	/* Update destination array's domain indices. */
 	for( n_i = nLocalNodes; n_i < nDomainNodes; n_i++ ) {
-		unsigned	dInd;
-
-		dInd = MeshTopology_DomainToGlobal( topo, MT_VERTEX, n_i );
-		dInd = Mesh_NodeMapGlobalToDomain( self->feMesh, dInd );
-
-		for( dof_i = 0; dof_i < nNodalDofs[dInd]; dof_i++ ) {
-			varInd = self->dofLayout->varIndices[dInd][dof_i];
-			if( !self->bcs || !VariableCondition_IsCondition( self->bcs, dInd, varInd ) )
-				dstArray[dInd][dof_i] = tuples[n_i * maxDofs + dof_i];
+		for( dof_i = 0; dof_i < nNodalDofs[n_i]; dof_i++ ) {
+			varInd = self->dofLayout->varIndices[n_i][dof_i];
+			if( !self->bcs || !VariableCondition_IsCondition( self->bcs, n_i, varInd ) )
+				dstArray[n_i][dof_i] = tuples[n_i * maxDofs + dof_i];
 			else
-				dstArray[dInd][dof_i] = -1;
+				dstArray[n_i][dof_i] = -1;
 		}
 	}
 
@@ -2274,9 +2362,10 @@
 
 	/* Build location matrix. */
 	for( e_i = 0; e_i < nDomainEls; e_i++ ) {
-		for( n_i = 0; n_i < nElNodes[e_i]; n_i++ ) {
-			for( dof_i = 0; dof_i < nNodalDofs[elNodes[e_i][n_i]]; dof_i++ )
-				locMat[e_i][n_i][dof_i] = dstArray[elNodes[e_i][n_i]][dof_i];
+		FeMesh_GetElementNodes( feMesh, e_i, &nElNodes, &elNodes );
+		for( n_i = 0; n_i < nElNodes; n_i++ ) {
+			for( dof_i = 0; dof_i < nNodalDofs[elNodes[n_i]]; dof_i++ )
+				locMat[e_i][n_i][dof_i] = dstArray[elNodes[n_i]][dof_i];
 		}
 	}
 
@@ -2290,10 +2379,9 @@
 	self->lastOwnedEqNum = subTotal - 1;
 
 	/* Bcast global sum from highest rank. */
-	MPI_Bcast( &self->globalSumUnconstrainedDofs, 1, MPI_UNSIGNED, commTopo->nProcs - 1, commTopo->comm );
+	MPI_Bcast( &self->globalSumUnconstrainedDofs, 1, MPI_UNSIGNED, nProcs - 1, comm );
 
 	/* Construct lowest global equation number list. */
-	self->_lowestGlobalEqNums = Memory_Alloc_Array_Unnamed( int, self->feMesh->topo->domains[0]->commTopo->nProcs );
-	MPI_Allgather( &self->firstOwnedEqNum, 1, MPI_UNSIGNED, self->_lowestGlobalEqNums, 1, MPI_UNSIGNED, 
-		       self->feMesh->topo->domains[0]->commTopo->comm );
+	self->_lowestGlobalEqNums = AllocArray( int, nProcs );
+	MPI_Allgather( &self->firstOwnedEqNum, 1, MPI_UNSIGNED, self->_lowestGlobalEqNums, 1, MPI_UNSIGNED, comm );
 }

Modified: long/3D/Gale/trunk/src/StgFEM/Discretisation/src/FeEquationNumber.h
===================================================================
--- long/3D/Gale/trunk/src/StgFEM/Discretisation/src/FeEquationNumber.h	2006-12-07 23:26:14 UTC (rev 5532)
+++ long/3D/Gale/trunk/src/StgFEM/Discretisation/src/FeEquationNumber.h	2006-12-07 23:29:43 UTC (rev 5533)
@@ -99,7 +99,7 @@
 		Stream*					debugLM; \
 		Stream*					warning; \
 		/** attached feMesh */ \
-		FiniteElement_Mesh*			feMesh; \
+		FeMesh*					feMesh; \
 		/** DofLayout describing the discretisation of an FeVariable over the mesh */ \
 		DofLayout*				dofLayout; \
 		/** LinkedEquationInfo - information on which dofs are linked together */ \
@@ -239,7 +239,7 @@
 	Partition_Index FeEquationNumber_CalculateOwningProcessorOfEqNum( void* self, Dof_EquationNumber eqNum );
 
 	/** build the processor's location matrix mapping elements, element node, dof -> eq num */
-	void FeEquationNumber_BuildLocationMatrix( FeEquationNumber* self );
+	void FeEquationNumber_BuildLocationMatrix( void* feEquationNumber );
 	
 	/** Build an element's local location matrix */
 	Dof_EquationNumber** FeEquationNumber_BuildOneElementLocationMatrix( void* feEquationNumber, Element_LocalIndex lElement_I );

Added: long/3D/Gale/trunk/src/StgFEM/Discretisation/src/FeMesh.c
===================================================================
--- long/3D/Gale/trunk/src/StgFEM/Discretisation/src/FeMesh.c	2006-12-07 23:26:14 UTC (rev 5532)
+++ long/3D/Gale/trunk/src/StgFEM/Discretisation/src/FeMesh.c	2006-12-07 23:29:43 UTC (rev 5533)
@@ -0,0 +1,392 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+**
+** Copyright (C), 2003, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street, Melbourne, 3053, Australia.
+**
+** Authors:
+**	Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
+**	Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
+**	Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
+**	Siew-Ching Tan, Software Engineer, VPAC. (siew at vpac.org)
+**	Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
+**	Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
+**
+**  This library is free software; you can redistribute it and/or
+**  modify it under the terms of the GNU Lesser General Public
+**  License as published by the Free Software Foundation; either
+**  version 2.1 of the License, or (at your option) any later version.
+**
+**  This library 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
+**  Lesser General Public License for more details.
+**
+**  You should have received a copy of the GNU Lesser General Public
+**  License along with this library; if not, write to the Free Software
+**  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+**
+** $Id$
+**
+**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include <mpi.h>
+
+#include "StGermain/StGermain.h"
+#include "Discretisation.h"
+
+
+/* Textual name of this class */
+const Type FeMesh_Type = "FeMesh";
+
+
+/*----------------------------------------------------------------------------------------------------------------------------------
+** Constructors
+*/
+
+FeMesh* FeMesh_New( Name name ) {
+	return _FeMesh_New( sizeof(FeMesh), 
+			  FeMesh_Type, 
+			  _FeMesh_Delete, 
+			  _FeMesh_Print, 
+			  NULL, 
+			  (void* (*)(Name))_FeMesh_New, 
+			  _FeMesh_Construct, 
+			  _FeMesh_Build, 
+			  _FeMesh_Initialise, 
+			  _FeMesh_Execute, 
+			  _FeMesh_Destroy, 
+			  name, 
+			  NON_GLOBAL );
+}
+
+FeMesh* _FeMesh_New( FEMESH_DEFARGS ) {
+	FeMesh*	self;
+
+	/* Allocate memory */
+	assert( sizeOfSelf >= sizeof(FeMesh) );
+	self = (FeMesh*)_Mesh_New( MESH_PASSARGS );
+
+	/* Virtual info */
+
+	/* FeMesh info */
+	_FeMesh_Init( self );
+
+	return self;
+}
+
+void _FeMesh_Init( FeMesh* self ) {
+	self->elMesh = (Mesh*)self;
+	self->feElType = NULL;
+	self->feElFamily = NULL;
+}
+
+
+/*----------------------------------------------------------------------------------------------------------------------------------
+** Virtual functions
+*/
+
+void _FeMesh_Delete( void* feMesh ) {
+	FeMesh*	self = (FeMesh*)feMesh;
+
+	FeMesh_Destruct( self );
+
+	/* Delete the parent. */
+	_Mesh_Delete( self );
+}
+
+void _FeMesh_Print( void* feMesh, Stream* stream ) {
+	FeMesh*	self = (FeMesh*)feMesh;
+	
+	/* Set the Journal for printing informations */
+	Stream* feMeshStream;
+	feMeshStream = Journal_Register( InfoStream_Type, "FeMeshStream" );
+
+	/* Print parent */
+	Journal_Printf( stream, "FeMesh (ptr): (%p)\n", self );
+	_Mesh_Print( self, stream );
+}
+
+void _FeMesh_Construct( void* feMesh, Stg_ComponentFactory* cf, void* data ) {
+	FeMesh*		self = (FeMesh*)feMesh;
+	char*		elMeshName;
+	Mesh*		elMesh;
+	char*		family;
+
+	assert( self );
+
+	_Mesh_Construct( self, cf, data );
+
+	elMeshName = Stg_ComponentFactory_GetString( cf, self->name, "elementMesh", "" );
+	if( !elMeshName || !strcmp( elMeshName, "" ) )
+		elMesh = NULL;
+	else
+		elMesh = Stg_ComponentFactory_ConstructByKey( cf, self->name, "elementMesh", Mesh, True, data );
+	family = Stg_ComponentFactory_GetString( cf, self->name, "elementType", "linear" );
+
+	FeMesh_SetElementMesh( self, elMesh );
+	FeMesh_SetElementFamily( self, family );
+}
+
+void _FeMesh_Build( void* feMesh, void* data ) {
+	FeMesh*		self = (FeMesh*)feMesh;
+	ElementType*	elType;
+
+	assert( self );
+
+	_Mesh_Build( self, data );
+
+	if( self->elMesh && self->elMesh != (Mesh*)self )
+		Build( self->elMesh, data, False );
+
+	if( !strcmp( self->feElFamily, "linear" ) ) {
+		unsigned	nDims;
+
+		nDims = Mesh_GetDimSize( self );
+		if( nDims == 2 )
+			elType = (ElementType*)BilinearElementType_New( "" );
+		else if( nDims == 3 )
+			elType = (ElementType*)TrilinearElementType_New( "" );
+		else
+			abort();
+	}
+	else if( !strcmp( self->feElFamily, "constant" ) ) {
+		elType = (ElementType*)ConstantElementType_New( "" );
+	}
+	else
+		abort();
+	FeMesh_SetElementType( self, elType );
+	if( self->feElType )
+		Stg_Component_Build( self->feElType, data, False );
+}
+
+void _FeMesh_Initialise( void* feMesh, void* data ) {
+	FeMesh*	self = (FeMesh*)feMesh;
+
+	assert( self );
+
+	_Mesh_Initialise( self, data );
+
+	if( self->elMesh && self->elMesh != (Mesh*)self )
+		Stg_Component_Initialise( self->elMesh, data, False );
+	if( self->feElType )
+		Stg_Component_Initialise( self->feElType, data, False );
+}
+
+void _FeMesh_Execute( void* feMesh, void* data ) {
+}
+
+void _FeMesh_Destroy( void* feMesh, void* data ) {
+}
+
+
+/*--------------------------------------------------------------------------------------------------------------------------
+** Public Functions
+*/
+
+void FeMesh_SetElementMesh( void* feMesh, Mesh* elementMesh ) {
+	FeMesh*	self = (FeMesh*)feMesh;
+
+	assert( self );
+
+	if( self->elMesh != (Mesh*)self )
+		Mesh_Destruct( (Mesh*)self );
+	FeMesh_Destruct( self );
+
+	if( elementMesh )
+		self->elMesh = elementMesh;
+}
+
+void FeMesh_SetElementType( void* feMesh, ElementType* elType ) {
+	FeMesh*	self = (FeMesh*)feMesh;
+
+	assert( self );
+
+	FreeObject( self->feElType );
+	self->feElType = elType;
+}
+
+void FeMesh_SetElementFamily( void* feMesh, const char* family ) {
+	FeMesh*	self = (FeMesh*)feMesh;
+
+	assert( self );
+
+	self->feElFamily = (char*)family;
+}
+
+Mesh* FeMesh_GetElementMesh( void* feMesh ) {
+	FeMesh*	self = (FeMesh*)feMesh;
+
+	assert( self );
+
+	return self->elMesh;
+}
+
+ElementType* FeMesh_GetElementType( void* feMesh, unsigned element ) {
+	FeMesh*	self = (FeMesh*)feMesh;
+
+	assert( self );
+
+	return self->feElType;
+}
+
+unsigned FeMesh_GetNodeLocalSize( void* feMesh ) {
+	return Mesh_GetLocalSize( feMesh, MT_VERTEX );
+}
+
+unsigned FeMesh_GetNodeRemoteSize( void* feMesh ) {
+	return Mesh_GetRemoteSize( feMesh, MT_VERTEX );
+}
+
+unsigned FeMesh_GetNodeDomainSize( void* feMesh ) {
+	return Mesh_GetDomainSize( feMesh, MT_VERTEX );
+}
+
+unsigned FeMesh_GetNodeGlobalSize( void* feMesh ) {
+	return Mesh_GetGlobalSize( feMesh, MT_VERTEX );
+}
+
+unsigned FeMesh_GetElementLocalSize( void* feMesh ) {
+	return Mesh_GetLocalSize( feMesh, Mesh_GetDimSize( feMesh ) );
+}
+
+unsigned FeMesh_GetElementRemoteSize( void* feMesh ) {
+	return Mesh_GetRemoteSize( feMesh, Mesh_GetDimSize( feMesh ) );
+}
+
+unsigned FeMesh_GetElementDomainSize( void* feMesh ) {
+	return Mesh_GetDomainSize( feMesh, Mesh_GetDimSize( feMesh ) );
+}
+
+unsigned FeMesh_GetElementGlobalSize( void* feMesh ) {
+	return Mesh_GetGlobalSize( feMesh, Mesh_GetDimSize( feMesh ) );
+}
+
+unsigned FeMesh_GetElementNodeSize( void* feMesh, unsigned element ) {
+	return Mesh_GetIncidenceSize( feMesh, Mesh_GetDimSize( feMesh ), element, MT_VERTEX );
+}
+
+unsigned FeMesh_GetNodeElementSize( void* feMesh, unsigned node ) {
+	return Mesh_GetIncidenceSize( feMesh, MT_VERTEX, node, Mesh_GetDimSize( feMesh ) );
+}
+
+void FeMesh_GetElementNodes( void* feMesh, unsigned element, unsigned* nNodes, unsigned** nodes ) {
+	Mesh_GetIncidence( feMesh, Mesh_GetDimSize( feMesh ), element, MT_VERTEX, nNodes, nodes );
+}
+
+void FeMesh_GetNodeElements( void* feMesh, unsigned node, unsigned* nElements, unsigned** elements ) {
+	Mesh_GetIncidence( feMesh, MT_VERTEX, node, Mesh_GetDimSize( feMesh ), nElements, elements );
+}
+
+unsigned FeMesh_ElementDomainToGlobal( void* feMesh, unsigned domain ) {
+	return Mesh_DomainToGlobal( feMesh, Mesh_GetDimSize( feMesh ), domain );
+}
+
+Bool FeMesh_ElementGlobalToDomain( void* feMesh, unsigned global, unsigned* domain ) {
+	return Mesh_GlobalToDomain( feMesh, Mesh_GetDimSize( feMesh ), global, domain );
+}
+
+unsigned FeMesh_NodeDomainToGlobal( void* feMesh, unsigned domain ) {
+	return Mesh_DomainToGlobal( feMesh, MT_VERTEX, domain );
+}
+
+Bool FeMesh_NodeGlobalToDomain( void* feMesh, unsigned global, unsigned* domain ) {
+	return Mesh_GlobalToDomain( feMesh, MT_VERTEX, global, domain );
+}
+
+void FeMesh_CoordGlobalToLocal( void* feMesh, unsigned element, double* global, double* local ) {
+	FeMesh*		self = (FeMesh*)feMesh;
+	ElementType*	elType;
+
+	assert( self );
+	assert( element < FeMesh_GetElementDomainSize( self ) );
+	assert( global );
+	assert( local );
+
+	elType = FeMesh_GetElementType( self, element );
+	ElementType_ConvertGlobalCoordToElLocal( elType, self, element, global, local );
+}
+
+void FeMesh_CoordLocalToGlobal( void* feMesh, unsigned element, double* local, double* global ) {
+	FeMesh*		self = (FeMesh*)feMesh;
+	unsigned	nDims;
+	ElementType*	elType;
+	double*		basis;
+	unsigned	nElNodes, *elNodes;
+	double		dimBasis;
+	double*		vert;
+	unsigned	n_i, d_i;
+
+	assert( self );
+	assert( element < FeMesh_GetElementDomainSize( self ) );
+	assert( global );
+	assert( local );
+
+	nDims = Mesh_GetDimSize( self );
+	elType = FeMesh_GetElementType( self, element );
+	FeMesh_GetElementNodes( self, element, &nElNodes, &elNodes );
+	basis = AllocArray( double, nElNodes );
+	ElementType_EvaluateShapeFunctionsAt( elType, local, basis );
+
+	memset( global, 0, nDims * sizeof(double) );
+	for( n_i = 0; n_i < nElNodes; n_i++ ) {
+		dimBasis = basis[n_i];
+		vert = Mesh_GetVertex( self, elNodes[n_i] );
+		for( d_i = 0; d_i < nDims; d_i++ )
+			global[d_i] += dimBasis * vert[d_i];
+	}
+}
+
+void FeMesh_EvalBasis( void* feMesh, unsigned element, double* localCoord, double* basis ) {
+	FeMesh*		self = (FeMesh*)feMesh;
+	ElementType*	elType;
+
+	assert( self );
+	assert( localCoord );
+
+	elType = FeMesh_GetElementType( self, element );
+	ElementType_EvaluateShapeFunctionsAt( elType, localCoord, basis );
+}
+
+void FeMesh_EvalLocalDerivs( void* feMesh, unsigned element, double* localCoord, double** derivs ) {
+	FeMesh*		self = (FeMesh*)feMesh;
+	ElementType*	elType;
+
+	assert( self );
+	assert( localCoord );
+	assert( derivs );
+
+	elType = FeMesh_GetElementType( self, element );
+	ElementType_EvaluateShapeFunctionLocalDerivsAt( elType, localCoord, derivs );
+}
+
+void FeMesh_EvalGlobalDerivs( void* feMesh, unsigned element, double* localCoord, double** derivs, double* jacDet ) {
+	FeMesh*		self = (FeMesh*)feMesh;
+	unsigned	nDims;
+	ElementType*	elType;
+	double		jd;
+
+	assert( self );
+	assert( localCoord );
+	assert( derivs );
+
+	nDims = Mesh_GetDimSize( self );
+	elType = FeMesh_GetElementType( self, element );
+	ElementType_ShapeFunctionsGlobalDerivs( elType, self, element, localCoord, nDims, 
+						&jd, derivs );
+	if( jacDet )
+		*jacDet = jd;
+}
+
+
+/*----------------------------------------------------------------------------------------------------------------------------------
+** Private Functions
+*/
+
+void FeMesh_Destruct( FeMesh* self ) {
+	self->elMesh = (Mesh*)self;
+	self->feElFamily = NULL;
+	KillObject( self->feElType );
+}


Property changes on: long/3D/Gale/trunk/src/StgFEM/Discretisation/src/FeMesh.c
___________________________________________________________________
Name: svn:keywords
   + LastChangedDate Author Id
Name: svn:eol-style
   + native

Added: long/3D/Gale/trunk/src/StgFEM/Discretisation/src/FeMesh.h
===================================================================
--- long/3D/Gale/trunk/src/StgFEM/Discretisation/src/FeMesh.h	2006-12-07 23:26:14 UTC (rev 5532)
+++ long/3D/Gale/trunk/src/StgFEM/Discretisation/src/FeMesh.h	2006-12-07 23:29:43 UTC (rev 5533)
@@ -0,0 +1,135 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+**
+** Copyright (C), 2003, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street, Melbourne, 3053, Australia.
+**
+** Authors:
+**	Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
+**	Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
+**	Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
+**	Siew-Ching Tan, Software Engineer, VPAC. (siew at vpac.org)
+**	Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
+**	Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
+**
+**  This library is free software; you can redistribute it and/or
+**  modify it under the terms of the GNU Lesser General Public
+**  License as published by the Free Software Foundation; either
+**  version 2.1 of the License, or (at your option) any later version.
+**
+**  This library 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
+**  Lesser General Public License for more details.
+**
+**  You should have received a copy of the GNU Lesser General Public
+**  License along with this library; if not, write to the Free Software
+**  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+**
+*/
+/** \file
+**  Role:
+**
+** Assumptions:
+**
+** Invariants:
+**
+** Comments:
+**
+** $Id$
+**
+**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#ifndef __StgFEM_Discretisation_Mesh_FeMesh_h__
+#define __StgFEM_Discretisation_Mesh_FeMesh_h__
+
+	/** Textual name of this class */
+	extern const Type FeMesh_Type;
+
+	/** Virtual function types */
+
+	/** Class contents */
+	#define __FeMesh				\
+		/* General info */			\
+		__Mesh					\
+							\
+		/* Virtual info */			\
+							\
+		/* FeMesh info */			\
+		Mesh*			elMesh;		\
+		char*			feElFamily;	\
+		ElementType*		feElType;
+
+	struct FeMesh { __FeMesh };
+
+	/*--------------------------------------------------------------------------------------------------------------------------
+	** Constructors
+	*/
+
+	#define FEMESH_DEFARGS	\
+		MESH_DEFARGS
+
+	#define FEMESH_PASSARGS	\
+		MESH_PASSARGS
+
+	FeMesh* FeMesh_New( Name name );
+	FeMesh* _FeMesh_New( FEMESH_DEFARGS );
+	void _FeMesh_Init( FeMesh* self );
+
+	/*--------------------------------------------------------------------------------------------------------------------------
+	** Virtual functions
+	*/
+
+	void _FeMesh_Delete( void* feMesh );
+	void _FeMesh_Print( void* feMesh, Stream* stream );
+	void _FeMesh_Construct( void* feMesh, Stg_ComponentFactory* cf, void* data );
+	void _FeMesh_Build( void* feMesh, void* data );
+	void _FeMesh_Initialise( void* feMesh, void* data );
+	void _FeMesh_Execute( void* feMesh, void* data );
+	void _FeMesh_Destroy( void* feMesh, void* data );
+
+	/*--------------------------------------------------------------------------------------------------------------------------
+	** Public functions
+	*/
+
+	void FeMesh_SetElementMesh( void* feMesh, Mesh* mesh );
+	void FeMesh_SetElementFamily( void* feMesh, const char* family );
+	void FeMesh_SetElementType( void* feMesh, ElementType* elType );
+
+	Mesh* FeMesh_GetElementMesh( void* feMesh );
+	ElementType* FeMesh_GetElementType( void* feMesh, unsigned element );
+
+	unsigned FeMesh_GetNodeLocalSize( void* feMesh );
+	unsigned FeMesh_GetNodeRemoteSize( void* feMesh );
+	unsigned FeMesh_GetNodeDomainSize( void* feMesh );
+	unsigned FeMesh_GetNodeGlobalSize( void* feMesh );
+	unsigned FeMesh_GetElementLocalSize( void* feMesh );
+	unsigned FeMesh_GetElementDomainSize( void* feMesh );
+	unsigned FeMesh_GetElementRemoteSize( void* feMesh );
+	unsigned FeMesh_GetElementGlobalSize( void* feMesh );
+
+	unsigned FeMesh_GetElementNodeSize( void* feMesh, unsigned element );
+	unsigned FeMesh_GetNodeElementSize( void* feMesh, unsigned node );
+	void FeMesh_GetElementNodes( void* feMesh, unsigned element, unsigned* nNodes, unsigned** nodes );
+	void FeMesh_GetNodeElements( void* feMesh, unsigned node, unsigned* nElements, unsigned** elements );
+
+	unsigned FeMesh_ElementDomainToGlobal( void* feMesh, unsigned domain );
+	Bool FeMesh_ElementGlobalToDomain( void* feMesh, unsigned global, unsigned* domain );
+	unsigned FeMesh_NodeDomainToGlobal( void* feMesh, unsigned domain );
+	Bool FeMesh_NodeGlobalToDomain( void* feMesh, unsigned global, unsigned* domain );
+
+	void FeMesh_CoordGlobalToLocal( void* feMesh, unsigned element, double* global, double* local );
+	void FeMesh_CoordLocalToGlobal( void* feMesh, unsigned element, double* local, double* global );
+	void FeMesh_EvalBasis( void* feMesh, unsigned element, double* localCoord, double* basis );
+	void FeMesh_EvalLocalDerivs( void* feMesh, unsigned element, double* localCoord, double** derivs );
+	void FeMesh_EvalGlobalDerivs( void* feMesh, unsigned element, double* localCoord, double** derivs, double* jacDet );
+
+	/*--------------------------------------------------------------------------------------------------------------------------
+	** Private Member functions
+	*/
+
+	void FeMesh_BuildNodes( FeMesh* self );
+	void FeMesh_BuildGlobalMap( FeMesh* self );
+	void FeMesh_BuildGlobalMap( FeMesh* self );
+
+	void FeMesh_Destruct( FeMesh* self );
+
+#endif /* __StgFEM_Discretisaton_Mesh_FeMesh_h__ */


Property changes on: long/3D/Gale/trunk/src/StgFEM/Discretisation/src/FeMesh.h
___________________________________________________________________
Name: svn:keywords
   + LastChangedDate Author Id
Name: svn:eol-style
   + native

Added: long/3D/Gale/trunk/src/StgFEM/Discretisation/src/FeMesh.meta
===================================================================
--- long/3D/Gale/trunk/src/StgFEM/Discretisation/src/FeMesh.meta	2006-12-07 23:26:14 UTC (rev 5532)
+++ long/3D/Gale/trunk/src/StgFEM/Discretisation/src/FeMesh.meta	2006-12-07 23:29:43 UTC (rev 5533)
@@ -0,0 +1,28 @@
+<?xml version="1.0"?>
+<!DOCTYPE StGermainData SYSTEM "stgermain.dtd">
+<StGermainData xmlns="http://www.vpac.org/StGermain/XML_IO_Handler/Jun2003">
+
+<param name="Name">FeMesh</param>
+<param name="Organisation">VPAC</param>
+<param name="Project">StgFEM</param>
+<param name="Location">./StgFEM/Discretisation/src/</param>
+<param name="Project Web">https://csd.vpac.org/twiki/bin/view/Stgfem/WebHome</param>
+<param name="Copyright">Copyright (C) 2004-2005 VPAC.</param>
+<param name="License">https://csd.vpac.org/twiki/bin/view/Stgermain/SoftwareLicense</param>
+<param name="Parent">Mesh</param>
+<param name="Description">...</param>
+
+<!--Now the interesting stuff-->
+
+
+<list name="Params">
+
+</list>
+
+<list name="Dependencies">
+
+</list>
+<!-- Add an exmaple XML if possible -->
+<param name="Example">...</param>
+
+</StGermainData>

Added: long/3D/Gale/trunk/src/StgFEM/Discretisation/src/FeMesh_Algorithms.c
===================================================================
--- long/3D/Gale/trunk/src/StgFEM/Discretisation/src/FeMesh_Algorithms.c	2006-12-07 23:26:14 UTC (rev 5532)
+++ long/3D/Gale/trunk/src/StgFEM/Discretisation/src/FeMesh_Algorithms.c	2006-12-07 23:29:43 UTC (rev 5533)
@@ -0,0 +1,218 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+**
+** Copyright (C), 2003, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street, Melbourne, 3053, Australia.
+**
+** Authors:
+**	Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
+**	Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
+**	Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
+**	Siew-Ching Tan, Software Engineer, VPAC. (siew at vpac.org)
+**	Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
+**	Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
+**
+**  This library is free software; you can redistribute it and/or
+**  modify it under the terms of the GNU Lesser General Public
+**  License as published by the Free Software Foundation; either
+**  version 2.1 of the License, or (at your option) any later version.
+**
+**  This library 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
+**  Lesser General Public License for more details.
+**
+**  You should have received a copy of the GNU Lesser General Public
+**  License along with this library; if not, write to the Free Software
+**  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+**
+** $Id: FeMesh_Algorithms.c 3584 2006-05-16 11:11:07Z PatrickSunter $
+**
+**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include <mpi.h>
+
+#include "StGermain/StGermain.h"
+#include "Discretisation.h"
+
+
+/* Textual name of this class */
+const Type FeMesh_Algorithms_Type = "FeMesh_Algorithms";
+
+
+/*----------------------------------------------------------------------------------------------------------------------------------
+** Constructors
+*/
+
+FeMesh_Algorithms* FeMesh_Algorithms_New( Name name ) {
+	return _FeMesh_Algorithms_New( sizeof(FeMesh_Algorithms), 
+				       FeMesh_Algorithms_Type, 
+				       _FeMesh_Algorithms_Delete, 
+				       _FeMesh_Algorithms_Print, 
+				       NULL, 
+				       (void* (*)(Name))_FeMesh_Algorithms_New, 
+				       _FeMesh_Algorithms_Construct, 
+				       _FeMesh_Algorithms_Build, 
+				       _FeMesh_Algorithms_Initialise, 
+				       _FeMesh_Algorithms_Execute, 
+				       _FeMesh_Algorithms_Destroy, 
+				       name, 
+				       NON_GLOBAL, 
+				       FeMesh_Algorithms_Search, 
+				       FeMesh_Algorithms_SearchElements, 
+				       FeMesh_Algorithms_GetMinimumSeparation, 
+				       FeMesh_Algorithms_GetLocalCoordRange, 
+				       FeMesh_Algorithms_GetDomainCoordRange, 
+				       FeMesh_Algorithms_GetGlobalCoordRange );
+}
+
+FeMesh_Algorithms* _FeMesh_Algorithms_New( MESH_ALGORITHMS_DEFARGS ) {
+	FeMesh_Algorithms*	self;
+
+	/* Allocate memory */
+	assert( sizeOfSelf >= sizeof(FeMesh_Algorithms) );
+	self = (FeMesh_Algorithms*)_Mesh_Algorithms_New( MESH_ALGORITHMS_PASSARGS );
+
+	/* Virtual info */
+
+	/* FeMesh_Algorithms info */
+	_FeMesh_Algorithms_Init( self );
+
+	return self;
+}
+
+void _FeMesh_Algorithms_Init( FeMesh_Algorithms* self ) {
+}
+
+
+/*----------------------------------------------------------------------------------------------------------------------------------
+** Virtual functions
+*/
+
+void _FeMesh_Algorithms_Delete( void* algorithms ) {
+	FeMesh_Algorithms*	self = (FeMesh_Algorithms*)algorithms;
+
+	/* Delete the parent. */
+	_Mesh_Algorithms_Delete( self );
+}
+
+void _FeMesh_Algorithms_Print( void* algorithms, Stream* stream ) {
+	FeMesh_Algorithms*	self = (FeMesh_Algorithms*)algorithms;
+	
+	/* Set the Journal for printing informations */
+	Stream* algorithmsStream;
+	algorithmsStream = Journal_Register( InfoStream_Type, "FeMesh_AlgorithmsStream" );
+
+	/* Print parent */
+	Journal_Printf( stream, "FeMesh_Algorithms (ptr): (%p)\n", self );
+	_Mesh_Algorithms_Print( self, stream );
+}
+
+void _FeMesh_Algorithms_Construct( void* algorithms, Stg_ComponentFactory* cf, void* data ) {
+}
+
+void _FeMesh_Algorithms_Build( void* algorithms, void* data ) {
+}
+
+void _FeMesh_Algorithms_Initialise( void* algorithms, void* data ) {
+}
+
+void _FeMesh_Algorithms_Execute( void* algorithms, void* data ) {
+}
+
+void _FeMesh_Algorithms_Destroy( void* algorithms, void* data ) {
+}
+
+Bool FeMesh_Algorithms_Search( void* algorithms, void* _mesh, double* point, 
+			       MeshTopology_Dim* dim, unsigned* ind )
+{
+	FeMesh_Algorithms*	self = (FeMesh_Algorithms*)algorithms;
+	FeMesh*			mesh = (FeMesh*)_mesh;
+
+	assert( self && Stg_CheckType( self, FeMesh_Algorithms ) );
+	assert( mesh && Stg_CheckType( mesh, FeMesh ) );
+
+	if( mesh->elMesh != (Mesh*)self )
+		return Mesh_Algorithms_Search( mesh->elMesh->algorithms, mesh->elMesh, point, dim, ind );
+	else
+		return _Mesh_Algorithms_Search( self, mesh, point, dim, ind );
+}
+
+Bool FeMesh_Algorithms_SearchElements( void* algorithms, void* _mesh, double* point, 
+				       unsigned* elInd )
+{
+	FeMesh_Algorithms*	self = (FeMesh_Algorithms*)algorithms;
+	FeMesh*			mesh = (FeMesh*)_mesh;
+
+	assert( self && Stg_CheckType( self, FeMesh_Algorithms ) );
+	assert( mesh && Stg_CheckType( mesh, FeMesh ) );
+
+	if( mesh->elMesh != (Mesh*)self )
+		return Mesh_Algorithms_SearchElements( mesh->elMesh->algorithms, mesh->elMesh, point, elInd );
+	else
+		return _Mesh_Algorithms_SearchElements( self, mesh, point, elInd );
+}
+
+double FeMesh_Algorithms_GetMinimumSeparation( void* algorithms, void* _mesh, double* perDim ) {
+	FeMesh_Algorithms*	self = (FeMesh_Algorithms*)algorithms;
+	FeMesh*			mesh = (FeMesh*)_mesh;
+
+	assert( self && Stg_CheckType( self, FeMesh_Algorithms ) );
+	assert( mesh && Stg_CheckType( mesh, FeMesh ) );
+
+	if( mesh->elMesh != (Mesh*)self )
+		return Mesh_Algorithms_GetMinimumSeparation( mesh->elMesh->algorithms, mesh->elMesh, perDim );
+	else
+		return _Mesh_Algorithms_GetMinimumSeparation( self, mesh, perDim );
+}
+
+void FeMesh_Algorithms_GetLocalCoordRange( void* algorithms, void* _mesh, double* min, double* max ) {
+	FeMesh_Algorithms*	self = (FeMesh_Algorithms*)algorithms;
+	FeMesh*			mesh = (FeMesh*)_mesh;
+
+	assert( self && Stg_CheckType( self, FeMesh_Algorithms ) );
+	assert( mesh && Stg_CheckType( mesh, FeMesh ) );
+
+	if( mesh->elMesh != (Mesh*)self )
+		Mesh_Algorithms_GetLocalCoordRange( mesh->elMesh->algorithms, mesh->elMesh, min, max );
+	else
+		_Mesh_Algorithms_GetLocalCoordRange( self, mesh, min, max );
+}
+
+void FeMesh_Algorithms_GetDomainCoordRange( void* algorithms, void* _mesh, double* min, double* max ) {
+	FeMesh_Algorithms*	self = (FeMesh_Algorithms*)algorithms;
+	FeMesh*			mesh = (FeMesh*)_mesh;
+
+	assert( self && Stg_CheckType( self, FeMesh_Algorithms ) );
+	assert( mesh && Stg_CheckType( mesh, FeMesh ) );
+
+	if( mesh->elMesh != (Mesh*)self )
+		Mesh_Algorithms_GetDomainCoordRange( mesh->elMesh->algorithms, mesh->elMesh, min, max );
+	else
+		_Mesh_Algorithms_GetDomainCoordRange( self, mesh, min, max );
+}
+
+void FeMesh_Algorithms_GetGlobalCoordRange( void* algorithms, void* _mesh, double* min, double* max ) {
+	FeMesh_Algorithms*	self = (FeMesh_Algorithms*)algorithms;
+	FeMesh*			mesh = (FeMesh*)_mesh;
+
+	assert( self && Stg_CheckType( self, FeMesh_Algorithms ) );
+	assert( mesh && Stg_CheckType( mesh, FeMesh ) );
+
+	if( mesh->elMesh != (Mesh*)self )
+		Mesh_Algorithms_GetGlobalCoordRange( mesh->elMesh->algorithms, mesh->elMesh, min, max );
+	else
+		_Mesh_Algorithms_GetGlobalCoordRange( self, mesh, min, max );
+}
+
+
+/*--------------------------------------------------------------------------------------------------------------------------
+** Public Functions
+*/
+
+
+/*----------------------------------------------------------------------------------------------------------------------------------
+** Private Functions
+*/

Added: long/3D/Gale/trunk/src/StgFEM/Discretisation/src/FeMesh_Algorithms.h
===================================================================
--- long/3D/Gale/trunk/src/StgFEM/Discretisation/src/FeMesh_Algorithms.h	2006-12-07 23:26:14 UTC (rev 5532)
+++ long/3D/Gale/trunk/src/StgFEM/Discretisation/src/FeMesh_Algorithms.h	2006-12-07 23:29:43 UTC (rev 5533)
@@ -0,0 +1,103 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+**
+** Copyright (C), 2003, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street, Melbourne, 3053, Australia.
+**
+** Authors:
+**	Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
+**	Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
+**	Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
+**	Siew-Ching Tan, Software Engineer, VPAC. (siew at vpac.org)
+**	Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
+**	Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
+**
+**  This library is free software; you can redistribute it and/or
+**  modify it under the terms of the GNU Lesser General Public
+**  License as published by the Free Software Foundation; either
+**  version 2.1 of the License, or (at your option) any later version.
+**
+**  This library 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
+**  Lesser General Public License for more details.
+**
+**  You should have received a copy of the GNU Lesser General Public
+**  License along with this library; if not, write to the Free Software
+**  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+**
+*/
+/** \file
+**  Role:
+**
+** Assumptions:
+**
+** Invariants:
+**
+** Comments:
+**
+** $Id: FeMesh_Algorithms.h 3584 2006-05-16 11:11:07Z PatrickSunter $
+**
+**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#ifndef __Discretisaton_Mesh_FeMesh_Algorithms_h__
+#define __Discretisaton_Mesh_FeMesh_Algorithms_h__
+
+	/** Textual name of this class */
+	extern const Type FeMesh_Algorithms_Type;
+
+	/** Virtual function types */
+
+	/** Class contents */
+	#define __FeMesh_Algorithms		\
+		/* General info */		\
+		__Mesh_Algorithms		\
+						\
+		/* Virtual info */		\
+						\
+		/* FeMesh_Algorithms info */
+
+	struct FeMesh_Algorithms { __FeMesh_Algorithms };
+
+	/*--------------------------------------------------------------------------------------------------------------------------
+	** Constructors
+	*/
+
+	#define FEMESH_ALGORITHMS_DEFARGS	\
+		MESH_ALGORITHMS_DEFARGS
+
+	#define FEMESH_ALGORITHMS_PASSARGS	\
+		MESH_ALGORITHMS_PASSARGS
+
+	FeMesh_Algorithms* FeMesh_Algorithms_New( Name name );
+	FeMesh_Algorithms* _FeMesh_Algorithms_New( FEMESH_ALGORITHMS_DEFARGS );
+	void _FeMesh_Algorithms_Init( FeMesh_Algorithms* self );
+
+	/*--------------------------------------------------------------------------------------------------------------------------
+	** Virtual functions
+	*/
+
+	void _FeMesh_Algorithms_Delete( void* algorithms );
+	void _FeMesh_Algorithms_Print( void* algorithms, Stream* stream );
+	void _FeMesh_Algorithms_Construct( void* algorithms, Stg_ComponentFactory* cf, void* data );
+	void _FeMesh_Algorithms_Build( void* algorithms, void* data );
+	void _FeMesh_Algorithms_Initialise( void* algorithms, void* data );
+	void _FeMesh_Algorithms_Execute( void* algorithms, void* data );
+	void _FeMesh_Algorithms_Destroy( void* algorithms, void* data );
+
+	Bool FeMesh_Algorithms_Search( void* algorithms, void* mesh, double* point, 
+					 MeshTopology_Dim* dim, unsigned* ind );
+	Bool FeMesh_Algorithms_SearchElements( void* algorithms, void* _mesh, double* point, 
+					      unsigned* elInd );
+	double FeMesh_Algorithms_GetMinimumSeparation( void* algorithms, void* mesh, double* perDim );
+	void FeMesh_Algorithms_GetLocalCoordRange( void* algorithms, void* mesh, double* min, double* max );
+	void FeMesh_Algorithms_GetDomainCoordRange( void* algorithms, void* _mesh, double* min, double* max );
+	void FeMesh_Algorithms_GetGlobalCoordRange( void* algorithms, void* mesh, double* min, double* max );
+
+	/*--------------------------------------------------------------------------------------------------------------------------
+	** Public functions
+	*/
+
+	/*--------------------------------------------------------------------------------------------------------------------------
+	** Private Member functions
+	*/
+
+#endif /* __Discretisaton_Mesh_FeMesh_Algorithms_h__ */

Added: long/3D/Gale/trunk/src/StgFEM/Discretisation/src/FeMesh_Algorithms.meta
===================================================================
--- long/3D/Gale/trunk/src/StgFEM/Discretisation/src/FeMesh_Algorithms.meta	2006-12-07 23:26:14 UTC (rev 5532)
+++ long/3D/Gale/trunk/src/StgFEM/Discretisation/src/FeMesh_Algorithms.meta	2006-12-07 23:29:43 UTC (rev 5533)
@@ -0,0 +1,15 @@
+<?xml version="1.0"?>
+<!DOCTYPE StGermainData SYSTEM "stgermain.dtd">
+<StGermainData xmlns="http://www.vpac.org/StGermain/XML_IO_Handler/Jun2003">
+
+<param name="Name">FeMesh_Algorithms</param>
+<param name="Organisation">VPAC</param>
+<param name="Project">StGermain</param>
+<param name="Location">./StgFEM/Discretisation/src/</param>
+<param name="Project Web">https://csd.vpac.org/twiki/bin/view/Stgermain/WebHome</param>
+<param name="Copyright">StGermain Framework. Copyright (C) 2003-2005 VPAC.</param>
+<param name="License">The Gnu Lesser General Public License http://www.gnu.org/licenses/lgpl.html</param>
+<param name="Parent">Stg_Component</param>
+<param name="Description">...</param>
+
+</StGermainData>

Added: long/3D/Gale/trunk/src/StgFEM/Discretisation/src/FeMesh_ElementType.c
===================================================================
--- long/3D/Gale/trunk/src/StgFEM/Discretisation/src/FeMesh_ElementType.c	2006-12-07 23:26:14 UTC (rev 5532)
+++ long/3D/Gale/trunk/src/StgFEM/Discretisation/src/FeMesh_ElementType.c	2006-12-07 23:29:43 UTC (rev 5533)
@@ -0,0 +1,146 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+**
+** Copyright (C), 2003, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street, Melbourne, 3053, Australia.
+**
+** Authors:
+**	Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
+**	Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
+**	Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
+**	Siew-Ching Tan, Software Engineer, VPAC. (siew at vpac.org)
+**	Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
+**	Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
+**
+**  This library is free software; you can redistribute it and/or
+**  modify it under the terms of the GNU Lesser General Public
+**  License as published by the Free Software Foundation; either
+**  version 2.1 of the License, or (at your option) any later version.
+**
+**  This library 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
+**  Lesser General Public License for more details.
+**
+**  You should have received a copy of the GNU Lesser General Public
+**  License along with this library; if not, write to the Free Software
+**  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+**
+** $Id: FeMesh_ElementType.c 3584 2006-05-16 11:11:07Z PatrickSunter $
+**
+**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include <mpi.h>
+
+#include "StGermain/StGermain.h"
+#include "Discretisation.h"
+
+
+/* Textual name of this class */
+const Type FeMesh_ElementType_Type = "FeMesh_ElementType";
+
+/*----------------------------------------------------------------------------------------------------------------------------------
+** Constructors
+*/
+
+FeMesh_ElementType* FeMesh_ElementType_New( Name name ) {
+	return _FeMesh_ElementType_New( sizeof(FeMesh_ElementType), 
+					FeMesh_ElementType_Type, 
+					_FeMesh_ElementType_Delete, 
+					_FeMesh_ElementType_Print, 
+					NULL, 
+					FeMesh_ElementType_ElementHasPoint, 
+					FeMesh_ElementType_GetMinimumSeparation, 
+					FeMesh_ElementType_GetCentroid );
+}
+
+FeMesh_ElementType* _FeMesh_ElementType_New( MESH_ELEMENTTYPE_DEFARGS ) {
+	FeMesh_ElementType*	self;
+
+	/* Allocate memory */
+	assert( sizeOfSelf >= sizeof(Mesh_ElementType) );
+	self = (FeMesh_ElementType*)_Mesh_ElementType_New( MESH_ELEMENTTYPE_PASSARGS );
+
+	/* Virtual info */
+
+	/* FeMesh_ElementType info */
+	_FeMesh_ElementType_Init( self );
+
+	return self;
+}
+
+void _FeMesh_ElementType_Init( FeMesh_ElementType* self ) {
+}
+
+
+/*----------------------------------------------------------------------------------------------------------------------------------
+** Virtual functions
+*/
+
+void _FeMesh_ElementType_Delete( void* elementType ) {
+	FeMesh_ElementType*	self = (FeMesh_ElementType*)elementType;
+
+	/* Delete the parent. */
+	_Mesh_ElementType_Delete( self );
+}
+
+void _FeMesh_ElementType_Print( void* elementType, Stream* stream ) {
+	FeMesh_ElementType*	self = (FeMesh_ElementType*)elementType;
+	Stream*			elementTypeStream;
+
+	elementTypeStream = Journal_Register( InfoStream_Type, "FeMesh_ElementTypeStream" );
+
+	/* Print parent */
+	Journal_Printf( stream, "FeMesh_ElementType (ptr): (%p)\n", self );
+	_Mesh_ElementType_Print( self, stream );
+}
+
+Bool FeMesh_ElementType_ElementHasPoint( void* elementType, void* _mesh, unsigned elInd, double* point, 
+					 MeshTopology_Dim* dim, unsigned* ind )
+{
+	FeMesh_ElementType*	self = (FeMesh_ElementType*)elementType;
+	FeMesh*			mesh = (FeMesh*)_mesh;
+
+	assert( self && Stg_CheckType( self, FeMesh_ElementType ) );
+	assert( mesh && Stg_CheckType( mesh, FeMesh ) );
+	assert( mesh != (FeMesh*)mesh->elMesh );
+
+	return Mesh_ElementType_ElementHasPoint( mesh->elMesh->algorithms, mesh->elMesh, elInd, point, 
+						 dim, ind );
+}
+
+double FeMesh_ElementType_GetMinimumSeparation( void* elementType, void* _mesh, unsigned elInd, double* perDim ) {
+	FeMesh_ElementType*	self = (FeMesh_ElementType*)elementType;
+	FeMesh*			mesh = (FeMesh*)_mesh;
+
+	assert( self && Stg_CheckType( self, FeMesh_ElementType ) );
+	assert( mesh && Stg_CheckType( mesh, FeMesh ) );
+	assert( mesh != (FeMesh*)mesh->elMesh );
+
+	return Mesh_ElementType_GetMinimumSeparation( mesh->elMesh->algorithms, mesh->elMesh, elInd, perDim );
+}
+
+void FeMesh_ElementType_GetCentroid( void* elementType, void* _mesh, unsigned element, double* centroid ) {
+	FeMesh_ElementType*	self = (FeMesh_ElementType*)elementType;
+	FeMesh*			mesh = (FeMesh*)_mesh;
+
+	assert( self && Stg_CheckType( self, FeMesh_ElementType ) );
+	assert( mesh && Stg_CheckType( mesh, FeMesh ) );
+
+	if( mesh->elMesh != (Mesh*)self )
+		Mesh_ElementType_GetCentroid( mesh->elMesh->algorithms, mesh->elMesh, element, centroid );
+	else
+		_Mesh_ElementType_GetCentroid( self, mesh, element, centroid );
+}
+
+
+/*--------------------------------------------------------------------------------------------------------------------------
+** Public Functions
+*/
+
+
+/*----------------------------------------------------------------------------------------------------------------------------------
+** Private Functions
+*/

Added: long/3D/Gale/trunk/src/StgFEM/Discretisation/src/FeMesh_ElementType.h
===================================================================
--- long/3D/Gale/trunk/src/StgFEM/Discretisation/src/FeMesh_ElementType.h	2006-12-07 23:26:14 UTC (rev 5532)
+++ long/3D/Gale/trunk/src/StgFEM/Discretisation/src/FeMesh_ElementType.h	2006-12-07 23:29:43 UTC (rev 5533)
@@ -0,0 +1,94 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+**
+** Copyright (C), 2003, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street, Melbourne, 3053, Australia.
+**
+** Authors:
+**	Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
+**	Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
+**	Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
+**	Siew-Ching Tan, Software Engineer, VPAC. (siew at vpac.org)
+**	Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
+**	Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
+**
+**  This library is free software; you can redistribute it and/or
+**  modify it under the terms of the GNU Lesser General Public
+**  License as published by the Free Software Foundation; either
+**  version 2.1 of the License, or (at your option) any later version.
+**
+**  This library 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
+**  Lesser General Public License for more details.
+**
+**  You should have received a copy of the GNU Lesser General Public
+**  License along with this library; if not, write to the Free Software
+**  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+**
+*/
+/** \file
+**  Role:
+**
+** Assumptions:
+**
+** Invariants:
+**
+** Comments:
+**
+** $Id: FeMesh_ElementType.h 3584 2006-05-16 11:11:07Z PatrickSunter $
+**
+**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#ifndef __Discretisaton_Mesh_FeMesh_ElementType_h__
+#define __Discretisaton_Mesh_FeMesh_ElementType_h__
+
+	/** Textual name of this class */
+	extern const Type FeMesh_ElementType_Type;
+
+	/** Virtual function types */
+
+	/** Class contents */
+	#define __FeMesh_ElementType		\
+		/* General info */		\
+		__Mesh_ElementType		\
+						\
+		/* Virtual info */		\
+						\
+		/* FeMesh_ElementType info */
+
+	struct FeMesh_ElementType { __FeMesh_ElementType };
+
+	/*--------------------------------------------------------------------------------------------------------------------------
+	** Constructors
+	*/
+
+	#define FEMESH_ELEMENTTYPE_DEFARGS	\
+		MESH_ELEMENTTYPE_DEFARGS
+
+	#define FEMESH_ELEMENTTYPE_PASSARGS	\
+		MESH_ELEMENTTYPE_PASSARGS
+
+	FeMesh_ElementType* FeMesh_ElementType_New();
+	FeMesh_ElementType* _FeMesh_ElementType_New( FEMESH_ELEMENTTYPE_DEFARGS );
+	void _FeMesh_ElementType_Init( FeMesh_ElementType* self );
+
+	/*--------------------------------------------------------------------------------------------------------------------------
+	** Virtual functions
+	*/
+
+	void _FeMesh_ElementType_Delete( void* elementType );
+	void _FeMesh_ElementType_Print( void* elementType, Stream* stream );
+
+	Bool FeMesh_ElementType_ElementHasPoint( void* elementType, void* mesh, unsigned elInd, double* point, 
+						 MeshTopology_Dim* dim, unsigned* ind );
+	double FeMesh_ElementType_GetMinimumSeparation( void* elementType, void* mesh, unsigned elInd, double* perDim );
+	void FeMesh_ElementType_GetCentroid( void* elementType, void* mesh, unsigned element, double* centroid );
+
+	/*--------------------------------------------------------------------------------------------------------------------------
+	** Public functions
+	*/
+
+	/*--------------------------------------------------------------------------------------------------------------------------
+	** Private Member functions
+	*/
+
+#endif /* __Discretisaton_Mesh_FeMesh_ElementType_h__ */

Added: long/3D/Gale/trunk/src/StgFEM/Discretisation/src/FeMesh_ElementType.meta
===================================================================
--- long/3D/Gale/trunk/src/StgFEM/Discretisation/src/FeMesh_ElementType.meta	2006-12-07 23:26:14 UTC (rev 5532)
+++ long/3D/Gale/trunk/src/StgFEM/Discretisation/src/FeMesh_ElementType.meta	2006-12-07 23:29:43 UTC (rev 5533)
@@ -0,0 +1,15 @@
+<?xml version="1.0"?>
+<!DOCTYPE StGermainData SYSTEM "stgermain.dtd">
+<StGermainData xmlns="http://www.vpac.org/StGermain/XML_IO_Handler/Jun2003">
+
+<param name="Name">FeMesh_ElementType</param>
+<param name="Organisation">VPAC</param>
+<param name="Project">StGermain</param>
+<param name="Location">./StGermain/Discretisation/Utils/src/</param>
+<param name="Project Web">https://csd.vpac.org/twiki/bin/view/Stgermain/WebHome</param>
+<param name="Copyright">StGermain Framework. Copyright (C) 2003-2005 VPAC.</param>
+<param name="License">The Gnu Lesser General Public License http://www.gnu.org/licenses/lgpl.html</param>
+<param name="Parent">Stg_Component</param>
+<param name="Description">...</param>
+
+</StGermainData>

Modified: long/3D/Gale/trunk/src/StgFEM/Discretisation/src/FeVariable.c
===================================================================
--- long/3D/Gale/trunk/src/StgFEM/Discretisation/src/FeVariable.c	2006-12-07 23:26:14 UTC (rev 5532)
+++ long/3D/Gale/trunk/src/StgFEM/Discretisation/src/FeVariable.c	2006-12-07 23:29:43 UTC (rev 5533)
@@ -43,11 +43,10 @@
 #include <StGermain/StGermain.h>
 #include "units.h"
 #include "types.h"
-#include "shortcuts.h"
 #include "ElementType.h"
 #include "ElementType_Register.h"
 #include "Element.h"
-#include "Mesh.h"
+#include "FeMesh.h"
 #include "FeEquationNumber.h"
 #include "FeVariable.h"
 #include "LinkedDofInfo.h"
@@ -134,7 +133,7 @@
 	    isCheckpointedAndReloaded,
 		importFormatType,
 		exportFormatType,
-		((Mesh*)feMesh)->layout->decomp->communicator,
+		((FeMesh*)feMesh)->topo->domains[MT_VERTEX]->commTopo->comm, 
 		fV_Register );
 }
 
@@ -328,11 +327,11 @@
 	/* FeVariable info */
 	self->isConstructed = True;
 	self->debug = Stream_RegisterChild( StgFEM_Discretisation_Debug, self->type );
-	self->feMesh = Stg_CheckType( feMesh, FiniteElement_Mesh );
+	self->feMesh = Stg_CheckType( feMesh, FeMesh );
 	/* Set pointer for geometry mesh - if none is provided then it'll use the feMesh */
 	self->geometryMesh = ( geometryMesh ? 
-			Stg_CheckType( geometryMesh, FiniteElement_Mesh ) : 
-			Stg_CheckType( feMesh, FiniteElement_Mesh ) );
+			Stg_CheckType( geometryMesh, FeMesh ) : 
+			Stg_CheckType( feMesh, FeMesh ) );
 	self->dofLayout = dofLayout;
 	if ( bcs )
 		self->bcs = Stg_CheckType( bcs, VariableCondition );
@@ -471,7 +470,7 @@
 	
 	if( deep ) {
 		newFeVariable->debug = self->debug; 
-		newFeVariable->feMesh = (FiniteElement_Mesh*)Stg_Class_Copy( self->feMesh, NULL, deep, nameExt, map );
+		newFeVariable->feMesh = (FeMesh*)Stg_Class_Copy( self->feMesh, NULL, deep, nameExt, map );
 		newFeVariable->dofLayout = (DofLayout*)Stg_Class_Copy( self->dofLayout, NULL, deep, nameExt, map );
 		newFeVariable->bcs = (VariableCondition*)Stg_Class_Copy( self->bcs, NULL, deep, nameExt, map );
 		newFeVariable->ics = self->ics ? (VariableCondition*)Stg_Class_Copy( self->ics, NULL, deep, nameExt, map ) : NULL;
@@ -533,6 +532,9 @@
 		if ( self->linkedDofInfo ) {
 			Build( self->linkedDofInfo, data, False );
 		}
+
+		/* Extract component count. */
+		self->fieldComponentCount = self->dofLayout->_totalVarCount;
 		
 		/* build the e.q. number array */
 		FeEquationNumber_Build( self->eqNum );
@@ -544,8 +546,8 @@
 void _FeVariable_Construct( void* variable, Stg_ComponentFactory* cf, void* data ) 
 {
 	FeVariable*         self          = (FeVariable*)variable;
-	FiniteElement_Mesh* feMesh        = NULL;
-	FiniteElement_Mesh* geometryMesh  = NULL;
+	FeMesh*			feMesh        = NULL;
+	FeMesh*			geometryMesh  = NULL;
 	DofLayout*          dofLayout     = NULL;
 	VariableCondition*  bc            = NULL;
 	VariableCondition*  ic            = NULL;
@@ -555,8 +557,8 @@
 
 	_FieldVariable_Construct( self, cf, data );
 
-	feMesh        = Stg_ComponentFactory_ConstructByKey( cf, self->name, "FEMesh",        FiniteElement_Mesh, True, data );
-	geometryMesh  = Stg_ComponentFactory_ConstructByKey( cf, self->name, "GeometryMesh",  FiniteElement_Mesh, False, data );
+	feMesh        = Stg_ComponentFactory_ConstructByKey( cf, self->name, "FEMesh",        FeMesh, True, data );
+	geometryMesh  = Stg_ComponentFactory_ConstructByKey( cf, self->name, "GeometryMesh",  FeMesh, False, data );
 	dofLayout     = Stg_ComponentFactory_ConstructByKey( cf, self->name, DofLayout_Type,  DofLayout,          True, data );
 	importFormatType =  Stg_ComponentFactory_GetString( cf, self->name, "importFormatType",
 		StgFEM_Native_ImportExportType );
@@ -567,8 +569,6 @@
 	bc            = Stg_ComponentFactory_ConstructByKey( cf, self->name, "BC",            VariableCondition,  False, data );
 	linkedDofInfo = Stg_ComponentFactory_ConstructByKey( cf, self->name, "LinkedDofInfo", LinkedDofInfo,      False, data );
 
-	self->fieldComponentCount = dofLayout->_totalVarCount;
-
 	_FeVariable_Init( self, feMesh, geometryMesh, dofLayout, bc, ic, linkedDofInfo, NULL,
 		importFormatType, exportFormatType );
 }
@@ -659,68 +659,17 @@
 
 	Journal_Printf( stream, "In %s: for FeVariable \"%s\":\n", __func__, self->name );
 
-	_FeVariable_PrintLocalOrDomainValues( variable, self->feMesh->nodeLocalCount, stream );
+	_FeVariable_PrintLocalOrDomainValues( variable, FeMesh_GetNodeLocalSize( self->feMesh ), stream );
 }
 
 
-unsigned _FeVariable_ClosestNode( FeVariable* self, Coord crd ) {
-	Bool		done;
-	Mesh*		mesh = (Mesh*)self->feMesh;
-	Coord*		nodeCrds = mesh->nodeCoord;
-	unsigned	curNode;
-	unsigned	nDims = self->dim;
-
-	/* Begin somewhere in the middle. */
-	curNode = mesh->nodeLocalCount / 2;
-
-	/* Loop until we've found closest local node. */
-	do {
-		unsigned	nNbrs = mesh->nodeNeighbourCountTbl[curNode];
-		unsigned*	nbrs = mesh->nodeNeighbourTbl[curNode];
-		double		dist;
-		double		tmp;
-		unsigned	nbr_i, d_i;
-
-		/* Assume we'll be done after this loop. */
-		done = True;
-
-		/* Calc distance squared to current node. */
-		tmp = nodeCrds[curNode][0] - crd[0];
-		dist = tmp * tmp;
-		for( d_i = 1; d_i < nDims; d_i++ ) {
-			tmp = nodeCrds[curNode][d_i] - crd[d_i];
-			dist += tmp * tmp;
-		}
-
-		/* Compare to neighbours. */
-		for( nbr_i = 0; nbr_i < nNbrs; nbr_i++ ) {
-			double	nbrDist;
-
-			/* Just in case... */
-			if( nbrs[nbr_i] >= mesh->nodeLocalCount )
-				continue;
-
-			tmp = nodeCrds[nbrs[nbr_i]][0] - crd[0];
-			nbrDist = tmp * tmp;
-			for( d_i = 1; d_i < nDims; d_i++ ) {
-				tmp = nodeCrds[nbrs[nbr_i]][d_i] - crd[d_i];
-				nbrDist += tmp * tmp;
-			}
-
-			if( nbrDist < dist ) {
-				curNode = nbrs[nbr_i];
-				dist = nbrDist;
-				done = False;
-			}
-		}
-	}
-	while( !done );
-
-	return curNode;
+unsigned _FeVariable_ClosestNode( FeVariable* self, double* crd ) {
+	assert( self );
+	return Mesh_NearestVertex( self->feMesh, crd );
 }
 
 
-InterpolationResult _FeVariable_InterpolateValueAt( void* variable, Coord globalCoord, double* value ) {
+InterpolationResult _FeVariable_InterpolateValueAt( void* variable, double* globalCoord, double* value ) {
 	FeVariable*		self = (FeVariable*)variable;
 	Element_DomainIndex	elementCoordIn = (unsigned)-1;
 	Coord			elLocalCoord={0,0,0};
@@ -751,13 +700,13 @@
 
 
 double _FeVariable_GetMinGlobalFieldMagnitude( void* feVariable ) {
-	FeVariable*			self = (FeVariable*)feVariable;
-	FiniteElement_Mesh*		mesh = self->feMesh;
-	int				node_lI=0;
-	int				nodeLocalCount = mesh->nodeLocalCount;
-	double				min = 0;
-	double				globalMin = 0;
-	double				currValue;
+	FeVariable*	self = (FeVariable*)feVariable;
+	FeMesh*		feMesh = self->feMesh;
+	int		node_lI=0;
+	int		nodeLocalCount = FeMesh_GetNodeLocalSize( feMesh );
+	double		min = 0;
+	double		globalMin = 0;
+	double		currValue;
 
 	min = FeVariable_GetScalarAtNode( self, 0 );
 	
@@ -776,13 +725,12 @@
 
 
 double _FeVariable_GetMaxGlobalFieldMagnitude( void* feVariable ) {
-	FeVariable*			self = (FeVariable*)feVariable;
-	FiniteElement_Mesh*		mesh = self->feMesh;
-	int				node_lI=0;
-	int				nodeLocalCount = mesh->nodeLocalCount;
-	double				max = 0;
-	double				globalMax = 0;
-	double				currValue;
+	FeVariable*	self = (FeVariable*)feVariable;
+	int		node_lI=0;
+	int		nodeLocalCount = FeMesh_GetNodeLocalSize( self->feMesh );
+	double		max = 0;
+	double		globalMax = 0;
+	double		currValue;
 
 	max = FeVariable_GetScalarAtNode( self, 0 );
 	
@@ -799,55 +747,21 @@
 	return globalMax;
 }
 
-void _FeVariable_GetMinAndMaxLocalCoords( void* feVariable, Coord min, Coord max ) {
-	FeVariable*		self = (FeVariable*)feVariable;
-	FiniteElement_Mesh*	mesh = self->feMesh;
-	ElementLayout*		eLayout = mesh->layout->elementLayout;
-	double*			currCoord = NULL;
-	Dimension_Index		dim_I = 0;
-	Node_LocalIndex		node_lI = 0;
+void _FeVariable_GetMinAndMaxLocalCoords( void* feVariable, double* min, double* max ) {
+	FeVariable*	self = (FeVariable*)feVariable;
 
-	if ( True == eLayout->getStaticMinAndMaxLocalCoords( eLayout, min, max ) ) {
-		return;
-	}
-	else {
-		/* Make sure that the mesh is initialised */
-		assert( mesh->isInitialised );
+	assert( self && Stg_CheckType( self, FeVariable ) );
 
-		/* No shortcut, so just loop through every node coord, and record min & max */
-		for (dim_I = 0; dim_I < self->dim ; dim_I++ ) {
-			min[dim_I] = mesh->nodeCoord[0][dim_I];
-			max[dim_I] = mesh->nodeCoord[0][dim_I];
-		}
-
-		for ( node_lI = 1; node_lI < mesh->nodeLocalCount; node_lI++ ) {
-			currCoord = mesh->nodeCoord[node_lI];
-
-			for (dim_I = 0; dim_I < self->dim ; dim_I++ ) {
-				if ( currCoord[dim_I] < min[dim_I] ) {
-					min[dim_I] = currCoord[dim_I];
-				}
-				else if ( currCoord[dim_I] > max[dim_I] ) {
-					max[dim_I] = currCoord[dim_I];
-				}
-			}
-		}
-	}
+	Mesh_GetLocalCoordRange( self->feMesh, min, max );
 }
 
 
-void _FeVariable_GetMinAndMaxGlobalCoords( void* feVariable, Coord min, Coord max ) {
-	FeVariable*		self = (FeVariable*)feVariable;
-	FiniteElement_Mesh*	mesh = self->feMesh;
-	ElementLayout*		eLayout = mesh->layout->elementLayout;
+void _FeVariable_GetMinAndMaxGlobalCoords( void* feVariable, double* min, double* max ) {
+	FeVariable*	self = (FeVariable*)feVariable;
 
-	if ( True == eLayout->getStaticMinAndMaxGlobalCoords( eLayout, min, max ) ) {
-		return;
-	}
-	else {
-		/* Use the default approach of each processor calculating min, then reduce */
-		_FieldVariable_GetMinAndMaxGlobalCoords( feVariable, min, max );
-	}
+	assert( self && Stg_CheckType( self, FeVariable ) );
+
+	Mesh_GetGlobalCoordRange( self->feMesh, min, max );
 }
 
 double FeVariable_GetScalarAtNode( void* feVariable, Node_LocalIndex lNode_I ) {
@@ -892,54 +806,21 @@
 
 /* --- Public Functions --- */
 
-InterpolationResult FeVariable_GetElementLocalCoordAtGlobalCoord( void* feVariable, Coord globalCoord, Coord elLocalCoord,
+InterpolationResult FeVariable_GetElementLocalCoordAtGlobalCoord( void* feVariable, double* globalCoord, double* elLocalCoord,
 		Element_DomainIndex* elementCoordInPtr )
 {
 	FeVariable*		self = (FeVariable*)feVariable;
-	MeshLayout*		mLayout = self->feMesh->layout;
-	ElementLayout*		eLayout = mLayout->elementLayout;
 	InterpolationResult	retValue;
+	unsigned		elDim, elInd;
 
-	(*elementCoordInPtr) = (unsigned)-1;
-	
 	/* locate which mesh element given coord is in : use inclusive upper boundaries to save
-		the need to use shadow space if possible */
-	(*elementCoordInPtr) = Mesh_ElementWithPoint( self->feMesh, globalCoord, INCLUSIVE_UPPER_BOUNDARY );
-#if 0
-	if( eLayout->type == ParallelPipedHexaEL_Type ) {
-		(*elementCoordInPtr) = eLayout->elementWithPoint( eLayout, mLayout->decomp, globalCoord,
-							    INCLUSIVE_UPPER_BOUNDARY, 0, NULL );
-	}
-	else {
-		unsigned	cNode;
-
-		/* Find closest node to point. */
-		cNode = _FeVariable_ClosestNode( self, globalCoord );
-
-		/* Find with hint of incident elements. */
-		(*elementCoordInPtr) = eLayout->elementWithPoint( eLayout, mLayout->decomp, globalCoord,
-							    INCLUSIVE_UPPER_BOUNDARY, 
-							    self->feMesh->nodeElementCountTbl[cNode], self->feMesh->nodeElementTbl[cNode] );
-
-		/* If still no cigar, brute force. */
-		if ( (*elementCoordInPtr) >= self->feMesh->elementDomainCount ) {
-			(*elementCoordInPtr) = eLayout->elementWithPoint( eLayout, mLayout->decomp, globalCoord,
-								    INCLUSIVE_UPPER_BOUNDARY, 0, NULL );
-		}
-	}
-#endif
-
-	if ( (*elementCoordInPtr) >= self->feMesh->elementDomainCount ) {
+	   the need to use shadow space if possible */
+	if( !Mesh_Search( self->feMesh, globalCoord, &elDim, &elInd ) ) {
 		Bool			outsideGlobal = False;
-		Coord			min, max;
+		double			min[3], max[3];
 		Dimension_Index		dim_I=0;
-		Bool			checkResult;
-		Stream*			errorStr = Journal_Register( Error_Type, self->type );
 
-		checkResult = ElementLayout_GetStaticMinAndMaxGlobalCoords( mLayout->elementLayout, min, max );
-		Journal_Firewall( True == checkResult, errorStr, "Error - in %s: current mesh doesn't"
-			"know how to calculate global max and min values.\n", __func__ );
-		
+		FieldVariable_GetMinAndMaxGlobalCoords( self, min, max );
 		for ( dim_I = 0; dim_I < self->dim; dim_I++ ) {
 			if ( ( globalCoord[dim_I] < min[dim_I] ) || (globalCoord[dim_I] > max[dim_I] ) ) {
 				outsideGlobal = True;
@@ -951,14 +832,22 @@
 		}
 		else {
 			return OTHER_PROC;
-		}	
-	}	
+		}
+	}
 	else /* We found the coord is within a local or shadow element */ {
-		Node_LocalIndex		currElementNodeCount=0;
-		Coord**			globalNodeCoordPtrs=NULL;
 		ElementType*		elementType = NULL;
+		unsigned		nInc, *inc;
+
+		if( elDim != Mesh_GetDimSize( self->feMesh ) ) {
+			Mesh_GetIncidence( self->feMesh, elDim, elInd, Mesh_GetDimSize( self->feMesh ), 
+					   &nInc, &inc );
+			assert( nInc );
+			*elementCoordInPtr = inc[0];
+		}
+		else
+			*elementCoordInPtr = elInd;
 	
-		if ( (*elementCoordInPtr) < self->feMesh->elementLocalCount ) {
+		if ( elInd < FeMesh_GetElementLocalSize( self->feMesh ) ) {
 			retValue = LOCAL;
 		}
 		else {
@@ -966,17 +855,11 @@
 		}
 
 		/* convert global coordinate to local co-ordinates of element the coord is in */
-		currElementNodeCount = self->feMesh->elementNodeCountTbl[(*elementCoordInPtr)];
-		globalNodeCoordPtrs = Memory_Alloc_Array( Coord*, currElementNodeCount, "globalNodeCoordPtrs" );
-		Mesh_GetNodeCoordPtrsOfElement( self->feMesh, (*elementCoordInPtr), globalNodeCoordPtrs );
+		elementType = FeMesh_GetElementType( self->feMesh, (*elementCoordInPtr) );
+		ElementType_ConvertGlobalCoordToElLocal( elementType, self->feMesh, *elementCoordInPtr, 
+							 globalCoord, elLocalCoord );
+	}
 
-		elementType = FeMesh_ElementTypeAt( self->feMesh, (*elementCoordInPtr) );
-		ElementType_ConvertGlobalCoordToElLocal( elementType, eLayout,
-			(const Coord**) globalNodeCoordPtrs, globalCoord, elLocalCoord );
-
-		Memory_Free( globalNodeCoordPtrs );
-	}	
-
 	return retValue;
 }
 
@@ -995,47 +878,69 @@
 
 
 void FeVariable_PrintLocalDiscreteValues_2dBox( void* variable, Stream* stream ) {
-	FeVariable*			self = (FeVariable*)variable;
-	FiniteElement_Mesh*		mesh = self->feMesh;
-	ParallelPipedHexaEL*		elementLayout = (ParallelPipedHexaEL*)mesh->layout->elementLayout;
-	Node_LocalIndex			node_lI=0;
-	Index				x_I, y_I;
-	Index				ii;
-	Dof_Index			dof_I=0;
-	Dof_Index			currNodeNumDofs=0;
-	BlockGeometry*			bGeometry = (BlockGeometry*)elementLayout->geometry;
-	Index				nx = 0;
-	Index				ny = 0;
-	double				dx = 0;
-	double				dy = 0;
-	DofLayout*			dofLayout = self->dofLayout;
-	Stream*				eStream = Journal_Register( Error_Type, self->type );
-	HexaMD*				hexaMD = (HexaMD*)mesh->layout->decomp;
-	Index				minLocalNodeX;
-	Index				minLocalNodeY;
-	Index				maxLocalNodeX;
-	Index				maxLocalNodeY;
+	FeVariable*		self = (FeVariable*)variable;
+	Node_LocalIndex		node_lI=0;
+	Index			x_I, y_I;
+	Index			ii;
+	Dof_Index		dof_I=0;
+	Dof_Index		currNodeNumDofs=0;
+	Index			nx = 0;
+	Index			ny = 0;
+	double			dx = 0;
+	double			dy = 0;
+	DofLayout*		dofLayout = self->dofLayout;
+	Stream*			eStream = Journal_Register( Error_Type, self->type );
+	Index			minLocalNodeX;
+	Index			minLocalNodeY;
+	Index			maxLocalNodeX;
+	Index			maxLocalNodeY;
+	Grid*			vertGrid;
+	unsigned		inds[2];
+	unsigned		vertInd;
+	double*			verts[2];
+	unsigned		*localOrigin, *localRange;
+	double			min[2], max[2];
 
-
-	if ( elementLayout->type != ParallelPipedHexaEL_Type && elementLayout->dim == 2 ) {
+	if( ExtensionManager_GetHandle( self->feMesh->info, "vertexGrid" ) == (unsigned)-1 || 
+	    Mesh_GetDimSize( self->feMesh ) != 2 )
+	  {
 		Journal_Printf( eStream, "Warning: %s called on variable \"%s\", but this isn't stored on a "
-			"regular 2D (%s) mesh - so just returning.\n", __func__, self->name, ParallelPipedHexaEL_Type );
+			"regular 2D mesh - so just returning.\n", __func__, self->name );
 		return;
-	}	
+	}
+
+	vertGrid = *(Grid**)ExtensionManager_Get( self->feMesh->info, self->feMesh, 
+					      ExtensionManager_GetHandle( self->feMesh->info, "vertexGrid" ) );
+	localOrigin = (unsigned*)ExtensionManager_Get( self->feMesh->info, self->feMesh, 
+						       ExtensionManager_GetHandle( self->feMesh->info, "localOrigin" ) );
+	localRange = (unsigned*)ExtensionManager_Get( self->feMesh->info, self->feMesh, 
+						      ExtensionManager_GetHandle( self->feMesh->info, "localRange" ) );
+
+	memcpy( inds, localOrigin, Mesh_GetDimSize( self->feMesh ) * sizeof(unsigned) );
+	insist( Mesh_GlobalToDomain( self->feMesh, MT_VERTEX, Grid_Project( vertGrid, inds ), &vertInd ) );
+	verts[0] = Mesh_GetVertex( self->feMesh, vertInd );
+	inds[0]++;
+	inds[1]++;
+	insist( Mesh_GlobalToDomain( self->feMesh, MT_VERTEX, Grid_Project( vertGrid, inds ), &vertInd ) );
+	verts[1] = Mesh_GetVertex( self->feMesh, vertInd );
 	
-	nx = bGeometry->size[I_AXIS];
-	ny = bGeometry->size[J_AXIS];
-	dx = elementLayout->elementLengthEachDim[I_AXIS];
-	dy = elementLayout->elementLengthEachDim[J_AXIS];
+	nx = vertGrid->sizes[0];
+	ny = vertGrid->sizes[1];
+	dx = verts[1][0] - verts[0][0];
+	dy = verts[1][1] - verts[0][1];
 
-	minLocalNodeX = hexaMD->_nodeOffsets[hexaMD->rank][I_AXIS];
-	minLocalNodeY = hexaMD->_nodeOffsets[hexaMD->rank][J_AXIS];
-	maxLocalNodeX = minLocalNodeX + hexaMD->nodeLocal3DCounts[hexaMD->rank][I_AXIS];
-	maxLocalNodeY = minLocalNodeY + hexaMD->nodeLocal3DCounts[hexaMD->rank][J_AXIS];
 
+
+	minLocalNodeX = localOrigin[0];
+	minLocalNodeY = localOrigin[1];
+	maxLocalNodeX = minLocalNodeX + localRange[0] + 1;
+	maxLocalNodeY = minLocalNodeY + localRange[1] + 1;
+
+	Mesh_GetGlobalCoordRange( self->feMesh, min, max );
+
 	Journal_Printf( stream, "display of Values in 2D box X:{%5.2f-%5.2f}, Y:{%5.2f-%5.2f}\n",
-		bGeometry->min[I_AXIS], bGeometry->max[I_AXIS],
-		bGeometry->min[J_AXIS], bGeometry->max[J_AXIS] );
+		min[I_AXIS], max[I_AXIS],
+		min[J_AXIS], max[J_AXIS] );
 	Journal_Printf( stream, "\twith %d elements in X (dx=%5.2f) and %d elements in Y (dy=%5.2f)\n\n",
 		nx-1, dx, ny-1, dy );
 
@@ -1076,7 +981,10 @@
 			if ( ( y_I >= minLocalNodeY ) && ( y_I < maxLocalNodeY )
 				&& ( x_I >= minLocalNodeX ) && ( x_I < maxLocalNodeX ) ) {
 
-				node_lI = RegularMeshUtils_Node_Global3DToLocal1D( hexaMD, x_I, y_I, 0 );
+				inds[0] = x_I;
+				inds[1] = y_I;
+				node_lI = RegularMeshUtils_Node_3DTo1D( self->feMesh, inds );
+				insist( Mesh_GlobalToDomain( self->feMesh, MT_VERTEX, node_lI, &node_lI ) );
 				currNodeNumDofs = dofLayout->dofCounts[node_lI];
 
 				if ( currNodeNumDofs == 1 ) {
@@ -1111,14 +1019,9 @@
 }
 
 
-Bool FeVariable_InterpolateDerivativesAt( void* variable, Coord globalCoord, double* value ) {
+Bool FeVariable_InterpolateDerivativesAt( void* variable, double* globalCoord, double* value ) {
 	FeVariable*	        self                 = (FeVariable*)variable;
-	MeshLayout*	        mLayout              = self->feMesh->layout;
-	ElementLayout*	    eLayout              = mLayout->elementLayout;
 	Element_DomainIndex	elementCoordIn       = (unsigned)-1;
-	Node_LocalIndex	    currElementNodeCount = 0;
-	Coord**			    globalNodeCoordPtrs  = NULL;
-	ElementType*		elementType          = NULL;
 	Coord               elLocalCoord         = {0,0,0};
 
 	/* Need a special rule for points on this processor's boundary: instead of the normal
@@ -1126,14 +1029,14 @@
 	
 	/* locate which mesh element given coord is in : use inclusive upper boundaries to save
 		the need to use shadow space if possible */
-	elementCoordIn = Mesh_ElementWithPoint( self->feMesh, globalCoord, INCLUSIVE_UPPER_BOUNDARY );
-
-	if ( elementCoordIn >= self->feMesh->elementDomainCount ) {
+	if ( Mesh_Algorithms_SearchElements( self->feMesh->algorithms, self->feMesh, globalCoord, 
+					     &elementCoordIn ) )
+	{
 		/* If coord isn't inside domain elements list, bail out */
 		return False;
 	}	
 	else /* We found the coord is within a local or shadow element */ {
-		if ( elementCoordIn >= self->feMesh->elementLocalCount ) {
+		if ( elementCoordIn >= FeMesh_GetElementLocalSize( self->feMesh ) ) {
 			if ( False == self->shadowValuesSynchronised ) {
 				Stream* warningStr = Journal_Register( Error_Type, self->type );
 				Journal_Printf( warningStr, "Warning - in %s: user asking to interpolate derivatives "
@@ -1143,18 +1046,12 @@
 				return False;	
 			}
 		}
+
 		/* convert global coordinate to local co-ordinates of element the coord is in */
-		currElementNodeCount = self->feMesh->elementNodeCountTbl[elementCoordIn];
-		globalNodeCoordPtrs = Memory_Alloc_Array( Coord*, currElementNodeCount, "globalNodeCoordPtrs" );
-		Mesh_GetNodeCoordPtrsOfElement( self->feMesh, elementCoordIn, globalNodeCoordPtrs );
+		FeMesh_CoordGlobalToLocal( self->feMesh, elementCoordIn, globalCoord, elLocalCoord );
 
-		elementType = FeMesh_ElementTypeAt( self->feMesh, elementCoordIn );
-		ElementType_ConvertGlobalCoordToElLocal( elementType, eLayout,
-			(const Coord**) globalNodeCoordPtrs, globalCoord, elLocalCoord );
-
 		/* Now interpolate the value at that coordinate, using shape functions */
 		FeVariable_InterpolateDerivativesToElLocalCoord( self, elementCoordIn, elLocalCoord, value );
-		Memory_Free( globalNodeCoordPtrs );
 	}	
 	
 	return True;
@@ -1162,7 +1059,7 @@
 
 void FeVariable_InterpolateDerivativesToElLocalCoord( void* _feVariable, Element_DomainIndex lElement_I, Coord elLocalCoord, double* value ) {
 	FeVariable*    self             = (FeVariable*) _feVariable;
-	ElementType*            elementType      = FeMesh_ElementTypeAt( self->feMesh, lElement_I );
+	ElementType*            elementType      = FeMesh_GetElementType( self->feMesh, lElement_I );
 	Node_Index              elementNodeCount = elementType->nodeCount;
 	double**                GNx; 
 	double                  detJac;
@@ -1184,14 +1081,14 @@
 
 void FeVariable_InterpolateDerivatives_WithGNx( void* _feVariable, Element_LocalIndex lElement_I, double** GNx, double* value ) {
 	FeVariable*             self        = (FeVariable*) _feVariable;
-	ElementType*            elementType = FeMesh_ElementTypeAt( self->feMesh, lElement_I );
+	ElementType*            elementType = FeMesh_GetElementType( self->feMesh, lElement_I );
 	Node_ElementLocalIndex  elLocalNode_I;
-	Node_ElementLocalIndex  elNodeCount = elementType->nodeCount;
 	Node_LocalIndex         lNode_I;
 	Dof_Index               dof_I;
 	Dof_Index               dofCount;
 	Variable*               dofVariable;
 	double                  nodeValue;
+	unsigned		nInc, *inc;
 	Dimension_Index         dim         = self->dim;
 
 	/* Gets number of degrees of freedom - assuming it is the same throughout the mesh */
@@ -1200,10 +1097,12 @@
 	/* Initialise */
 	memset( value, 0, sizeof( double ) * dofCount * dim );
 
+	FeMesh_GetElementNodes( self->feMesh, lElement_I, &nInc, &inc );
+
 	for ( dof_I = 0 ; dof_I < dofCount ; dof_I++ ) {
 		/* Interpolate derivative from nodes */
-		for ( elLocalNode_I = 0 ; elLocalNode_I < elNodeCount ; elLocalNode_I++) {
-			lNode_I      = self->feMesh->elementNodeTbl[ lElement_I ][ elLocalNode_I ];
+		for ( elLocalNode_I = 0 ; elLocalNode_I < nInc ; elLocalNode_I++) {
+			lNode_I      = inc[ elLocalNode_I ];
 			dofVariable  = DofLayout_GetVariable( self->dofLayout, lNode_I, dof_I );
 			nodeValue    = Variable_GetValueDouble( dofVariable, lNode_I );
 			
@@ -1214,142 +1113,70 @@
 		}
 	}
 }
-	
 
-void FeVariable_GetMinimumSeparation( void* feVariable, double* minSeparationPtr, double minSeparationEachDim[3] )
-{
-	FeVariable*            self = (FeVariable*) feVariable;
-	ParallelPipedHexaEL*   eLayout = (ParallelPipedHexaEL*) self->feMesh->layout->elementLayout;
-	FiniteElement_Mesh*    mesh = self->feMesh;
 
-	if ( Stg_Class_IsInstance( eLayout, ParallelPipedHexaEL_Type ) ) {
-		(*minSeparationPtr) = eLayout->elementLengthEachDim[I_AXIS];
-		minSeparationEachDim[I_AXIS] = eLayout->elementLengthEachDim[I_AXIS];
-		
-		if ( eLayout->elementLengthEachDim[J_AXIS] < *minSeparationPtr ) {
-			*minSeparationPtr = eLayout->elementLengthEachDim[J_AXIS];
-		}
-		minSeparationEachDim[J_AXIS] = eLayout->elementLengthEachDim[J_AXIS];
+void FeVariable_GetMinimumSeparation( void* feVariable, double* minSeparationPtr, double minSeparationEachDim[3] ) {
+	FeVariable*	self = (FeVariable*)feVariable;
 
-		if ( self->dim == 3 ) {
-			if ( eLayout->elementLengthEachDim[K_AXIS] < *minSeparationPtr ) {
-				*minSeparationPtr = eLayout->elementLengthEachDim[K_AXIS];
-			}
-			minSeparationEachDim[K_AXIS] = eLayout->elementLengthEachDim[K_AXIS];
-		}
-		else {
-			minSeparationEachDim[K_AXIS] = 0;
-		}
-	}
-	else if ( Stg_Class_IsInstance( eLayout, HexaEL_Type ) ) {
-		double              currElementSeparation[3] = {0,0,0};
-		double              currPairSeparation[3] = {0,0,0};
-		Element_LocalIndex  element_lI = 0;
+	assert( self && Stg_CheckType( self, FeVariable ) );
 
-		minSeparationEachDim[I_AXIS] = HUGE_VAL;
-		minSeparationEachDim[J_AXIS] = HUGE_VAL;
-		minSeparationEachDim[K_AXIS] = HUGE_VAL;
-		*minSeparationPtr = HUGE_VAL;
+	Mesh_GetMinimumSeparation( self->feMesh, minSeparationPtr, minSeparationEachDim );
+}	
 
-		for ( element_lI = 0; element_lI < mesh->elementLocalCount; element_lI++ ) {
-			/* Axis 0 (I) */
-			currPairSeparation[0] = mesh->nodeCoord[mesh->elementNodeTbl[element_lI][1]][0]
-				- mesh->nodeCoord[mesh->elementNodeTbl[element_lI][0]][0];
-			currElementSeparation[0] = currPairSeparation[0];
 
-			currPairSeparation[0] = mesh->nodeCoord[mesh->elementNodeTbl[element_lI][2]][0]
-				- mesh->nodeCoord[mesh->elementNodeTbl[element_lI][3]][0];
-			if ( currPairSeparation[0] < currElementSeparation[0] ) {
-				currElementSeparation[0] = currPairSeparation[0];
-			}
-			
-			if ( self->dim == 3 ) {
-				currPairSeparation[0] = mesh->nodeCoord[mesh->elementNodeTbl[element_lI][5]][0]
-					- mesh->nodeCoord[mesh->elementNodeTbl[element_lI][4]][0];
-				if ( currPairSeparation[0] < currElementSeparation[0] ) {
-					currElementSeparation[0] = currPairSeparation[0];
-				}
-				currPairSeparation[0] = mesh->nodeCoord[mesh->elementNodeTbl[element_lI][6]][0]
-					- mesh->nodeCoord[mesh->elementNodeTbl[element_lI][7]][0];
-				if ( currPairSeparation[0] < currElementSeparation[0] ) {
-					currElementSeparation[0] = currPairSeparation[0];
-				}
-			}
-			if ( currElementSeparation[0] < minSeparationEachDim[0] ) {
-				minSeparationEachDim[0] = currElementSeparation[0];
-			}
-			/* Axis 1 (J) */
-			currPairSeparation[1] = mesh->nodeCoord[mesh->elementNodeTbl[element_lI][3]][1]
-				- mesh->nodeCoord[mesh->elementNodeTbl[element_lI][0]][1];
-			currElementSeparation[1] = currPairSeparation[1];
+void FeVariable_SyncShadowValues( void* feVariable ) {
+	FeVariable*		self = (FeVariable*)feVariable;
+	DofLayout*		dofLayout;
+	Decomp_Sync*		vertSync;
+	Decomp_Sync_Array*	array;
+	unsigned		var_i;
 
-			currPairSeparation[1] = mesh->nodeCoord[mesh->elementNodeTbl[element_lI][2]][1]
-				- mesh->nodeCoord[mesh->elementNodeTbl[element_lI][1]][1];
-			if ( currPairSeparation[1] < currElementSeparation[1] ) {
-				currElementSeparation[1] = currPairSeparation[1];
-			}
-			
-			if ( self->dim == 3 ) {
-				currPairSeparation[1] = mesh->nodeCoord[mesh->elementNodeTbl[element_lI][7]][1]
-					- mesh->nodeCoord[mesh->elementNodeTbl[element_lI][4]][1];
-				if ( currPairSeparation[1] < currElementSeparation[1] ) {
-					currElementSeparation[1] = currPairSeparation[1];
-				}
-				currPairSeparation[1] = mesh->nodeCoord[mesh->elementNodeTbl[element_lI][6]][1]
-					- mesh->nodeCoord[mesh->elementNodeTbl[element_lI][5]][1];
-				if ( currPairSeparation[1] < currElementSeparation[1] ) {
-					currElementSeparation[1] = currPairSeparation[1];
-				}
-			}
-			if ( currElementSeparation[1] < minSeparationEachDim[1] ) {
-				minSeparationEachDim[1] = currElementSeparation[1];
-			}
-			/* Axis 2 (K) */
-			if ( self->dim == 3 ) {
-				currPairSeparation[2] = mesh->nodeCoord[mesh->elementNodeTbl[element_lI][4]][2]
-					- mesh->nodeCoord[mesh->elementNodeTbl[element_lI][0]][2];
-				currElementSeparation[2] = currPairSeparation[2];
+	assert( self );
 
-				currPairSeparation[2] = mesh->nodeCoord[mesh->elementNodeTbl[element_lI][5]][2]
-					- mesh->nodeCoord[mesh->elementNodeTbl[element_lI][1]][2];
-				if ( currPairSeparation[2] < currElementSeparation[2] ) {
-					currElementSeparation[2] = currPairSeparation[2];
-				}
-			
-				currPairSeparation[2] = mesh->nodeCoord[mesh->elementNodeTbl[element_lI][7]][2]
-					- mesh->nodeCoord[mesh->elementNodeTbl[element_lI][3]][2];
-				if ( currPairSeparation[2] < currElementSeparation[2] ) {
-					currElementSeparation[2] = currPairSeparation[2];
-				}
-				currPairSeparation[2] = mesh->nodeCoord[mesh->elementNodeTbl[element_lI][6]][2]
-					- mesh->nodeCoord[mesh->elementNodeTbl[element_lI][2]][2];
-				if ( currPairSeparation[2] < currElementSeparation[2] ) {
-					currElementSeparation[2] = currPairSeparation[2];
-				}
-				if ( currElementSeparation[2] < minSeparationEachDim[2] ) {
-					minSeparationEachDim[2] = currElementSeparation[2];
-				}
-			}
-			else {
-				minSeparationEachDim[2] = 0;
-			}
-		}	
-		*minSeparationPtr = minSeparationEachDim[0];
-		*minSeparationPtr = minSeparationEachDim[1] < *minSeparationPtr ? minSeparationEachDim[1] : *minSeparationPtr;
-		if ( self->dim == 3 ) {
-			*minSeparationPtr = minSeparationEachDim[2] < *minSeparationPtr ? minSeparationEachDim[2] : *minSeparationPtr;
+	/* Shortcuts. */
+	dofLayout = self->dofLayout;
+
+	/* Create a distributed array based on the mesh's vertices. */
+	vertSync = Mesh_GetSync( self->feMesh, MT_VERTEX );
+	array = Decomp_Sync_Array_New();
+	Decomp_Sync_Array_SetSync( array, vertSync );
+
+	/*
+	** For each variable in the dof layout, we need to create a distributed array and update
+	** shadow values.
+	*/
+
+	for( var_i = 0; var_i < dofLayout->_totalVarCount; var_i++ ) {
+		unsigned	varInd;
+		Variable*	var;
+		unsigned	field_i;
+
+		/* Get the variable. */
+		varInd = dofLayout->_varIndicesMapping[var_i];
+		var = Variable_Register_GetByIndex( dofLayout->_variableRegister, varInd );
+
+		/* Each field of the variable will need to be handled individually. */
+		for( field_i = 0; field_i < var->offsetCount; field_i++ ) {
+			unsigned	offs, size;
+			Stg_Byte	*arrayStart, *arrayEnd;
+
+			offs = var->offsets[field_i];
+			size = var->dataSizes[field_i];
+
+			arrayStart = (Stg_Byte*)var->arrayPtr + offs;
+			arrayEnd = arrayStart + var->structSize * FeMesh_GetNodeLocalSize( self->feMesh );
+			Decomp_Sync_Array_SetMemory( array, 
+						     arrayStart, arrayEnd, 
+						     var->structSize, var->structSize, 
+						     size );
+
+			Decomp_Sync_Array_Sync( array );
 		}
 	}
-	else  {
-		Stream*    errorStr = Journal_Register( Error_Type, self->type );
-		Journal_Firewall( 0, errorStr, "Error: in %s - Don't know how to find minSeparation for element type %s.\n",
-			__func__, eLayout->type );
-	}
-}	
 
+	self->shadowValuesSynchronised = True;
 
-void FeVariable_SyncShadowValues( void* feVariable ) {
-	FeVariable*			self = (FeVariable*)feVariable;
+#if 0
 	Neighbour_Index			nbr_I = 0;
 	Node_Index			node_stI = 0;
 	Node_DomainIndex		node_dI = 0;
@@ -1360,13 +1187,12 @@
 	double**			incomingDofValues = NULL;
 	MPI_Request**			incomingDofValRequests = NULL;
 	Node_Index			myShadowNodesOnThisNbrCount = 0;
-	Dof_Index			incomingDof_I;
-	Index*				outgoingDofTotals = NULL;			
-	double**			outgoingDofValues = NULL;
-	MPI_Request**			outgoingDofValRequests = NULL;
-	Node_Index			nbrShadowNodesOnMeCount = 0;
-	Dof_Index			outgoingDof_I;
-	FiniteElement_Mesh*		mesh = self->feMesh;
+	Dof_Index		incomingDof_I;
+	Index*			outgoingDofTotals = NULL;
+	double**		outgoingDofValues = NULL;
+	MPI_Request**		outgoingDofValRequests = NULL;
+	Node_Index		nbrShadowNodesOnMeCount = 0;
+	Dof_Index		outgoingDof_I;
 	MPI_Status			status;
 	int				incomingDofValueSetsYetToReceive;
 	Bool*				incomingDofValueSetsReceived;
@@ -1529,6 +1355,7 @@
 	Memory_Free( outgoingDofValRequests );
 	
 	Stream_UnIndent( self->debug );
+#endif
 }
 
 
@@ -1537,14 +1364,13 @@
 
 	Journal_Printf( stream, "In %s: for FeVariable \"%s\":\n", __func__, self->name );
 
-	_FeVariable_PrintLocalOrDomainValues( variable, self->feMesh->nodeDomainCount, stream );
+	_FeVariable_PrintLocalOrDomainValues( variable, FeMesh_GetNodeDomainSize( self->feMesh ), stream );
 }
 
 void FeVariable_PrintCoordsAndValues( void* _feVariable, Stream* stream ) {
 	FeVariable*         self            = (FeVariable*) _feVariable;
-	FiniteElement_Mesh* mesh            = self->feMesh;
 	Node_LocalIndex     node_I          = 0;
-	Node_LocalIndex     nodeLocalCount  = mesh->nodeLocalCount;
+	Node_LocalIndex     nodeLocalCount  = FeMesh_GetNodeLocalSize( self->feMesh );
 	Dof_Index           currNodeNumDofs;
 	Dof_Index           nodeLocalDof_I;
 	Variable*           currVariable;
@@ -1565,7 +1391,7 @@
 		currNodeNumDofs = self->dofLayout->dofCounts[ node_I ];
 
 		/* Get Coordinate of Node */
-		nodeCoord = Mesh_CoordAt( mesh, node_I );
+		nodeCoord = Mesh_GetVertex( self->feMesh, node_I );
 		Journal_Printf( stream, "%12.6g   %12.6g   %12.6g   ", 
 				nodeCoord[ I_AXIS ], nodeCoord[ J_AXIS ], nodeCoord[ K_AXIS ] );
 		
@@ -1587,19 +1413,20 @@
 	Dof_Index		nodeLocalDof_I=0;
 	Dof_Index		dofCountThisNode=0;
 	Node_ElementLocalIndex	elLocalNode_I=0;
-	Node_ElementLocalIndex	nodeCountThisElement=0;
 	double*			shapeFuncsEvaluatedAtCoord=NULL;
 	Node_LocalIndex		lNode_I=0;
 	Variable*		currVariable=NULL;
 	double			dofValueAtCurrNode=0;
+	unsigned		nInc, *inc;
 
-	nodeCountThisElement = self->feMesh->elementNodeCountTbl[element_lI];
+	FeMesh_GetElementNodes( self->feMesh, element_lI, &nInc, &inc );
+
 	/* Gets number of degrees of freedom - assuming it is the same throughout the mesh */
 	dofCountThisNode = self->dofLayout->dofCounts[lNode_I];
 
 	/* evaluate shape function values of current element at elLocalCoords */
-	elementType = FeMesh_ElementTypeAt( self->feMesh, element_lI );
-	shapeFuncsEvaluatedAtCoord = Memory_Alloc_Array_Unnamed( double, elementType->nodeCount );
+	elementType = FeMesh_GetElementType( self->feMesh, element_lI );
+	shapeFuncsEvaluatedAtCoord = AllocArray( double, nInc );
 	ElementType_EvaluateShapeFunctionsAt( elementType, elLocalCoord, shapeFuncsEvaluatedAtCoord );
 
 	for ( nodeLocalDof_I=0; nodeLocalDof_I < dofCountThisNode; nodeLocalDof_I++ ) {
@@ -1607,8 +1434,8 @@
 	}
 
 	/* Now for each node, add that node's contribution at point */
-	for ( elLocalNode_I=0; elLocalNode_I < nodeCountThisElement; elLocalNode_I++ ) {
-		lNode_I = self->feMesh->elementNodeTbl[element_lI][elLocalNode_I];
+	for ( elLocalNode_I=0; elLocalNode_I < nInc; elLocalNode_I++ ) {
+		lNode_I = inc[elLocalNode_I];
 		
 		for ( nodeLocalDof_I=0; nodeLocalDof_I < dofCountThisNode; nodeLocalDof_I++ ) {
 			currVariable = DofLayout_GetVariable( self->dofLayout, lNode_I, nodeLocalDof_I );
@@ -1616,7 +1443,7 @@
 			value[nodeLocalDof_I] += dofValueAtCurrNode * shapeFuncsEvaluatedAtCoord[elLocalNode_I];
 		}	
 	}
-	Memory_Free( shapeFuncsEvaluatedAtCoord );
+	FreeArray( shapeFuncsEvaluatedAtCoord );
 }
 
 
@@ -1630,7 +1457,7 @@
 	Variable*		currVariable;
 	
 	for( node_I=0; node_I < localOrDomainCount; node_I++ ) {
-		gNode_I = self->feMesh->nodeD2G[node_I];
+		gNode_I = FeMesh_NodeDomainToGlobal( self->feMesh, node_I );
 		Journal_Printf( stream, "node %d (global index %d):\n", node_I, gNode_I );
 		
 		currNodeNumDofs = self->fieldComponentCount;
@@ -1662,8 +1489,8 @@
 {
 	FeVariable*          self               = (FeVariable*)         feVariable;
 	Swarm*               swarm              = (Swarm*)              _swarm;
-	FiniteElement_Mesh*  feMesh             = self->feMesh;
-	FiniteElement_Mesh*  geometryMesh       = self->geometryMesh;
+	FeMesh*			feMesh             = self->feMesh;
+	FeMesh*			geometryMesh;
 	ElementType*         elementType;
 	ElementType*         geometryElementType;
 	Cell_LocalIndex      cell_I;
@@ -1678,8 +1505,9 @@
 	integral = 0.0;
 
 	/* Use feVariable's mesh as geometry mesh if one isn't passed in */
-	elementType = FeMesh_ElementTypeAt( feMesh, dElement_I );
-	geometryElementType = FeMesh_ElementTypeAt( geometryMesh, dElement_I );
+	geometryMesh = (feMesh->elMesh == (Mesh*)feMesh) ? feMesh : feMesh->elMesh;
+	elementType = FeMesh_GetElementType( geometryMesh, dElement_I );
+	geometryElementType = FeMesh_GetElementType( geometryMesh, dElement_I );
 
 	/* Determine number of particles in element */
 	cell_I = CellLayout_MapElementIdToCellId( swarm->cellLayout, dElement_I );
@@ -1707,9 +1535,9 @@
 double FeVariable_Integrate( void* feVariable, void* _swarm ) {
 	FeVariable*          self               = (FeVariable*)         feVariable;
 	Swarm*               swarm              = (Swarm*)              _swarm;
-	FiniteElement_Mesh*  feMesh             = self->feMesh;
+	FeMesh*			feMesh             = self->feMesh;
 	Element_LocalIndex   lElement_I;
-	Element_LocalIndex   elementLocalCount  = feMesh->elementLocalCount;
+	Element_LocalIndex   elementLocalCount  = FeMesh_GetElementLocalSize( feMesh );
 	double               integral, integralGlobal;
 	
 	/* Initialise Summation of Integral */
@@ -1727,12 +1555,12 @@
 
 double FeVariable_AverageTopLayer( void* feVariable, void* swarm, Axis layerAxis ) {
 	FeVariable*                self               = (FeVariable*)         feVariable;
-	FiniteElement_Mesh*        feMesh             = self->feMesh;
-	ElementLayout*             elementLayout      = feMesh->layout->elementLayout;
-	IJKTopology*               elementTopology    = (IJKTopology*) elementLayout->topology;
-	Index                      layerIndex         = elementTopology->size[ layerAxis ] - 1;
+	Grid*			elGrid;
 
-	return FeVariable_AverageLayer( self, swarm, layerAxis, layerIndex );
+	elGrid = *(Grid**)ExtensionManager_Get( self->feMesh->info, self->feMesh, 
+						ExtensionManager_GetHandle( self->feMesh->info, "elementGrid" ) );
+
+	return FeVariable_AverageLayer( self, swarm, layerAxis, elGrid->sizes[1] - 1 );
 }
 
 double FeVariable_AverageBottomLayer( void* feVariable, void* swarm, Axis layerAxis ) {
@@ -1746,19 +1574,40 @@
 	Axis                       aAxis              = ( layerAxis == I_AXIS ? J_AXIS : I_AXIS );
 	Axis                       bAxis              = ( layerAxis == K_AXIS ? J_AXIS : K_AXIS );
 	Dimension_Index            dim                = self->dim;
-	FiniteElement_Mesh*        feMesh             = self->feMesh;
-	BlockGeometry*             geometry           = (BlockGeometry*)feMesh->layout->elementLayout->geometry;
 	double                     integral;
 	double                     layerThickness     = 0.0;
+	Grid*			vertGrid;
+	unsigned*		inds;
+	double			heights[2];
+	double			*min, *max;
+	unsigned		d_i;
 	
 	integral = FeVariable_IntegrateLayer( self, swarm, layerAxis, layerIndex );
 
-	/* Calculate Layer Thickness */
-	layerThickness = ((ParallelPipedHexaEL*) feMesh->layout->elementLayout)->elementLengthEachDim[ layerAxis ];
+	/* Calculate layer thickness.  This assumes the mesh is regular. */
+	vertGrid = *(Grid**)ExtensionManager_Get( self->feMesh->info, self->feMesh, 
+						  ExtensionManager_GetHandle( self->feMesh->info, "vertexGrid" ) );
+	inds = Memory_Alloc_Array_Unnamed( unsigned, Mesh_GetDimSize( self->feMesh ) );
+	for( d_i = 0; d_i < Mesh_GetDimSize( self->feMesh ); d_i++ ) {
+		if( d_i != layerAxis )
+			inds[d_i] = 0;
+		else
+			inds[d_i] = layerIndex;
+	}
+	heights[0] = Mesh_GetVertex( self->feMesh, Grid_Project( vertGrid, inds ) )[layerAxis];
+	inds[layerAxis]++;
+	heights[1] = Mesh_GetVertex( self->feMesh, Grid_Project( vertGrid, inds ) )[layerAxis];
+	FreeArray( inds );
+	layerThickness = heights[1] - heights[0];
 
-	integral /= layerThickness * ( geometry->max[ aAxis ] - geometry->min[ aAxis ] );
+	min = Memory_Alloc_Array_Unnamed( double, Mesh_GetDimSize( self->feMesh ) );
+	max = Memory_Alloc_Array_Unnamed( double, Mesh_GetDimSize( self->feMesh ) );
+	Mesh_GetGlobalCoordRange( self->feMesh, min, max );
+	integral /= layerThickness * ( max[ aAxis ] - min[ aAxis ] );
 	if ( dim == 3 )
-		integral /= geometry->max[ bAxis ] - geometry->min[ bAxis ];
+		integral /= max[ bAxis ] - min[ bAxis ];
+	FreeArray( min );
+	FreeArray( max );
 
 	return integral;
 }
@@ -1771,14 +1620,9 @@
 { 
 	FeVariable*                self               = (FeVariable*)         feVariable;
 	Swarm*                     swarm              = (Swarm*)              _swarm;
-	FiniteElement_Mesh*        feMesh             = self->feMesh;
-	ElementLayout*             elementLayout      = feMesh->layout->elementLayout;
-	IJKTopology*               elementTopology    = (IJKTopology*) elementLayout->topology;
-	MeshDecomp*                meshDecomp         = feMesh->layout->decomp;
 	Element_LocalIndex         lElement_I;
 	Element_GlobalIndex        gElement_I;
 	IJK                        elementIJK;
-	Element_LocalIndex         elementLocalCount  = feMesh->elementLocalCount;
 	double                     elementIntegral;
 	double                     integral;
 	double                     integralGlobal;
@@ -1789,16 +1633,16 @@
 	integral = 0.0;
 
 	Stream_Indent( self->debug );
-	for ( gElement_I = 0 ; gElement_I < feMesh->elementGlobalCount ; gElement_I++ ) {
-		IJK_1DTo3D( elementTopology, gElement_I, elementIJK );
+	for ( gElement_I = 0 ; gElement_I < FeMesh_GetElementGlobalSize( self->feMesh ); gElement_I++ ) {
+		RegularMeshUtils_Element_1DTo3D( self->feMesh, gElement_I, elementIJK );
 
 		/* Check if element is in layer plane */
 		if ( elementIJK[ layerAxis ] != layerIndex )
 			continue;
 
 		/* Check if element is local */
-		lElement_I = meshDecomp->elementMapGlobalToLocal( meshDecomp, gElement_I );
-		if ( lElement_I >= elementLocalCount ) 
+		insist( FeMesh_ElementGlobalToDomain( self->feMesh, gElement_I, &lElement_I ) );
+		if( lElement_I >= FeMesh_GetElementLocalSize( self->feMesh ) )
 			continue;
 
 		elementIntegral = FeVariable_IntegrateElement_AxisIndependent( self, swarm, lElement_I, dim, axis0, axis1, axis2 );
@@ -1821,27 +1665,25 @@
 	Axis                       aAxis              = ( planeAxis == I_AXIS ? J_AXIS : I_AXIS );
 	Axis                       bAxis              = ( planeAxis == K_AXIS ? J_AXIS : K_AXIS );
 	Dimension_Index            dim                = self->dim;
-	BlockGeometry*             geometry           = (BlockGeometry*) self->feMesh->layout->elementLayout->geometry;
+	double				min[3], max[3];
 	
 	integral = FeVariable_IntegratePlane( self, planeAxis, planeHeight );
 
-	integral /= geometry->max[ aAxis ] - geometry->min[ aAxis ];
+	Mesh_GetGlobalCoordRange( self->feMesh, min, max );
+
+	integral /= max[ aAxis ] - min[ aAxis ];
 	if ( dim == 3 )
-		integral /= geometry->max[ bAxis ] - geometry->min[ bAxis ];
+		integral /= max[ bAxis ] - min[ bAxis ];
 
 	return integral;
 }
 
 double FeVariable_IntegratePlane( void* feVariable, Axis planeAxis, double planeHeight ) {
 	FeVariable*                self               = (FeVariable*)         feVariable;
-	FiniteElement_Mesh*        feMesh             = self->feMesh;
-	MeshDecomp*                meshDecomp         = feMesh->layout->decomp;
-	ElementLayout*             elementLayout      = feMesh->layout->elementLayout;
-	IJKTopology*               elementTopology    = (IJKTopology*) elementLayout->topology;
 	IJK                        planeIJK;
 	Element_LocalIndex         lElement_I;
 	Element_GlobalIndex        gElement_I;
-	Element_LocalIndex         elementLocalCount  = feMesh->elementLocalCount;
+	Element_LocalIndex         elementLocalCount  = FeMesh_GetElementLocalSize( self->feMesh );
 	Axis                       aAxis              = ( planeAxis == I_AXIS ? J_AXIS : I_AXIS );
 	Axis                       bAxis              = ( planeAxis == K_AXIS ? J_AXIS : K_AXIS );
 	double                     integral;
@@ -1856,9 +1698,6 @@
 	/* Plane location stuff */
 	double                     storedXi_J_AXIS;
 	Coord                      planeCoord;
-	Element_NodeIndex          elementNodeCount;
-	Coord**                    globalNodeCoordPtrs;
-	ElementType*               elementType;
 	double                     planeXi           = -1;
 	double                     planeXiGlobal;
 	Index                      planeLayer        = 0;
@@ -1866,27 +1705,21 @@
 	Particle_InCellIndex       particlesPerDim[] = {2,2,2};
 
 	/* Find Elements which plane cuts through */
-	memcpy( planeCoord, Mesh_CoordAt( feMesh, 0 ), sizeof( Coord ) );
+	memcpy( planeCoord, Mesh_GetVertex( self->feMesh, 0 ), sizeof( Coord ) );
 	planeCoord[ planeAxis ] = planeHeight;
-	lElement_I = elementLayout->elementWithPoint( elementLayout, meshDecomp, planeCoord, feMesh, 
-						      EXCLUSIVE_UPPER_BOUNDARY, 0, NULL );
 
-	if ( lElement_I < elementLocalCount ) {
-		Coord planeXiCoord;
-		gElement_I = _MeshDecomp_Element_LocalToGlobal1D( meshDecomp, lElement_I );
-		IJK_1DTo3D( elementTopology, gElement_I, planeIJK );
+	if( Mesh_Algorithms_SearchElements( self->feMesh->algorithms, self->feMesh, planeCoord, &lElement_I ) && 
+	    lElement_I < elementLocalCount )
+	{
+		Coord		planeXiCoord;
+
+		gElement_I = FeMesh_ElementDomainToGlobal( self->feMesh, lElement_I );
+		RegularMeshUtils_Element_1DTo3D( self->feMesh, gElement_I, planeIJK );
 		planeLayer = planeIJK[ planeAxis ];
 		
 		/* Find Local Coordinate of plane */
-		elementNodeCount = feMesh->elementNodeCountTbl[lElement_I];
-		globalNodeCoordPtrs = Memory_Alloc_Array( Coord*, elementNodeCount, "globalNodeCoordPtrs" );
-		Mesh_GetNodeCoordPtrsOfElement( feMesh, lElement_I, globalNodeCoordPtrs );
-
-		elementType = FeMesh_ElementTypeAt( feMesh, lElement_I );
-		ElementType_ConvertGlobalCoordToElLocal( elementType, elementLayout,
-			(const Coord**) globalNodeCoordPtrs, planeCoord, planeXiCoord );
+		FeMesh_CoordGlobalToLocal( self->feMesh, lElement_I, planeCoord, planeXiCoord );
 		planeXi = planeXiCoord[ planeAxis ];
-		Memory_Free( globalNodeCoordPtrs );
 	}
 	
 	/* Should be broadcast */
@@ -1989,9 +1822,13 @@
 	double             variableValues[MAX_FIELD_COMPONENTS];	
 	const int          FINISHED_WRITING_TAG = 100;
 	int                confirmation = 0;
-	int                myRank = self->feMesh->layout->decomp->rank; 
+	MPI_Comm	comm = CommTopology_GetComm( Mesh_GetCommTopology( self->feMesh, MT_VERTEX ) );
+	int                myRank;
+	int                nProcs;
 	MPI_Status         status;
-	MPI_Comm           comm = self->feMesh->layout->decomp->communicator;
+
+	MPI_Comm_size( comm, (int*)&nProcs );
+	MPI_Comm_rank( comm, (int*)&myRank );
 	
 	/*                                                prefix             self->name       . 00000 .  dat \0 */
 	filename = Memory_Alloc_Array_Unnamed( char, strlen(prefixStr) + strlen(self->name) + 1 + 5 + 1 + 3 + 1 );
@@ -2012,10 +1849,10 @@
 	/* Note: assumes same number of dofs at each node */
 	dofAtEachNodeCount = self->fieldComponentCount;
 
-	for ( lNode_I = 0; lNode_I < self->feMesh->nodeLocalCount; lNode_I++ ) {
-		gNode_I = self->feMesh->nodeL2G[lNode_I];
+	for ( lNode_I = 0; lNode_I < FeMesh_GetNodeLocalSize( self->feMesh ); lNode_I++ ) {
+		gNode_I = FeMesh_NodeDomainToGlobal( self->feMesh, lNode_I );
 		fprintf( outputFile, "%u ", gNode_I );
-		coord = self->feMesh->nodeCoord[lNode_I];
+		coord = Mesh_GetVertex( self->feMesh, lNode_I );
 		fprintf( outputFile, "%.15g %.15g %.15g ", coord[0], coord[1], coord[2] );
 		FeVariable_GetValueAtNode( self, lNode_I, variableValues );
 		for ( dof_I = 0; dof_I < dofAtEachNodeCount; dof_I++ ) {
@@ -2027,7 +1864,7 @@
 	fclose( outputFile );
 	
 	/* send go-ahead from process ranked lower than me, to avoid competition writing to file */
-	if ( myRank != (self->feMesh->layout->decomp->nproc-1) ) {
+	if ( myRank != nProcs - 1 ) {
 		MPI_Ssend( &confirmation, 1, MPI_INT, myRank + 1, FINISHED_WRITING_TAG, comm );
 	}	
 	
@@ -2050,6 +1887,9 @@
 							self->importFormatType );
 		assert( importExportInfo );
 		importExportInfo->readNodalValuesFromFile( feVariable, prefixStr, timeStep );
+
+		/* Need to re-sync the values. */
+		FeVariable_SyncShadowValues( self );
 	}
 }
 
@@ -2067,13 +1907,15 @@
 	const char         MAX_LINE_LENGTH = 100;
 	Processor_Index    proc_I=0;
 	Dimension_Index    dim_I=0;
-	BlockGeometry*     geometry = (BlockGeometry*)self->feMesh->layout->elementLayout->geometry;
 	Coord              localGeometryMin;
 	Coord              localGeometryMax;
-	
-	/* Necessary for now since we need to update the geometry min and max - see comment below */
-	Stg_CheckType( geometry, BlockGeometry );
+	MPI_Comm	comm = CommTopology_GetComm( Mesh_GetCommTopology( self->feMesh, MT_VERTEX ) );
+	unsigned		rank;
+	unsigned		nProcs;
 
+	MPI_Comm_rank( comm, (int*)&rank );
+	MPI_Comm_size( comm, (int*)&nProcs );
+	
 	/*                                                prefix            self->name        . 00000 .  dat \0 */
 	filename = Memory_Alloc_Array_Unnamed( char, strlen(prefixStr) + strlen(self->name) + 1 + 5 + 1 + 3 + 1 );
 	sprintf( filename, "%s%s.%.5u.dat", prefixStr, self->name, timeStep );
@@ -2082,9 +1924,9 @@
 	
 	/* This loop used to stop 2 processors trying to open the file at the same time, which
 	  * seems to cause problems */
-	for ( proc_I = 0; proc_I < self->feMesh->layout->decomp->nproc; proc_I++ ) {
-		MPI_Barrier( self->feMesh->layout->decomp->communicator );
-		if ( proc_I == self->feMesh->layout->decomp->rank ) {	
+	for ( proc_I = 0; proc_I < nProcs; proc_I++ ) {
+		MPI_Barrier( comm );
+		if ( proc_I == rank ) {
 			inputFile = fopen( filename, "r" );
 		}
 	}
@@ -2108,19 +1950,21 @@
 
 	while ( !feof(inputFile) ) {
 		fscanf( inputFile, "%u ", &gNode_I );
-		lNode_I = Mesh_NodeMapGlobalToLocal( self->feMesh, gNode_I );
-		if ( lNode_I != Mesh_Node_Invalid( self->feMesh ) ) {
+		if( FeMesh_NodeGlobalToDomain( self->feMesh, gNode_I, &lNode_I ) && 
+		    lNode_I < FeMesh_GetNodeLocalSize( self->feMesh ) )
+		{
 			/* Note: until we have proper mesh geometry, topology etc checkpointing, we re-load the 
 			node co-ords from the feVariable file - and also update the geometry */
-			fscanf( inputFile, "%lg %lg %lg ", &self->feMesh->nodeCoord[lNode_I][0], &self->feMesh->nodeCoord[lNode_I][1],
-				&self->feMesh->nodeCoord[lNode_I][2] );
+			fscanf( inputFile, "%lg %lg %lg ", Mesh_GetVertex( self->feMesh, lNode_I ), 
+				Mesh_GetVertex( self->feMesh, lNode_I ) + 1, 
+				Mesh_GetVertex( self->feMesh, lNode_I ) + 2 );
 
 			for ( dim_I = 0; dim_I < 3; dim_I++ ) {
-				if ( self->feMesh->nodeCoord[lNode_I][dim_I] < localGeometryMin[dim_I] ) {
-					localGeometryMin[dim_I] = self->feMesh->nodeCoord[lNode_I][dim_I];
+				if ( Mesh_GetVertex( self->feMesh, lNode_I )[dim_I] < localGeometryMin[dim_I] ) {
+					localGeometryMin[dim_I] = Mesh_GetVertex( self->feMesh, lNode_I )[dim_I];
 				}
-				else if ( self->feMesh->nodeCoord[lNode_I][dim_I] > localGeometryMax[dim_I] ) {
-					localGeometryMax[dim_I] = self->feMesh->nodeCoord[lNode_I][dim_I];
+				else if ( Mesh_GetVertex( self->feMesh, lNode_I )[dim_I] > localGeometryMax[dim_I] ) {
+					localGeometryMax[dim_I] = Mesh_GetVertex( self->feMesh, lNode_I )[dim_I];
 				}
 			}
 			
@@ -2134,22 +1978,4 @@
 		}	
 	}			
 	fclose( inputFile );
-
-	/* Note: this is a bit of a hack - we really should be loading the mesh from a separate checkpoint file
-	anyway - but for now, we'll just check that its a CornerNL type eg velocity, since BodyNL node points
-	are at the centroids, and would hence stuff the Geometry object */
-	if ( self->feMesh->layout->nodeLayout->type == CornerNL_Type ) {
-		/* TODO: separate into re-usable function */
-		/* Since we could be loading in parallel, need to find global min and max of geometry */
-		for ( dim_I = 0; dim_I < 3; dim_I++ ) {
-			MPI_Allreduce( localGeometryMin, geometry->min, 3, MPI_DOUBLE, MPI_MIN, 
-				self->feMesh->layout->decomp->communicator );
-			MPI_Allreduce( localGeometryMax, geometry->max, 3, MPI_DOUBLE, MPI_MAX, 
-				self->feMesh->layout->decomp->communicator );
-		}
-	}
-
-	if ( Stg_Class_IsInstance( self->feMesh->layout->elementLayout, ParallelPipedHexaEL_Type ) ) {
-		ParallelPipedHexaEL_UpdateGeometryPartitionInfo( self->feMesh->layout->elementLayout, self->feMesh->layout->decomp );
-	}
 }

Modified: long/3D/Gale/trunk/src/StgFEM/Discretisation/src/FeVariable.h
===================================================================
--- long/3D/Gale/trunk/src/StgFEM/Discretisation/src/FeVariable.h	2006-12-07 23:26:14 UTC (rev 5532)
+++ long/3D/Gale/trunk/src/StgFEM/Discretisation/src/FeVariable.h	2006-12-07 23:29:43 UTC (rev 5533)
@@ -55,7 +55,7 @@
 	/** Textual name of this class */
 	extern const Type FeVariable_Type;
 
-	typedef void (FeVariable_InterpolateWithinElementFunction) (void* fieldVariable, Element_DomainIndex dElement_I, Coord xi, double* value );
+	typedef void (FeVariable_InterpolateWithinElementFunction) (void* fieldVariable, Element_DomainIndex dElement_I, double* xi, double* value );
 	typedef void (FeVariable_GetValueAtNodeFunction) (void* feVariable, Node_DomainIndex dNode_I, double* value );
 	
 	/* Function prototypes for import / export */
@@ -99,9 +99,9 @@
 		\
 		Stream*                                           debug; \
 		/** Mesh that this variable is discretised over */ \
-		FiniteElement_Mesh*                               feMesh; \
+		FeMesh*						feMesh; \
 		/** The mesh that this variable can create the determinant of the jacobian from */ \
-		FiniteElement_Mesh*                               geometryMesh; \
+		FeMesh*						geometryMesh; \
 		/** DofLayout for this variable: relates each mesh node to the Variable's */ \
 		DofLayout*                                        dofLayout; \
 		/** Boundary conditions applied to this variable - Compulsory, so the eq num table can be worked out*/ \
@@ -266,7 +266,7 @@
 	void FeVariable_ApplyBCs( void* variable, void* data );
 	
 	/** Interpolate the value of the FE variable at a particular coord **/
-	InterpolationResult _FeVariable_InterpolateValueAt( void* variable, Coord coord, double* value );
+	InterpolationResult _FeVariable_InterpolateValueAt( void* variable, double* coord, double* value );
 	
 	/* Implementations of the min and max val functions */
 	double _FeVariable_GetMinGlobalFieldMagnitude( void* feVariable );
@@ -274,9 +274,9 @@
 	double _FeVariable_GetMaxGlobalFieldMagnitude( void* feVariable );
 	
 	/* Implementations of the coord-getting functions */
-	void _FeVariable_GetMinAndMaxLocalCoords( void* feVariable, Coord min, Coord max ) ;
+	void _FeVariable_GetMinAndMaxLocalCoords( void* feVariable, double* min, double* max ) ;
 
-	void _FeVariable_GetMinAndMaxGlobalCoords( void* feVariable, Coord min, Coord max ) ;
+	void _FeVariable_GetMinAndMaxGlobalCoords( void* feVariable, double* min, double* max ) ;
 
 	/** Prints out the value at each DOF for this FeVariable */
 	void FeVariable_PrintLocalDiscreteValues( void* variable, Stream* stream );
@@ -287,8 +287,8 @@
 
 	/** Calculates the domain element & element local coord that a particular global coord lives in.
 		Same return status conventions as for the InterpolateValueAt function. */
-	InterpolationResult FeVariable_GetElementLocalCoordAtGlobalCoord( void* feVariable, Coord globalCoord,
-		Coord elLocalCoord, Element_DomainIndex* elementCoordInPtr );
+	InterpolationResult FeVariable_GetElementLocalCoordAtGlobalCoord( void* feVariable, double* globalCoord,
+		double* elLocalCoord, Element_DomainIndex* elementCoordInPtr );
 
 	/** Updates a single component of the value at a certain node */
 	#define FeVariable_SetComponentAtNode( feVariable, dNode_I, dof_I, componentVal ) \
@@ -316,9 +316,9 @@
 	void FeVariable_ReadNodalValuesFromFile_StgFEM_Native( void* feVariable, const char* prefixStr, unsigned int timeStep );
 
 	/** Evaluates Spatial Derivatives using shape functions */
-	Bool FeVariable_InterpolateDerivativesAt( void* variable, Coord globalCoord, double* value ) ;
+	Bool FeVariable_InterpolateDerivativesAt( void* variable, double* globalCoord, double* value ) ;
 	
-	void FeVariable_InterpolateDerivativesToElLocalCoord( void* _feVariable, Element_LocalIndex lElement_I, Coord elLocalCoord, double* value ) ;
+	void FeVariable_InterpolateDerivativesToElLocalCoord( void* _feVariable, Element_LocalIndex lElement_I, double* elLocalCoord, double* value ) ;
 	
 	void FeVariable_InterpolateDerivatives_WithGNx( void* _feVariable, Element_LocalIndex lElement_I, double** GNx, double* value ) ;
 	
@@ -363,7 +363,7 @@
 	/* --- Private Functions --- */
 
 	/** Evaluates the value at a point within a given element, based on the current values of the nodes in that element */
-	void _FeVariable_InterpolateNodeValuesToElLocalCoord( void* self, Element_DomainIndex element_lI, Coord elLocalCoord, double* value );
+	void _FeVariable_InterpolateNodeValuesToElLocalCoord( void* self, Element_DomainIndex element_lI, double* elLocalCoord, double* value );
 
 	/** Utility function:- saves duplication of the print local and print domain functions */
 	void _FeVariable_PrintLocalOrDomainValues( void* variable, Index localOrDomainCount, Stream* stream );

Modified: long/3D/Gale/trunk/src/StgFEM/Discretisation/src/Init.c
===================================================================
--- long/3D/Gale/trunk/src/StgFEM/Discretisation/src/Init.c	2006-12-07 23:26:14 UTC (rev 5532)
+++ long/3D/Gale/trunk/src/StgFEM/Discretisation/src/Init.c	2006-12-07 23:29:43 UTC (rev 5533)
@@ -40,31 +40,17 @@
 **~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
 
 #include <mpi.h>
-#include <StGermain/StGermain.h>
-#include "units.h"
-#include "types.h"
-#include "shortcuts.h"
-#include "Init.h"
-
-#include "FeEquationNumber.h"
-#include "FeVariable.h"
-#include "OperatorFeVariable.h"
-#include "ShapeFeVariable.h"
-#include "FeSwarmVariable.h"
-#include "Mesh.h"
-#include "ElementType.h"
-#include "ElementType_Register.h"
-#include "BilinearElementType.h"
-#include "TrilinearElementType.h"
-#include "ConstantElementType.h"
-#include "LinearTriangleElementType.h"
-#include "LinkedDofInfo.h"
 #include <stdio.h>
 
+#include "StGermain/StGermain.h"
+#include "Discretisation.h"
+
+
 Stream* StgFEM_Debug = NULL;
 Stream* StgFEM_Warning = NULL;
 Stream* StgFEM_Discretisation_Debug = NULL;
 
+
 /** Initialises the Linear Algebra package, then any init for this package
 such as streams etc */
 Bool StgFEM_Discretisation_Init( int* argc, char** argv[] ) {
@@ -91,7 +77,9 @@
 	Stg_ComponentRegister_Add( componentRegister, OperatorFeVariable_Type, "0", OperatorFeVariable_DefaultNew );
 	Stg_ComponentRegister_Add( componentRegister, ShapeFeVariable_Type,    "0", ShapeFeVariable_DefaultNew );
 	Stg_ComponentRegister_Add( componentRegister, FeSwarmVariable_Type,    "0", _FeSwarmVariable_DefaultNew );
-	Stg_ComponentRegister_Add( componentRegister, FiniteElement_Mesh_Type, "0", FiniteElement_Mesh_DefaultNew );
+	Stg_ComponentRegister_Add( componentRegister, FeMesh_Algorithms_Type, "0", FeMesh_Algorithms_New );
+	Stg_ComponentRegister_Add( componentRegister, FeMesh_Type, "0", FeMesh_New );
+	Stg_ComponentRegister_Add( componentRegister, C0Generator_Type, "0", C0Generator_New );
 
 	/** Register Parents for type checking */
 	RegisterParent( ElementType_Type,                  Stg_Component_Type );
@@ -103,7 +91,9 @@
 
 	RegisterParent( FeEquationNumber_Type,             Stg_Component_Type );
 	RegisterParent( LinkedDofInfo_Type,                Stg_Component_Type );
-	RegisterParent( FiniteElement_Mesh_Type,           Mesh_Type );
+	RegisterParent( FeMesh_Algorithms_Type, Mesh_Algorithms_Type );
+	RegisterParent( FeMesh_Type, Mesh_Type );
+	RegisterParent( C0Generator_Type, MeshGenerator_Type );
 	
 	RegisterParent( FeVariable_Type,                   FieldVariable_Type );
 	RegisterParent( OperatorFeVariable_Type,           FeVariable_Type );
@@ -111,7 +101,7 @@
 	RegisterParent( FeSwarmVariable_Type,              SwarmVariable_Type );
 
 	/* initialise new MPI types */
-	FeEquationNumber_Create_CritPointInfo_MPI_Datatype();
+	/*FeEquationNumber_Create_CritPointInfo_MPI_Datatype();*/
 
 	/* Initialise singletons / registers */
 	FeVariable_FileFormatImportExportList = Stg_ObjectList_New();

Modified: long/3D/Gale/trunk/src/StgFEM/Discretisation/src/LinkedDofInfo.c
===================================================================
--- long/3D/Gale/trunk/src/StgFEM/Discretisation/src/LinkedDofInfo.c	2006-12-07 23:26:14 UTC (rev 5532)
+++ long/3D/Gale/trunk/src/StgFEM/Discretisation/src/LinkedDofInfo.c	2006-12-07 23:29:43 UTC (rev 5533)
@@ -387,8 +387,8 @@
 				
 	shape = Stg_ComponentFactory_ConstructByName( context->CF, shapeStr, Stg_Shape, True, data ) ;
 				
-				for ( lNode_I = 0; lNode_I < self->mesh->nodeLocalCount; lNode_I++ ) {
-					if ( Stg_Shape_IsCoordInside( shape, self->mesh->nodeCoord[lNode_I] ) ) {
+				for ( lNode_I = 0; lNode_I < Mesh_GetLocalSize( self->mesh, MT_VERTEX ); lNode_I++ ) {
+					if ( Stg_Shape_IsCoordInside( shape, Mesh_GetVertex( self->mesh, lNode_I ) ) ) {
 						LinkedDofInfo_AddDofToSet( self, dofSet, lNode_I, nodalDof );
 					}
 				}	
@@ -433,7 +433,7 @@
 				/* In parallel, there may be several processors in the middle who aren't holding the
 				 * walls, but need to know they exist. Hence use an MPI_Allreduce to get the count */
 				MPI_Allreduce( &numExtraDofSetsNeeded, &globallyKnownExtraDofSetsNeeded, 1, MPI_UNSIGNED,
-					MPI_MAX, self->mesh->layout->decomp->communicator );
+					       MPI_MAX, Mesh_GetCommTopology( self->mesh, MT_VERTEX )->comm );
 
 				for( dofSet_I = 0; dofSet_I < globallyKnownExtraDofSetsNeeded; dofSet_I++ ) {	
 					LinkedDofInfo_AddDofSet( linkedDofInfo );

Deleted: long/3D/Gale/trunk/src/StgFEM/Discretisation/src/Mesh.c
===================================================================
--- long/3D/Gale/trunk/src/StgFEM/Discretisation/src/Mesh.c	2006-12-07 23:26:14 UTC (rev 5532)
+++ long/3D/Gale/trunk/src/StgFEM/Discretisation/src/Mesh.c	2006-12-07 23:29:43 UTC (rev 5533)
@@ -1,584 +0,0 @@
-/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-**
-** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
-**	Melbourne, 3053, Australia.
-**
-** Primary Contributing Organisations:
-**	Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
-**	Australian Computational Earth Systems Simulator - http://www.access.edu.au
-**	Monash Cluster Computing - http://www.mcc.monash.edu.au
-**	Computational Infrastructure for Geodynamics - http://www.geodynamics.org
-**
-** Contributors:
-**	Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
-**	Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
-**	Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
-**	David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
-**	Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
-**	Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
-**	Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
-**	Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
-**	Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
-**	Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
-**
-**  This library is free software; you can redistribute it and/or
-**  modify it under the terms of the GNU Lesser General Public
-**  License as published by the Free Software Foundation; either
-**  version 2.1 of the License, or (at your option) any later version.
-**
-**  This library 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
-**  Lesser General Public License for more details.
-**
-**  You should have received a copy of the GNU Lesser General Public
-**  License along with this library; if not, write to the Free Software
-**  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-**
-** $Id$
-**
-**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
-
-#include <mpi.h>
-#include <StGermain/StGermain.h>
-#include "units.h"
-#include "types.h"
-#include "shortcuts.h"
-#include "Mesh.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <assert.h>
-#include <string.h>
-#include "Element.h"
-#include "ElementType.h"
-#include "ConstantElementType.h"
-#include "BilinearElementType.h"
-#include "TrilinearElementType.h"
-#include "LinearTriangleElementType.h"
-#include "ElementType_Register.h"
-
-const Type FiniteElement_Mesh_Type = "FiniteElement_Mesh";
-
-void* FiniteElement_Mesh_DefaultNew( Name name ) {
-	return _FiniteElement_Mesh_New(
-		sizeof(FiniteElement_Mesh),
-		FiniteElement_Mesh_Type,
-		_FiniteElement_Mesh_Delete, 
-		_FiniteElement_Mesh_Print,
-		_FiniteElement_Mesh_Copy,
-		FiniteElement_Mesh_DefaultNew,
-		_FiniteElement_Mesh_Construct,
-		_FiniteElement_Mesh_Build,
-		_FiniteElement_Mesh_Initialise,
-		_FiniteElement_Mesh_Execute, 
-		_FiniteElement_Mesh_Destroy,
-		name,
-		False,
-		_Mesh_Node_IsLocal1D,
-		_Mesh_Node_IsShadow1D,
-		_Mesh_Element_IsLocal1D,
-		_Mesh_Element_IsShadow1D,
-		NULL, 
-		0,
-		0, 
-		NULL,
-		NULL,
-		NULL);
-}
-
-FiniteElement_Mesh* FiniteElement_Mesh_New(
-		Name					name,
-		void*					layout,
-		SizeT					nodeSize,
-		SizeT					elementSize,
-		void*					extensionMgr_Register,
-		void*					elementType_Register,
-		Dictionary*				dictionary )
-{
-	return _FiniteElement_Mesh_New(
-		sizeof(FiniteElement_Mesh),
-		FiniteElement_Mesh_Type,
-		_FiniteElement_Mesh_Delete, 
-		_FiniteElement_Mesh_Print,
-		_FiniteElement_Mesh_Copy,
-		FiniteElement_Mesh_DefaultNew,
-		_FiniteElement_Mesh_Construct,
-		_FiniteElement_Mesh_Build,
-		_FiniteElement_Mesh_Initialise,
-		_FiniteElement_Mesh_Execute, 
-		_FiniteElement_Mesh_Destroy, 
-		name,
-		True,
-		_Mesh_Node_IsLocal1D,
-		_Mesh_Node_IsShadow1D,
-		_Mesh_Element_IsLocal1D,
-		_Mesh_Element_IsShadow1D,
-		layout, 
-		nodeSize,
-		elementSize, 
-		extensionMgr_Register,
-		elementType_Register,
-		dictionary );
-}
-
-void FiniteElement_Mesh_Init(
-		FiniteElement_Mesh*			self,
-		Name					name,
-		void*					layout,
-		SizeT					nodeSize,
-		SizeT					elementSize,
-		void*					extensionMgr_Register,
-		void*					elementType_Register,
-		Dictionary*				dictionary )
-{
-	/* General info */
-	self->type = FiniteElement_Mesh_Type;
-	self->_sizeOfSelf = sizeof(FiniteElement_Mesh);
-	self->_deleteSelf = False;
-	
-	/* Virtual info */
-	self->_delete = _FiniteElement_Mesh_Delete;
-	self->_print = _FiniteElement_Mesh_Print;
-	self->_copy = _FiniteElement_Mesh_Copy;
-	self->_defaultConstructor = FiniteElement_Mesh_DefaultNew;
-	self->_construct = _FiniteElement_Mesh_Construct;
-	self->_build = _FiniteElement_Mesh_Build;
-	self->_initialise = _FiniteElement_Mesh_Initialise;
-	self->_execute = _FiniteElement_Mesh_Execute;
-	self->_destroy = _FiniteElement_Mesh_Destroy;
-	self->nodeIsLocal = _Mesh_Node_IsLocal1D;
-	self->nodeIsShadow = _Mesh_Node_IsShadow1D;
-	self->elementIsLocal = _Mesh_Element_IsLocal1D;
-	self->elementIsShadow = _Mesh_Element_IsShadow1D;
-
-	_Stg_Class_Init( (Stg_Class*)self );
-	_Stg_Object_Init( (Stg_Object*)self, name, NON_GLOBAL );
-	_Stg_Component_Init( (Stg_Component*)self );
-	_Mesh_Init( (Mesh*)self, layout, nodeSize, elementSize, extensionMgr_Register );
-	
-	/* FiniteElement_Mesh info */
-	_FiniteElement_Mesh_Init( self, elementType_Register );
-}
-
-
-FiniteElement_Mesh* _FiniteElement_Mesh_New( 
-		SizeT					_sizeOfSelf,
-		Type					type,
-		Stg_Class_DeleteFunction*			_delete,
-		Stg_Class_PrintFunction*			_print,
-		Stg_Class_CopyFunction*			_copy, 
-		Stg_Component_DefaultConstructorFunction*	_defaultConstructor,
-		Stg_Component_ConstructFunction*	_construct,
-		Stg_Component_BuildFunction*		_build,
-		Stg_Component_InitialiseFunction*		_initialise,
-		Stg_Component_ExecuteFunction*		_execute,
-		Stg_Component_DestroyFunction*		_destroy,
-		Name					name,
-		Bool					initFlag,
-		Mesh_Node_IsLocalFunction*		_nodeIsLocal,
-		Mesh_Node_IsShadowFunction*		_nodeIsShadow,
-		Mesh_Element_IsLocalFunction*		_elementIsLocal,
-		Mesh_Element_IsShadowFunction*		_elementIsShadow,
-		void*					layout,
-		SizeT					nodeSize,
-		SizeT					elementSize, 
-		void*					extensionMgr_Register,
-		void*					elementType_Register,
-		Dictionary*				dictionary )
-{
-	FiniteElement_Mesh*			self;
-	
-	/* Allocate memory */
-	assert( _sizeOfSelf >= sizeof(FiniteElement_Mesh) );
-	/* Construct using parent */
-	self = (FiniteElement_Mesh*)_Mesh_New( _sizeOfSelf, type, _delete, _print, _copy, _defaultConstructor, _construct,
-			_build, _initialise, _execute, _destroy, name, initFlag, _nodeIsLocal, _nodeIsShadow, _elementIsLocal, _elementIsShadow,
-		layout, nodeSize, elementSize, extensionMgr_Register, dictionary );
-
-	/* General info */
-	
-	/* Virtual functions */
-	
-	/* FiniteElement_Mesh info */
-	if( initFlag ){
-		_FiniteElement_Mesh_Init( self, elementType_Register );
-	}
-	
-	return self;
-}
-
-void _FiniteElement_Mesh_Init(
-		FiniteElement_Mesh*			self,
-		void*					elementType_Register )
-{
-	/* General and Virtual info should already be set */
-	
-	/* FiniteElement_Mesh info */
-	self->isConstructed = True;
-	self->elementType_Register = (ElementType_Register*)elementType_Register;
-
-	self->debug = Stream_RegisterChild( StgFEM_Discretisation_Debug, self->type );
-
-	/* Check the mesh is appropriately configured for F.E. problems */
-	Mesh_ActivateElementNodeTbl( self );
-	Mesh_ActivateNodeElementTbl( self );
-	Mesh_ActivateNodeLocalToGlobalMap( self );
-	if ( self->layout->decomp->allowPartitionOnElement == True ) {
-		Stream* feMeshError = Journal_Register( ErrorStream_Type, self->type );
-		if ( self->isBuilt ) {
-			Journal_Printf( feMeshError, "Error: Mesh already built using illegal partition on element." );
-			assert( 0 );
-		}
-		else {
-			Journal_Printf( feMeshError, "Warning: setting Mesh to only partition on node." );
-			self->layout->decomp->allowPartitionOnElement = False;
-			self->layout->decomp->allowPartitionOnNode = True;
-		}
-	}
-}
-
-void _FiniteElement_Mesh_Delete( void* feMesh ) {
-	FiniteElement_Mesh* self = (FiniteElement_Mesh*)feMesh;
-	
-	Journal_DPrintf( self->debug, "In %s - for %s\n", __func__, self->name );
-	/* Stg_Class_Delete parent*/
-	_Mesh_Delete( self );
-	
-	/* mesh, elementType_Register are purposely not deleted */
-}
-
-void _FiniteElement_Mesh_Print( void* feMesh, Stream* stream ) {
-	FiniteElement_Mesh* self = (FiniteElement_Mesh*)feMesh;
-	
-	/* General info */
-	Journal_Printf( stream, "FiniteElement_Mesh (ptr): %p\n", self );
-	
-	/* Print parent */
-	_Mesh_Print( self, stream );
-	
-	/* Virtual info */
-	
-	/* FiniteElement_Mesh info */
-	Journal_Printf( stream, "Available element types:\n" );
-	Print( self->elementType_Register, stream );
-}
-
-
-void* _FiniteElement_Mesh_Copy( void* feMesh, void* dest, Bool deep, Name nameExt, PtrMap* ptrMap ) {
-	FiniteElement_Mesh*	self = (FiniteElement_Mesh*)feMesh;
-	FiniteElement_Mesh*	newFeMesh;
-	PtrMap*			map = ptrMap;
-	Bool			ownMap = False;
-	
-	if( !map ) {
-		map = PtrMap_New( 10 );
-		ownMap = True;
-	}
-	
-	newFeMesh = (FiniteElement_Mesh*)_Mesh_Copy( self, dest, deep, nameExt, map );
-	
-	newFeMesh->elementType_Register = self->elementType_Register;
-	
-	newFeMesh->debug = self->debug;
-	
-	if( ownMap ) {
-		Stg_Class_Delete( map );
-	}
-	
-	return (void*)newFeMesh;
-}
-
-void _FiniteElement_Mesh_Construct( void* feMesh, Stg_ComponentFactory* cf, void* data ) 
-{
-	FiniteElement_Mesh *self = (FiniteElement_Mesh*)feMesh;
-	void *elementType_Register = NULL;
-
-	_Mesh_Construct( self, cf, data );
-	
-	elementType_Register = Stg_ObjectList_Get( cf->registerRegister, "ElementType_Register" );
-	assert( elementType_Register );
-	_FiniteElement_Mesh_Init( (FiniteElement_Mesh*)self, elementType_Register );
-}
-
-void _FiniteElement_Mesh_Build( void* feMesh, void* data ) {
-	FiniteElement_Mesh* self = (FiniteElement_Mesh*)feMesh;
-	
-	Journal_DPrintf( self->debug, "In %s - for %s\n", __func__, self->name );
-	_Mesh_Build( self, data );
-
-}
-
-
-void _FiniteElement_Mesh_Initialise( void* feMesh, void* data ) {
-	FiniteElement_Mesh* self = (FiniteElement_Mesh*)feMesh;
-	
-	Journal_DPrintf( self->debug, "In %s - for %s\n", __func__, self->name );
-	_Mesh_Initialise( self, data );
-	Stream_IndentBranch( StgFEM_Debug );
-
-	/* TODO: generalise into an entry point so it can easily be over-ridden */
-	_FiniteElement_Mesh_SetupElementTypes_Default( self );
-	
-	#if DEBUG
-	if ( Stream_IsPrintableLevel( self->debug, 3 ) ) {
-		_Mesh_PrintCoords( (Mesh*) self, self->debug );
-	}
-	#endif
-	Stream_UnIndentBranch( StgFEM_Debug );
-}
-
-
-void _FiniteElement_Mesh_SetupElementTypes_Default( FiniteElement_Mesh* self ) {
-	ElementLayout*     elementLayout         = self->layout->elementLayout;
-	Type               elementLayoutType     = elementLayout->type;
-	Type               nodeLayoutType        = self->layout->nodeLayout->type;
-	ElementType_Index  elementTypeIndexToUse = (ElementType_Index) -1;
-	Type               elementTypeToUse      = NULL;
-	Element_LocalIndex element_I             = 0;
-	Stream*            error                 = Journal_Register( ErrorStream_Type, self->type );
-	
-	Journal_DPrintf( self->debug, "In %s - for %s\n", __func__, self->name );
-	Stream_IndentBranch( StgFEM_Debug );
-
-	/* TODO: this will need to be generalised when we allow meshes that are composed of different elements */
-
-	if ( nodeLayoutType == BodyNL_Type ) {
-		/* A Body (1 node at centre of each element) NodeLayout implies Constant shape func FE element types */
-		elementTypeIndexToUse = ElementType_Register_GetIndex( self->elementType_Register, ConstantElementType_Type );
-		Journal_DPrintf( self->debug, "Detected %s node layout -> setting all my element types to %s.\n",
-			BodyNL_Type, ConstantElementType_Type );
-	}
-	else {
-		if ( strstr( elementLayoutType, IrregEL_Type ) ) {
-			/* Irregular topology: only have linear triangular so far */
-			if ( nodeLayoutType == CornerNL_Type ) {
-				elementTypeToUse = LinearTriangleElementType_Type;
-				elementTypeIndexToUse = ElementType_Register_GetIndex( self->elementType_Register, LinearTriangleElementType_Type );
-			}	
-		}		
-		else if ( strstr( elementLayoutType, HexaEL_Type ) ) {
-			/* Hexahedral 3D elements: */
-			if ( ((HexaEL*)elementLayout)->dim == 2 ) {
-				if ( nodeLayoutType == CornerNL_Type ) {
-					elementTypeToUse = BilinearElementType_Type;
-					elementTypeIndexToUse = ElementType_Register_GetIndex( self->elementType_Register, BilinearElementType_Type );
-				}
-			}
-			else {
-				elementTypeToUse = TrilinearElementType_Type;
-				if ( nodeLayoutType == CornerNL_Type ) {
-					elementTypeIndexToUse = ElementType_Register_GetIndex( self->elementType_Register, TrilinearElementType_Type );
-				}
-			}
-		}
-		else {
-			Journal_Firewall( 0, error, "Error: Don't know what FE Element type to set for element "
-				"layout/node layout combo %s/%s. Please override this Hook with code to set the FE "
-				"element types for your non-standard mesh.\n", elementLayoutType, nodeLayoutType );
-		}
-
-		Journal_DPrintf( self->debug, "Detected %s el. layout, %s node layout -> setting all element types to %s "
-			"(index %u).\n", elementLayoutType, nodeLayoutType, elementTypeToUse, elementTypeIndexToUse );
-	}		
-
-	Journal_Firewall( (elementTypeIndexToUse != (unsigned int)-1), error,
-		"Stuffup: should have worked out which element type to use by now.\n" );
-
-	for( element_I = 0; element_I < self->elementDomainCount; element_I++ ) {
-		FeMesh_ElementAt( self, element_I )->elementType_I = elementTypeIndexToUse;
-		/* TODO: stick to default FE cell index till we sort that design issue out... */
-		FeMesh_ElementAt( self, element_I )->cell_I = 0;
-	}
-	Stream_UnIndentBranch( StgFEM_Debug );
-
-}
-
-
-void _FiniteElement_Mesh_Execute( void* feMesh, void* data ) {
-	/* Do nothing */
-}
-
-void _FiniteElement_Mesh_Destroy( void* feMesh, void* data ) {
-	/* Do nothing */
-}
-
-double* _FiniteElement_Mesh_CoordAt( void* feMesh, Node_DomainIndex node_dI ) {
-	FiniteElement_Mesh* self = (FiniteElement_Mesh*)feMesh;
-	
-	return FiniteElement_Mesh_CoordAt( self, node_dI );
-}
-
-Node* _FiniteElement_Mesh_NodeAt( void* feMesh, Node_DomainIndex node_dI ) {
-	FiniteElement_Mesh* self = (FiniteElement_Mesh*)feMesh;
-	
-	return FiniteElement_Mesh_NodeAt( self, node_dI );
-}
-
-FiniteElement_Element* _FiniteElement_Mesh_ElementAt( void* feMesh, Element_DomainIndex element_I ) {
-	FiniteElement_Mesh* self = (FiniteElement_Mesh*)feMesh;
-	
-	return FiniteElement_Mesh_ElementAt( self, element_I );
-}
-
-ElementType* _FiniteElement_Mesh_ElementTypeAt( void* feMesh, Element_DomainIndex element_I ) {
-	FiniteElement_Mesh* self = (FiniteElement_Mesh*)feMesh;
-	
-	return FiniteElement_Mesh_ElementTypeAt( self, element_I );
-}
-
-Variable* FiniteElement_Mesh_RegisterNodeCoordsAsVariables( void* feMesh, void* _variable_Register, Variable** variableList ) {
-	FiniteElement_Mesh* self              = (FiniteElement_Mesh*)feMesh;
-	Variable_Register*  variable_Register = (Variable_Register*) _variable_Register;
-	Variable*           variable;
-	Name                variableName;
-	Name                variableNameX;
-	Name                variableNameY;
-	Name                variableNameZ;
-	
-	/* Append Extension onto names */
-	variableName  = Memory_Alloc_Array( char, strlen( self->name ) + strlen( "NodeCoords" ) + 1, "variableName" );
-	sprintf( variableName , "%sNodeCoords", self->name );
-	
-	variableNameX = Memory_Alloc_Array( char, strlen( self->name ) + strlen( "NodeCoordX" ) + 1, "variableNameX" );
-	sprintf( variableNameX, "%sNodeCoordX", self->name );
-
-	variableNameY = Memory_Alloc_Array( char, strlen( self->name ) + strlen( "NodeCoordY" ) + 1, "variableNameY" );
-	sprintf( variableNameY, "%sNodeCoordY", self->name );
-
-	variableNameZ = Memory_Alloc_Array( char, strlen( self->name ) + strlen( "NodeCoordZ" ) + 1, "variableNameZ" );
-	sprintf( variableNameZ, "%sNodeCoordZ", self->name );
-	
-	/* Construct */
-	variable = Variable_NewVector( 
-		variableName, 
-		Variable_DataType_Double, 
-		3, 
-		&self->nodeDomainCount, 
-		(void**)&self->nodeCoord, 
-		variable_Register, 
-		variableNameX,
-		variableNameY,
-		variableNameZ );
-
-	if ( variableList != NULL ) {
-		variableList[ I_AXIS ] = Variable_Register_GetByName( variable_Register, variableNameX );
-		variableList[ J_AXIS ] = Variable_Register_GetByName( variable_Register, variableNameY );
-		variableList[ K_AXIS ] = Variable_Register_GetByName( variable_Register, variableNameZ );
-	}
-
-	/* Clean Up */
-	Memory_Free( variableNameZ );
-	Memory_Free( variableNameY );
-	Memory_Free( variableNameX );
-	Memory_Free( variableName );
-
-	return variable;
-}
-
-Variable* FiniteElement_Mesh_RegisterLocalNodeCoordsAsVariables( void* feMesh, void* _variable_Register, Variable** variableList ) {
-	FiniteElement_Mesh* self              = (FiniteElement_Mesh*)feMesh;
-	Variable_Register*  variable_Register = (Variable_Register*) _variable_Register;
-	Variable*           variable;
-	Name                variableName;
-	Name                variableNameX;
-	Name                variableNameY;
-	Name                variableNameZ;
-	
-	/* Append Extension onto names */
-	variableName  = Memory_Alloc_Array( char, strlen( self->name ) + strlen( "NodeCoords" ) + 1, "variableName" );
-	sprintf( variableName , "%sNodeCoords", self->name );
-	
-	variableNameX = Memory_Alloc_Array( char, strlen( self->name ) + strlen( "NodeCoordX" ) + 1, "variableNameX" );
-	sprintf( variableNameX, "%sNodeCoordX", self->name );
-
-	variableNameY = Memory_Alloc_Array( char, strlen( self->name ) + strlen( "NodeCoordY" ) + 1, "variableNameY" );
-	sprintf( variableNameY, "%sNodeCoordY", self->name );
-
-	variableNameZ = Memory_Alloc_Array( char, strlen( self->name ) + strlen( "NodeCoordZ" ) + 1, "variableNameZ" );
-	sprintf( variableNameZ, "%sNodeCoordZ", self->name );
-	
-	/* Construct */
-	variable = Variable_NewVector( 
-		variableName, 
-		Variable_DataType_Double, 
-		3, 
-		&self->nodeLocalCount, 
-		(void**)&self->nodeCoord, 
-		variable_Register, 
-		variableNameX,
-		variableNameY,
-		variableNameZ );
-
-	if ( variableList != NULL ) {
-		variableList[ I_AXIS ] = Variable_Register_GetByName( variable_Register, variableNameX );
-		variableList[ J_AXIS ] = Variable_Register_GetByName( variable_Register, variableNameY );
-		variableList[ K_AXIS ] = Variable_Register_GetByName( variable_Register, variableNameZ );
-	}
-
-	/* Clean Up */
-	Memory_Free( variableNameZ );
-	Memory_Free( variableNameY );
-	Memory_Free( variableNameX );
-	Memory_Free( variableName );
-
-	return variable;
-}
-
-void FiniteElement_Mesh_CalcGlobalCoordFromLocalCoord( void* feMesh, Dimension_Index dim, Element_LocalIndex lElement_I, Coord xi, Coord globalCoord ) {
-	FiniteElement_Mesh*        self                = (FiniteElement_Mesh*) feMesh;
-	ElementType*               elementType         = FeMesh_ElementTypeAt( self, lElement_I );
-	Node_Index                 elementNodeCount    = elementType->nodeCount;
-	Node_Index                 elLocalNode_I;
-	Node_Index                 lNode_I;
-	double*                    evaluatedShapeFuncs;
-	double                     shapeFunc;
-	double*                    nodeCoord;
-	
-	/* Evaluate Shape Functions at this point */
-	evaluatedShapeFuncs = Memory_Alloc_Array( double, elementNodeCount, "evaluatedShapeFuncs" );
-	ElementType_EvaluateShapeFunctionsAt( elementType, xi, evaluatedShapeFuncs );
-	
-	/* See FEM/BEM notes pg. 9
-	x(Xi) = \Sigma phi_n(xi) * x_n  */
-	memset( globalCoord, 0, sizeof(Coord) );
-	for ( elLocalNode_I = 0; elLocalNode_I < elementNodeCount; elLocalNode_I++ ) {
-		shapeFunc = evaluatedShapeFuncs[elLocalNode_I];
-		lNode_I   = Mesh_Element_Node_I( self, lElement_I, elLocalNode_I );
-		nodeCoord = Mesh_CoordAt( self, lNode_I );
-
-		globalCoord[ 0 ] += shapeFunc * nodeCoord[ 0 ];
-		globalCoord[ 1 ] += shapeFunc * nodeCoord[ 1 ];
-		if ( dim == 3 )
-			globalCoord[ 2 ] += shapeFunc * nodeCoord[ 2 ];
-	}	
-
-	Memory_Free( evaluatedShapeFuncs );
-}
-
-
-void FiniteElement_Mesh_CalcLocalCoordFromGlobalCoord(
-		void* feMesh,
-		Element_DomainIndex elementCoordIn,
-		const Coord globalCoord,
-		Coord elLocalCoord )
-{
-	FiniteElement_Mesh*     self                = (FiniteElement_Mesh*) feMesh;
-	Node_LocalIndex		currElementNodeCount=0;
-	Coord**			globalNodeCoordPtrs=NULL;
-	ElementType*		elementType = NULL;
-
-	// TODO: would be good to do an optional cautious check that the provided global 
-	// coord is actually in the provided element 
-
-	/* convert global coordinate to local co-ordinates of element the coord is in */
-	currElementNodeCount = self->elementNodeCountTbl[elementCoordIn];
-	globalNodeCoordPtrs = Memory_Alloc_Array( Coord*, currElementNodeCount, "globalNodeCoordPtrs" );
-	Mesh_GetNodeCoordPtrsOfElement( self, elementCoordIn, globalNodeCoordPtrs );
-
-	elementType = FeMesh_ElementTypeAt( self, elementCoordIn );
-	ElementType_ConvertGlobalCoordToElLocal( elementType, self->layout->elementLayout,
-		(const Coord**) globalNodeCoordPtrs, globalCoord, elLocalCoord );
-
-	Memory_Free( globalNodeCoordPtrs );
-}

Deleted: long/3D/Gale/trunk/src/StgFEM/Discretisation/src/Mesh.h
===================================================================
--- long/3D/Gale/trunk/src/StgFEM/Discretisation/src/Mesh.h	2006-12-07 23:26:14 UTC (rev 5532)
+++ long/3D/Gale/trunk/src/StgFEM/Discretisation/src/Mesh.h	2006-12-07 23:29:43 UTC (rev 5533)
@@ -1,213 +0,0 @@
-/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-**
-** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
-**	Melbourne, 3053, Australia.
-**
-** Primary Contributing Organisations:
-**	Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
-**	Australian Computational Earth Systems Simulator - http://www.access.edu.au
-**	Monash Cluster Computing - http://www.mcc.monash.edu.au
-**	Computational Infrastructure for Geodynamics - http://www.geodynamics.org
-**
-** Contributors:
-**	Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
-**	Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
-**	Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
-**	David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
-**	Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
-**	Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
-**	Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
-**	Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
-**	Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
-**	Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
-**
-**  This library is free software; you can redistribute it and/or
-**  modify it under the terms of the GNU Lesser General Public
-**  License as published by the Free Software Foundation; either
-**  version 2.1 of the License, or (at your option) any later version.
-**
-**  This library 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
-**  Lesser General Public License for more details.
-**
-**  You should have received a copy of the GNU Lesser General Public
-**  License along with this library; if not, write to the Free Software
-**  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-**
-*/
-/** \file
-**  Role:
-**	Brings together the geometry and node interconnectivity of a mesh, plus the element type (i.e. shape functions) needed by the finite element method.
-**
-** Assumptions:
-**	Elements used with this mesh inherit from FiniteElement_Element.
-**	The contents of the mesh's elements must be initialised by the user.
-**
-** Comments:
-**	This mesh inherits from the parent Discretisation-level Mesh class, which defines how
-**	the mesh is laid out, manages local to global mappings etc.
-**	The extra complexity this class adds from an FE perspective is the relationship between
-**	the geometric element /node types to the F.E. ElementType determining shape functions.
-**
-**	Situations involving this class become interesting when using multiple FeVariable objects
-**	in a simulation. See the Twiki notes at 
-**	csd.vpac.org/twiki/bin/view/Stgermain/FiniteElement_Mesh for more on this.
-**
-** $Id $
-**
-**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
-
-#ifndef __StgFEM_Discretisation_FiniteElement_Mesh_h__
-#define __StgFEM_Discretisation_FiniteElement_Mesh_h__
-	
-	/** Textual name of this class */
-	extern const Type FiniteElement_Mesh_Type;
-	
-	/** FiniteElement_Mesh information */
-	#define __FiniteElement_Mesh \
-		/* General info */ \
-		__Mesh \
-		\
-		/* Virtual info */ \
-		\
-		/* FiniteElement_Mesh info */ \
-		/** The basic discretisation Mesh */ \
-		ElementType_Register*			elementType_Register; \
-		
-	/** Brings together and manages the life-cycle of a a mesh and all the 
-	info relevant to it for the Finite Element Method. See Mesh.h for more. */
-	struct FiniteElement_Mesh { __FiniteElement_Mesh };
-	
-	/* --- Constructors / Destructor --- */
-	
-	/** Create a new FiniteElement_Mesh and initialise */
-
-	void* FiniteElement_Mesh_DefaultNew( Name name );
-	
-	FiniteElement_Mesh* FiniteElement_Mesh_New(
-		Name					name,
-		void*					layout,
-		SizeT					nodeSize,
-		SizeT					elementSize,
-		void*					extension_Register,
-		void*					elementType_Register,
-		Dictionary*				dictionary );
-
-	void FiniteElement_Mesh_LoadFromDict( void* mesh, Dictionary* subDict, Dictionary* dictionary, Stg_ObjectList* objList);
-	
-	/* Initialise a FiniteElement_Mesh construct */
-	void FiniteElement_Mesh_Init(
-		FiniteElement_Mesh*			self,
-		Name					name,
-		void*					layout,
-		SizeT					nodeSize,
-		SizeT					elementSize,
-		void*					extension_Register,
-		void*					elementType_Register,
-		Dictionary*				dictionary );
-	
-	/* Creation implementation / Virtual constructor */
-	FiniteElement_Mesh* _FiniteElement_Mesh_New(
-		SizeT					_sizeOfSelf,
-		Type					type,
-		Stg_Class_DeleteFunction*			_delete,
-		Stg_Class_PrintFunction*			_print,
-		Stg_Class_CopyFunction*			_copy,
-		Stg_Component_DefaultConstructorFunction*	_defaultConstructor,
-		Stg_Component_ConstructFunction*	_construct,
-		Stg_Component_BuildFunction*		_build,
-		Stg_Component_InitialiseFunction*		_initialise,
-		Stg_Component_ExecuteFunction*		_execute,
-		Stg_Component_DestroyFunction*		_destroy,
-		Name					name,
-		Bool					initFlag,
-		Mesh_Node_IsLocalFunction*		_nodeIsLocal,
-		Mesh_Node_IsShadowFunction*		_nodeIsShadow,
-		Mesh_Element_IsLocalFunction*		_elementIsLocal,
-		Mesh_Element_IsShadowFunction*		_elementIsShadow,
-		void*					layout,
-		SizeT					nodeSize,
-		SizeT					elementSize, 
-		void*					extension_Register,
-		void*					elementType_Register,
-		Dictionary*				dictionary );
-
-	/* Initialise implementation */
-	void _FiniteElement_Mesh_Init( 
-		FiniteElement_Mesh*			self,
-		void*					elementType_Register );
-	
-	/* Stg_Class_Delete a FiniteElement_Mesh construst */
-	void _FiniteElement_Mesh_Delete( void* feMesh );
-
-	/* --- Virtual Function implementations --- */
-	
-	/* Print the contents of an FiniteElement_Mesh construct */
-	void _FiniteElement_Mesh_Print( void* feMesh, Stream* stream );
-	
-	/* Copy */
-	#define FiniteElement_Mesh_Copy( self ) \
-		(FiniteElement_Mesh*)Stg_Class_Copy( self, NULL, False, NULL, NULL )
-	#define FiniteElement_Mesh_DeepCopy( self ) \
-		(FiniteElement_Mesh*)Stg_Class_Copy( self, NULL, True, NULL, NULL )
-	
-	void* _FiniteElement_Mesh_Copy( void* feMesh, void* dest, Bool deep, Name nameExt, PtrMap* ptrMap );
-	
-	/* Build implementation */
-	void _FiniteElement_Mesh_Build( void* feMesh, void* data );
-	
-	/* Construct implementation */
-	void _FiniteElement_Mesh_Construct( void* feMesh, Stg_ComponentFactory* cf, void* data );
-	
-	/* Initialisation implementation */
-	void _FiniteElement_Mesh_Initialise( void* feMesh, void* data );
-	
-	/* Execution implementation */
-	void _FiniteElement_Mesh_Execute( void* feMesh, void* data );
-	
-	/* Destruct Implementation */
-	void _FiniteElement_Mesh_Destroy( void* feMesh, void* data );
-
-	/* --- Public Functions --- */
-	
-	/* For use when Node is not yet a complete type */
-	#define FiniteElement_Mesh_CoordAt( self, node_dI ) \
-		Mesh_CoordAt( self, node_dI )
-	double* _FiniteElement_Mesh_CoordAt( void* feMesh, Node_DomainIndex node_dI );
-	
-	/* For use when Node is not yet a complete type */
-	#define FiniteElement_Mesh_NodeAt( self, node_dI ) \
-		Mesh_NodeAt( self, node_dI )
-	Node* _FiniteElement_Mesh_NodeAt( void* feMesh, Node_DomainIndex node_I );
-	
-	/* For use when Element is not yet a complete type */
-	#define FiniteElement_Mesh_ElementAt( self, element_I ) \
-		((FiniteElement_Element*)Mesh_ElementAt( self, element_I ))
-	FiniteElement_Element* _FiniteElement_Mesh_ElementAt( void* feMesh, Element_DomainIndex element_I );
-	
-	/** Get the element type of an element */
-	#define FiniteElement_Mesh_ElementTypeAt( self, el_I ) \
-		(ElementType_Register_At( (self)->elementType_Register, FiniteElement_Mesh_ElementAt( self, el_I )->elementType_I ))
-	ElementType* _FiniteElement_Mesh_ElementTypeAt( void* feMesh, Element_DomainIndex element_I );
-	
-	/* --- Private Functions --- */
-	
-	void _FiniteElement_Mesh_SetupElementTypes_Default( FiniteElement_Mesh* self );
-
-	/* --- Public Functions --- */
-	Variable* FiniteElement_Mesh_RegisterNodeCoordsAsVariables( void* feMesh, void* _variable_Register, Variable** variableList ) ;
-	Variable* FiniteElement_Mesh_RegisterLocalNodeCoordsAsVariables( void* feMesh, void* _variable_Register, Variable** variableList );
-	void FiniteElement_Mesh_CalcGlobalCoordFromLocalCoord( void* feMesh, Dimension_Index dim, Element_LocalIndex lElement_I, Coord xi, Coord globalCoord ) ;
-
-	/** This is a higher-level function to the actual one on the elementType that does the work.
-		It was decided the user should pass in the current element, since they usually know this when doing this
-		conversion */
-	void FiniteElement_Mesh_CalcLocalCoordFromGlobalCoord(
-		void* feMesh,
-		Element_DomainIndex elementCoordIn,
-		const Coord globalCoord,
-		Coord elLocalCoord );
-
-	
-#endif /* __StgFEM_Discretisation_FiniteElement_Mesh_h__ */

Deleted: long/3D/Gale/trunk/src/StgFEM/Discretisation/src/Mesh.meta
===================================================================
--- long/3D/Gale/trunk/src/StgFEM/Discretisation/src/Mesh.meta	2006-12-07 23:26:14 UTC (rev 5532)
+++ long/3D/Gale/trunk/src/StgFEM/Discretisation/src/Mesh.meta	2006-12-07 23:29:43 UTC (rev 5533)
@@ -1,28 +0,0 @@
-<?xml version="1.0"?>
-<!DOCTYPE StGermainData SYSTEM "stgermain.dtd">
-<StGermainData xmlns="http://www.vpac.org/StGermain/XML_IO_Handler/Jun2003">
-
-<param name="Name">FiniteElement_Mesh</param>
-<param name="Organisation">VPAC</param>
-<param name="Project">StgFEM</param>
-<param name="Location">./StgFEM/Discretisation/src/</param>
-<param name="Project Web">https://csd.vpac.org/twiki/bin/view/Stgfem/WebHome</param>
-<param name="Copyright">Copyright (C) 2004-2005 VPAC.</param>
-<param name="License">https://csd.vpac.org/twiki/bin/view/Stgermain/SoftwareLicense</param>
-<param name="Parent">Mesh</param>
-<param name="Description">...</param>
-
-<!--Now the interesting stuff-->
-
-
-<list name="Params">
-
-</list>
-
-<list name="Dependencies">
-
-</list>
-<!-- Add an exmaple XML if possible -->
-<param name="Example">...</param>
-
-</StGermainData>

Modified: long/3D/Gale/trunk/src/StgFEM/Discretisation/src/OperatorFeVariable.c
===================================================================
--- long/3D/Gale/trunk/src/StgFEM/Discretisation/src/OperatorFeVariable.c	2006-12-07 23:26:14 UTC (rev 5532)
+++ long/3D/Gale/trunk/src/StgFEM/Discretisation/src/OperatorFeVariable.c	2006-12-07 23:29:43 UTC (rev 5533)
@@ -268,36 +268,8 @@
 
 	/* Assign values to object */
 	self->feVariableCount     = feVariableCount;
+	self->operatorName = operatorName;
 
-	/* Check if we are using a gradient operator */
-	if ( strcasecmp( operatorName, "gradient" ) == 0 ) {
-		self->useGradient = True;
-		assert( feVariableCount == 1 );
-		self->fieldComponentCount = feVariableList[0]->fieldComponentCount * self->dim;
-	}
-	else {
-		/* just use normal operator */
-		self->useGradient = False;
-		/* Added 5 May 2006 by P Sunter: in the case of VectorScale, the fieldComponentCount should be based
-		on the 2nd operator. Also make sure the 2nd operator has at least as may dofs per node as the first. */
-		if ( feVariableCount == 2 ) {
-			Journal_Firewall( feVariableList[1]->fieldComponentCount >= feVariableList[0]->fieldComponentCount,
-				errorStream, "Error - in %s: tried to create a %s operator from feVariables \"%s\" "
-				"and \"%s\" - who have fieldCounts %d and %d - unsupported since operations "
-				"such as VectorScale require the 2nd feVariable to have >= the first's field count.\n",
-				__func__, operatorName, feVariableList[0]->name, feVariableList[1]->name,
-				feVariableList[0]->fieldComponentCount, feVariableList[1]->fieldComponentCount );
-			self->_operator  = Operator_NewFromName( operatorName, feVariableList[1]->fieldComponentCount,
-				self->dim );
-		}
-		else {	
-			self->_operator  = Operator_NewFromName( operatorName, feVariableList[0]->fieldComponentCount,
-				self->dim );
-		}
-
-		self->fieldComponentCount = self->_operator->resultDofs; /* reset this value from that which is from operator */
-	}
-
 	/* Copy field variable list */
 	self->feVariableList      = Memory_Alloc_Array( FeVariable*, feVariableCount, "Array of Field Variables" );
 	memcpy( self->feVariableList, feVariableList, feVariableCount * sizeof( FeVariable* ) );
@@ -309,8 +281,6 @@
 		Journal_Firewall( feVariable->fieldComponentCount <= MAX_FIELD_COMPONENTS,
 				errorStream, "In func %s: Field Variable '%s' has too many components.\n", __func__, feVariable->name );
 	}
-	_OperatorFeVariable_SetFunctions( self );
-
 }
 
 void _OperatorFeVariable_Delete( void* _feVariable ) {
@@ -405,9 +375,40 @@
 void _OperatorFeVariable_Build( void* feVariable, void* data ) {
 	OperatorFeVariable* self = (OperatorFeVariable*) feVariable;
 	Index                  feVariable_I;
+	Stream*                     errorStream       = Journal_Register( Error_Type, self->type );
 
 	for ( feVariable_I = 0 ; feVariable_I < self->feVariableCount ; feVariable_I++ ) 
 		Build( self->feVariableList[ feVariable_I ] , data, False );
+
+	/* Check if we are using a gradient operator */
+	if ( strcasecmp( self->operatorName, "gradient" ) == 0 ) {
+		self->useGradient = True;
+		assert( self->feVariableCount == 1 );
+		self->fieldComponentCount = self->feVariableList[0]->fieldComponentCount * self->dim;
+	}
+	else {
+		/* just use normal operator */
+		self->useGradient = False;
+		/* Added 5 May 2006 by P Sunter: in the case of VectorScale, the fieldComponentCount should be based
+		on the 2nd operator. Also make sure the 2nd operator has at least as may dofs per node as the first. */
+		if ( self->feVariableCount == 2 ) {
+			Journal_Firewall( self->feVariableList[1]->fieldComponentCount >= self->feVariableList[0]->fieldComponentCount,
+				errorStream, "Error - in %s: tried to create a %s operator from feVariables \"%s\" "
+				"and \"%s\" - who have fieldCounts %d and %d - unsupported since operations "
+				"such as VectorScale require the 2nd feVariable to have >= the first's field count.\n",
+				__func__, self->operatorName, self->feVariableList[0]->name, self->feVariableList[1]->name,
+				self->feVariableList[0]->fieldComponentCount, self->feVariableList[1]->fieldComponentCount );
+			self->_operator  = Operator_NewFromName( self->operatorName, self->feVariableList[1]->fieldComponentCount,
+				self->dim );
+		}
+		else {	
+			self->_operator  = Operator_NewFromName( self->operatorName, self->feVariableList[0]->fieldComponentCount,
+				self->dim );
+		}
+
+		self->fieldComponentCount = self->_operator->resultDofs; /* reset this value from that which is from operator */
+	}
+	_OperatorFeVariable_SetFunctions( self );
 }
 
 void _OperatorFeVariable_Initialise( void* feVariable, void* data ) {
@@ -581,7 +582,7 @@
 	Mesh*               mesh            = (Mesh*) self->feMesh;
 	double*             coord;
 
-	coord = Mesh_CoordAt( mesh, dNode_I );
+	coord = Mesh_GetVertex( mesh, dNode_I );
 
 	memset( value, 0, self->fieldComponentCount * sizeof(double) );
 	FeVariable_InterpolateDerivativesAt( self->feVariableList[0], coord, value );

Modified: long/3D/Gale/trunk/src/StgFEM/Discretisation/src/OperatorFeVariable.h
===================================================================
--- long/3D/Gale/trunk/src/StgFEM/Discretisation/src/OperatorFeVariable.h	2006-12-07 23:26:14 UTC (rev 5532)
+++ long/3D/Gale/trunk/src/StgFEM/Discretisation/src/OperatorFeVariable.h	2006-12-07 23:29:43 UTC (rev 5533)
@@ -78,6 +78,7 @@
 		__FeVariable \
 		\
 		/* Other info */ \
+		char*							    operatorName;	\
 		Operator*                                                   _operator;           \
 		Index                                                       feVariableCount;  \
 		FeVariable**                                                feVariableList;   \

Modified: long/3D/Gale/trunk/src/StgFEM/Discretisation/src/ShapeFeVariable.c
===================================================================
--- long/3D/Gale/trunk/src/StgFEM/Discretisation/src/ShapeFeVariable.c	2006-12-07 23:26:14 UTC (rev 5532)
+++ long/3D/Gale/trunk/src/StgFEM/Discretisation/src/ShapeFeVariable.c	2006-12-07 23:29:43 UTC (rev 5533)
@@ -44,7 +44,7 @@
 #include <StGermain/StGermain.h>
 
 #include "types.h"
-#include "Mesh.h"
+#include "FeMesh.h"
 #include "FeVariable.h"
 #include "ShapeFeVariable.h"
 
@@ -217,8 +217,8 @@
 	_FeVariable_Initialise( self, data );
 
 	/* Set up the basic "level set" describiing if nodes are inside the shape or not */
-	for ( node_dI = 0; node_dI < self->feMesh->nodeDomainCount; node_dI++ ) {
-		if ( True == Stg_Shape_IsCoordInside( self->shape, self->feMesh->nodeCoord[node_dI] ) ) {
+	for ( node_dI = 0; node_dI < Mesh_GetDomainSize( self->feMesh, MT_VERTEX ); node_dI++ ) {
+		if ( True == Stg_Shape_IsCoordInside( self->shape, Mesh_GetVertex( self->feMesh, node_dI ) ) ) {
 			//set value = 1
 			FeVariable_SetComponentAtNode( self, node_dI, 0, 1 );
 		}		

Modified: long/3D/Gale/trunk/src/StgFEM/Discretisation/src/TrilinearElementType.c
===================================================================
--- long/3D/Gale/trunk/src/StgFEM/Discretisation/src/TrilinearElementType.c	2006-12-07 23:26:14 UTC (rev 5532)
+++ long/3D/Gale/trunk/src/StgFEM/Discretisation/src/TrilinearElementType.c	2006-12-07 23:29:43 UTC (rev 5533)
@@ -127,11 +127,25 @@
 		self->elLocalLength[dim_I] = self->maxElLocalCoord[dim_I] - self->minElLocalCoord[dim_I];
 	}
 
+	/* Set up the tetrahedral indices. */
+	self->tetInds = Memory_Alloc_2DArray( unsigned, 10, 4, "Mesh_HexType::tetInds" );
+	self->tetInds[0][0] = 0; self->tetInds[0][1] = 1; self->tetInds[0][2] = 2; self->tetInds[0][3] = 4;
+	self->tetInds[1][0] = 1; self->tetInds[1][1] = 2; self->tetInds[1][2] = 3; self->tetInds[1][3] = 7;
+	self->tetInds[2][0] = 1; self->tetInds[2][1] = 4; self->tetInds[2][2] = 5; self->tetInds[2][3] = 7;
+	self->tetInds[3][0] = 2; self->tetInds[3][1] = 4; self->tetInds[3][2] = 6; self->tetInds[3][3] = 7;
+	self->tetInds[4][0] = 1; self->tetInds[4][1] = 2; self->tetInds[4][2] = 4; self->tetInds[4][3] = 7;
+	self->tetInds[5][0] = 0; self->tetInds[5][1] = 1; self->tetInds[5][2] = 3; self->tetInds[5][3] = 5;
+	self->tetInds[6][0] = 0; self->tetInds[6][1] = 4; self->tetInds[6][2] = 5; self->tetInds[6][3] = 6;
+	self->tetInds[7][0] = 0; self->tetInds[7][1] = 2; self->tetInds[7][2] = 3; self->tetInds[7][3] = 6;
+	self->tetInds[8][0] = 3; self->tetInds[8][1] = 5; self->tetInds[8][2] = 6; self->tetInds[8][3] = 7;
+	self->tetInds[9][0] = 0; self->tetInds[9][1] = 3; self->tetInds[9][2] = 5; self->tetInds[9][3] = 6;
 }
 
 void _TrilinearElementType_Delete( void* elementType ) {
 	TrilinearElementType* self = (TrilinearElementType*)elementType;
 	Journal_DPrintf( self->debug, "In %s\n", __func__ );
+
+	FreeArray( self->tetInds );
 	
 	/* Stg_Class_Delete parent*/
 	_ElementType_Delete( self );
@@ -227,13 +241,13 @@
 	zeta = localCoord[2];	
 	
 	evaluatedValues[0] = 0.125*( 1.0-xi )*( 1.0-eta )*( 1.0-zeta );
-	evaluatedValues[3] = 0.125*( 1.0-xi )*( 1.0+eta )*( 1.0-zeta );
-	evaluatedValues[2] = 0.125*( 1.0+xi )*( 1.0+eta )*( 1.0-zeta );
+	evaluatedValues[2] = 0.125*( 1.0-xi )*( 1.0+eta )*( 1.0-zeta );
+	evaluatedValues[3] = 0.125*( 1.0+xi )*( 1.0+eta )*( 1.0-zeta );
 	evaluatedValues[1] = 0.125*( 1.0+xi )*( 1.0-eta )*( 1.0-zeta );
 	
 	evaluatedValues[4] = 0.125*( 1.0-xi )*( 1.0-eta )*( 1.0+zeta );
-	evaluatedValues[7] = 0.125*( 1.0-xi )*( 1.0+eta )*( 1.0+zeta );
-	evaluatedValues[6] = 0.125*( 1.0+xi )*( 1.0+eta )*( 1.0+zeta );
+	evaluatedValues[6] = 0.125*( 1.0-xi )*( 1.0+eta )*( 1.0+zeta );
+	evaluatedValues[7] = 0.125*( 1.0+xi )*( 1.0+eta )*( 1.0+zeta );
 	evaluatedValues[5] = 0.125*( 1.0+xi )*( 1.0-eta )*( 1.0+zeta );
 }
 
@@ -249,107 +263,65 @@
 	
 	/* derivatives wrt xi */
 	evaluatedDerivatives[0][0] = - 0.125*( 1.0-eta )*( 1.0-zeta );
-	evaluatedDerivatives[0][3] = - 0.125*( 1.0+eta )*( 1.0-zeta );
-	evaluatedDerivatives[0][2] =   0.125*( 1.0+eta )*( 1.0-zeta );
+	evaluatedDerivatives[0][2] = - 0.125*( 1.0+eta )*( 1.0-zeta );
+	evaluatedDerivatives[0][3] =   0.125*( 1.0+eta )*( 1.0-zeta );
 	evaluatedDerivatives[0][1] =   0.125*( 1.0-eta )*( 1.0-zeta );
 	evaluatedDerivatives[0][4] = - 0.125*( 1.0-eta )*( 1.0+zeta );
-	evaluatedDerivatives[0][7] = - 0.125*( 1.0+eta )*( 1.0+zeta );
-	evaluatedDerivatives[0][6] =   0.125*( 1.0+eta )*( 1.0+zeta );
+	evaluatedDerivatives[0][6] = - 0.125*( 1.0+eta )*( 1.0+zeta );
+	evaluatedDerivatives[0][7] =   0.125*( 1.0+eta )*( 1.0+zeta );
 	evaluatedDerivatives[0][5] =   0.125*( 1.0-eta )*( 1.0+zeta );
 	
 	/* derivatives wrt eta */	
 	evaluatedDerivatives[1][0] = - 0.125*( 1.0-xi )*( 1.0-zeta );
-	evaluatedDerivatives[1][3] =   0.125*( 1.0-xi )*( 1.0-zeta );
-	evaluatedDerivatives[1][2] =   0.125*( 1.0+xi )*( 1.0-zeta );
+	evaluatedDerivatives[1][2] =   0.125*( 1.0-xi )*( 1.0-zeta );
+	evaluatedDerivatives[1][3] =   0.125*( 1.0+xi )*( 1.0-zeta );
 	evaluatedDerivatives[1][1] = - 0.125*( 1.0+xi )*( 1.0-zeta );
 	evaluatedDerivatives[1][4] = - 0.125*( 1.0-xi )*( 1.0+zeta );
-	evaluatedDerivatives[1][7] =   0.125*( 1.0-xi )*( 1.0+zeta );
-	evaluatedDerivatives[1][6] =   0.125*( 1.0+xi )*( 1.0+zeta );
+	evaluatedDerivatives[1][6] =   0.125*( 1.0-xi )*( 1.0+zeta );
+	evaluatedDerivatives[1][7] =   0.125*( 1.0+xi )*( 1.0+zeta );
 	evaluatedDerivatives[1][5] = - 0.125*( 1.0+xi )*( 1.0+zeta );
 	
 	/* derivatives wrt zeta */		
 	evaluatedDerivatives[2][0] = -0.125*( 1.0-xi )*( 1.0-eta );
-	evaluatedDerivatives[2][3] = -0.125*( 1.0-xi )*( 1.0+eta );
-	evaluatedDerivatives[2][2] = -0.125*( 1.0+xi )*( 1.0+eta );
+	evaluatedDerivatives[2][2] = -0.125*( 1.0-xi )*( 1.0+eta );
+	evaluatedDerivatives[2][3] = -0.125*( 1.0+xi )*( 1.0+eta );
 	evaluatedDerivatives[2][1] = -0.125*( 1.0+xi )*( 1.0-eta );
 	evaluatedDerivatives[2][4] =  0.125*( 1.0-xi )*( 1.0-eta );
-	evaluatedDerivatives[2][7] =  0.125*( 1.0-xi )*( 1.0+eta );
-	evaluatedDerivatives[2][6] =  0.125*( 1.0+xi )*( 1.0+eta );
+	evaluatedDerivatives[2][6] =  0.125*( 1.0-xi )*( 1.0+eta );
+	evaluatedDerivatives[2][7] =  0.125*( 1.0+xi )*( 1.0+eta );
 	evaluatedDerivatives[2][5] =  0.125*( 1.0+xi )*( 1.0-eta );
 }
 
 
 void _TrilinearElementType_ConvertGlobalCoordToElLocal(
 		void*		elementType,
-		ElementLayout*	elementLayout,
-		const Coord**	globalNodeCoordPtrsInElement,
-		const Coord	globalCoord,
-		Coord		elLocalCoord )
+		void*		_mesh, 
+		unsigned	element, 
+		const double*	globalCoord,
+		double*		elLocalCoord )
 {
 	TrilinearElementType*	self = (TrilinearElementType*)elementType;
-	Dimension_Index		dim_I = 0;
-	double			globalToElLocalScaling[3] = {0.0,0.0,0.0};
-	Coord			relToBottomLeftGlobalCoord = {0.0,0.0,0.0};
+	Mesh*			mesh = (Mesh*)_mesh;
+	unsigned		inside;
+	double			bc[3];
+	static double		lCrds[8][3] = {{-1.0, -1.0, -1.0}, {1.0, -1.0, -1.0}, 
+					       {-1.0, 1.0, -1.0}, {1.0, 1.0, -1.0}, 
+					       {-1.0, -1.0, 1.0}, {1.0, -1.0, 1.0}, 
+					       {-1.0, 1.0, 1.0}, {1.0, 1.0, 1.0}};
+	unsigned		nInc, *inc;
+	unsigned		bc_i;
 
-	if ( elementLayout->type == ParallelPipedHexaEL_Type ) {
-		double	elLen[3];
-		elLen[0] = (*(globalNodeCoordPtrsInElement[1]))[0] - (*(globalNodeCoordPtrsInElement[0]))[0];
-		elLen[1] = (*(globalNodeCoordPtrsInElement[3]))[1] - (*(globalNodeCoordPtrsInElement[0]))[1];
-		elLen[2] = (*(globalNodeCoordPtrsInElement[4]))[2] - (*(globalNodeCoordPtrsInElement[0]))[2];
-		
-		/*
-		** Storing the element length in each dimension on the element layout is causing a bit of hassle with MG.
-		** I'm going to change it so that this is calculated from the global node coords passed in.  This shouldn't
-		** affect anything really.  If anyone can think of any reasons why this is a bad idea, let me know as we'll
-		** have to figure out a compromise for MG.  Luke - 03/08/2005
-		*/
+	Mesh_GetIncidence( mesh, MT_VOLUME, element, MT_VERTEX, &nInc, &inc );
+	assert( nInc == 8 );
 
-		/* Initially set elLocalCoord to (0,0,0) */
-		memset( elLocalCoord, 0, sizeof( Coord ) );
-	
-		for( dim_I=0; dim_I < 3; dim_I++ ) {
-			globalToElLocalScaling[dim_I] = self->elLocalLength[dim_I] / elLen[dim_I];
-			/* The bottom left node is always at index zero */
-			relToBottomLeftGlobalCoord[dim_I] = globalCoord[dim_I] - (*(globalNodeCoordPtrsInElement[0]))[dim_I];
+	insist( Simplex_Search3D( mesh->verts, inc, 10, self->tetInds, (double*)globalCoord, bc, &inside ) );
 
-			elLocalCoord[dim_I] =  self->minElLocalCoord[dim_I] + relToBottomLeftGlobalCoord[dim_I] * globalToElLocalScaling[dim_I];
-		}	
+	elLocalCoord[0] = bc[0] * lCrds[self->tetInds[inside][0]][0];
+	elLocalCoord[1] = bc[0] * lCrds[self->tetInds[inside][0]][1];
+	elLocalCoord[2] = bc[0] * lCrds[self->tetInds[inside][0]][2];
+	for( bc_i = 1; bc_i < 4; bc_i++ ) {
+		elLocalCoord[0] += bc[bc_i] * lCrds[self->tetInds[inside][bc_i]][0];
+		elLocalCoord[1] += bc[bc_i] * lCrds[self->tetInds[inside][bc_i]][1];
+		elLocalCoord[2] += bc[bc_i] * lCrds[self->tetInds[inside][bc_i]][2];
 	}
-	else if( elementLayout->type == HexaEL_Type ) {
-		Coord		crds[8];
-		double		bc[4];
-		unsigned	inds[4];
-		Coord		lCrds[8] = {{-1.0, -1.0, -1.0}, {1.0, -1.0, -1.0}, 
-					    {-1.0, 1.0, -1.0}, {1.0, 1.0, -1.0}, 
-					    {-1.0, -1.0, 1.0}, {1.0, -1.0, 1.0}, 
-					    {-1.0, 1.0, 1.0}, {1.0, 1.0, 1.0}};
-		unsigned	bc_i;
-
-		memcpy( crds[0], *(globalNodeCoordPtrsInElement[0]), sizeof(Coord) );
-		memcpy( crds[1], *(globalNodeCoordPtrsInElement[1]), sizeof(Coord) );
-		memcpy( crds[2], *(globalNodeCoordPtrsInElement[3]), sizeof(Coord) );
-		memcpy( crds[3], *(globalNodeCoordPtrsInElement[2]), sizeof(Coord) );
-		memcpy( crds[4], *(globalNodeCoordPtrsInElement[4]), sizeof(Coord) );
-		memcpy( crds[5], *(globalNodeCoordPtrsInElement[5]), sizeof(Coord) );
-		memcpy( crds[6], *(globalNodeCoordPtrsInElement[7]), sizeof(Coord) );
-		memcpy( crds[7], *(globalNodeCoordPtrsInElement[6]), sizeof(Coord) );
-#ifndef NDEBUG
-		assert( _HexaEL_FindTetBarycenter( crds, globalCoord, bc, inds, INCLUSIVE_UPPER_BOUNDARY, NULL, 0 ) );
-#else
-		_HexaEL_FindTetBarycenter( crds, globalCoord, bc, inds, INCLUSIVE_UPPER_BOUNDARY, NULL, 0 );
-#endif
-
-		/* Interpolate. */
-		memset( elLocalCoord, 0, sizeof(Coord) );
-		for( bc_i = 0; bc_i < 4; bc_i++ ) {
-			elLocalCoord[0] += bc[bc_i] * lCrds[inds[bc_i]][0];
-			elLocalCoord[1] += bc[bc_i] * lCrds[inds[bc_i]][1];
-			elLocalCoord[2] += bc[bc_i] * lCrds[inds[bc_i]][2];
-		}
-	}
-	else {
-		/* Not a box element -> Just use the general version */
-		_ElementType_ConvertGlobalCoordToElLocal( self, elementLayout, globalNodeCoordPtrsInElement,
-			globalCoord, elLocalCoord );
-	}
 }

Modified: long/3D/Gale/trunk/src/StgFEM/Discretisation/src/TrilinearElementType.h
===================================================================
--- long/3D/Gale/trunk/src/StgFEM/Discretisation/src/TrilinearElementType.h	2006-12-07 23:26:14 UTC (rev 5532)
+++ long/3D/Gale/trunk/src/StgFEM/Discretisation/src/TrilinearElementType.h	2006-12-07 23:29:43 UTC (rev 5533)
@@ -64,6 +64,8 @@
 		Coord	minElLocalCoord; /** Bottom corner in elLocal mathematical space */ \
 		Coord	maxElLocalCoord; /** Top corner in elLocal mathematical space */ \
 		double	elLocalLength[3]; /** Length of element in elLocal space */ \
+		\
+		unsigned**	tetInds;
 		
 	struct TrilinearElementType { __TrilinearElementType };
 	
@@ -124,9 +126,9 @@
 	Uses a shortcut approach if using "box" elements - otherwise uses the general function. */
 	void _TrilinearElementType_ConvertGlobalCoordToElLocal(
 		void*		elementType,
-		ElementLayout*	elementLayout,
-		const Coord**	globalNodeCoordPtrsInElement,
-		const Coord	globalCoord,
-		Coord		elLocalCoord );
+		void*		mesh, 
+		unsigned	element, 
+		const double*	globalCoord,
+		double*		elLocalCoord );
 	
 #endif /* __StgFEM_Discretisation_TrilinearElementType_h__ */

Modified: long/3D/Gale/trunk/src/StgFEM/Discretisation/src/types.h
===================================================================
--- long/3D/Gale/trunk/src/StgFEM/Discretisation/src/types.h	2006-12-07 23:26:14 UTC (rev 5532)
+++ long/3D/Gale/trunk/src/StgFEM/Discretisation/src/types.h	2006-12-07 23:29:43 UTC (rev 5533)
@@ -59,7 +59,10 @@
 	typedef struct TrilinearElementType      TrilinearElementType;
 	typedef struct LinearTriangleElementType LinearTriangleElementType;
 	typedef struct FiniteElement_Element     FiniteElement_Element;
-	typedef struct FiniteElement_Mesh        FiniteElement_Mesh;
+	typedef struct FeMesh			FeMesh;
+	typedef struct FeMesh_ElementType	FeMesh_ElementType;
+	typedef struct FeMesh_Algorithms	FeMesh_Algorithms;
+	typedef struct C0Generator		C0Generator;
 	typedef struct LinkedDofInfo             LinkedDofInfo;
 	typedef struct FeEquationNumber          FeEquationNumber;
 	typedef struct FeVariable                FeVariable;

Added: long/3D/Gale/trunk/src/StgFEM/Discretisation/tests/data/wallVC.xml
===================================================================
--- long/3D/Gale/trunk/src/StgFEM/Discretisation/tests/data/wallVC.xml	2006-12-07 23:26:14 UTC (rev 5532)
+++ long/3D/Gale/trunk/src/StgFEM/Discretisation/tests/data/wallVC.xml	2006-12-07 23:29:43 UTC (rev 5533)
@@ -0,0 +1,24 @@
+<?xml version="1.0"?>
+<!DOCTYPE StGermainData SYSTEM "stgermain.dtd">
+<!-- A StGermain input file -->
+<!-- DTD to validate against -->
+<StGermainData xmlns="http://www.vpac.org/StGermain/XML_IO_Handler/Jun2003">
+
+	<struct name="wallVC">
+		<param name="type"> WallVC </param>
+		<param name="wall"> bottom </param>
+		<list name="variables">
+			<struct>
+				<param name="name"> one </param>
+				<param name="type"> double </param>
+				<param name="value" type="double"> 1 </param>
+			</struct>
+			<struct>
+				<param name="name"> two </param>
+				<param name="type"> double </param>
+				<param name="value" type="double"> 3 </param>
+			</struct>
+		</list>
+	</struct>
+
+</StGermainData>

Modified: long/3D/Gale/trunk/src/StgFEM/Discretisation/tests/testElementType.c
===================================================================
--- long/3D/Gale/trunk/src/StgFEM/Discretisation/tests/testElementType.c	2006-12-07 23:26:14 UTC (rev 5532)
+++ long/3D/Gale/trunk/src/StgFEM/Discretisation/tests/testElementType.c	2006-12-07 23:29:43 UTC (rev 5533)
@@ -45,6 +45,7 @@
 
 #include <stdio.h>
 #include <stdlib.h>
+#include <assert.h>
 #include "petsc.h"
 
 struct _Node {
@@ -59,27 +60,46 @@
 	Coord coord;
 };
 
+FeMesh* buildFeMesh( unsigned nDims ) {
+	CartesianGenerator*	gen;
+	FeMesh*			feMesh;
+	unsigned		maxDecomp[3] = {0, 1, 1};
+	unsigned		sizes[3];
+	double			minCrd[3];
+	double			maxCrd[3];
+
+	sizes[0] = sizes[1] = 6;
+	sizes[2] = 1;
+	minCrd[0] = minCrd[1] = minCrd[2] = 0.0;
+	maxCrd[0] = maxCrd[1] = maxCrd[2] = 1.2;
+
+	gen = CartesianGenerator_New( "" );
+	CartesianGenerator_SetTopologyParams( gen, nDims, sizes, 0, NULL, maxDecomp );
+	CartesianGenerator_SetGeometryParams( gen, minCrd, maxCrd );
+	CartesianGenerator_SetShadowDepth( gen, 0 );
+
+	feMesh = FeMesh_New( "" );
+	Mesh_SetGenerator( feMesh, gen );
+	FeMesh_SetElementFamily( feMesh, "linear" );
+	Build( feMesh, NULL, False );
+
+	return feMesh;
+}
+
 int main( int argc, char* argv[] ) {
 	MPI_Comm			CommWorld;
 	int				rank;
 	int				numProcessors;
 	int				procToWatch;
 	Dictionary*			dictionary;
-	Topology*			nTopology;
-	ElementLayout*			eLayout;
-	NodeLayout*			nLayout;
-	MeshDecomp*			decomp;
-	MeshLayout*			meshLayout;
-	ElementType_Register*		elementType_Register;
 	ExtensionManager_Register*		extensionMgr_Register;
-	FiniteElement_Mesh*		feMesh;
+	FeMesh*		feMesh;
 	DiscretisationContext* context;
 	Index				test_I;
 	Stream*				stream;
 	Coord               globalCoord;
 	Coord               elLocalCoord;
 	Coord               elLocalCoordGeneral;
-	Coord**             globalNodeCoordPtrs;
 	Element_Index       elementCoordIn;
 	Node_Index          currElementNodeCount;
 	const Index         maxTests            = 40;
@@ -112,18 +132,6 @@
 	dictionary = Dictionary_New();
 	Dictionary_Add( dictionary, "rank", Dictionary_Entry_Value_FromUnsignedInt( rank ) );
 	Dictionary_Add( dictionary, "numProcessors", Dictionary_Entry_Value_FromUnsignedInt( numProcessors ) );
-	Dictionary_Add( dictionary, "meshSizeI", Dictionary_Entry_Value_FromUnsignedInt( 7 ) );
-	Dictionary_Add( dictionary, "meshSizeJ", Dictionary_Entry_Value_FromUnsignedInt( 7 ) );
-	Dictionary_Add( dictionary, "meshSizeK", Dictionary_Entry_Value_FromUnsignedInt( 2 ) );
-	Dictionary_Add( dictionary, "minX", Dictionary_Entry_Value_FromDouble( 0.0f ) );
-	Dictionary_Add( dictionary, "minY", Dictionary_Entry_Value_FromDouble( 0.0f ) );
-	Dictionary_Add( dictionary, "minZ", Dictionary_Entry_Value_FromDouble( 0.0f ) );
-	Dictionary_Add( dictionary, "maxX", Dictionary_Entry_Value_FromDouble( 1.2f ) );
-	Dictionary_Add( dictionary, "maxY", Dictionary_Entry_Value_FromDouble( 1.2f ) );
-	Dictionary_Add( dictionary, "maxZ", Dictionary_Entry_Value_FromDouble( 1.2f ) );
-	Dictionary_Add( dictionary, "allowPartitionOnElement", Dictionary_Entry_Value_FromBool( False ) );
-	Dictionary_Add( dictionary, "buildElementNodeTbl", Dictionary_Entry_Value_FromBool( True ) );
-
 	Dictionary_ReadAllParamFromCommandLine( dictionary, argc, argv );
 	
 	/* Create Context */
@@ -147,64 +155,42 @@
 	context->dim = Dictionary_GetUnsignedInt_WithDefault( dictionary, "dim", 2 );
 	
 	/* create the layout, dof and mesh to use */
-	nTopology = (Topology*)IJK6Topology_New( "IJK6Topology", dictionary );
-	eLayout = (ElementLayout*)ParallelPipedHexaEL_New( "PPHexaEL", context->dim, dictionary );
-	nLayout = (NodeLayout*)CornerNL_New( "CornerNL", dictionary, eLayout, nTopology );
-	decomp = (MeshDecomp*)HexaMD_New( "HexaMD", dictionary, MPI_COMM_WORLD, eLayout, nLayout );
-	meshLayout = MeshLayout_New( "MeshLayout", eLayout, nLayout, decomp );
-	
 	extensionMgr_Register = ExtensionManager_Register_New();
-	elementType_Register = ElementType_Register_New("elementTypeRegister");
-	ElementType_Register_Add( elementType_Register, (ElementType*)ConstantElementType_New("constant") );
-	ElementType_Register_Add( elementType_Register, (ElementType*)BilinearElementType_New("bilinear") );
-	ElementType_Register_Add( elementType_Register, (ElementType*)TrilinearElementType_New("trilinear") );
-	feMesh = FiniteElement_Mesh_New( "testMesh", meshLayout, sizeof(Node), sizeof(Element), extensionMgr_Register,
-		elementType_Register, dictionary );
+	feMesh = buildFeMesh( context->dim );
 	Build( feMesh, 0, False );
 	Initialise( feMesh, 0, False );
-	
+
 	srand48(0);
 	for ( test_I = 0 ; test_I < maxTests ; test_I++ ) {
 		globalCoord[ I_AXIS ] = drand48();
 		globalCoord[ J_AXIS ] = drand48();
 		globalCoord[ K_AXIS ] = drand48();
-		elementCoordIn = eLayout->elementWithPoint( eLayout, meshLayout->decomp, globalCoord, NULL, 
-							    INCLUSIVE_UPPER_BOUNDARY, 0, NULL );
-		currElementNodeCount = feMesh->elementNodeCountTbl[elementCoordIn];
-		globalNodeCoordPtrs = Memory_Alloc_Array( Coord*, currElementNodeCount, "globalNodeCoordPtrs" );
-		elementType = FeMesh_ElementTypeAt( feMesh, elementCoordIn );
-		Mesh_GetNodeCoordPtrsOfElement( feMesh, elementCoordIn, globalNodeCoordPtrs );
+		Mesh_Algorithms_SearchElements( feMesh->algorithms, feMesh, globalCoord, &elementCoordIn );
+		currElementNodeCount = FeMesh_GetElementNodeSize( feMesh, elementCoordIn );
+		elementType = FeMesh_GetElementType( feMesh, elementCoordIn );
 
-		_ElementType_ConvertGlobalCoordToElLocal( elementType, eLayout,
-				(const Coord**) globalNodeCoordPtrs, globalCoord, elLocalCoordGeneral );
+		_ElementType_ConvertGlobalCoordToElLocal( elementType, feMesh, elementCoordIn, 
+							  globalCoord, elLocalCoordGeneral );
 
 		if ( context->dim == 2 ) {
-			_BilinearElementType_ConvertGlobalCoordToElLocal( elementType, eLayout, 
-					(const Coord**) globalNodeCoordPtrs, globalCoord, elLocalCoord );
+			_BilinearElementType_ConvertGlobalCoordToElLocal( elementType, feMesh, elementCoordIn, 
+									  globalCoord, elLocalCoord );
 		}
 		else {
-			_TrilinearElementType_ConvertGlobalCoordToElLocal( elementType, eLayout,
-					(const Coord**) globalNodeCoordPtrs, globalCoord, elLocalCoord );
+			_TrilinearElementType_ConvertGlobalCoordToElLocal( elementType, feMesh, elementCoordIn, 
+									   globalCoord, elLocalCoord );
 		}
 
 		StGermain_VectorSubtraction( errorVector, elLocalCoordGeneral, elLocalCoord, context->dim );
 
 		error += StGermain_VectorMagnitude( errorVector, context->dim );
-
-		Memory_Free( globalNodeCoordPtrs );
 	}
 
 	Journal_PrintBool( stream, error < tolerance );
 	
 	/* Destroy stuff */
 	Stg_Class_Delete( feMesh );
-	Stg_Class_Delete( elementType_Register );
 	Stg_Class_Delete( extensionMgr_Register );
-	Stg_Class_Delete( meshLayout );
-	Stg_Class_Delete( decomp );
-	Stg_Class_Delete( nLayout );
-	Stg_Class_Delete( eLayout );
-	Stg_Class_Delete( nTopology );
 	Stg_Class_Delete( dictionary );
 	
 	StgFEM_Discretisation_Finalise();

Deleted: long/3D/Gale/trunk/src/StgFEM/Discretisation/tests/testFeEquationNumber-LM.c
===================================================================
--- long/3D/Gale/trunk/src/StgFEM/Discretisation/tests/testFeEquationNumber-LM.c	2006-12-07 23:26:14 UTC (rev 5532)
+++ long/3D/Gale/trunk/src/StgFEM/Discretisation/tests/testFeEquationNumber-LM.c	2006-12-07 23:29:43 UTC (rev 5533)
@@ -1,401 +0,0 @@
-/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-**
-** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
-**	Melbourne, 3053, Australia.
-**
-** Primary Contributing Organisations:
-**	Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
-**	Australian Computational Earth Systems Simulator - http://www.access.edu.au
-**	Monash Cluster Computing - http://www.mcc.monash.edu.au
-**	Computational Infrastructure for Geodynamics - http://www.geodynamics.org
-**
-** Contributors:
-**	Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
-**	Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
-**	Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
-**	David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
-**	Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
-**	Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
-**	Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
-**	Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
-**	Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
-**	Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
-**
-**  This library is free software; you can redistribute it and/or
-**  modify it under the terms of the GNU Lesser General Public
-**  License as published by the Free Software Foundation; either
-**  version 2.1 of the License, or (at your option) any later version.
-**
-**  This library 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
-**  Lesser General Public License for more details.
-**
-**  You should have received a copy of the GNU Lesser General Public
-**  License along with this library; if not, write to the Free Software
-**  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-**
-** $Id$
-**
-**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
-
-#include <mpi.h>
-#include <StGermain/StGermain.h>
-#include "StgFEM/Discretisation/Discretisation.h"
-#include <string.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <petsc.h>
-
-struct _Node {
-	Coord coord;
-	double temp;
-};
-
-struct _Element {
-	__FiniteElement_Element
-};
-
-struct _Particle {
-	Coord coord;
-};
-
-
-void Test_FeEquationNumberRun_Regular( Dictionary* dictionary, const char* nLayoutType, IJK elSizes, Partition_Index rank, Partition_Index procToWatch );
-void Test_FeEquationNumberRun_Irregular( Dictionary* dictionary, const char* nLayoutType, Partition_Index rank,
-Partition_Index procToWatch );
-void Test_FeEquationNumberRun_Core( Dictionary* dictionary, MeshLayout* meshLayout, Partition_Index rank,
-Partition_Index procToWatch );
-
-
-int main( int argc, char* argv[] ) {
-	MPI_Comm			CommWorld;
-	int				rank;
-	int				numProcessors;
-	int				procToWatch;
-	Dictionary*			dictionary;
-	Dictionary_Entry_Value*		setBC;
-	Dictionary_Entry_Value*		wallBC;
-	Dictionary_Entry_Value*		variablesList;
-	Dictionary_Entry_Value*		xVariable;
-	Dictionary_Entry_Value*		indicesList;
-	XML_IO_Handler*			geomIO_Handler;
-	Index					elSizes[3];
-	Stream* 				feDebugStream;
-	#if 0
-	JournalFile*			file;
-	#endif
-	
-	/* Initialise MPI, get world info */
-	MPI_Init( &argc, &argv );
-	MPI_Comm_dup( MPI_COMM_WORLD, &CommWorld );
-	MPI_Comm_size( CommWorld, &numProcessors );
-	MPI_Comm_rank( CommWorld, &rank );
-	
-	StGermain_Init( &argc, &argv );
-	StgFEM_Discretisation_Init( &argc, &argv );
-	MPI_Barrier( CommWorld ); /* Ensures copyright info always come first in output */
-
-	Journal_Enable_TypedStream( DebugStream_Type, False );
-	feDebugStream = Journal_Register( DebugStream_Type, "StgFEM" );
-	Stream_SetLevelBranch( feDebugStream, 2 );
-	Stream_EnableBranch( feDebugStream, True );
-	#if 0
-	Stream_SetLevelBranch( feDebugStream, 1 );
-	Stream_Enable( feDebugStream, True );
-	Stream_EnableBranch( Journal_Register( DebugStream_Type, "StgFEM.StgFEM_Discretisation" ), True );
-	file = CFile_New();
-	if ( JournalFile_Open( file, "debugInfo" ) )
-	{
-		Journal_RegisterFile( file );
-	}
-	Stream_SetFile( Journal_GetTypedStream( DebugStream_Type ), file );
-	Stream_SetFile( feDebugStream, file );
-	Stream_SetFile( Journal_Register( DebugStream_Type, "StgFEM.StgFEM_Discretisation.FeEquationNumber" ), file );
-	Stream_SetFile( Journal_Register( DebugStream_Type, "StgFEM.StgFEM_Discretisation.FeEquationNumber.LM" ), file );
-	#endif
-	
-	if( argc >= 2 ) {
-		procToWatch = atoi( argv[1] );
-	}
-	else {
-		procToWatch = 0;
-	}
-	if( rank == procToWatch ) printf( "Watching rank: %i\n", rank );
-	
-	/* Read input */
-	dictionary = Dictionary_New();
-	geomIO_Handler = XML_IO_Handler_New();
-	IO_Handler_ReadAllFromFile( geomIO_Handler, "data/triMeshAndBCs.xml", dictionary );
-	Dictionary_Add( dictionary, "rank", Dictionary_Entry_Value_FromUnsignedInt( rank ) );
-	Dictionary_Add( dictionary, "numProcessors", Dictionary_Entry_Value_FromUnsignedInt( numProcessors ) );
-	Dictionary_Add( dictionary, "minX", Dictionary_Entry_Value_FromDouble( 0.0f ) );
-	Dictionary_Add( dictionary, "minY", Dictionary_Entry_Value_FromDouble( 0.0f ) );
-	Dictionary_Add( dictionary, "minZ", Dictionary_Entry_Value_FromDouble( 0.0f ) );
-	Dictionary_Add( dictionary, "maxX", Dictionary_Entry_Value_FromDouble( 300.0f ) );
-	Dictionary_Add( dictionary, "maxY", Dictionary_Entry_Value_FromDouble( 12.0f ) );
-	Dictionary_Add( dictionary, "maxZ", Dictionary_Entry_Value_FromDouble( 300.0f ) );
-	Dictionary_Add( dictionary, "allowPartitionOnElement", Dictionary_Entry_Value_FromBool( False ) );
-	Dictionary_Add( dictionary, "allowUnbalancing", Dictionary_Entry_Value_FromBool( True ) );
-	Dictionary_Add( dictionary, "buildElementNodeTbl", Dictionary_Entry_Value_FromBool( True ) );
-	
-	wallBC = Dictionary_Entry_Value_NewStruct();
-	Dictionary_Add( dictionary, "wallBC", wallBC );
-	Dictionary_Entry_Value_AddMember( wallBC, "type", Dictionary_Entry_Value_FromString( "WallVC" ) );
-	Dictionary_Entry_Value_AddMember( wallBC, "wall", Dictionary_Entry_Value_FromString( "left" ) );
-	variablesList = Dictionary_Entry_Value_NewList();
-	Dictionary_Entry_Value_AddMember( wallBC, "variables", variablesList );
-	xVariable = Dictionary_Entry_Value_NewStruct();
-	Dictionary_Entry_Value_AddElement( variablesList, xVariable );
-	Dictionary_Entry_Value_AddMember( xVariable, "name", Dictionary_Entry_Value_FromString( "x" ) );
-	Dictionary_Entry_Value_AddMember( xVariable, "type", Dictionary_Entry_Value_FromString( "double" ) );
-	Dictionary_Entry_Value_AddMember( xVariable, "value", Dictionary_Entry_Value_FromDouble( -1.0f ) );
-
-	setBC = Dictionary_Entry_Value_NewStruct();
-	Dictionary_Add( dictionary, "setBC", setBC );
-	Dictionary_Entry_Value_AddMember( setBC, "type", Dictionary_Entry_Value_FromString( "SetVC" ) );
-	Dictionary_Entry_Value_AddMember( setBC, "indexCount", Dictionary_Entry_Value_FromUnsignedInt( 16 ) );
-	indicesList = Dictionary_Entry_Value_NewList();
-	Dictionary_Entry_Value_AddMember( setBC, "indices", indicesList );
-	Dictionary_Entry_Value_AddElement( indicesList, Dictionary_Entry_Value_FromUnsignedInt( 0 ) );
-	Dictionary_Entry_Value_AddElement( indicesList, Dictionary_Entry_Value_FromUnsignedInt( 3 ) );
-	Dictionary_Entry_Value_AddElement( indicesList, Dictionary_Entry_Value_FromUnsignedInt( 4 ) );
-	Dictionary_Entry_Value_AddElement( indicesList, Dictionary_Entry_Value_FromUnsignedInt( 10 ) );
-	Dictionary_Entry_Value_AddElement( indicesList, Dictionary_Entry_Value_FromUnsignedInt( 11 ) );
-	Dictionary_Entry_Value_AddElement( indicesList, Dictionary_Entry_Value_FromUnsignedInt( 12 ) );
-	variablesList = Dictionary_Entry_Value_NewList();
-	Dictionary_Entry_Value_AddMember( setBC, "variables", variablesList );
-	xVariable = Dictionary_Entry_Value_NewStruct();
-	Dictionary_Entry_Value_AddElement( variablesList, xVariable );
-	Dictionary_Entry_Value_AddMember( xVariable, "name", Dictionary_Entry_Value_FromString( "x" ) );
-	Dictionary_Entry_Value_AddMember( xVariable, "type", Dictionary_Entry_Value_FromString( "double" ) );
-	Dictionary_Entry_Value_AddMember( xVariable, "value", Dictionary_Entry_Value_FromDouble( -1.0f ) );
-
-	Dictionary_Add( dictionary, "meshSizeI", Dictionary_Entry_Value_FromUnsignedInt( 0 ) );
-	Dictionary_Add( dictionary, "meshSizeJ", Dictionary_Entry_Value_FromUnsignedInt( 0 ) );
-	Dictionary_Add( dictionary, "meshSizeK", Dictionary_Entry_Value_FromUnsignedInt( 0 ) );
-
-	if( rank == procToWatch ) printf( "\n***  REGULAR node/element layout tests ***\n" );
-
-	if( rank == procToWatch ) printf( "\n***  Corner Node layout tests ***\n" );
-	if( rank == procToWatch ) printf( "\n***  Balanced: 6*1*1 elements ***\n" );
-	elSizes[I_AXIS] = 6; elSizes[J_AXIS] = 1; elSizes[K_AXIS] = 1;
-	Test_FeEquationNumberRun_Regular( dictionary, "corner", elSizes, rank, procToWatch );
-	if( rank == procToWatch ) printf( "\n***  Unbalanced: 7*1*1 elements ***\n" );
-	elSizes[I_AXIS] = 7; elSizes[J_AXIS] = 1; elSizes[K_AXIS] = 1;
-	Test_FeEquationNumberRun_Regular( dictionary, "corner", elSizes, rank, procToWatch );
-
-	if( rank == procToWatch ) printf( "\n\n***  Body (Pressure) Node layout tests ***\n" );
-	if( rank == procToWatch ) printf( "\n***  Balanced: 6*1*1 elements ***\n" );
-	elSizes[I_AXIS] = 6; elSizes[J_AXIS] = 1; elSizes[K_AXIS] = 1;
-	Test_FeEquationNumberRun_Regular( dictionary, "body", elSizes, rank, procToWatch );
-	if( rank == procToWatch ) printf( "\n***  Unbalanced: 7*1*1 elements ***\n" );
-	elSizes[I_AXIS] = 7; elSizes[J_AXIS] = 1; elSizes[K_AXIS] = 1;
-	Test_FeEquationNumberRun_Regular( dictionary, "body", elSizes, rank, procToWatch );
-
-	/* TODO: once parallel irregular decomps available, improve this */
-	if (numProcessors == 1) {
-		if( rank == procToWatch ) printf( "\n***  IRREGULAR node/element layout tests ***\n" );
-		Test_FeEquationNumberRun_Irregular( dictionary, "corner", rank, procToWatch );
-	}
-
-
-	Stg_Class_Delete( dictionary );
-	Stg_Class_Delete( geomIO_Handler );
-	//if( rank == procToWatch ) Memory_Print();
-
-	StgFEM_Discretisation_Finalise();
-	StGermain_Finalise();
-
-	/* Close off MPI */
-	MPI_Finalize();
-	
-	return 0; /* success */
-}
-
-
-void Test_FeEquationNumberRun_Regular( Dictionary* dictionary, const char* nLayoutType, IJK elSizes,
-	Partition_Index rank, Partition_Index procToWatch )
-{
-	Topology*			nTopology;
-	ElementLayout*			eLayout;
-	NodeLayout*			nLayout;
-	MeshDecomp*			decomp;
-	MeshLayout*			meshLayout;
-
-	if( rank == procToWatch ) printf("Creating Geometry, Decomps and Layouts:\n");
-	Dictionary_Set( dictionary, "meshSizeI", Dictionary_Entry_Value_FromUnsignedInt( elSizes[0]+1 ) );
-	Dictionary_Set( dictionary, "meshSizeJ", Dictionary_Entry_Value_FromUnsignedInt( elSizes[1]+1 ) );
-	Dictionary_Set( dictionary, "meshSizeK", Dictionary_Entry_Value_FromUnsignedInt( elSizes[2]+1 ) );
-	/* create the layout, dof and mesh to use */
-	eLayout = (ElementLayout*)ParallelPipedHexaEL_New( "PPHexaEL", 3, dictionary );
-	if ("corner" == nLayoutType) {
-		nTopology = (Topology*)IJK6Topology_New( "IJK6Topology", dictionary );
-		nLayout = (NodeLayout*)CornerNL_New( "CornerNL", dictionary, eLayout, nTopology );
-	}
-	else {
-		/* TODO: This is a temporary issue with the body mesh stuff. */
-		Dictionary_Set( dictionary, "meshSizeI", Dictionary_Entry_Value_FromUnsignedInt( elSizes[0] ) );
-		Dictionary_Set( dictionary, "meshSizeJ", Dictionary_Entry_Value_FromUnsignedInt( elSizes[1] ) );
-		Dictionary_Set( dictionary, "meshSizeK", Dictionary_Entry_Value_FromUnsignedInt( elSizes[2] ) );
-		nTopology = (Topology*)IJK6Topology_New( "IJK6Topology", dictionary );
-		nLayout = (NodeLayout*)BodyNL_New( "BodyNL", dictionary, eLayout, nTopology );
-	}
-	decomp = (MeshDecomp*)HexaMD_New( "HexaMD", dictionary, MPI_COMM_WORLD, eLayout, nLayout );
-	meshLayout = MeshLayout_New( "MeshLayout", eLayout, nLayout, decomp );
-	Test_FeEquationNumberRun_Core( dictionary, meshLayout, rank, procToWatch );
-
-	Stg_Class_Delete( meshLayout );
-	Stg_Class_Delete( decomp );
-	Stg_Class_Delete( nLayout );
-	Stg_Class_Delete( eLayout );
-	Stg_Class_Delete( nTopology );
-}	
-
-
-void Test_FeEquationNumberRun_Irregular( Dictionary* dictionary, const char* nLayoutType, Partition_Index rank, Partition_Index procToWatch ) {
-	Topology*			eTopology;
-	Topology*			nTopology;
-	ElementLayout*		eLayout;
-	Geometry*			geometry = NULL; 
-	NodeLayout*			nLayout;
-	MeshDecomp*			decomp;
-	MeshLayout*			meshLayout;
-
-	if( rank == procToWatch ) printf("Creating Geometry, Decomps and Layouts:\n");
-
-	eTopology = (Topology*)IrregTopology_New( "elementIrregTopology", dictionary, "imElementNeighbours" );
-	nTopology = (Topology*)IrregTopology_New( "nodeIrregTopology", dictionary, "imNodeNeighbours" );
-	geometry = (Geometry*)IrregGeometry_New( "irregGeometry", dictionary, "imGeometry" );
-
-	eLayout = (ElementLayout*)IrregEL_New( "IrregEL", dictionary, geometry, eTopology, "imElements" );
-	if ( 0 == strcmp( "corner", nLayoutType) ) {
-		nLayout = (NodeLayout*)CornerNL_New( "CornerNL", dictionary, eLayout, nTopology );
-	}
-	else {
-		nLayout = (NodeLayout*)BodyNL_New( "BodyNL", dictionary, eLayout, nTopology );
-	}
-	decomp = (MeshDecomp*)DummyMD_New( "DummyMD", dictionary, MPI_COMM_WORLD, eLayout, nLayout );
-	meshLayout = MeshLayout_New( "MeshLayout", eLayout, nLayout, decomp );
-	Test_FeEquationNumberRun_Core( dictionary, meshLayout, rank, procToWatch );
-
-	Stg_Class_Delete( eTopology );
-	Stg_Class_Delete( geometry );
-	Stg_Class_Delete( meshLayout );
-	Stg_Class_Delete( decomp );
-	Stg_Class_Delete( nLayout );
-	Stg_Class_Delete( eLayout );
-	Stg_Class_Delete( nTopology );
-}	
-
-
-void Test_FeEquationNumberRun_Core( Dictionary* dictionary, MeshLayout* meshLayout, Partition_Index rank, Partition_Index procToWatch ) {
-	ElementType_Register*		elementType_Register;
-	ExtensionManager_Register*		extensionMgr_Register;
-	FiniteElement_Mesh*		feMesh;
-	VariableCondition*		vc;
-	FeEquationNumber*		feEquationNumber;
-	char*				varNames[] = {"x", "y", "z"};
-	Index				i, j;
-	Node_GlobalIndex		nodeCount;
-	Index				numVars = 3;
-	Variable_Register*		variableRegister;
-	DofLayout*			dofs;
-	Stream*				stream;
-
-	stream = Journal_Register (Info_Type, "myStream");
-
-	extensionMgr_Register = ExtensionManager_Register_New();
-	elementType_Register = ElementType_Register_New("elementTypeRegister");
-	ElementType_Register_Add( elementType_Register, (ElementType*)ConstantElementType_New("constant") );
-	ElementType_Register_Add( elementType_Register, (ElementType*)BilinearElementType_New("bilinear") );
-	ElementType_Register_Add( elementType_Register, (ElementType*)TrilinearElementType_New("trilinear") );
-	ElementType_Register_Add( elementType_Register, (ElementType*)LinearTriangleElementType_New("linear") );
-	if( rank == procToWatch ) printf("Creating F.E. Mesh:\n");
-	feMesh = FiniteElement_Mesh_New( "testMesh", meshLayout, sizeof(Node), sizeof(Element), extensionMgr_Register,
-		elementType_Register, dictionary );
-	
-	/* Create variable register */
-	variableRegister = Variable_Register_New();
-	
-	/* Create variables */
-	if( rank == procToWatch ) printf("Creating Vars:\n");
-	Variable_NewVector( 
-		"coords", 
-		Variable_DataType_Double, 
-		3, 
-		&feMesh->nodeLocalCount, 
-		(void**)&feMesh->nodeCoord, 
-		variableRegister, 
-		varNames[0], 
-		varNames[1], 
-		varNames[2] );
-
-
-	nodeCount = feMesh->layout->decomp->nodeLocalCount;
-	dofs = DofLayout_New( "dofLayout", variableRegister, nodeCount );
-
-	for (i = 0; i < nodeCount; i++)
-	{
-		for (j = 0; j < numVars; j++) {
-			DofLayout_AddDof_ByVarName(dofs, varNames[j], i);
-		}
-	}
-	Build(dofs, 0, False);
-	
-	if( rank == procToWatch ) printf("Creating VC:\n");
-	if ( IrregEL_Type == meshLayout->elementLayout->type) {
-		vc = (VariableCondition*) SetVC_New( "SetVC", "setBC", variableRegister, NULL, dictionary );
-	}
-	else {
-		vc = (VariableCondition*) WallVC_New( "WallVC", "wallBC", variableRegister, NULL, dictionary, feMesh );
-	}
-	
-	if( rank == procToWatch ) printf("Creating EQ num:\n");
-	/* Create the finite element equation number utility */
-	feEquationNumber = FeEquationNumber_New( "feEquationNumber", feMesh, dofs, vc, NULL );
-	
-	
-	if( rank == procToWatch ) printf("Building:\n");
-	/* Build and initialise system */
-	if( rank == procToWatch ) printf("Building mesh:\n");
-	Build( feMesh, 0, False );
-	if( rank == procToWatch ) printf("Building Variable Conditions:\n");
-	Build( vc, 0, False );
-	if( rank == procToWatch ) printf("Building FE Eq num:\n");
-	FeEquationNumber_Build( feEquationNumber );
-	
-	if( rank == procToWatch ) printf("Initialising:\n");
-	Initialise( feMesh, 0, False );
-	FeEquationNumber_Initialise( feEquationNumber );
-	
-	if( rank == procToWatch ) printf("Building LM:\n");
-	FeEquationNumber_BuildLocationMatrix( feEquationNumber );
-	
-	if( rank == procToWatch ) {
-		Node_LocalIndex		lNode_I = 0;
-		Dof_EquationNumber	lowestActiveEqNumAtNode;
-	
-		Journal_Printf( stream, "V.C. applied: " );
-		VariableCondition_PrintConcise( vc, stream );
-		FeEquationNumber_PrintDestinationArray( feEquationNumber, stream );
-		FeEquationNumber_PrintLocationMatrix( feEquationNumber, stream );
-		Journal_Printf( stream, "Printing the counts of active EQ nums at each node:\n" );
-		for ( lNode_I=0; lNode_I < feMesh->nodeLocalCount; lNode_I++ ) {
-			Journal_Printf( stream, "\tNode %d: %d active dofs\n", lNode_I,
-				FeEquationNumber_CalculateActiveEqCountAtNode( feEquationNumber, lNode_I,
-				&lowestActiveEqNumAtNode ) );
-		}
-	}
-	
-	
-	/* Destroy stuff */
-	if( rank == procToWatch ) printf("Cleaning Up:\n");
-	Stg_Class_Delete( feEquationNumber );
-	Stg_Class_Delete( vc );
-	Stg_Class_Delete( feMesh );
-	Stg_Class_Delete( extensionMgr_Register );
-	Stg_Class_Delete( elementType_Register );
-	Stg_Class_Delete( variableRegister );
-	Stg_Class_Delete( dofs );
-}

Modified: long/3D/Gale/trunk/src/StgFEM/Discretisation/tests/testFeEquationNumber-LinkedDofs.c
===================================================================
--- long/3D/Gale/trunk/src/StgFEM/Discretisation/tests/testFeEquationNumber-LinkedDofs.c	2006-12-07 23:26:14 UTC (rev 5532)
+++ long/3D/Gale/trunk/src/StgFEM/Discretisation/tests/testFeEquationNumber-LinkedDofs.c	2006-12-07 23:29:43 UTC (rev 5533)
@@ -66,6 +66,7 @@
 void Test_FeEquationNumberRun_Regular( Dictionary* dictionary, void* context, const char* nLayoutType, IJK elSizes, Partition_Index rank, Partition_Index procToWatch );
 
 int main( int argc, char* argv[] ) {
+#if 0
 	MPI_Comm			CommWorld;
 	int				rank;
 	int				numProcessors;
@@ -323,4 +324,5 @@
 	Stg_Class_Delete( nLayout );
 	Stg_Class_Delete( eLayout );
 	Stg_Class_Delete( nTopology );
+#endif
 }

Modified: long/3D/Gale/trunk/src/StgFEM/Discretisation/tests/testFeEquationNumber-LinkedDofs2.c
===================================================================
--- long/3D/Gale/trunk/src/StgFEM/Discretisation/tests/testFeEquationNumber-LinkedDofs2.c	2006-12-07 23:26:14 UTC (rev 5532)
+++ long/3D/Gale/trunk/src/StgFEM/Discretisation/tests/testFeEquationNumber-LinkedDofs2.c	2006-12-07 23:29:43 UTC (rev 5533)
@@ -64,6 +64,7 @@
 void Test_FeEquationNumberRun_Regular( Dictionary* dictionary, const char* nLayoutType, IJK elSizes, Partition_Index rank, Partition_Index procToWatch );
 
 int main( int argc, char* argv[] ) {
+#if 0
 	MPI_Comm			CommWorld;
 	int				rank;
 	int				numProcessors;
@@ -319,4 +320,5 @@
 	Stg_Class_Delete( nLayout );
 	Stg_Class_Delete( eLayout );
 	Stg_Class_Delete( nTopology );
+#endif
 }	

Added: long/3D/Gale/trunk/src/StgFEM/Discretisation/tests/testFeEquationNumber.c
===================================================================
--- long/3D/Gale/trunk/src/StgFEM/Discretisation/tests/testFeEquationNumber.c	2006-12-07 23:26:14 UTC (rev 5532)
+++ long/3D/Gale/trunk/src/StgFEM/Discretisation/tests/testFeEquationNumber.c	2006-12-07 23:29:43 UTC (rev 5533)
@@ -0,0 +1,369 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+**
+** Copyright (C), 2003, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street, Melbourne, 3053, Australia.
+**
+** Authors:
+**	Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
+**	Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
+**	Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
+**	Siew-Ching Tan, Software Engineer, VPAC. (siew at vpac.org)
+**	Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
+**	Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
+**
+**  This library is free software; you can redistribute it and/or
+**  modify it under the terms of the GNU Lesser General Public
+**  License as published by the Free Software Foundation; either
+**  version 2.1 of the License, or (at your option) any later version.
+**
+**  This library 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
+**  Lesser General Public License for more details.
+**
+**  You should have received a copy of the GNU Lesser General Public
+**  License along with this library; if not, write to the Free Software
+**  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+**
+** $Id$
+**
+**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <mpi.h>
+#include <mpi.h>
+
+#include "StGermain/StGermain.h"
+#include "Discretisation/Discretisation.h"
+
+
+FeEquationNumber* buildEqNum( unsigned nProcs ) {
+	CartesianGenerator*	gen;
+	FeMesh*			feMesh;
+	DofLayout*		dofs;
+	FeEquationNumber*	eqNum;
+	Variable_Register*	varReg;
+	Variable*		vars[2];
+	unsigned		maxDecomp[3] = {0, 1, 1};
+	unsigned		sizes[3];
+	double			minCrd[3];
+	double			maxCrd[3];
+	SizeT			dataOffs = 1;
+	Variable_DataType	dataType = Variable_DataType_Double;
+	unsigned		nDataTypes = 1;
+	char*			dataNames = "nothing";
+	static SizeT		structSize = sizeof(double);
+	static unsigned		arraySize;
+	static void*		arrayPtrs[2];
+
+	sizes[0] = nProcs * 2;
+	sizes[1] = sizes[2] = 2;
+	minCrd[0] = minCrd[1] = minCrd[2] = 0.0;
+	maxCrd[0] = maxCrd[1] = maxCrd[2] = (double)nProcs;
+
+	gen = CartesianGenerator_New( "" );
+	CartesianGenerator_SetTopologyParams( gen, 3, sizes, 0, NULL, maxDecomp );
+	CartesianGenerator_SetGeometryParams( gen, minCrd, maxCrd );
+	CartesianGenerator_SetShadowDepth( gen, 0 );
+
+	feMesh = FeMesh_New( "" );
+	Mesh_SetGenerator( feMesh, gen );
+	FeMesh_SetElementFamily( feMesh, "linear" );
+	Build( feMesh, NULL, False );
+
+	varReg = Variable_Register_New();
+
+	arraySize = Mesh_GetDomainSize( feMesh, MT_VERTEX );
+	arrayPtrs[0] = Memory_Alloc_Array_Unnamed( double, arraySize );
+	arrayPtrs[1] = Memory_Alloc_Array_Unnamed( double, arraySize );
+	vars[0] = Variable_New( "one", 1, &dataOffs, &dataType, &nDataTypes, &dataNames, 
+				&structSize, &arraySize, arrayPtrs, varReg );
+	vars[1] = Variable_New( "two", 1, &dataOffs, &dataType, &nDataTypes, &dataNames, 
+				&structSize, &arraySize, arrayPtrs + 1, varReg );
+
+	dofs = DofLayout_New( "", varReg, 0, feMesh );
+	dofs->nBaseVariables = 2;
+	dofs->baseVariables = Memory_Alloc_Array_Unnamed( Variable*, 2 );
+	dofs->baseVariables[0] = vars[0];
+	dofs->baseVariables[1] = vars[1];
+	Build( dofs, NULL, False );
+	Initialise( dofs, NULL, False );
+
+	eqNum = FeEquationNumber_New( "", feMesh, dofs, NULL, NULL );
+	Build( eqNum, NULL, False );
+	Initialise( eqNum, NULL, False );
+
+	return eqNum;
+}
+
+FeEquationNumber* buildEqNumWithBCs( unsigned nProcs ) {
+	CartesianGenerator*		gen;
+	FeMesh*				feMesh;
+	DofLayout*			dofs;
+	FeEquationNumber*		eqNum;
+	VariableCondition*		bcs;
+	Variable_Register*		varReg;
+	ConditionFunction_Register*	cfReg;
+	Variable*			vars[2];
+	unsigned			maxDecomp[3] = {0, 1, 1};
+	unsigned			sizes[3];
+	double				minCrd[3];
+	double				maxCrd[3];
+	SizeT				dataOffs = 1;
+	Variable_DataType		dataType = Variable_DataType_Double;
+	unsigned			nDataTypes = 1;
+	char*				dataNames = "nothing";
+	static SizeT			structSize = sizeof(double);
+	static unsigned			arraySize;
+	static void*			arrayPtrs[2];
+	Dictionary*			dict;
+	XML_IO_Handler*			ioHandler;
+
+	sizes[0] = nProcs * 2;
+	sizes[1] = sizes[2] = 2;
+	minCrd[0] = minCrd[1] = minCrd[2] = 0.0;
+	maxCrd[0] = maxCrd[1] = maxCrd[2] = (double)nProcs;
+
+	gen = CartesianGenerator_New( "" );
+	CartesianGenerator_SetTopologyParams( gen, 3, sizes, 0, NULL, maxDecomp );
+	CartesianGenerator_SetGeometryParams( gen, minCrd, maxCrd );
+	CartesianGenerator_SetShadowDepth( gen, 0 );
+
+	feMesh = FeMesh_New( "" );
+	Mesh_SetGenerator( feMesh, gen );
+	FeMesh_SetElementFamily( feMesh, "linear" );
+	Build( feMesh, NULL, False );
+
+	varReg = Variable_Register_New();
+	cfReg = ConditionFunction_Register_New();
+
+	arraySize = Mesh_GetDomainSize( feMesh, MT_VERTEX );
+	arrayPtrs[0] = Memory_Alloc_Array_Unnamed( double, arraySize );
+	arrayPtrs[1] = Memory_Alloc_Array_Unnamed( double, arraySize );
+	vars[0] = Variable_New( "one", 1, &dataOffs, &dataType, &nDataTypes, &dataNames, 
+				&structSize, &arraySize, arrayPtrs, varReg );
+	vars[1] = Variable_New( "two", 1, &dataOffs, &dataType, &nDataTypes, &dataNames, 
+				&structSize, &arraySize, arrayPtrs + 1, varReg );
+
+	dofs = DofLayout_New( "", varReg, 0, feMesh );
+	dofs->nBaseVariables = 2;
+	dofs->baseVariables = Memory_Alloc_Array_Unnamed( Variable*, 2 );
+	dofs->baseVariables[0] = vars[0];
+	dofs->baseVariables[1] = vars[1];
+	Build( dofs, NULL, False );
+	Initialise( dofs, NULL, False );
+
+	ioHandler = XML_IO_Handler_New();
+	dict = Dictionary_New();
+	IO_Handler_ReadAllFromFile( ioHandler, "data/wallVC.xml", dict );
+	bcs = (VariableCondition*)WallVC_New( "", "wallVC", varReg, cfReg, dict, feMesh );
+	Build( bcs, NULL, False );
+	Initialise( bcs, NULL, False );
+
+	eqNum = FeEquationNumber_New( "", feMesh, dofs, bcs, NULL );
+	Build( eqNum, NULL, False );
+	Initialise( eqNum, NULL, False );
+
+	return eqNum;
+}
+
+
+Bool testLocalDstArray( unsigned rank, unsigned nProcs, unsigned watch ) {
+	Bool			result = True;
+	FeEquationNumber*	eqNum;
+
+	eqNum = buildEqNum( nProcs );
+
+	if( rank == watch ) {
+		FeMesh*		feMesh;
+		unsigned	eqNumsPerProc;
+		unsigned	curEqNum;
+		unsigned	n_i;
+
+		feMesh = eqNum->feMesh;
+		eqNumsPerProc = (Mesh_GetDimSize( feMesh ) == 3) ? 27 :
+			(Mesh_GetDimSize( feMesh ) == 2) ? 9 :
+			3;
+		curEqNum = eqNumsPerProc * rank;
+		if( rank >= 1 )
+			curEqNum -= (eqNumsPerProc / 3) * (rank - 1);
+		curEqNum *= 2;
+
+		for( n_i = 0; n_i < Mesh_GetLocalSize( feMesh, MT_VERTEX ); n_i++ ) {
+			unsigned	nDofs;
+			unsigned	dof_i;
+
+			nDofs = eqNum->dofLayout->dofCounts[n_i];
+			for( dof_i = 0; dof_i < nDofs; dof_i++ ) {
+				if( eqNum->destinationArray[n_i][dof_i] != curEqNum++ ) {
+					result = False;
+					goto done;
+				}
+			}
+		}
+	}
+
+done:
+	FreeObject( eqNum );
+
+	return result;
+}
+
+Bool testShadowDstArray( unsigned rank, unsigned nProcs, unsigned watch ) {
+	Bool			result = True;
+	FeEquationNumber*	eqNum;
+
+	eqNum = buildEqNum( nProcs );
+
+	if( rank == watch ) {
+		FeMesh*		feMesh;
+		unsigned	nLocalNodes, nDomainNodes;
+		unsigned	eqNumsPerProc;
+		unsigned	curEqNum;
+		unsigned	n_i;
+
+		feMesh = eqNum->feMesh;
+		eqNumsPerProc = (Mesh_GetDimSize( feMesh ) == 3) ? 27 :
+			(Mesh_GetDimSize( feMesh ) == 2) ? 9 :
+			3;
+		if( rank >= 2 ) {
+			curEqNum = eqNumsPerProc;
+			curEqNum += 2 * (eqNumsPerProc / 3) * (rank - 2);
+			curEqNum += 1;
+		}
+		else if( rank == 1 )
+			curEqNum = 2;
+		curEqNum *= 2;
+
+		nLocalNodes = Mesh_GetLocalSize( feMesh, MT_VERTEX );
+		nDomainNodes = Mesh_GetDomainSize( feMesh, MT_VERTEX );
+		for( n_i = nLocalNodes; n_i < nDomainNodes; n_i++ ) {
+			unsigned	nDofs;
+			unsigned	dof_i;
+
+			nDofs = eqNum->dofLayout->dofCounts[n_i];
+			for( dof_i = 0; dof_i < nDofs; dof_i++ ) {
+				if( eqNum->destinationArray[n_i][dof_i] != curEqNum++ ) {
+					result = False;
+					goto done;
+				}
+			}
+
+			if( rank == 1 )
+				curEqNum += 4;
+			else
+				curEqNum += 2;
+		}
+	}
+
+done:
+	FreeObject( eqNum );
+
+	return result;
+}
+
+Bool testBCs( unsigned rank, unsigned nProcs, unsigned watch ) {
+	Bool			result = True;
+	FeEquationNumber*	eqNum;
+
+	eqNum = buildEqNumWithBCs( nProcs );
+
+	if( rank == watch ) {
+		FeMesh*		feMesh;
+		unsigned	nLocalNodes, nDomainNodes;
+		unsigned	eqNumsPerProc;
+		unsigned	curEqNum;
+		unsigned	n_i;
+
+		feMesh = eqNum->feMesh;
+		eqNumsPerProc = (Mesh_GetDimSize( feMesh ) == 3) ? 18 :
+			(Mesh_GetDimSize( feMesh ) == 2) ? 6 :
+			0;
+		if( rank >= 2 ) {
+			curEqNum = eqNumsPerProc;
+			curEqNum += 2 * (eqNumsPerProc / 3) * (rank - 2);
+			curEqNum += 1;
+		}
+		else if( rank == 1 )
+			curEqNum = 2;
+		curEqNum *= 2;
+
+		nLocalNodes = Mesh_GetLocalSize( feMesh, MT_VERTEX );
+		nDomainNodes = Mesh_GetDomainSize( feMesh, MT_VERTEX );
+		for( n_i = nLocalNodes; n_i < nDomainNodes; n_i++ ) {
+			unsigned	nDofs;
+			unsigned	dof_i;
+
+			nDofs = eqNum->dofLayout->dofCounts[n_i];
+			for( dof_i = 0; dof_i < nDofs; dof_i++ ) {
+				unsigned	eq;
+
+				eq = eqNum->destinationArray[n_i][dof_i];
+
+				if( n_i % 3 == 0 ) {
+					if( eq != (unsigned)-1 ) {
+						result = False;
+						goto done;
+					}
+				}
+				else if( eq != curEqNum++ ) {
+					result = False;
+					goto done;
+				}
+			}
+
+			if( n_i % 3 != 0 ) {
+				if( rank == 1 )
+					curEqNum += 4;
+				else
+					curEqNum += 2;
+			}
+		}
+	}
+
+done:
+	FreeObject( eqNum );
+
+	return result;
+}
+
+
+#define nTests	3
+
+TestSuite_Test	tests[nTests] = {{"test local destination array", testLocalDstArray, 1}, 
+				 {"test shadow destination array", testShadowDstArray, 1}, 
+				 {"test destination array with BCs", testBCs, 1}};
+
+
+int main( int argc, char* argv[] ) {
+	TestSuite*	suite;
+
+	/* Initialise MPI, get world info. */
+	MPI_Init( &argc, &argv );
+
+	/* Initialise StGermain. */
+	StGermain_Init( &argc, &argv );
+	StgFEM_Discretisation_Init( &argc, &argv );
+
+	/* Create the test suite. */
+	suite = TestSuite_New();
+	TestSuite_SetProcToWatch( suite, (argc >= 2) ? atoi( argv[1] ) : 0 );
+	TestSuite_SetTests( suite, nTests, tests );
+
+	/* Run the tests. */
+	TestSuite_Run( suite );
+
+	/* Destroy test suites. */
+	FreeObject( suite );
+
+	/* Finalise StGermain. */
+	BaseContainer_Finalise();
+	BaseIO_Finalise();
+	BaseFoundation_Finalise();
+
+	/* Close off MPI */
+	MPI_Finalize();
+
+	return MPI_SUCCESS;
+}


Property changes on: long/3D/Gale/trunk/src/StgFEM/Discretisation/tests/testFeEquationNumber.c
___________________________________________________________________
Name: svn:keywords
   + LastChangedDate Author Id
Name: svn:eol-style
   + native

Modified: long/3D/Gale/trunk/src/StgFEM/Discretisation/tests/testFeVariable-saveAndLoad.c
===================================================================
--- long/3D/Gale/trunk/src/StgFEM/Discretisation/tests/testFeVariable-saveAndLoad.c	2006-12-07 23:26:14 UTC (rev 5532)
+++ long/3D/Gale/trunk/src/StgFEM/Discretisation/tests/testFeVariable-saveAndLoad.c	2006-12-07 23:29:43 UTC (rev 5533)
@@ -60,6 +60,7 @@
 };
 
 int main( int argc, char* argv[] ) {
+#if 0
 	MPI_Comm			CommWorld;
 	int				rank;
 	int				numProcessors;
@@ -255,4 +256,5 @@
 	MPI_Finalize();
 	
 	return 0; /* success */
+#endif
 }

Modified: long/3D/Gale/trunk/src/StgFEM/Discretisation/tests/testFeVariable-shadowing.c
===================================================================
--- long/3D/Gale/trunk/src/StgFEM/Discretisation/tests/testFeVariable-shadowing.c	2006-12-07 23:26:14 UTC (rev 5532)
+++ long/3D/Gale/trunk/src/StgFEM/Discretisation/tests/testFeVariable-shadowing.c	2006-12-07 23:29:43 UTC (rev 5533)
@@ -60,6 +60,7 @@
 };
 
 int main( int argc, char* argv[] ) {
+#if 0
 	MPI_Comm			CommWorld;
 	int				rank;
 	int				numProcessors;
@@ -261,4 +262,5 @@
 	MPI_Finalize();
 	
 	return 0; /* success */
+#endif
 }

Modified: long/3D/Gale/trunk/src/StgFEM/Discretisation/tests/testFeVariable.c
===================================================================
--- long/3D/Gale/trunk/src/StgFEM/Discretisation/tests/testFeVariable.c	2006-12-07 23:26:14 UTC (rev 5532)
+++ long/3D/Gale/trunk/src/StgFEM/Discretisation/tests/testFeVariable.c	2006-12-07 23:29:43 UTC (rev 5533)
@@ -60,6 +60,7 @@
 };
 
 int main( int argc, char* argv[] ) {
+#if 0
 	MPI_Comm			CommWorld;
 	int				rank;
 	int				numProcessors;
@@ -395,4 +396,5 @@
 	MPI_Finalize();
 	
 	return 0; /* success */
+#endif
 }

Modified: long/3D/Gale/trunk/src/StgFEM/Discretisation/tests/testIntegration.c
===================================================================
--- long/3D/Gale/trunk/src/StgFEM/Discretisation/tests/testIntegration.c	2006-12-07 23:26:14 UTC (rev 5532)
+++ long/3D/Gale/trunk/src/StgFEM/Discretisation/tests/testIntegration.c	2006-12-07 23:29:43 UTC (rev 5533)
@@ -61,6 +61,7 @@
 };
 
 int main( int argc, char* argv[] ) {
+#if 0
 	MPI_Comm                   CommWorld;
 	int                        rank;
 	int                        numProcessors;
@@ -329,4 +330,5 @@
 	MPI_Finalize();
 	
 	return 0; /* success */
+#endif
 }

Modified: long/3D/Gale/trunk/src/StgFEM/Discretisation/tests/testTrilinearShapeFunc.c
===================================================================
--- long/3D/Gale/trunk/src/StgFEM/Discretisation/tests/testTrilinearShapeFunc.c	2006-12-07 23:26:14 UTC (rev 5532)
+++ long/3D/Gale/trunk/src/StgFEM/Discretisation/tests/testTrilinearShapeFunc.c	2006-12-07 23:29:43 UTC (rev 5533)
@@ -61,6 +61,7 @@
 };
 
 int main( int argc, char* argv[] ) {
+#if 0
 	MPI_Comm			CommWorld;
 	int				rank;
 	int				numProcessors;
@@ -293,4 +294,5 @@
 	MPI_Finalize();
 	
 	return 0; /* success */
+#endif
 }

Modified: long/3D/Gale/trunk/src/StgFEM/Discretisation/tests/testTrilinearShapeFuncLocalDerivs.c
===================================================================
--- long/3D/Gale/trunk/src/StgFEM/Discretisation/tests/testTrilinearShapeFuncLocalDerivs.c	2006-12-07 23:26:14 UTC (rev 5532)
+++ long/3D/Gale/trunk/src/StgFEM/Discretisation/tests/testTrilinearShapeFuncLocalDerivs.c	2006-12-07 23:29:43 UTC (rev 5533)
@@ -61,6 +61,7 @@
 };
 
 int main( int argc, char* argv[] ) {
+#if 0
 	MPI_Comm			CommWorld;
 	int				rank;
 	int				numProcessors;
@@ -269,4 +270,5 @@
 	MPI_Finalize();
 	
 	return 0; /* success */
+#endif
 }

Modified: long/3D/Gale/trunk/src/StgFEM/SLE/MultiGrid/src/MGCoarsener_RegCartesian.c
===================================================================
--- long/3D/Gale/trunk/src/StgFEM/SLE/MultiGrid/src/MGCoarsener_RegCartesian.c	2006-12-07 23:26:14 UTC (rev 5532)
+++ long/3D/Gale/trunk/src/StgFEM/SLE/MultiGrid/src/MGCoarsener_RegCartesian.c	2006-12-07 23:29:43 UTC (rev 5533)
@@ -206,9 +206,11 @@
 	IJK				newElSizes;
 	IJK				prevElSizes;
 	IJK				topElSizes;
-	IJK				dimMap;
 	unsigned			denom;
 	unsigned			nDims;
+	Mesh*				mesh;
+	Grid*				vertGrid;
+	unsigned			*localOrigin, *localRange;
 
 	void _MGCoarsener_RegCartesian_Coarsen3D( MGCoarsener_RegCartesian* self, 
 						  IJK newElSizes, IJK prevElSizes, 
@@ -223,13 +225,20 @@
 						  unsigned denom, 
 						  MGMapping* dstMap );
 
+	mesh = self->mesh;
+	nDims = Mesh_GetDimSize( mesh );
+	vertGrid = *(Grid**)ExtensionManager_Get( mesh->info, mesh, 
+						  ExtensionManager_GetHandle( mesh->info, "vertexGrid" ) );
+	localOrigin = (unsigned*)ExtensionManager_Get( mesh->info, mesh, 
+						       ExtensionManager_GetHandle( mesh->info, "localOrigin" ) );
+	localRange = (unsigned*)ExtensionManager_Get( mesh->info, mesh, 
+						      ExtensionManager_GetHandle( mesh->info, "localRange" ) );
 
 	/*
 	** Calculate the new dimensional element counts as well as a few other things.
 	*/
 	
 	{
-		HexaMD*		decomp = (HexaMD*)self->mesh->layout->decomp;
 		unsigned	el_k, el_j, el_i;
 		unsigned	dim_i;
 		
@@ -239,35 +248,45 @@
 			denom *= 2;
 		}
 
-		nDims = 0;
-		for( dim_i = 0; dim_i < 3; dim_i++ ) {
+		for( dim_i = 0; dim_i < nDims; dim_i++ ) {
 			div_t	res;
 
-			if( decomp->nodeGlobal3DCounts[dim_i] == 1 ) {
+			if( vertGrid->sizes[dim_i] == 1 ) {
 				newElSizes[dim_i] = 0;
 				prevElSizes[dim_i] = 0;
 				continue;
 			}
 			
-			res = div( decomp->elementLocal3DCounts[decomp->rank][dim_i], denom );
+			res = div( localRange[dim_i], denom );
 			assert( res.rem == 0 );
 			
 			newElSizes[dim_i] = res.quot;
 			prevElSizes[dim_i] = newElSizes[dim_i] * 2;
-			topElSizes[dim_i] = decomp->elementLocal3DCounts[decomp->rank][dim_i];
-			dimMap[nDims++] = dim_i;
+			topElSizes[dim_i] = localRange[dim_i];
 		}
 
+		if( nDims <= 2 ) {
+			newElSizes[2] = 0;
+			prevElSizes[2] = 0;
+			topElSizes[2] = 0;
+		}
+
+		if( nDims <= 1 ) {
+			newElSizes[1] = 0;
+			prevElSizes[1] = 0;
+			topElSizes[1] = 0;
+		}
+
 		/* Calc the number of coarse elements. */
 		dstMap->nEls = 1;
 		for( dim_i = 0; dim_i < nDims; dim_i++ ) {
-			dstMap->nEls *= newElSizes[dimMap[dim_i]];
+			dstMap->nEls *= newElSizes[dim_i];
 		}
 
 		/* ... and the number of coarse nodes. */
 		dstMap->nNodes = 1;
 		for( dim_i = 0; dim_i < nDims; dim_i++ ) {
-			dstMap->nNodes *= (newElSizes[dimMap[dim_i]] + 1);
+			dstMap->nNodes *= (newElSizes[dim_i] + 1);
 		}
 
 		/* Map the coarse nodes to top-level nodes. */
@@ -276,12 +295,17 @@
 			for( el_j = 0; el_j < (newElSizes[1] + 1); el_j++ ) {
 				for( el_i = 0; el_i < (newElSizes[0] + 1); el_i++ ) {
 					unsigned	ind;
+					unsigned	topInds[3];
 
 					ind = el_k * (newElSizes[1] + 1) * (newElSizes[0] + 1) + el_j * (newElSizes[0] + 1) + el_i;
-					dstMap->nodesTop[ind] = RegularMeshUtils_Node_Local3DTo1D( decomp, 
-												   el_i * denom, 
-												   el_j * denom, 
-												   el_k * denom );
+					topInds[0] = el_i * denom + localOrigin[0];
+					if( nDims >= 2 )
+						topInds[1] = el_j * denom + localOrigin[1];
+					if( nDims >= 3 )
+						topInds[2] = el_k * denom + localOrigin[2];
+					dstMap->nodesTop[ind] = RegularMeshUtils_Node_3DTo1D( mesh, topInds );
+					insist( Mesh_GlobalToDomain( mesh, MT_VERTEX, dstMap->nodesTop[ind], 
+								     dstMap->nodesTop + ind ) );
 				}
 			}
 		}
@@ -299,21 +323,14 @@
 						     dstMap );
 	}
 	else if( nDims == 2 ) {
-		IJK	newMappedSizes = { newElSizes[dimMap[0]], newElSizes[dimMap[1]], 0 };
-		IJK	prevMappedSizes = { prevElSizes[dimMap[0]], prevElSizes[dimMap[1]], 0 };
-		IJK	topMappedSizes = { topElSizes[dimMap[0]], topElSizes[dimMap[1]], 0 };
-
 		_MGCoarsener_RegCartesian_Coarsen2D( self, 
-						     newMappedSizes, prevMappedSizes, topMappedSizes, 
+						     newElSizes, prevElSizes, topElSizes, 
 						     denom, 
 						     dstMap );
 	}
 	else {
-		IJK	newMappedSizes = { newElSizes[dimMap[0]], 0, 0 };
-		IJK	prevMappedSizes = { prevElSizes[dimMap[0]], 0, 0 };
-
 		_MGCoarsener_RegCartesian_Coarsen1D( self, 
-						     newMappedSizes, prevMappedSizes, 
+						     newElSizes, prevElSizes, 
 						     denom, 
 						     dstMap );
 	}
@@ -325,7 +342,6 @@
 					  unsigned denom, 
 					  MGMapping* dstMap )
 {
-	HexaMD*		decomp = (HexaMD*)self->mesh->layout->decomp;
 	unsigned	el_i, el_j, el_k;
 	unsigned	node_i, node_j, node_k;
 

Modified: long/3D/Gale/trunk/src/StgFEM/SLE/ProvidedSystems/AdvectionDiffusion/src/AdvectionDiffusionSLE.c
===================================================================
--- long/3D/Gale/trunk/src/StgFEM/SLE/ProvidedSystems/AdvectionDiffusion/src/AdvectionDiffusionSLE.c	2006-12-07 23:26:14 UTC (rev 5532)
+++ long/3D/Gale/trunk/src/StgFEM/SLE/ProvidedSystems/AdvectionDiffusion/src/AdvectionDiffusionSLE.c	2006-12-07 23:29:43 UTC (rev 5533)
@@ -155,9 +155,6 @@
 		FieldVariable_Register*                            fieldVariable_Register )		
 {
 	AdvectionDiffusionSLE* self          = (AdvectionDiffusionSLE*)sle;
-	Variable*              variable;
-	unsigned int           *nodeDomainCountPtr;
-	Node_DomainIndex       node_I;
 
 	self->isConstructed = True;
 
@@ -187,35 +184,9 @@
 		SystemLinearEquations_AddStiffnessMatrix( self, massMatrix );
 	}
 
-	/* Create New FeVariable for Phi Dot */
-	if (phiField) {
-		nodeDomainCountPtr = &phiField->feMesh->layout->decomp->nodeDomainCount;
-		Variable_NewScalar( 
-			"phiDot", 
-			Variable_DataType_Double, 
-			nodeDomainCountPtr, 
-			(void**)&self->phiDotArray, 
-			variable_Register );
+	self->variableReg = variable_Register;
+	self->fieldVariableReg = fieldVariable_Register;
 
-		variable = Variable_Register_GetByName( variable_Register, "phiDot" );
-		self->phiDotDofLayout = DofLayout_New( "dofLayout1", variable_Register, *nodeDomainCountPtr );
-		for( node_I = 0; node_I < *nodeDomainCountPtr ; node_I++ ) 
-			DofLayout_AddDof_ByVarName( self->phiDotDofLayout, variable->name, node_I );
-
-		self->phiDotField = FeVariable_New_FromTemplate(
-			"phiDotField",
-			self->phiField,
-			self->phiDotDofLayout,
-			NULL,
-			self->phiField->importFormatType,
-			self->phiField->exportFormatType,
-			fieldVariable_Register );
-
-		/* Construct Solution Vectors */
-		self->phiVector    = SolutionVector_New( "PhiVector", phiField->communicator, phiField );
-		self->phiDotVector = SolutionVector_New( "PhiDotVector", phiField->communicator, self->phiDotField );
-	}
-
 	if ( self->context ) 
 		EP_AppendClassHook( self->context->calcDtEP, AdvectionDiffusionSLE_CalculateDt, self );
 }	
@@ -401,9 +372,49 @@
 	Index                   forceTerm_I;
 	Index                   forceTermCount = Stg_ObjectList_Count( self->residual->forceTermList );
 	ForceTerm*              forceTerm;
+	unsigned int           *nodeDomainCountPtr;
+	Variable*              variable;
+	Node_DomainIndex       node_I;
 
 	Journal_DPrintf( self->debug, "In %s()\n", __func__ );
 
+	/* Create New FeVariable for Phi Dot */
+	if (self->phiField) {
+		Variable_Register*	variable_Register;
+		FieldVariable_Register*	fieldVariable_Register;
+
+		variable_Register = self->variableReg;
+		fieldVariable_Register = self->fieldVariableReg;
+
+		Build( self->phiField->feMesh, NULL, False );
+
+		nodeDomainCountPtr = &self->phiField->feMesh->topo->domains[MT_VERTEX]->nDomains;
+		Variable_NewScalar( 
+			"phiDot", 
+			Variable_DataType_Double, 
+			nodeDomainCountPtr, 
+			(void**)&self->phiDotArray, 
+			variable_Register );
+
+		variable = Variable_Register_GetByName( variable_Register, "phiDot" );
+		self->phiDotDofLayout = DofLayout_New( "dofLayout1", variable_Register, *nodeDomainCountPtr, NULL );
+		for( node_I = 0; node_I < *nodeDomainCountPtr ; node_I++ ) 
+			DofLayout_AddDof_ByVarName( self->phiDotDofLayout, variable->name, node_I );
+
+		self->phiDotField = FeVariable_New_FromTemplate(
+			"phiDotField",
+			self->phiField,
+			self->phiDotDofLayout,
+			NULL,
+			self->phiField->importFormatType,
+			self->phiField->exportFormatType,
+			fieldVariable_Register );
+
+		/* Construct Solution Vectors */
+		self->phiVector    = SolutionVector_New( "PhiVector", self->phiField->communicator, self->phiField );
+		self->phiDotVector = SolutionVector_New( "PhiDotVector", self->phiField->communicator, self->phiDotField );
+	}
+
 	_SystemLinearEquations_Build( self, data );
 
 	/* Get pointer to residual force term 
@@ -432,7 +443,7 @@
 
 	if ( self->phiDotField ) {
 		self->phiDotArray = Memory_Alloc_Array( 
-				double, self->phiDotField->feMesh->layout->decomp->nodeDomainCount, "phiDotArray" );
+			double, Mesh_GetDomainSize( self->phiDotField->feMesh, MT_VERTEX ), "phiDotArray" );
 	}
 
 	/* Force Vectors */

Modified: long/3D/Gale/trunk/src/StgFEM/SLE/ProvidedSystems/AdvectionDiffusion/src/AdvectionDiffusionSLE.h
===================================================================
--- long/3D/Gale/trunk/src/StgFEM/SLE/ProvidedSystems/AdvectionDiffusion/src/AdvectionDiffusionSLE.h	2006-12-07 23:26:14 UTC (rev 5532)
+++ long/3D/Gale/trunk/src/StgFEM/SLE/ProvidedSystems/AdvectionDiffusion/src/AdvectionDiffusionSLE.h	2006-12-07 23:29:43 UTC (rev 5533)
@@ -62,6 +62,9 @@
 		double                                             currentDt;                      \
 		double                                             courantFactor;                  \
 		double                                             maxDiffusivity;                 \
+									\
+		Variable_Register*		variableReg;		\
+		FieldVariable_Register*		fieldVariableReg;
 	
 	struct AdvectionDiffusionSLE { __AdvectionDiffusionSLE };
 		

Modified: long/3D/Gale/trunk/src/StgFEM/SLE/ProvidedSystems/AdvectionDiffusion/src/LumpedMassMatrixForceTerm.c
===================================================================
--- long/3D/Gale/trunk/src/StgFEM/SLE/ProvidedSystems/AdvectionDiffusion/src/LumpedMassMatrixForceTerm.c	2006-12-07 23:26:14 UTC (rev 5532)
+++ long/3D/Gale/trunk/src/StgFEM/SLE/ProvidedSystems/AdvectionDiffusion/src/LumpedMassMatrixForceTerm.c	2006-12-07 23:29:43 UTC (rev 5533)
@@ -187,14 +187,18 @@
 void _LumpedMassMatrixForceTerm_AssembleElement( void* forceTerm, ForceVector* forceVector ,Element_LocalIndex lElement_I, double* elForceVector ) {
 	LumpedMassMatrixForceTerm* self              = Stg_CheckType( forceTerm, LumpedMassMatrixForceTerm );
 	FeVariable*                feVariable        = forceVector->feVariable;
-	FiniteElement_Mesh*        mesh              = feVariable->feMesh;
-		
+	FeMesh*				feMesh              = feVariable->feMesh;
+
+#if 0
 	if ( Stg_Class_IsInstance( mesh->layout->elementLayout, ParallelPipedHexaEL_Type ) ) {
 		ForceTerm_SetAssembleElementFunction( self, _LumpedMassMatrixForceTerm_AssembleElement_Box  );
 	}
 	else {
+#endif
 		ForceTerm_SetAssembleElementFunction( self, _LumpedMassMatrixForceTerm_AssembleElement_General  );
+#if 0
 	}
+#endif
 
 	ForceTerm_AssembleElement( self, forceVector, lElement_I, elForceVector );
 }
@@ -204,9 +208,8 @@
 	FeVariable*                feVariable        = forceVector->feVariable;
 	Dimension_Index            dim               = forceVector->dim;
 	Swarm*                     swarm             = self->integrationSwarm;
-	FiniteElement_Mesh*        mesh              = feVariable->feMesh;
-	Element_NodeIndex          elementNodeCount  = mesh->elementNodeCountTbl[ lElement_I ];
-	ElementType*               elementType       = FeMesh_ElementTypeAt( mesh, lElement_I );
+	FeMesh*				feMesh              = feVariable->feMesh;
+	ElementType*               elementType       = FeMesh_GetElementType( feMesh, lElement_I );
 	Cell_Index                 cell_I            = CellLayout_MapElementIdToCellId( swarm->cellLayout, lElement_I );
 	Particle_InCellIndex       cellParticleCount;
 	Particle_InCellIndex       cParticle_I;
@@ -216,7 +219,9 @@
 	double                     factor;
 	double                     detJac;
 	double                     shapeFunc[8];
+	unsigned			elementNodeCount;
 
+	elementNodeCount = FeMesh_GetElementNodeSize( feMesh, lElement_I );
 	cellParticleCount = swarm->cellParticleCountTbl[ cell_I ];
 	
 	for( cParticle_I = 0 ; cParticle_I < cellParticleCount; cParticle_I++ ) {
@@ -225,7 +230,7 @@
 
 		/* Evalutate Shape Functions and Jacobian Determinant */
 		ElementType_EvaluateShapeFunctionsAt( elementType, particle->xi, shapeFunc );
-		detJac = ElementType_JacobianDeterminant( elementType, mesh, lElement_I, particle->xi, dim );
+		detJac = ElementType_JacobianDeterminant( elementType, feMesh, lElement_I, particle->xi, dim );
 	
 		/* Integrate \int_{\Omgea} N_i N_i d\Omega and lump onto vector in one step */
 		factor = detJac * particle->weight;
@@ -239,14 +244,17 @@
 void _LumpedMassMatrixForceTerm_AssembleElement_Box( void* forceTerm, ForceVector* forceVector, Element_LocalIndex lElement_I, double* elForceVector ) {
 	FeVariable*                feVariable        = forceVector->feVariable;
 	Dimension_Index            dim               = forceVector->dim;
-	FiniteElement_Mesh*        mesh              = feVariable->feMesh;
-	Element_NodeIndex          elementNodeCount  = mesh->elementNodeCountTbl[ lElement_I ];
-	ElementType*               elementType       = FeMesh_ElementTypeAt( mesh, lElement_I );
+	FeMesh*			feMesh              = feVariable->feMesh;
+	Element_NodeIndex          elementNodeCount;
+	ElementType*               elementType;
 	Node_Index                 node_I;
 	double                     detJac;
 	Coord                      xi = {0.0,0.0,0.0};
+
+	elementNodeCount = FeMesh_GetElementNodeSize( feMesh, lElement_I );
+	elementType = FeMesh_GetElementType( feMesh, lElement_I );
 	
-	detJac = ElementType_JacobianDeterminant( elementType, mesh, lElement_I, xi, dim );
+	detJac = ElementType_JacobianDeterminant( elementType, feMesh, lElement_I, xi, dim );
 	for ( node_I = 0 ; node_I < elementNodeCount ; node_I++ ) 
 		elForceVector[ node_I ] = detJac;
 }

Modified: long/3D/Gale/trunk/src/StgFEM/SLE/ProvidedSystems/AdvectionDiffusion/src/Residual.c
===================================================================
--- long/3D/Gale/trunk/src/StgFEM/SLE/ProvidedSystems/AdvectionDiffusion/src/Residual.c	2006-12-07 23:26:14 UTC (rev 5532)
+++ long/3D/Gale/trunk/src/StgFEM/SLE/ProvidedSystems/AdvectionDiffusion/src/Residual.c	2006-12-07 23:29:43 UTC (rev 5533)
@@ -283,7 +283,7 @@
 	double                     totalDerivative, diffusionTerm;
 	double                     diffusivity         = self->defaultDiffusivity;
 	Variable*                  diffusivityVariable = self->diffusivityVariable;
-	ElementType*               elementType         = FeMesh_ElementTypeAt( phiField->feMesh, lElement_I );
+	ElementType*               elementType         = FeMesh_GetElementType( phiField->feMesh, lElement_I );
 	Node_Index                 elementNodeCount    = elementType->nodeCount;
 	Node_Index                 node_I;
 	double                     factor;

Modified: long/3D/Gale/trunk/src/StgFEM/SLE/ProvidedSystems/AdvectionDiffusion/src/ShapeFunctions.c
===================================================================
--- long/3D/Gale/trunk/src/StgFEM/SLE/ProvidedSystems/AdvectionDiffusion/src/ShapeFunctions.c	2006-12-07 23:26:14 UTC (rev 5532)
+++ long/3D/Gale/trunk/src/StgFEM/SLE/ProvidedSystems/AdvectionDiffusion/src/ShapeFunctions.c	2006-12-07 23:29:43 UTC (rev 5533)
@@ -58,7 +58,7 @@
  * Returns memory to new shape functions - which then must be free'd */
 double** AdvDiffResidualForceTerm_BuildSUPGShapeFunctions( AdvDiffResidualForceTerm* self, AdvectionDiffusionSLE* sle, Swarm* swarm, Element_LocalIndex lElement_I, Dimension_Index dim ) {
 	FeVariable*                velocityField    = self->velocityField;
-	FiniteElement_Mesh*        mesh             = velocityField->feMesh;
+	FeMesh*				feMesh             = velocityField->feMesh;
 	double**                   elShapeFunc; 
 	double**                   GNx;
 	double*                    xi;
@@ -73,7 +73,7 @@
 	Particle_InCellIndex       cParticle_I;
 	Particle_InCellIndex       particleCount;
 	Cell_Index                 cell_I;
-	ElementType*               elementType = FeMesh_ElementTypeAt( mesh, lElement_I );
+	ElementType*               elementType = FeMesh_GetElementType( feMesh, lElement_I );
 	Node_Index                 nodeCount = elementType->nodeCount;
 	Node_Index                 node_I;
 	IntegrationPoint*          particle;
@@ -122,7 +122,7 @@
 		/* Get Shape Functions Derivatives */
 		ElementType_ShapeFunctionsGlobalDerivs( 
 			elementType,
-			mesh, lElement_I,
+			feMesh, lElement_I,
 			xi, dim, &detJac, GNx );
 
 		/* Calculate Velocity on Particle */

Modified: long/3D/Gale/trunk/src/StgFEM/SLE/ProvidedSystems/AdvectionDiffusion/src/Timestep.c
===================================================================
--- long/3D/Gale/trunk/src/StgFEM/SLE/ProvidedSystems/AdvectionDiffusion/src/Timestep.c	2006-12-07 23:26:14 UTC (rev 5532)
+++ long/3D/Gale/trunk/src/StgFEM/SLE/ProvidedSystems/AdvectionDiffusion/src/Timestep.c	2006-12-07 23:29:43 UTC (rev 5533)
@@ -99,7 +99,7 @@
 	AdvectionDiffusionSLE*    self              = (AdvectionDiffusionSLE*) advectionDiffusionSLE;
 	AdvDiffResidualForceTerm* residualForceTerm = self->advDiffResidualForceTerm;
 	FeVariable*               velocityField     = residualForceTerm->velocityField;
-	Node_LocalIndex           nodeLocalCount    = velocityField->feMesh->nodeLocalCount;
+	Node_LocalIndex           nodeLocalCount    = Mesh_GetLocalSize( velocityField->feMesh, MT_VERTEX );
 	Node_LocalIndex           node_I;
 	Dimension_Index           dim               = self->dim;
 	Dimension_Index           dim_I;

Modified: long/3D/Gale/trunk/src/StgFEM/SLE/ProvidedSystems/AdvectionDiffusion/src/UpwindParameter.c
===================================================================
--- long/3D/Gale/trunk/src/StgFEM/SLE/ProvidedSystems/AdvectionDiffusion/src/UpwindParameter.c	2006-12-07 23:26:14 UTC (rev 5532)
+++ long/3D/Gale/trunk/src/StgFEM/SLE/ProvidedSystems/AdvectionDiffusion/src/UpwindParameter.c	2006-12-07 23:29:43 UTC (rev 5533)
@@ -58,7 +58,7 @@
  * All equations refer to this paper if not otherwise indicated */
 double AdvDiffResidualForceTerm_UpwindDiffusivity( AdvDiffResidualForceTerm* self, Element_LocalIndex lElement_I, double diffusivity, Dimension_Index dim ){
 	FeVariable*                velocityField   = self->velocityField;
-	FiniteElement_Mesh*        mesh            = velocityField->feMesh;
+	FeMesh*				feMesh            = velocityField->feMesh;
 	Coord                      xiElementCentre = {0.0,0.0,0.0};
 	double                     xiUpwind;
 	double                     velocityCentre[3];
@@ -69,6 +69,7 @@
 	double*                    leastCoord;
 	double*                    greatestCoord;
 	Node_LocalIndex            nodeIndex_LeastValues, nodeIndex_GreatestValues;
+	unsigned			nInc, *inc;
 	
 	/* Change Diffusivity if it is too small */
 	if ( diffusivity < MIN_DIFFUSIVITY ) 
@@ -78,10 +79,11 @@
 	FeVariable_InterpolateWithinElement( velocityField, lElement_I, xiElementCentre, velocityCentre );
 
 	/* Calculate Length Scales - See Fig 3.4 - ASSUMES BOX MESH TODO - fix */
-	nodeIndex_LeastValues = mesh->elementNodeTbl[lElement_I][0];
-	nodeIndex_GreatestValues = (dim == 2) ?  mesh->elementNodeTbl[lElement_I][2] : mesh->elementNodeTbl[lElement_I][6];
-	leastCoord    = Mesh_CoordAt( mesh, nodeIndex_LeastValues );
-	greatestCoord = Mesh_CoordAt( mesh, nodeIndex_GreatestValues );
+	FeMesh_GetElementNodes( feMesh, lElement_I, &nInc, &inc );
+	nodeIndex_LeastValues = inc[0];
+	nodeIndex_GreatestValues = (dim == 2) ? inc[3] : inc[7];
+	leastCoord    = Mesh_GetVertex( feMesh, nodeIndex_LeastValues );
+	greatestCoord = Mesh_GetVertex( feMesh, nodeIndex_GreatestValues );
 
 	upwindDiffusivity = 0.0;
 	for ( dim_I = 0 ; dim_I < dim ; dim_I++ ) {

Modified: long/3D/Gale/trunk/src/StgFEM/SLE/ProvidedSystems/AdvectionDiffusion/tests/testLumpedMassMatrix.c
===================================================================
--- long/3D/Gale/trunk/src/StgFEM/SLE/ProvidedSystems/AdvectionDiffusion/tests/testLumpedMassMatrix.c	2006-12-07 23:26:14 UTC (rev 5532)
+++ long/3D/Gale/trunk/src/StgFEM/SLE/ProvidedSystems/AdvectionDiffusion/tests/testLumpedMassMatrix.c	2006-12-07 23:29:43 UTC (rev 5533)
@@ -62,6 +62,36 @@
 	Coord coord;
 };
 
+
+FeMesh* buildFeMesh( unsigned nDims, unsigned* size, 
+		     double* minCrds, double* maxCrds, 
+		     ExtensionManager_Register* emReg, 
+		     ElementType_Register* etReg )
+{
+	CartesianGenerator*	gen;
+	FeMesh*			feMesh;
+	unsigned		maxDecomp[3] = {0, 1, 1};
+
+	gen = CartesianGenerator_New( "" );
+	gen->shadowDepth = 0;
+	CartesianGenerator_SetTopologyParams( gen, nDims, size, 0, NULL, maxDecomp );
+	CartesianGenerator_SetGeometryParams( gen, minCrds, maxCrds );
+
+	feMesh = FeMesh_New( "" );
+	Mesh_SetExtensionManagerRegister( feMesh, emReg );
+	Mesh_SetGenerator( feMesh, gen );
+	FeMesh_SetElementFamily( feMesh, "linear" );
+
+	Mesh_SetTopologyDataSize( feMesh, MT_VERTEX, sizeof(Node) );
+	Mesh_SetTopologyDataSize( feMesh, nDims, sizeof(Element) );
+
+	Build( feMesh, NULL, False );
+	Initialise( feMesh, NULL, False );
+
+	return feMesh;
+}
+
+
 int main( int argc, char* argv[] ) {
 	MPI_Comm                   CommWorld;
 	int                        rank;
@@ -70,15 +100,18 @@
 	Dictionary*                dictionary;
 	Dictionary_Entry_Value*    currBC;
 	Dictionary_Entry_Value*	   bcList;
-	Topology*                  nTopology;
-	ElementLayout*             eLayout;
-	NodeLayout*                nLayout;
-	MeshDecomp*                decomp;
-	MeshLayout*	               meshLayout;
+
+	unsigned	nDims = 2;
+	unsigned	meshSize[3] = {2, 2, 0};
+	double		minCrds[3] = {0.0, 0.0, 0.0};
+	double		maxCrds[3] = {1.2, 1.2, 1.2};
+	FeMesh*		feMesh;
+	unsigned	nDomainVerts;
+	Node*		nodes;
+
 	DofLayout*                 dofs;
 	ElementType_Register*      elementType_Register;
 	ExtensionManager_Register* extensionMgr_Register;
-	FiniteElement_Mesh*        feMesh;
 	WallVC*                    wallVC;
 	FieldVariable_Register*    fV_Register;
 	FeVariable*                feVariable;
@@ -126,17 +159,6 @@
 	dictionary = Dictionary_New();
 	Dictionary_Add( dictionary, "rank", Dictionary_Entry_Value_FromUnsignedInt( rank ) );
 	Dictionary_Add( dictionary, "numProcessors", Dictionary_Entry_Value_FromUnsignedInt( numProcessors ) );
-	Dictionary_Add( dictionary, "meshSizeI", Dictionary_Entry_Value_FromUnsignedInt( 3 ) );
-	Dictionary_Add( dictionary, "meshSizeJ", Dictionary_Entry_Value_FromUnsignedInt( 3 ) );
-	Dictionary_Add( dictionary, "meshSizeK", Dictionary_Entry_Value_FromUnsignedInt( 1 ) );
-	Dictionary_Add( dictionary, "minX", Dictionary_Entry_Value_FromDouble( 0.0f ) );
-	Dictionary_Add( dictionary, "minY", Dictionary_Entry_Value_FromDouble( 0.0f ) );
-	Dictionary_Add( dictionary, "minZ", Dictionary_Entry_Value_FromDouble( 0.0f ) );
-	Dictionary_Add( dictionary, "maxX", Dictionary_Entry_Value_FromDouble( 1.2f ) );
-	Dictionary_Add( dictionary, "maxY", Dictionary_Entry_Value_FromDouble( 1.2f ) );
-	Dictionary_Add( dictionary, "maxZ", Dictionary_Entry_Value_FromDouble( 1.2f ) );
-	Dictionary_Add( dictionary, "allowPartitionOnElement", Dictionary_Entry_Value_FromBool( False ) );
-	Dictionary_Add( dictionary, "buildElementNodeTbl", Dictionary_Entry_Value_FromBool( True ) );
 	Dictionary_Add( dictionary, "gaussParticlesX", Dictionary_Entry_Value_FromUnsignedInt( 2 ) );
 	Dictionary_Add( dictionary, "gaussParticlesY", Dictionary_Entry_Value_FromUnsignedInt( 2 ) );
 	
@@ -159,19 +181,16 @@
 	Stream_EnableBranch( StgFEM_Debug, True );
 	
 	/* create the layout, dof and mesh to use */
-	nTopology = (Topology*)IJK6Topology_New( "IJK6Topology", dictionary );
-	eLayout = (ElementLayout*)ParallelPipedHexaEL_New( "ElementLayout", dim, dictionary );
-	nLayout = (NodeLayout*)CornerNL_New( "CornerNL", dictionary, eLayout, nTopology );
-	decomp = (MeshDecomp*)HexaMD_New( "HexaMD", dictionary, MPI_COMM_WORLD, eLayout, nLayout );
-	meshLayout = MeshLayout_New( "MeshLayout", eLayout, nLayout, decomp );
-	
 	extensionMgr_Register = ExtensionManager_Register_New();
 	elementType_Register = ElementType_Register_New("elementTypeRegister");
 	ElementType_Register_Add( elementType_Register, (ElementType*)ConstantElementType_New("constant") );
 	ElementType_Register_Add( elementType_Register, (ElementType*)BilinearElementType_New("bilinear") );
 	ElementType_Register_Add( elementType_Register, (ElementType*)TrilinearElementType_New("trilinear") );
-	feMesh = FiniteElement_Mesh_New( "testMesh", meshLayout, sizeof(Node), sizeof(Element), extensionMgr_Register,
-		elementType_Register, dictionary );
+
+	feMesh = buildFeMesh( nDims, meshSize, minCrds, maxCrds, 
+			      extensionMgr_Register, elementType_Register );
+	nDomainVerts = Mesh_GetDomainSize( feMesh, MT_VERTEX );
+	nodes = Mesh_GetTopologyData( feMesh, MT_VERTEX );
 	
 	/* Create variable register */
 	variableRegister = Variable_Register_New();
@@ -180,12 +199,12 @@
 	Variable_NewScalar( 
 		"phi", 
 		Variable_DataType_Double, 
-		&feMesh->nodeDomainCount, 
-		(void**)&feMesh->node, 
+		&nDomainVerts, 
+		(void**)&nodes, 
 		variableRegister );
 
-	dofs = DofLayout_New( "dofLayout", variableRegister, decomp->nodeLocalCount );
-	for (i = 0; i < decomp->nodeLocalCount; i++)
+	dofs = DofLayout_New( "dofLayout", variableRegister, Mesh_GetDomainSize( feMesh, MT_VERTEX ), NULL );
+	for (i = 0; i < Mesh_GetDomainSize( feMesh, MT_VERTEX ); i++)
 		DofLayout_AddDof_ByVarName(dofs, "phi", i);
 	
 	wallVC = WallVC_New( "WallVC", "boundaryCondition", variableRegister, NULL, dictionary, feMesh );
@@ -202,7 +221,7 @@
 	/* Create Swarm */
 	if ( 3 == dim ) 
 		dimExists[K_AXIS] = True;
-	singleCellLayout    = (CellLayout*)    SingleCellLayout_New( "SingleCellLayout", dimExists, NULL, NULL );
+	singleCellLayout    = (CellLayout*)SingleCellLayout_New( "SingleCellLayout", dimExists, NULL, NULL );
 	gaussParticleLayout = (ParticleLayout*)GaussParticleLayout_New( "GaussParticleLayout", dim, particlesPerDim );
 	swarm = Swarm_New( "gaussSwarm", singleCellLayout, gaussParticleLayout, dim,
 		sizeof(IntegrationPoint), context->extensionMgr_Register, context->variable_Register, MPI_COMM_WORLD );
@@ -256,11 +275,6 @@
 	Stg_Class_Delete( elementType_Register );
 	Stg_Class_Delete( extensionMgr_Register );
 	Stg_Class_Delete( dofs );
-	Stg_Class_Delete( meshLayout );
-	Stg_Class_Delete( decomp );
-	Stg_Class_Delete( nLayout );
-	Stg_Class_Delete( eLayout );
-	Stg_Class_Delete( nTopology );
 	Stg_Class_Delete( dictionary );
 	
 	StgFEM_Discretisation_Finalise();

Modified: long/3D/Gale/trunk/src/StgFEM/SLE/ProvidedSystems/AdvectionDiffusion/tests/testSUPGShapeFunc.c
===================================================================
--- long/3D/Gale/trunk/src/StgFEM/SLE/ProvidedSystems/AdvectionDiffusion/tests/testSUPGShapeFunc.c	2006-12-07 23:26:14 UTC (rev 5532)
+++ long/3D/Gale/trunk/src/StgFEM/SLE/ProvidedSystems/AdvectionDiffusion/tests/testSUPGShapeFunc.c	2006-12-07 23:29:43 UTC (rev 5533)
@@ -70,7 +70,7 @@
 		particle->xi[valueAxis]    = value;
 	}
 }
-void CheckShapeFunc( AdvectionDiffusionSLE* advDiffSLE, AdvDiffResidualForceTerm* residualForceTerm, Swarm* gaussSwarm, Element_Index lElement_I, Dimension_Index dim, FiniteElement_Mesh* feMesh, Stream* stream ) {
+void CheckShapeFunc( AdvectionDiffusionSLE* advDiffSLE, AdvDiffResidualForceTerm* residualForceTerm, Swarm* gaussSwarm, Element_Index lElement_I, Dimension_Index dim, FeMesh* feMesh, Stream* stream ) {
 	double**                   shapeFunc;
 	Node_Index                 nodeCount;
 	ElementType*               elementType;
@@ -84,34 +84,70 @@
 
 	/* Print Shape Funcions */
 	cell_I = CellLayout_MapElementIdToCellId( gaussSwarm->cellLayout, lElement_I );
-	elementType = FeMesh_ElementTypeAt( feMesh, lElement_I );
+	elementType = FeMesh_GetElementType( feMesh, lElement_I );
 	nodeCount = elementType->nodeCount;
 	for ( node_I = 0 ; node_I < nodeCount ; node_I++ ) {
+		unsigned	nodeInd;
+
+		nodeInd = (node_I == 2) ? 3 : (node_I == 3) ? 2 : node_I;
 		for ( cParticle_I = 0 ; cParticle_I < gaussSwarm->cellParticleCountTbl[ cell_I ] ; cParticle_I++ ) {
 			particle = (IntegrationPoint*)Swarm_ParticleInCellAt( gaussSwarm, cell_I, cParticle_I );
 
 			ElementType_EvaluateShapeFunctionsAt( elementType, particle->xi, Ni );
 
-			Journal_Printf( stream, "%12.6g %12.6g %12.6g %12.6g %12.6g\n", (double)node_I, particle->xi[0], particle->xi[1], shapeFunc[ cParticle_I ][ node_I ], Ni[ node_I ] );
+			Journal_Printf( stream, "%12.6g %12.6g %12.6g %12.6g %12.6g\n", (double)node_I, particle->xi[0], particle->xi[1], shapeFunc[ cParticle_I ][ nodeInd ], Ni[ nodeInd ] );
 		}
 	}
 }
 
+
+FeMesh* buildFeMesh( unsigned nDims, unsigned* size, 
+		     double* minCrds, double* maxCrds, 
+		     ExtensionManager_Register* emReg, 
+		     ElementType_Register* etReg )
+{
+	CartesianGenerator*	gen;
+	FeMesh*			feMesh;
+	unsigned		maxDecomp[3] = {0, 1, 1};
+
+	gen = CartesianGenerator_New( "" );
+	gen->shadowDepth = 0;
+	CartesianGenerator_SetTopologyParams( gen, nDims, size, 0, NULL, maxDecomp );
+	CartesianGenerator_SetGeometryParams( gen, minCrds, maxCrds );
+
+	feMesh = FeMesh_New( "" );
+	Mesh_SetExtensionManagerRegister( feMesh, emReg );
+	Mesh_SetGenerator( feMesh, gen );
+	FeMesh_SetElementFamily( feMesh, "linear" );
+
+	Mesh_SetTopologyDataSize( feMesh, MT_VERTEX, sizeof(Node) );
+	Mesh_SetTopologyDataSize( feMesh, nDims, sizeof(Element) );
+
+	Build( feMesh, NULL, False );
+	Initialise( feMesh, NULL, False );
+
+	return feMesh;
+}
+
+
 int main( int argc, char* argv[] ) {
 	MPI_Comm                   CommWorld;
 	int                        rank;
 	int                        numProcessors;
 	int                        procToWatch;
 	Dictionary*                dictionary;
-	Topology*                  nTopology;
-	ElementLayout*             eLayout;
-	NodeLayout*                nLayout;
-	MeshDecomp*                decomp;
-	MeshLayout*                meshLayout;
+
+	unsigned	nDims = 2;
+	unsigned	meshSize[3] = {6, 6, 0};
+	double		minCrds[3] = {0.0, 0.0, 0.0};
+	double		maxCrds[3] = {1.2, 2.2, 1.2};
+	FeMesh*		feMesh;
+	unsigned	nDomainVerts;
+	Node*		nodes;
+
 	DofLayout*                 dofs;
 	ElementType_Register*      elementType_Register;
 	ExtensionManager_Register* extensionMgr_Register;
-	FiniteElement_Mesh*        feMesh;
 	FeVariable*                feVariable;
 	Variable_Register*         variableRegister;
 	DiscretisationContext*     context;
@@ -128,8 +164,6 @@
 	Particle_InCellIndex       particlesPerDim[] = {2,2,2};
 	ForceVector*               residual;
 	AdvDiffResidualForceTerm*  residualForceTerm;
-
-
 	
 	/* Initialise MPI, get world info */
 	MPI_Init( &argc, &argv );
@@ -158,18 +192,6 @@
 	dictionary = Dictionary_New();
 	Dictionary_Add( dictionary, "rank", Dictionary_Entry_Value_FromUnsignedInt( rank ) );
 	Dictionary_Add( dictionary, "numProcessors", Dictionary_Entry_Value_FromUnsignedInt( numProcessors ) );
-	Dictionary_Add( dictionary, "dim", Dictionary_Entry_Value_FromUnsignedInt( 2 ) );
-	Dictionary_Add( dictionary, "meshSizeI", Dictionary_Entry_Value_FromUnsignedInt( 7 ) );
-	Dictionary_Add( dictionary, "meshSizeJ", Dictionary_Entry_Value_FromUnsignedInt( 7 ) );
-	Dictionary_Add( dictionary, "meshSizeK", Dictionary_Entry_Value_FromUnsignedInt( 1 ) );
-	Dictionary_Add( dictionary, "minX", Dictionary_Entry_Value_FromDouble( 0.0f ) );
-	Dictionary_Add( dictionary, "minY", Dictionary_Entry_Value_FromDouble( 0.0f ) );
-	Dictionary_Add( dictionary, "minZ", Dictionary_Entry_Value_FromDouble( 0.0f ) );
-	Dictionary_Add( dictionary, "maxX", Dictionary_Entry_Value_FromDouble( 1.2f ) );
-	Dictionary_Add( dictionary, "maxY", Dictionary_Entry_Value_FromDouble( 2.2f ) );
-	Dictionary_Add( dictionary, "maxZ", Dictionary_Entry_Value_FromDouble( 1.2f ) );
-	Dictionary_Add( dictionary, "allowPartitionOnElement", Dictionary_Entry_Value_FromBool( False ) );
-	Dictionary_Add( dictionary, "buildElementNodeTbl", Dictionary_Entry_Value_FromBool( True ) );
 	Dictionary_Add( dictionary, "gaussParticlesX", Dictionary_Entry_Value_FromUnsignedInt( 2 ) );
 	Dictionary_Add( dictionary, "gaussParticlesY", Dictionary_Entry_Value_FromUnsignedInt( 2 ) );
 	
@@ -193,19 +215,16 @@
 			CommWorld, dictionary );
 	
 	/* create the layout, dof and mesh to use */
-	nTopology = (Topology*)IJK6Topology_New( "IJK6Topology", dictionary );
-	eLayout = (ElementLayout*)ParallelPipedHexaEL_New( "ElementLayout", 2, dictionary );
-	nLayout = (NodeLayout*)CornerNL_New( "CornerNL", dictionary, eLayout, nTopology );
-	decomp = (MeshDecomp*)HexaMD_New( "HexaMD", dictionary, MPI_COMM_WORLD, eLayout, nLayout );
-	meshLayout = MeshLayout_New( "MeshLayout", eLayout, nLayout, decomp );
-	
 	extensionMgr_Register = ExtensionManager_Register_New();
 	elementType_Register = ElementType_Register_New("elementTypeRegister");
 	ElementType_Register_Add( elementType_Register, (ElementType*)ConstantElementType_New("constantElementType") );
 	ElementType_Register_Add( elementType_Register, (ElementType*)BilinearElementType_New("BilinearElementType") );
 	ElementType_Register_Add( elementType_Register, (ElementType*)TrilinearElementType_New("TrilinearElementType") );
-	feMesh = FiniteElement_Mesh_New( "testMesh", meshLayout, sizeof(Node), sizeof(Element), extensionMgr_Register,
-		elementType_Register, dictionary );
+
+	feMesh = buildFeMesh( nDims, meshSize, minCrds, maxCrds, 
+			      extensionMgr_Register, elementType_Register );
+	nDomainVerts = Mesh_GetDomainSize( feMesh, MT_VERTEX );
+	nodes = Mesh_GetTopologyData( feMesh, MT_VERTEX );
 	
 	/* Create variable register */
 	variableRegister = Variable_Register_New();
@@ -215,16 +234,16 @@
 		"velocity", 
 		Variable_DataType_Double, 
 		3, 
-		&feMesh->nodeDomainCount, 
-		(void**)&feMesh->node, 
+		&nDomainVerts, 
+		(void**)&nodes, 
 		variableRegister, 
 		"vx", 
 		"vy", 
 		"vz" );
 
 
-	dofs = DofLayout_New( "dofLayout", variableRegister, decomp->nodeLocalCount );
-	for (node_I = 0; node_I < decomp->nodeLocalCount; node_I++)	{
+	dofs = DofLayout_New( "dofLayout", variableRegister, nDomainVerts, NULL );
+	for (node_I = 0; node_I < nDomainVerts; node_I++) {
 		DofLayout_AddDof_ByVarName(dofs, "vx", node_I);
 		DofLayout_AddDof_ByVarName(dofs, "vy", node_I);
 	}
@@ -312,28 +331,38 @@
 
 	Journal_Printf(stream, "#Checking pure diffusion\n");
 	/* Apply some arbitrary initial conditions */
-	for ( node_I = 0; node_I < decomp->nodeDomainCount; node_I++ ) {
-		feMesh->node[node_I].velocity[0] = 0.0;
-		feMesh->node[node_I].velocity[1] = 0.0;
-		feMesh->node[node_I].velocity[2] = 0.0;
+	for ( node_I = 0; node_I < nDomainVerts; node_I++ ) {
+		unsigned	d_i;
+
+		for( d_i = 0; d_i < Mesh_GetDimSize( feMesh ); d_i++ ) {
+			nodes[node_I].velocity[d_i] = 0.0;
+		}
 	}
 	residualForceTerm->defaultDiffusivity = 1.0;
 	CheckShapeFunc( advDiffSLE, residualForceTerm, gaussSwarm, lElement_I, context->dim, feMesh, stream );
 	
 	Journal_Printf(stream, "#Checking pure advection vx = 1.0\n");
-	for ( node_I = 0; node_I < decomp->nodeDomainCount; node_I++ ) {
-		feMesh->node[node_I].velocity[0] = 1.0;
-		feMesh->node[node_I].velocity[1] = 0.0;
-		feMesh->node[node_I].velocity[2] = 0.0;
+	for ( node_I = 0; node_I < nDomainVerts; node_I++ ) {
+		unsigned	d_i;
+
+		nodes[node_I].velocity[0] = 1.0;
+		for( d_i = 1; d_i < Mesh_GetDimSize( feMesh ); d_i++ ) {
+			nodes[node_I].velocity[d_i] = 0.0;
+		}
 	}
 	residualForceTerm->defaultDiffusivity = 0.0;
 	CheckShapeFunc( advDiffSLE, residualForceTerm, gaussSwarm, lElement_I, context->dim, feMesh, stream );
 	
 	Journal_Printf(stream, "#Checking pure advection vy = 1.0\n");
-	for ( node_I = 0; node_I < decomp->nodeDomainCount; node_I++ ) {
-		feMesh->node[node_I].velocity[0] = 0.0;
-		feMesh->node[node_I].velocity[1] = 1.0;
-		feMesh->node[node_I].velocity[2] = 0.0;
+	for ( node_I = 0; node_I < nDomainVerts; node_I++ ) {
+		unsigned	d_i;
+
+		for( d_i = 0; d_i < Mesh_GetDimSize( feMesh ); d_i++ ) {
+			if( d_i == 1 )
+				nodes[node_I].velocity[d_i] = 1.0;
+			else
+				nodes[node_I].velocity[d_i] = 0.0;
+		}
 	}
 	residualForceTerm->defaultDiffusivity = 0.0;
 	CheckShapeFunc( advDiffSLE, residualForceTerm, gaussSwarm, lElement_I, context->dim, feMesh, stream );
@@ -346,11 +375,6 @@
 	Stg_Class_Delete( elementType_Register );
 	Stg_Class_Delete( extensionMgr_Register );
 	Stg_Class_Delete( dofs );
-	Stg_Class_Delete( meshLayout );
-	Stg_Class_Delete( decomp );
-	Stg_Class_Delete( nLayout );
-	Stg_Class_Delete( eLayout );
-	Stg_Class_Delete( nTopology );
 	Stg_Class_Delete( dictionary );
 	
 	StgFEM_SLE_SystemSetup_Finalise();

Modified: long/3D/Gale/trunk/src/StgFEM/SLE/ProvidedSystems/Energy/src/Energy_SLE_Solver.c
===================================================================
--- long/3D/Gale/trunk/src/StgFEM/SLE/ProvidedSystems/Energy/src/Energy_SLE_Solver.c	2006-12-07 23:26:14 UTC (rev 5532)
+++ long/3D/Gale/trunk/src/StgFEM/SLE/ProvidedSystems/Energy/src/Energy_SLE_Solver.c	2006-12-07 23:29:43 UTC (rev 5533)
@@ -207,10 +207,10 @@
 	
 	/* MG: If multi-grid is enabled, enable it on the velocity matrix solver. */
 	if( sle->mgEnabled ) {
-		MultiGrid_InitMatrixSolver( sle->mgHandles[0], self->matrixSolver );
+		/*MultiGrid_InitMatrixSolver( sle->mgHandles[0], self->matrixSolver );*/
 		
-		MultiGrid_BuildGridOps( sle->mgHandles[0] );
-		MultiGrid_BuildWorkVectors( sle->mgHandles[0] );
+		/*MultiGrid_BuildGridOps( sle->mgHandles[0] );*/
+		/*MultiGrid_BuildWorkVectors( sle->mgHandles[0] );*/
 	}
 }
 
@@ -266,8 +266,8 @@
 	
 	/* Handle MG. */
 	if( sle->mgEnabled ) {
-		MultiGrid_BuildSmoothers( sle->mgHandles[0] );
-		MultiGrid_UpdateMatrixSolver( sle->mgHandles[0], self->matrixSolver, (SLE_Solver*)self );
+		/*MultiGrid_BuildSmoothers( sle->mgHandles[0] );*/
+		/*MultiGrid_UpdateMatrixSolver( sle->mgHandles[0], self->matrixSolver, (SLE_Solver*)self );*/
 	}
 	
 	/* If a stat solve was specified then do so. */

Modified: long/3D/Gale/trunk/src/StgFEM/SLE/ProvidedSystems/StokesFlow/src/Stokes_SLE_UzawaSolver.c
===================================================================
--- long/3D/Gale/trunk/src/StgFEM/SLE/ProvidedSystems/StokesFlow/src/Stokes_SLE_UzawaSolver.c	2006-12-07 23:26:14 UTC (rev 5532)
+++ long/3D/Gale/trunk/src/StgFEM/SLE/ProvidedSystems/StokesFlow/src/Stokes_SLE_UzawaSolver.c	2006-12-07 23:29:43 UTC (rev 5533)
@@ -287,7 +287,7 @@
 	
 	/* MG: If multi-grid is enabled, enable it on the velocity matrix solver. */
 	if( sle->mgEnabled ) {
-		MultiGrid_InitMatrixSolver( sle->mgHandles[0], self->velSolver );
+		/*MultiGrid_InitMatrixSolver( sle->mgHandles[0], self->velSolver );*/
 	}
 
 	if ( sle->context && (True == sle->context->loadFromCheckPoint) ) {
@@ -320,13 +320,13 @@
 
 	if( sle->mgEnabled ) {
 		if( sle->mgUpdate ) {
-			MultiGrid_BuildGridOps( sle->mgHandles[0] );
-			MultiGrid_BuildWorkVectors( sle->mgHandles[0] );
+			/*MultiGrid_BuildGridOps( sle->mgHandles[0] );*/
+			/*MultiGrid_BuildWorkVectors( sle->mgHandles[0] );*/
 			sle->mgUpdate = False;
 		}
 
-		MultiGrid_BuildSmoothers( sle->mgHandles[0] );
-		MultiGrid_UpdateMatrixSolver( sle->mgHandles[0], self->velSolver, (SLE_Solver*)self );
+		/*MultiGrid_BuildSmoothers( sle->mgHandles[0] );*/
+		/*MultiGrid_UpdateMatrixSolver( sle->mgHandles[0], self->velSolver, (SLE_Solver*)self );*/
 	}
 
 	Stream_UnIndentBranch( StgFEM_Debug );

Modified: long/3D/Gale/trunk/src/StgFEM/SLE/ProvidedSystems/StokesFlow/src/UzawaPreconditionerTerm.c
===================================================================
--- long/3D/Gale/trunk/src/StgFEM/SLE/ProvidedSystems/StokesFlow/src/UzawaPreconditionerTerm.c	2006-12-07 23:26:14 UTC (rev 5532)
+++ long/3D/Gale/trunk/src/StgFEM/SLE/ProvidedSystems/StokesFlow/src/UzawaPreconditionerTerm.c	2006-12-07 23:29:43 UTC (rev 5533)
@@ -198,13 +198,13 @@
 	Stokes_SLE*            sle              = Stg_DCheckType( _sle, Stokes_SLE );
 	StiffnessMatrix*       gMatrix          = sle->gStiffMat;
 	FeVariable*            gFeVariable_col  = gMatrix->columnVariable;
-	ElementType*           gElementType_col = FeMesh_ElementTypeAt( gFeVariable_col->feMesh, lElement_I );
+	ElementType*           gElementType_col = FeMesh_GetElementType( gFeVariable_col->feMesh, lElement_I );
 	Node_ElementLocalIndex gColCount        = gElementType_col->nodeCount;
 	double**               gElementMatrix;
 
 	StiffnessMatrix*       kMatrix          = sle->kStiffMat;
 	FeVariable*            kFeVariable_row  = kMatrix->rowVariable;
-	ElementType*           kElementType_row = FeMesh_ElementTypeAt( kFeVariable_row->feMesh, lElement_I );
+	ElementType*           kElementType_row = FeMesh_GetElementType( kFeVariable_row->feMesh, lElement_I );
 	Node_ElementLocalIndex kRowCount        = kElementType_row->nodeCount;
 
 	Index                  velocityDofCount;

Modified: long/3D/Gale/trunk/src/StgFEM/SLE/SystemSetup/src/ForceVector.c
===================================================================
--- long/3D/Gale/trunk/src/StgFEM/SLE/SystemSetup/src/ForceVector.c	2006-12-07 23:26:14 UTC (rev 5532)
+++ long/3D/Gale/trunk/src/StgFEM/SLE/SystemSetup/src/ForceVector.c	2006-12-07 23:29:43 UTC (rev 5533)
@@ -351,12 +351,19 @@
 		Dof_EquationNumber** elementLM,
 		double* elForceVecToAdd )
 {
-	Dof_Index		dofsPerNode = self->feVariable->dofLayout->dofCounts[ self->feVariable->feMesh->elementNodeTbl[element_lI][0] ];
-	Node_LocalIndex		nodesThisEl = self->feVariable->feMesh->elementNodeCountTbl[element_lI];
+	DofLayout*		dofLayout = self->feVariable->dofLayout;
+	FeMesh*			feMesh = self->feVariable->feMesh;
+	unsigned		nInc, *inc;
+	Dof_Index		dofsPerNode;
+	Node_LocalIndex		nodesThisEl;
 	Node_LocalIndex		node_I;
 	Dof_Index		dof_I;
 	Index			vec_I;
 
+	FeMesh_GetElementNodes( feMesh, element_lI, &nInc, &inc );
+	dofsPerNode = dofLayout->dofCounts[inc[0]];
+	nodesThisEl = nInc;
+
 	for ( node_I=0; node_I < nodesThisEl; node_I++ ) {
 		for ( dof_I = 0; dof_I < dofsPerNode; dof_I++ ) {
 			vec_I = node_I * dofsPerNode + dof_I;
@@ -396,17 +403,19 @@
 		return;
 	}
 
-	elementLocalCount = feVar->feMesh->elementLocalCount;
+	elementLocalCount = FeMesh_GetElementLocalSize( feVar->feMesh );
 
 	/* Initialise Vector */
 	outputInterval = (int)( (outputPercentage/100.0)*(double)(elementLocalCount) );
 	if( outputInterval == 0 ) { outputInterval = elementLocalCount; }
 	
 	for( element_lI = 0; element_lI < elementLocalCount; element_lI++ ) {  
+		unsigned	nInc, *inc;
 		
-		nodeCountCurrElement = feVar->feMesh->elementNodeCountTbl[ element_lI ];
+		FeMesh_GetElementNodes( feVar->feMesh, element_lI, &nInc, &inc );
+		nodeCountCurrElement = nInc;
 		/* Get the local node ids */
-		nodeIdsInCurrElement = feVar->feMesh->elementNodeTbl[ element_lI ];
+		nodeIdsInCurrElement = inc;
 
 		/* Set value of elementLM: will automatically just index into global LM table if built */
 		elementLM = FeEquationNumber_BuildOneElementLocationMatrix( feVar->eqNum, element_lI );

Modified: long/3D/Gale/trunk/src/StgFEM/SLE/SystemSetup/src/SolutionVector.c
===================================================================
--- long/3D/Gale/trunk/src/StgFEM/SLE/SystemSetup/src/SolutionVector.c	2006-12-07 23:26:14 UTC (rev 5532)
+++ long/3D/Gale/trunk/src/StgFEM/SLE/SystemSetup/src/SolutionVector.c	2006-12-07 23:29:43 UTC (rev 5533)
@@ -324,7 +324,8 @@
 	Dof_Index		nodeLocalDof_I;
 	Partition_Index		ownerProc;
 	FeVariable*		feVar = self->feVariable;
-	FiniteElement_Mesh*	feMesh = feVar->feMesh;
+	FeMesh*			feMesh = feVar->feMesh;
+	MPI_Comm		comm;
 	FeEquationNumber*	eqNum = feVar->eqNum;
 	Dof_EquationNumber	currEqNum;
 	Index			indexIntoLocalSolnVecValues;
@@ -332,8 +333,9 @@
 	Index*			reqFromOthersSizes;
 	RequestInfo**		reqFromOthersInfos;
 	Dof_EquationNumber**	reqFromOthers;
-	Partition_Index		nProc = self->feVariable->feMesh->layout->decomp->nproc;
-	Partition_Index		myRank = self->feVariable->feMesh->layout->decomp->rank;
+	CommTopology*		commTopo;
+	Partition_Index		nProc;
+	Partition_Index		myRank;
 	Partition_Index		proc_I;
 	double			initialGuessAtNonLocalEqNumsRatio = 0.1;
 	double			ratioToIncreaseRequestArraySize = 1.5;
@@ -349,6 +351,11 @@
 	}
 	#endif
 
+	commTopo = Mesh_GetCommTopology( feMesh, MT_VERTEX );
+	comm = CommTopology_GetComm( commTopo );
+	MPI_Comm_size( comm, (int*)&nProc );
+	MPI_Comm_rank( comm, (int*)&myRank );
+
 	/* allocate arrays for nodes that I want on each processor */
 	reqFromOthersCounts = Memory_Alloc_Array( Index, nProc, "reqFromOthersCounts" );
 	reqFromOthersSizes = Memory_Alloc_Array( Index, nProc, "reqFromOthersSizes" );
@@ -375,7 +382,7 @@
 	/* Get the locally held part of the vector */
 	Vector_Get( self->vector, &localSolnVecValues );
 	
-	for( lNode_I=0; lNode_I < feMesh->nodeLocalCount; lNode_I++ ) {
+	for( lNode_I=0; lNode_I < Mesh_GetLocalSize( feMesh, MT_VERTEX ); lNode_I++ ) {
 		currNodeNumDofs = feVar->dofLayout->dofCounts[ lNode_I ];
 		Journal_DPrintfL( self->debug, 3, "getting solutions for local node %d, has %d dofs.\n", lNode_I, currNodeNumDofs );
 		
@@ -449,6 +456,12 @@
 
 	Vector_Restore( self->vector, &localSolnVecValues );
 
+	/*
+	** Syncronise the FEVariable in question.
+	*/
+
+	FeVariable_SyncShadowValues( feVar );
+
 	Stream_UnIndentBranch( StgFEM_Debug );
 }
 
@@ -462,11 +475,12 @@
 {
 
 	FeVariable*		feVar = self->feVariable;
-	FiniteElement_Mesh*	feMesh = feVar->feMesh;
+	FeMesh*			feMesh = feVar->feMesh;
 	FeEquationNumber*	eqNum = feVar->eqNum;
-	MeshDecomp*		meshDecomp = feMesh->layout->decomp;
-	Partition_Index		nProc = self->feVariable->feMesh->layout->decomp->nproc;
-	Partition_Index		myRank = self->feVariable->feMesh->layout->decomp->rank;
+	CommTopology*		commTopo;
+	MPI_Comm		comm;
+	Partition_Index		nProc;
+	Partition_Index		myRank;
 	Partition_Index		proc_I;
 	Index			req_I;
 	Index			indexIntoLocalSolnVecValues;
@@ -486,6 +500,11 @@
 	Journal_DPrintf( self->debug, "In %s - for \"%s\"\n", __func__, self->name );
 	Stream_IndentBranch( StgFEM_Debug );
 
+	commTopo = Mesh_GetCommTopology( feMesh, MT_VERTEX );
+	comm = CommTopology_GetComm( commTopo );
+	MPI_Comm_size( comm, (int*)&nProc );
+	MPI_Comm_rank( comm, (int*)&myRank );
+
 	reqFromMeCounts = Memory_Alloc_Array( Index, nProc, "reqFromMeCounts" );
 	reqFromOthersHandles = Memory_Alloc_Array_Unnamed( MPI_Request*, nProc );
 	reqValuesFromOthersHandles = Memory_Alloc_Array_Unnamed( MPI_Request*, nProc );
@@ -512,7 +531,7 @@
 	
 	/* send out my request counts, receive the req. counts others want from me */
 	MPI_Alltoall( reqFromOthersCounts, 1, MPI_UNSIGNED,
-		reqFromMeCounts, 1, MPI_UNSIGNED, meshDecomp->communicator );
+		      reqFromMeCounts, 1, MPI_UNSIGNED, comm );
 
 	Journal_DPrintf( self->debug, "After MPI_Alltoall- counts are:\n" );
 	totalRequestedFromOthers = 0;
@@ -560,7 +579,7 @@
 
 			reqFromOthersHandles[proc_I] = Memory_Alloc_Unnamed( MPI_Request );
 			MPI_Isend( reqFromOthers[proc_I], reqFromOthersCounts[proc_I], MPI_UNSIGNED,
-				proc_I, VALUE_REQUEST_TAG, meshDecomp->communicator, reqFromOthersHandles[proc_I] );
+				proc_I, VALUE_REQUEST_TAG, comm, reqFromOthersHandles[proc_I] );
 		}	
 	}
 	Stream_UnIndent( self->debug );
@@ -576,7 +595,7 @@
 				reqFromOthersCounts[proc_I], proc_I, VALUE_TAG );
 			reqValuesFromOthersHandles[proc_I] = Memory_Alloc_Unnamed( MPI_Request );
 			MPI_Irecv( reqValuesFromOthers[proc_I], reqFromOthersCounts[proc_I], MPI_DOUBLE,
-				proc_I, VALUE_TAG, meshDecomp->communicator, reqValuesFromOthersHandles[proc_I] );
+				proc_I, VALUE_TAG, comm, reqValuesFromOthersHandles[proc_I] );
 		}	
 	}
 	Stream_UnIndent( self->debug );
@@ -591,7 +610,7 @@
 ///Journal_Printf( Journal_Register( Info_Type, "mpi" ),  "!!! line %d, proc_I %d: count = %u\n", __LINE__, proc_I, reqFromMeCounts[proc_I] );
 		if ( reqFromMeCounts[proc_I] > 0 ) {
 			MPI_Recv( reqFromMe[proc_I], reqFromMeCounts[proc_I], MPI_UNSIGNED,
-				proc_I, VALUE_REQUEST_TAG, meshDecomp->communicator, &status );
+				proc_I, VALUE_REQUEST_TAG, comm, &status );
 			Journal_DPrintfL( self->debug, 3, "Received a list of %u requested vector entry indices from proc %u, "
 				"with tag %d\n", reqFromMeCounts[proc_I], proc_I, status.MPI_TAG );
 		}	
@@ -637,7 +656,7 @@
 				"\t(tracking via reqValuesFromMe[%d], tag %d)\n", proc_I,
 				reqFromMeCounts[proc_I], proc_I, VALUE_TAG );
 			MPI_Isend( reqValuesFromMe[proc_I], reqFromMeCounts[proc_I], MPI_DOUBLE,
-				proc_I, VALUE_TAG, meshDecomp->communicator, reqValuesFromMeHandles[proc_I] );
+				proc_I, VALUE_TAG, comm, reqValuesFromMeHandles[proc_I] );
 		}	
 	}
 	Stream_UnIndent( self->debug );
@@ -760,13 +779,13 @@
 void SolutionVector_LoadCurrentFeVariableValuesOntoVector( void* solutionVector ) {
 	SolutionVector*		self = (SolutionVector*)solutionVector;
 	FeVariable*		feVar = self->feVariable;
-	FiniteElement_Mesh*	feMesh = feVar->feMesh;
+	FeMesh*			feMesh = feVar->feMesh;
 	Node_LocalIndex		node_lI = 0;
 	Dof_Index		dof_I = 0;
 	double			value = 0;
 	Index			insertionIndex = 0;
 	
-	for ( node_lI = 0; node_lI < feMesh->nodeLocalCount; node_lI++ ) {
+	for ( node_lI = 0; node_lI < FeMesh_GetNodeLocalSize( feMesh ); node_lI++ ) {
 		for ( dof_I = 0; dof_I < feVar->dofLayout->dofCounts[node_lI]; dof_I++ ) {
 			value = DofLayout_GetValueDouble( feVar->dofLayout, node_lI, dof_I );
 			insertionIndex = feVar->eqNum->destinationArray[node_lI][dof_I];

Modified: long/3D/Gale/trunk/src/StgFEM/SLE/SystemSetup/src/StiffnessMatrix.c
===================================================================
--- long/3D/Gale/trunk/src/StgFEM/SLE/SystemSetup/src/StiffnessMatrix.c	2006-12-07 23:26:14 UTC (rev 5532)
+++ long/3D/Gale/trunk/src/StgFEM/SLE/SystemSetup/src/StiffnessMatrix.c	2006-12-07 23:29:43 UTC (rev 5533)
@@ -220,8 +220,6 @@
 	Journal_Firewall( (rhs != NULL), error, "Error: NULL rhs ForceVector provided to \"%s\" %s.\n",
 		self->name, self->type );
 	self->rhs = (ForceVector*)rhs;
-	Journal_Firewall( (comm != 0), error, "Error: NULL Comm provided to \"%s\" %s.\n",
-		self->name, self->type );
 	self->applicationDepInfo = applicationDepInfo;
 	self->comm = comm;
 	self->dim = dim;
@@ -254,10 +252,10 @@
 	StiffnessMatrix* self = (StiffnessMatrix*)stiffnessMatrix;
 	
 	Journal_DPrintf( self->debug, "In %s - for matrix %s\n", __func__, self->name );
-	Stg_Class_Delete( self->stiffnessMatrixTermList );
-	Memory_Free( self->_assembleStiffnessMatrixEPName );
-	Memory_Free( self->diagonalNonZeroIndices );
-	Memory_Free( self->offDiagonalNonZeroIndices );
+	FreeObject( self->stiffnessMatrixTermList );
+	FreeArray( self->_assembleStiffnessMatrixEPName );
+	FreeArray( self->diagonalNonZeroIndices );
+	FreeArray( self->offDiagonalNonZeroIndices );
 	/* Don't delete entry points: E.P. register will delete them automatically */
 
 	/* Stg_Class_Delete parent*/
@@ -399,7 +397,6 @@
 	Dimension_Index  dim                = 0;
 	Bool             isNonLinear;
 	Bool             allowZeroElementContributions;
-	MPI_Comm         comm               = 0;
 	
 	rowVar             = Stg_ComponentFactory_ConstructByKey( cf, self->name, "RowVariable",        FeVariable,    True, data );
 	colVar             = Stg_ComponentFactory_ConstructByKey( cf, self->name, "ColumnVariable",     FeVariable,    True, data );
@@ -416,8 +413,6 @@
 
 	/* Default is to allow zero element contributions - to allow backward compatibility */
 	allowZeroElementContributions = Stg_ComponentFactory_GetBool( cf, self->name, "allowZeroElementContributions", True );
-	
-	comm = rowVar->feMesh->layout->decomp->communicator;
 
 	_StiffnessMatrix_Init( 
 			self, 
@@ -429,7 +424,7 @@
 			isNonLinear,
 			allowZeroElementContributions,
 			entryPointRegister, 
-			comm ); 
+			0 );
 }
 
 void _StiffnessMatrix_Build( void* stiffnessMatrix, void* data ) {
@@ -437,10 +432,17 @@
 
 	Journal_DPrintf( self->debug, "In %s - for matrix %s\n", __func__, self->name );
 	Stream_IndentBranch( StgFEM_Debug );
-	
+
 	/* ensure variables are built */
 	if( self->rowVariable )
 		Build( self->rowVariable, data, False );
+
+	/* If we don't have a communicator, grab one off the mesh. */
+	if( !self->comm ) {
+		self->comm = Mesh_GetCommTopology( self->rowVariable->feMesh, MT_VERTEX )->comm;
+		Journal_Firewall( (self->comm != 0), self->debug, "Error: NULL Comm provided to \"%s\" %s.\n",
+				  self->name, self->type );
+	}
 	
 	if( self->columnVariable )
 		Build( self->columnVariable, data, False );
@@ -520,8 +522,8 @@
 
 void _StiffnessMatrix_CalculateNonZeroEntries( void* stiffnessMatrix ) {
 	StiffnessMatrix*	self = (StiffnessMatrix*)stiffnessMatrix;
-	FiniteElement_Mesh*	rFeMesh = self->rowVariable->feMesh;
-	FiniteElement_Mesh*	cFeMesh = self->columnVariable->feMesh;
+	FeMesh*			rFeMesh = self->rowVariable->feMesh;
+	FeMesh*			cFeMesh = self->columnVariable->feMesh;
 	FeEquationNumber*	rowEqNum = self->rowVariable->eqNum;
 	Dof_EquationNumber	currMatrixRow = 0;
 	Node_LocalIndex		rowNode_lI = 0;
@@ -537,8 +539,8 @@
 	assert ( self->rowVariable );
 	assert ( self->columnVariable );
 
-	Journal_DPrintfL( self->debug, 1, "row nodeLocalCount %d\n", rFeMesh->nodeLocalCount );
-	Journal_DPrintfL( self->debug, 1, "column nodeLocalCount %d\n", cFeMesh->nodeLocalCount );
+	Journal_DPrintfL( self->debug, 1, "row nodeLocalCount %d\n", FeMesh_GetNodeLocalSize( rFeMesh ) );
+	Journal_DPrintfL( self->debug, 1, "column nodeLocalCount %d\n", FeMesh_GetNodeLocalSize( cFeMesh ) );
 	
 	self->diagonalNonZeroIndices = Memory_Alloc_Array  ( Index, self->rowLocalSize, "diagonalNonZeroIndices" );
 	self->offDiagonalNonZeroIndices = Memory_Alloc_Array  ( Index, self->rowLocalSize, "offDiagonalNonZeroIndices" );
@@ -547,7 +549,7 @@
 		self->offDiagonalNonZeroIndices[rowNode_lI] = 0;
 	}
 
-	for( rowNode_lI = 0; rowNode_lI < rFeMesh->nodeLocalCount; rowNode_lI++ ) {
+	for( rowNode_lI = 0; rowNode_lI < FeMesh_GetNodeLocalSize( rFeMesh ); rowNode_lI++ ) {
 		activeEqsAtCurrRowNodeCount = FeEquationNumber_CalculateActiveEqCountAtNode( rowEqNum, rowNode_lI,
 			&lowestActiveEqNumAtCurrRowNode );
 
@@ -585,8 +587,8 @@
 		Dof_EquationNumber	currMatrixRow,
 		Index			activeEqsAtCurrRowNode )
 {
-	FiniteElement_Mesh*	rFeMesh = self->rowVariable->feMesh;
-	FiniteElement_Mesh*	cFeMesh = self->columnVariable->feMesh;
+	FeMesh*			rFeMesh = self->rowVariable->feMesh;
+	FeMesh*			cFeMesh = self->columnVariable->feMesh;
 	DofLayout*		colDofLayout = self->columnVariable->dofLayout;
 	FeEquationNumber*	rowEqNum = self->rowVariable->eqNum;
 	FeEquationNumber*	colEqNum = self->columnVariable->eqNum;
@@ -602,18 +604,20 @@
 	Node_Index		uniqueRelatedColNode_I = 0;
 	Dof_Index		currNodeDof_I = 0;
 	Dof_EquationNumber	currDofMatrixRow = 0;
+	unsigned		nNodeInc, *nodeInc;
 
 	Journal_DPrintfL( self->debug, 3, "In %s - for row local node %d\n", __func__, rowNode_lI );
 	Stream_Indent( self->debug );
 
-	for ( rowNodeElement_I = 0; rowNodeElement_I < rFeMesh->nodeElementCountTbl[rowNode_lI]; rowNodeElement_I++ ) {
+	FeMesh_GetNodeElements( rFeMesh, rowNode_lI, &nNodeInc, &nodeInc );
+	for ( rowNodeElement_I = 0; rowNodeElement_I < nNodeInc; rowNodeElement_I++ ) {
+		unsigned	nElInc;
+
 		/* note the dI (domain index) - some of these elements may be in shadow space */
-		element_dI = rFeMesh->nodeElementTbl[rowNode_lI][rowNodeElement_I];
-		/* Needed because the nodeElementTbl has empty spots to indicate geographic positions */
-		if ( element_dI == rFeMesh->elementGlobalCount ) {
-			continue;
-		}
-		uniqueRelatedColNodes_AllocCount += cFeMesh->elementNodeCountTbl[element_dI];
+		element_dI = nodeInc[rowNodeElement_I];
+
+		nElInc = FeMesh_GetElementNodeSize( cFeMesh, element_dI );
+		uniqueRelatedColNodes_AllocCount += nElInc;
 	}
 	
 	Journal_DPrintfL( self->debug, 3, "Calculated the max possible number of unique related nodes as %d\n",
@@ -700,37 +704,34 @@
 		Node_DomainIndex*	uniqueRelatedColNodes,
 		Node_Index*		uniqueRelatedColNodesCountPtr )
 {
-	FiniteElement_Mesh*	rFeMesh = self->rowVariable->feMesh;
-	FiniteElement_Mesh*	cFeMesh = self->columnVariable->feMesh;
+	FeMesh*			rFeMesh = self->rowVariable->feMesh;
+	FeMesh*			cFeMesh = self->columnVariable->feMesh;
 	Element_Index		rowNodeElement_I = 0;
 	Element_DomainIndex	element_dI = 0;
 	Node_Index		colElLocalNode_I = 0;
 	Node_DomainIndex	colNode_dI = 0;
 	Node_Index		uniqueRelatedColNode_I = 0;
+	unsigned		nNodeInc, *nodeInc;
 
+	FeMesh_GetNodeElements( rFeMesh, rowNode_lI, &nNodeInc, &nodeInc );
 	Journal_DPrintfL( self->debug, 3, "Searching the %d elements this node belongs to for unique related col nodes:\n",
-		rFeMesh->nodeElementCountTbl[rowNode_lI] );
+		nNodeInc );
 	
 	Stream_Indent( self->debug );
-	for ( rowNodeElement_I = 0; rowNodeElement_I < rFeMesh->nodeElementCountTbl[rowNode_lI]; rowNodeElement_I++ ) {
+	for ( rowNodeElement_I = 0; rowNodeElement_I < nNodeInc; rowNodeElement_I++ ) {
+		unsigned	nElInc, *elInc;
+
 		/* note the dI (domain index) - some of these elements may be in shadow space */
-		element_dI = rFeMesh->nodeElementTbl[rowNode_lI][rowNodeElement_I];
+		element_dI = nodeInc[rowNodeElement_I];
 
 		Journal_DPrintfL( self->debug, 3, "rowNodeElement_I: ", rowNodeElement_I );
-		/* Needed because the nodeElementTbl has empty spots to indicate geographic positions */
-		if ( element_dI == rFeMesh->elementGlobalCount ) {
-			Journal_DPrintfL( self->debug, 3, "Nonexistent element ->continue\n" );
-			continue;
-		}
-		else {
-			Journal_DPrintfL( self->debug, 3, "domain element %d\n", element_dI );
-		}
+		Journal_DPrintfL( self->debug, 3, "domain element %d\n", element_dI );
 		
 		Stream_Indent( self->debug );
-		Journal_DPrintfL( self->debug, 3, "Searching the %d column var nodes in this el:\n",
-			cFeMesh->elementNodeCountTbl[element_dI] );
-		for ( colElLocalNode_I =0; colElLocalNode_I < cFeMesh->elementNodeCountTbl[element_dI]; colElLocalNode_I++ ) {
-			colNode_dI = cFeMesh->elementNodeTbl[element_dI][colElLocalNode_I];
+		FeMesh_GetElementNodes( cFeMesh, element_dI, &nElInc, &elInc );
+		Journal_DPrintfL( self->debug, 3, "Searching the %d column var nodes in this el:\n", nElInc );
+		for ( colElLocalNode_I =0; colElLocalNode_I < nElInc; colElLocalNode_I++ ) {
+			colNode_dI = elInc[colElLocalNode_I];
 			
 			Journal_DPrintfL( self->debug, 3, "Col domain node %d: ", colNode_dI );
 			for ( uniqueRelatedColNode_I = 0; uniqueRelatedColNode_I < (*uniqueRelatedColNodesCountPtr); uniqueRelatedColNode_I++ )
@@ -828,6 +829,8 @@
 	double                  matAddingTime         = 0;
 	double                  elStiffMatBuildStart;
 	double                  elStiffMatBuildTime   = 0;
+	Bool			updateRHS;
+	MPI_Comm		comm;
 
 	/* Do some type checking */
 	if ( sle ) {
@@ -836,6 +839,9 @@
 	
 	feVars[0] = self->rowVariable;
 	feVars[1] = self->columnVariable;
+
+	/* Get communicator. */
+	comm = Mesh_GetCommTopology( feVars[0]->feMesh, MT_VERTEX )->comm;
 	
 	startTime = MPI_Wtime();
 
@@ -868,13 +874,13 @@
 	}
 	
 	/* Assumes that both row and col variables have same number of variables */
-	nLocalElements = feVars[ROW_VAR]->feMesh->elementLocalCount;
+	nLocalElements = FeMesh_GetElementLocalSize( feVars[ROW_VAR]->feMesh );
 	
 	/* Initialise matrix */
 	Matrix_Zero( self->matrix );
 	outputInterval = (int)( (outputPercentage/100.0)*(double)(nLocalElements) );
 	if( outputInterval == 0 ) { outputInterval = nLocalElements; }
-	
+
 	for( element_lI = 0; element_lI < nLocalElements; element_lI++ ) {  
 		
 		/* This loop is how we handle the possiblity of different row-column variables: if both variables are
@@ -884,18 +890,26 @@
 			FeEquationNumber* 		feEqNum = feVars[feVar_I]->eqNum;
 			DofLayout*			dofLayout = feVars[feVar_I]->dofLayout;
 			Dof_Index			dofCountLastNode;
+			unsigned			nDofsThisEl;
+			unsigned			n_i;
 
 			/* Get the local node ids */
-			nodeCountThisEl = feVars[feVar_I]->feMesh->elementNodeCountTbl[element_lI];
-			nodeIdsThisEl = feVars[feVar_I]->feMesh->elementNodeTbl[element_lI];
+			FeMesh_GetElementNodes( feVars[feVar_I]->feMesh, element_lI, 
+						&nodeCountThisEl, &nodeIdsThisEl );
 
 			/* Set value of elementLM: will automatically use large one if built */
 			elementLM[feVar_I] = FeEquationNumber_BuildOneElementLocationMatrix( feEqNum, element_lI );
 
 			/* work out number of dofs at the node, based on LM */
-			dofCountLastNode = dofLayout->dofCounts[nodeIdsThisEl[nodeCountThisEl-1]]; 
+			dofCountLastNode = dofLayout->dofCounts[nodeIdsThisEl[nodeCountThisEl-1]];
+			nDofsThisEl = dofLayout->dofCounts[nodeIdsThisEl[0]];
+			for( n_i = 1; n_i < nodeCountThisEl; n_i++ )
+				nDofsThisEl += dofLayout->dofCounts[nodeIdsThisEl[n_i]];
+			*totalDofsThisElement[feVar_I] = nDofsThisEl;
+/*
 			*totalDofsThisElement[feVar_I] = &elementLM[feVar_I][nodeCountThisEl-1][dofCountLastNode-1]
 				- &elementLM[feVar_I][0][0] + 1;
+*/
 
 			if ( *totalDofsThisElement[feVar_I] > *totalDofsPrevElement[feVar_I] ) {
 				Journal_DPrintfL( self->debug, 2, "Reallocating bcLM_Id and bcValues for fe var \"%s\" "
@@ -936,7 +950,7 @@
 			StiffnessMatrix_CheckElementAssembly( self, element_lI, elStiffMatToAdd, *totalDofsThisElement[ROW_VAR],
 				*totalDofsThisElement[COL_VAR] );
 		}	
-			
+
 		/* This loop is how we handle the possiblity of different row-column variables: if both variables are
 		 * the same, then numFeVars is set to 1 and the loop only progresses through once.
 		-- PatrickSunter 13 September 2004 */
@@ -947,19 +961,23 @@
 
 			/* Check if we want to build table of corrected BC info for the matrix */
 			if( bcRemoveQuery == True ) {
+				unsigned	nNodeInc, *nodeInc;
+
+				FeMesh_GetElementNodes( feVars[feVar_I]->feMesh, element_lI, 
+							&nNodeInc, &nodeInc );
 				_StiffnessMatrix_UpdateBC_CorrectionTables(
 					self,
 					feVars[feVar_I]->eqNum, 
 					feVars[feVar_I]->dofLayout,
 					elementLM[feVar_I],
-					feVars[feVar_I]->feMesh->elementNodeCountTbl[element_lI],
-					feVars[feVar_I]->feMesh->elementNodeTbl[element_lI],
+					nNodeInc, 
+					nodeInc, 
 					bcLM_Id[feVar_I],
 					bcValues[feVar_I],
 					&(nBC_NodalDof[feVar_I]) );
 			}
 		}	
-		
+
 		/* If there is only one feVar, use the same LM for both row and col insertion */
 		if ( numFeVars == 1 ) elementLM[COL_VAR] = elementLM[ROW_VAR];
 
@@ -1002,7 +1020,6 @@
 				nBC_NodalDof[ROW_VAR] );
 		}
 
-
 		/*
 		** If not keeping BCs in, we may need to zero some of these element values, or set them to one.
 		*/
@@ -1053,7 +1070,6 @@
 			}
 		}
 
-
 		/* Add to the global matrix. */
 		matAddingStart = MPI_Wtime();
 		Matrix_AddTo( self->matrix, *totalDofsThisElement[ROW_VAR], (Index *)(elementLM[ROW_VAR][0]), *totalDofsThisElement[COL_VAR],
@@ -1083,10 +1099,11 @@
 	Matrix_AssemblyBegin( self->matrix );
 	Matrix_AssemblyEnd( self->matrix );	
 	
-	if( modifiedRHS_Vec_cont == True && bcRemoveQuery ) {
+	MPI_Allreduce( &modifiedRHS_Vec_cont, &updateRHS, 1, MPI_UNSIGNED, MPI_LOR, comm );
+	if( updateRHS == True && bcRemoveQuery ) {
 		/* stuff was submitted to vec (at least once) and needs to be assembled */
 		Vector_AssemblyBegin( self->rhs->vector );
-		Vector_AssemblyEnd( self->rhs->vector ); 
+		Vector_AssemblyEnd( self->rhs->vector );
 	}
 
 	////////////////////////////////////////////////////////
@@ -1099,9 +1116,9 @@
 	    (!self->columnVariable || !self->columnVariable->eqNum->removeBCs) )
 	{
 		FeEquationNumber*	colEqNum = self->columnVariable->eqNum;
-		FiniteElement_Mesh*	feMesh = self->columnVariable->feMesh;
+		FeMesh*			feMesh = self->columnVariable->feMesh;
 		DofLayout*		dofLayout = self->columnVariable->dofLayout;
-		unsigned		nNodes = feMesh->nodeLocalCount;
+		unsigned		nNodes = FeMesh_GetNodeLocalSize( feMesh );
 		unsigned		node_i;
 
 		/* What to do if they aren't the same? */
@@ -1175,8 +1192,8 @@
 	Dof_Index*			dofCounts = dofLayout->dofCounts;
 	Dof_Index			dofCountThisNode=0;
 	Dof_Index			dof_nodeLocalI=0;
+	unsigned			pos = 0;
 
-
 	for( node_elLocalI = 0; node_elLocalI < nodeCountThisEl; node_elLocalI++ ) {
 		node_lI = nodeIdsThisEl[node_elLocalI];
 		dofCountThisNode = dofCounts[node_lI];
@@ -1187,7 +1204,7 @@
 			/* Can only use 'elementLM' if FeEquationNumber has been told to remove BCs.  Otherwise
 			   we'll need to determine if the VariableCondition has a value specified for this 
 			   node/dof. - Luke */
-			if( elementLM[node_elLocalI][dof_nodeLocalI] != -1 ) {
+			if( elementLM[node_elLocalI][dof_nodeLocalI] != (unsigned)-1 ) {
 				unsigned	lEqNum = elementLM[node_elLocalI][dof_nodeLocalI] - eqNum->_lowestLocalEqNum;
 
 				if( eqNum->bcEqNums && IndexSet_IsMember( eqNum->bcEqNums, lEqNum ) ) {
@@ -1200,7 +1217,10 @@
 
 			if ( isBC ) {
 				/* offset into the elementStiffness matrix */
+				bcLM_Id[ *nBC_NodalDofPtr ] = pos;
+/*
 				bcLM_Id[ *nBC_NodalDofPtr ] = &elementLM[node_elLocalI][dof_nodeLocalI] - &elementLM[0][0];
+*/
 
 				// get bc values from the bc_layout 
 				bcValues[ *nBC_NodalDofPtr ]  = DofLayout_GetValueDouble( dofLayout, node_lI, dof_nodeLocalI );
@@ -1212,6 +1232,9 @@
 
 				(*nBC_NodalDofPtr)++;
 			}
+
+			/* Move to next element stiffness matrix entry. */
+			pos++;
 		}
 	}
 }	
@@ -1247,6 +1270,7 @@
 		}
 		h2Add[colDof_elLocalI] = sum;
 	}
+
 	Vector_AddTo( self->rhs->vector, *totalDofsThisElement[COL_VAR], (Index *)(elementLM[COL_VAR][0]), h2Add );
 	
 	/* assume that K is symetric, so corrections are made with KTrans.
@@ -1297,14 +1321,26 @@
 		Dof_EquationNumber** colElementLM,
 		double** elStiffMatToAdd )
 {
-	Dof_Index		rowDofsPerNode = self->rowVariable->dofLayout->dofCounts[ self->rowVariable->feMesh->elementNodeTbl[element_lI][0] ];
-	Dof_Index		colDofsPerNode = self->columnVariable->dofLayout->dofCounts[ self->columnVariable->feMesh->elementNodeTbl[element_lI][0] ];
-	Node_LocalIndex		rowNodesThisEl = self->rowVariable->feMesh->elementNodeCountTbl[element_lI];
-	Node_LocalIndex		colNodesThisEl = self->columnVariable->feMesh->elementNodeCountTbl[element_lI];
+	FeMesh*			rFeMesh = self->rowVariable->feMesh;
+	FeMesh*			cFeMesh = self->columnVariable->feMesh;
+	Dof_Index		rowDofsPerNode;
+	Dof_Index		colDofsPerNode;
+	Node_LocalIndex		rowNodesThisEl;
+	Node_LocalIndex		colNodesThisEl;
 	Node_LocalIndex		rowNode_I, colNode_I;
 	Dof_Index		rowDof_I, colDof_I;
 	Index			rowIndex, colIndex;
+	unsigned		nRowElInc, *rowElInc;
+	unsigned		nColElInc, *colElInc;
 
+	FeMesh_GetElementNodes( rFeMesh, element_lI, &nRowElInc, &rowElInc );
+	FeMesh_GetElementNodes( cFeMesh, element_lI, &nColElInc, &colElInc );
+
+	rowDofsPerNode = self->rowVariable->dofLayout->dofCounts[rowElInc[0]];
+	colDofsPerNode = self->columnVariable->dofLayout->dofCounts[colElInc[0]];
+	rowNodesThisEl = nRowElInc;
+	colNodesThisEl = nColElInc;
+
 	for ( rowNode_I=0; rowNode_I < rowNodesThisEl; rowNode_I++ ) {
 		for ( rowDof_I = 0; rowDof_I < rowDofsPerNode; rowDof_I++ ) {
 			for ( colNode_I=0; colNode_I < colNodesThisEl; colNode_I++ ) {

Added: long/3D/Gale/trunk/src/StgFEM/SLE/SystemSetup/tests/data/wallVC.xml
===================================================================
--- long/3D/Gale/trunk/src/StgFEM/SLE/SystemSetup/tests/data/wallVC.xml	2006-12-07 23:26:14 UTC (rev 5532)
+++ long/3D/Gale/trunk/src/StgFEM/SLE/SystemSetup/tests/data/wallVC.xml	2006-12-07 23:29:43 UTC (rev 5533)
@@ -0,0 +1,24 @@
+<?xml version="1.0"?>
+<!DOCTYPE StGermainData SYSTEM "stgermain.dtd">
+<!-- A StGermain input file -->
+<!-- DTD to validate against -->
+<StGermainData xmlns="http://www.vpac.org/StGermain/XML_IO_Handler/Jun2003">
+
+	<struct name="wallVC">
+		<param name="type"> WallVC </param>
+		<param name="wall"> bottom </param>
+		<list name="variables">
+			<struct>
+				<param name="name"> one </param>
+				<param name="type"> double </param>
+				<param name="value" type="double"> 1 </param>
+			</struct>
+			<struct>
+				<param name="name"> two </param>
+				<param name="type"> double </param>
+				<param name="value" type="double"> 3 </param>
+			</struct>
+		</list>
+	</struct>
+
+</StGermainData>

Modified: long/3D/Gale/trunk/src/StgFEM/SLE/SystemSetup/tests/testSolutionVector.c
===================================================================
--- long/3D/Gale/trunk/src/StgFEM/SLE/SystemSetup/tests/testSolutionVector.c	2006-12-07 23:26:14 UTC (rev 5532)
+++ long/3D/Gale/trunk/src/StgFEM/SLE/SystemSetup/tests/testSolutionVector.c	2006-12-07 23:29:43 UTC (rev 5533)
@@ -62,6 +62,7 @@
 };
 
 int main( int argc, char* argv[] ) {
+#if 0
 	MPI_Comm			CommWorld;
 	int				rank;
 	int				numProcessors;
@@ -278,4 +279,5 @@
 	MPI_Finalize();
 	
 	return 0; /* success */
+#endif
 }

Modified: long/3D/Gale/trunk/src/StgFEM/SLE/SystemSetup/tests/testStiffnessMatrix-nonZeroCalculation-linkedDofs.c
===================================================================
--- long/3D/Gale/trunk/src/StgFEM/SLE/SystemSetup/tests/testStiffnessMatrix-nonZeroCalculation-linkedDofs.c	2006-12-07 23:26:14 UTC (rev 5532)
+++ long/3D/Gale/trunk/src/StgFEM/SLE/SystemSetup/tests/testStiffnessMatrix-nonZeroCalculation-linkedDofs.c	2006-12-07 23:29:43 UTC (rev 5533)
@@ -63,6 +63,7 @@
 
 
 int main( int argc, char* argv[] ) {
+#if 0
 	MPI_Comm			CommWorld;
 	int				rank;
 	int				numProcessors;
@@ -321,4 +322,5 @@
 	MPI_Finalize();
 	
 	return 0; /* success */
+#endif
 }

Modified: long/3D/Gale/trunk/src/StgFEM/SLE/SystemSetup/tests/testStiffnessMatrix-nonZeroCalculation.c
===================================================================
--- long/3D/Gale/trunk/src/StgFEM/SLE/SystemSetup/tests/testStiffnessMatrix-nonZeroCalculation.c	2006-12-07 23:26:14 UTC (rev 5532)
+++ long/3D/Gale/trunk/src/StgFEM/SLE/SystemSetup/tests/testStiffnessMatrix-nonZeroCalculation.c	2006-12-07 23:29:43 UTC (rev 5533)
@@ -63,6 +63,7 @@
 
 
 int main( int argc, char* argv[] ) {
+#if 0
 	MPI_Comm			CommWorld;
 	int				rank;
 	int				numProcessors;
@@ -309,4 +310,5 @@
 	MPI_Finalize();
 	
 	return 0; /* success */
+#endif
 }

Added: long/3D/Gale/trunk/src/StgFEM/SLE/SystemSetup/tests/testStiffnessMatrix.c
===================================================================
--- long/3D/Gale/trunk/src/StgFEM/SLE/SystemSetup/tests/testStiffnessMatrix.c	2006-12-07 23:26:14 UTC (rev 5532)
+++ long/3D/Gale/trunk/src/StgFEM/SLE/SystemSetup/tests/testStiffnessMatrix.c	2006-12-07 23:29:43 UTC (rev 5533)
@@ -0,0 +1,263 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+**
+** Copyright (C), 2003, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street, Melbourne, 3053, Australia.
+**
+** Authors:
+**	Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
+**	Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
+**	Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
+**	Siew-Ching Tan, Software Engineer, VPAC. (siew at vpac.org)
+**	Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
+**	Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
+**
+**  This library is free software; you can redistribute it and/or
+**  modify it under the terms of the GNU Lesser General Public
+**  License as published by the Free Software Foundation; either
+**  version 2.1 of the License, or (at your option) any later version.
+**
+**  This library 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
+**  Lesser General Public License for more details.
+**
+**  You should have received a copy of the GNU Lesser General Public
+**  License along with this library; if not, write to the Free Software
+**  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+**
+** $Id: testStiffnessMatrix.c 3664 2006-07-04 04:26:57Z PatrickSunter $
+**
+**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include <mpi.h>
+
+#include "StGermain/StGermain.h"
+#include "StgFEM/Discretisation/Discretisation.h"
+#include "StgFEM/SLE/LinearAlgebra/LinearAlgebra.h"
+#include "StgFEM/SLE/SystemSetup/SystemSetup.h"
+
+
+struct _Particle {
+	__IntegrationPoint
+};
+
+
+void identityAssembly( void* term, StiffnessMatrix* stiffMat, 
+		       unsigned element, 
+		       SystemLinearEquations* sle, 
+		       double** elStiffMat )
+{
+	FeMesh*			feMesh = stiffMat->rowVariable->feMesh;
+	FeEquationNumber*	eqNum = stiffMat->rowVariable->eqNum;
+	DofLayout*		dofs = stiffMat->rowVariable->dofLayout;
+	unsigned		nIncNodes, *incNodes;
+	unsigned		nIncEls;
+	unsigned		row, col;
+	unsigned		eqI, eqJ;
+	unsigned		n_i, n_j;
+	unsigned		dof_i, dof_j;
+
+	FeMesh_GetElementNodes( feMesh, element, &nIncNodes, &incNodes );
+
+	row = 0;
+	for( n_i = 0; n_i < nIncNodes; n_i++ ) {
+		for( dof_i = 0; dof_i < dofs->dofCounts[n_i]; dof_i++ ) {
+			eqI = eqNum->destinationArray[n_i][dof_i];
+			col = 0;
+
+			for( n_j = 0; n_j < nIncNodes; n_j++ ) {
+				for( dof_j = 0; dof_j < dofs->dofCounts[n_j]; dof_j++ ) {
+					eqJ = eqNum->destinationArray[n_j][dof_j];
+
+					if( eqI == eqJ ) {
+						nIncEls = FeMesh_GetNodeElementSize( feMesh, n_i );
+						elStiffMat[row][col] = 1.0 / (double)nIncEls;
+					}
+					else
+						elStiffMat[row][col] = 0.0;
+
+					col++;
+				}
+			}
+
+			row++;
+		}
+	}
+}
+
+
+StiffnessMatrix* buildStiffMat( unsigned nProcs ) {
+	CartesianGenerator*		gen;
+	FeMesh*				feMesh;
+	DofLayout*			dofs;
+	VariableCondition*		bcs;
+	FeEquationNumber*		eqNum;
+	FeVariable*			feVar;
+	ForceVector*			rhs;
+	StiffnessMatrix*		stiffMat;
+	CellLayout*			cellLayout;
+	ParticleLayout*			particleLayout;
+	Swarm*				swarm;
+	StiffnessMatrixTerm*		term;
+	ExtensionManager_Register*	emReg;
+	Variable_Register*		varReg;
+	ConditionFunction_Register*	cfReg;
+	FieldVariable_Register*		fvReg;
+	EntryPoint_Register*		epReg;
+	Variable*			vars[2];
+	unsigned			sizes[3];
+	double				minCrd[3];
+	double				maxCrd[3];
+	Bool				dimExists[3];
+	unsigned			particlesPerDim[3];
+	SizeT				dataOffs = 1;
+	Variable_DataType		dataType = Variable_DataType_Double;
+	unsigned			nDataTypes = 1;
+	char*				dataNames = "nothing";
+	static SizeT			structSize = sizeof(double);
+	static unsigned			arraySize;
+	static void*			arrayPtrs[2];
+	Dictionary*			dict;
+	XML_IO_Handler*			ioHandler;
+
+	sizes[0] = sizes[1] = sizes[2] = nProcs * 2;
+	minCrd[0] = minCrd[1] = minCrd[2] = 0.0;
+	maxCrd[0] = maxCrd[1] = maxCrd[2] = (double)nProcs;
+	dimExists[0] = dimExists[1] = dimExists[2] = True;
+	particlesPerDim[0] = particlesPerDim[1] = particlesPerDim[2] = 2;
+
+	gen = CartesianGenerator_New( "" );
+	CartesianGenerator_SetTopologyParams( gen, 3, sizes, 0, NULL, NULL );
+	CartesianGenerator_SetGeometryParams( gen, minCrd, maxCrd );
+	CartesianGenerator_SetShadowDepth( gen, 0 );
+
+	feMesh = FeMesh_New( "" );
+	Mesh_SetGenerator( feMesh, gen );
+	FeMesh_SetElementFamily( feMesh, "linear" );
+	Build( feMesh, NULL, False );
+
+	emReg = ExtensionManager_Register_New();
+	varReg = Variable_Register_New();
+	fvReg = FieldVariable_Register_New();
+	epReg = EntryPoint_Register_New();
+
+	arraySize = FeMesh_GetNodeDomainSize( feMesh );
+	arrayPtrs[0] = Memory_Alloc_Array_Unnamed( double, arraySize );
+	arrayPtrs[1] = Memory_Alloc_Array_Unnamed( double, arraySize );
+	vars[0] = Variable_New( "one", 1, &dataOffs, &dataType, &nDataTypes, &dataNames, 
+				&structSize, &arraySize, arrayPtrs, varReg );
+	vars[1] = Variable_New( "two", 1, &dataOffs, &dataType, &nDataTypes, &dataNames, 
+				&structSize, &arraySize, arrayPtrs + 1, varReg );
+
+	dofs = DofLayout_New( "", varReg, 0, feMesh );
+	dofs->nBaseVariables = 2;
+	dofs->baseVariables = Memory_Alloc_Array_Unnamed( Variable*, 2 );
+	dofs->baseVariables[0] = vars[0];
+	dofs->baseVariables[1] = vars[1];
+	Build( dofs, NULL, False );
+	Initialise( dofs, NULL, False );
+
+	ioHandler = XML_IO_Handler_New();
+	dict = Dictionary_New();
+	IO_Handler_ReadAllFromFile( ioHandler, "data/wallVC.xml", dict );
+	bcs = (VariableCondition*)WallVC_New( "", "wallVC", varReg, cfReg, dict, feMesh );
+	Build( bcs, NULL, False );
+	Initialise( bcs, NULL, False );
+
+	eqNum = FeEquationNumber_New( "", feMesh, dofs, bcs, NULL );
+	Build( eqNum, NULL, False );
+	Initialise( eqNum, NULL, False );
+
+	feVar = FeVariable_New( "", 
+				feMesh, NULL, 
+				dofs, bcs, NULL, 
+				NULL, Mesh_GetDimSize( feMesh ), False, 
+				StgFEM_Native_ImportExportType, StgFEM_Native_ImportExportType, fvReg );
+	Build( feVar, NULL, False );
+	Initialise( feVar, NULL, False );
+
+	rhs = ForceVector_New( "", 
+			       feVar, Mesh_GetDimSize( feMesh ), 
+			       epReg, MPI_COMM_WORLD );
+	Build( rhs, NULL, False );
+	Initialise( rhs, NULL, False );
+
+	stiffMat = StiffnessMatrix_New( "", 
+					feVar, feVar, 
+					rhs, 
+					NULL, Mesh_GetDimSize( feMesh ), False, False, epReg, MPI_COMM_WORLD );
+
+	cellLayout = (CellLayout*)SingleCellLayout_New( "", dimExists, minCrd, maxCrd );
+	particleLayout = (ParticleLayout*)GaussParticleLayout_New( "", Mesh_GetDimSize( feMesh ), particlesPerDim );
+	swarm = Swarm_New( "", cellLayout, particleLayout, Mesh_GetDimSize( feMesh ), sizeof(Particle), 
+			   emReg, varReg, MPI_COMM_WORLD );
+
+	term = StiffnessMatrixTerm_New( "", stiffMat, swarm, NULL );
+	term->_assembleElement = identityAssembly;
+	StiffnessMatrix_AddStiffnessMatrixTerm( stiffMat, term );
+
+	Build( stiffMat, NULL, False );
+	Initialise( stiffMat, NULL, False );
+
+	return stiffMat;
+}
+
+
+Bool testStiffMat( unsigned rank, unsigned nProcs, unsigned watch ) {
+	Bool			result = True;
+	StiffnessMatrix*	stiffMat;
+
+	stiffMat = buildStiffMat( nProcs );
+	StiffnessMatrix_Assemble( stiffMat, True, NULL );
+
+	if( rank == watch ) {
+	}
+
+done:
+	FreeObject( stiffMat );
+
+	return result;
+}
+
+
+#define nTests	1
+
+TestSuite_Test	tests[nTests] = {{"test stiffness matrix", testStiffMat, 1}};
+
+
+int main( int argc, char* argv[] ) {
+	TestSuite*	suite;
+
+	/* Initialise MPI, get world info. */
+	MPI_Init( &argc, &argv );
+
+	/* Initialise StGermain. */
+	StGermain_Init( &argc, &argv );
+	StgFEM_Discretisation_Init( &argc, &argv );
+	StgFEM_SLE_LinearAlgebra_Init( &argc, &argv );
+	StgFEM_SLE_SystemSetup_Init( &argc, &argv );
+
+	/* Create the test suite. */
+	suite = TestSuite_New();
+	TestSuite_SetProcToWatch( suite, (argc >= 2) ? atoi( argv[1] ) : 0 );
+	TestSuite_SetTests( suite, nTests, tests );
+
+	/* Run the tests. */
+	TestSuite_Run( suite );
+
+	/* Destroy test suites. */
+	FreeObject( suite );
+
+	/* Finalise StGermain. */
+	BaseContainer_Finalise();
+	BaseIO_Finalise();
+	BaseFoundation_Finalise();
+
+	/* Close off MPI */
+	MPI_Finalize();
+
+	return MPI_SUCCESS;
+}

Modified: long/3D/Gale/trunk/src/StgFEM/SLE/src/Init.c
===================================================================
--- long/3D/Gale/trunk/src/StgFEM/SLE/src/Init.c	2006-12-07 23:26:14 UTC (rev 5532)
+++ long/3D/Gale/trunk/src/StgFEM/SLE/src/Init.c	2006-12-07 23:29:43 UTC (rev 5533)
@@ -47,7 +47,6 @@
 #include "StgFEM/SLE/ProvidedSystems/ProvidedSystems.h"
 
 #include "types.h"
-#include "StiffRemesher.h"
 #include "Init.h"
 
 #include <stdio.h>
@@ -70,9 +69,5 @@
 	StgFEM_SLE_SystemSetup_Init( argc, argv );
 	StgFEM_SLE_ProvidedSystems_Init( argc, argv );
 
-	Stg_ComponentRegister_Add( Stg_ComponentRegister_Get_ComponentRegister(), StiffRemesher_Type, "0", _StiffRemesher_DefaultNew );
-
-	RegisterParent( StiffRemesher_Type, Remesher_Type );
-
 	return True;
 }

Modified: long/3D/Gale/trunk/src/StgFEM/SLE/src/SLE.h
===================================================================
--- long/3D/Gale/trunk/src/StgFEM/SLE/src/SLE.h	2006-12-07 23:26:14 UTC (rev 5532)
+++ long/3D/Gale/trunk/src/StgFEM/SLE/src/SLE.h	2006-12-07 23:29:43 UTC (rev 5533)
@@ -55,11 +55,9 @@
 	
 	#include "LinearAlgebra/LinearAlgebra.h"
 	#include "SystemSetup/SystemSetup.h"
-	#include "MultiGrid/MultiGrid.h"
 	#include "ProvidedSystems/ProvidedSystems.h"
 
 	#include "types.h"
-	#include "StiffRemesher.h"
 
 	#include "Init.h"
 	#include "Finalise.h"

Deleted: long/3D/Gale/trunk/src/StgFEM/SLE/src/StiffRemesher.c
===================================================================
--- long/3D/Gale/trunk/src/StgFEM/SLE/src/StiffRemesher.c	2006-12-07 23:26:14 UTC (rev 5532)
+++ long/3D/Gale/trunk/src/StgFEM/SLE/src/StiffRemesher.c	2006-12-07 23:29:43 UTC (rev 5533)
@@ -1,713 +0,0 @@
-/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-**
-** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
-**	Melbourne, 3053, Australia.
-**
-** Primary Contributing Organisations:
-**	Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
-**	Australian Computational Earth Systems Simulator - http://www.access.edu.au
-**	Monash Cluster Computing - http://www.mcc.monash.edu.au
-**	Computational Infrastructure for Geodynamics - http://www.geodynamics.org
-**
-** Contributors:
-**	Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
-**	Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
-**	Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
-**	David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
-**	Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
-**	Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
-**	Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
-**	Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
-**	Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
-**	Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
-**
-**  This library is free software; you can redistribute it and/or
-**  modify it under the terms of the GNU Lesser General Public
-**  License as published by the Free Software Foundation; either
-**  version 2.1 of the License, or (at your option) any later version.
-**
-**  This library 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
-**  Lesser General Public License for more details.
-**
-**  You should have received a copy of the GNU Lesser General Public
-**  License along with this library; if not, write to the Free Software
-**  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-**
-** $Id:  $
-**
-**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <math.h>
-#include <assert.h>
-#include <mpi.h>
-#include <StGermain/StGermain.h>
-#include <StgFEM/Discretisation/Discretisation.h>
-#include <StgFEM/SLE/LinearAlgebra/LinearAlgebra.h>
-
-#include "types.h"
-#include "StiffRemesher.h"
-
-
-/* Textual name of this class */
-const Type StiffRemesher_Type = "StiffRemesher";
-
-
-/*----------------------------------------------------------------------------------------------------------------------------------
-** Constructors
-*/
-
-#define REMESHER_DEFARGS				\
-	sizeof(StiffRemesher),				\
-	StiffRemesher_Type,				\
-	_StiffRemesher_Delete,				\
-	_StiffRemesher_Print,				\
-	NULL,						\
-	(void*(*)(Name))_StiffRemesher_DefaultNew,	\
-	_StiffRemesher_Construct,			\
-	_StiffRemesher_Build,				\
-	_StiffRemesher_Initialise,			\
-	_StiffRemesher_Execute,				\
-	_StiffRemesher_Destroy,				\
-	name,						\
-	False,						\
-	_StiffRemesher_SetMesh
-
-
-StiffRemesher* StiffRemesher_New( Name name ) {
-	return _StiffRemesher_New( REMESHER_DEFARGS );
-}
-
-
-StiffRemesher* _StiffRemesher_New( CLASS_ARGS, 
-				   COMPONENT_ARGS, 
-				   REMESHER_ARGS )
-{
-	StiffRemesher*	self;
-
-	/* Allocate memory. */
-	self = (StiffRemesher*)_Remesher_New( _sizeOfSelf,
-					    type,
-					    _delete,
-					    _print, 
-					    _copy, 
-					    _defaultConstructor, 
-					    _construct, 
-					    _build, 
-					    _initialise, 
-					    _execute, 
-					    _destroy, 
-					    name, 
-					      initFlag, 
-					      setMeshFunc );
-
-	/* StiffRemesher info */
-	if( initFlag ) {
-		_StiffRemesher_Init( self );
-	}
-
-	return self;
-}
-
-
-void StiffRemesher_Init( StiffRemesher* self ) {
-	assert( 0 ); /* TODO */
-#if 0
-	/* General info */
-	self->type = StiffRemesher_Type;
-	self->_sizeOfSelf = sizeof(StiffRemesher);
-	self->_deleteSelf = False;
-	
-	/* Virtual info */
-	self->_delete = _StiffRemesher_Delete;
-	self->_print = _StiffRemesher_Print;
-	self->_copy = NULL;
-	_Stg_Class_Init( (Stg_Class*)self );
-	
-	/* StiffRemesher info */
-	_StiffRemesher_Init( self );
-#endif
-}
-
-
-void _StiffRemesher_Init( StiffRemesher* self ) {
-	/* StiffRemesher info */
-	memset( &self->nDims, 
-		0, 
-		(size_t)&self->matSolver - (size_t)&self->rests + sizeof(MatrixSolver*) );
-}
-
-
-/*----------------------------------------------------------------------------------------------------------------------------------
-** Virtual functions
-*/
-
-void _StiffRemesher_Delete( void* stiffRemesher ) {
-	StiffRemesher*	self = (StiffRemesher*)stiffRemesher;
-
-	/* Delete the class itself */
-	_StiffRemesher_Free( self );
-
-	/* Delete parent */
-	_Stg_Component_Delete( stiffRemesher );
-}
-
-
-void _StiffRemesher_Print( void* stiffRemesher, Stream* stream ) {
-	StiffRemesher*	self = (StiffRemesher*)stiffRemesher;
-	Stream*		myStream;
-	
-	/* Set the Journal for printing informations */
-	myStream = Journal_Register( InfoStream_Type, "StiffRemesherStream" );
-
-	/* Print parent */
-	_Stg_Component_Print( self, stream );
-
-	/* General info */
-	Journal_Printf( myStream, "StiffRemesher (ptr): (%p)\n", self );
-
-	/* Virtual info */
-
-	/* StiffRemesher info */
-}
-
-
-StiffRemesher* _StiffRemesher_DefaultNew( Name name ) {
-	return _StiffRemesher_New( REMESHER_DEFARGS );
-}
-
-
-void _StiffRemesher_Construct( void* stiffRemesher, Stg_ComponentFactory* cf, void* data ) {
-	StiffRemesher*	self = (StiffRemesher*)stiffRemesher;
-	Dictionary*	dict;
-	char*		swarmName;
-
-	assert( self );
-	assert( cf );
-	assert( cf->componentDict );
-
-	_Remesher_Construct( self, cf, data );
-
-	/* Get the number of dimensions. */
-	dict = Dictionary_Entry_Value_AsDictionary( Dictionary_Get( cf->componentDict, self->name ) );
-	self->nDims = Dictionary_GetUnsignedInt( dict, "dims" );
-	assert( self->nDims > 0 );
-
-	/* Get the swarm. */
-	swarmName = Dictionary_GetString( dict, "swarm" );
-	assert( swarmName );
-	self->swarm = Stg_ComponentFactory_ConstructByName( cf, swarmName, Swarm, True, data ); 
-}
-
-
-void _StiffRemesher_Build( void* stiffRemesher, void* data ) {
-	StiffRemesher*	self = (StiffRemesher*)stiffRemesher;
-
-	assert( self );
-
-	if( !self->meshType ) {
-		return;
-	}
-
-	assert( self->mesh );
-
-	/* Build parent. */
-	_Remesher_Build( self, data );
-
-	/* Set the restricted nodes based on mesh type. */
-	if( !strcmp( self->meshType, "regular" ) ) {
-		GRM		grm;
-		unsigned*	dimInds;
-		unsigned	n_i;
-
-		/* When regular meshing is required, boundary nodes are restricted. Construct a boundary set of indices. */
-		RegMesh_Generalise( self->mesh, &grm );
-		dimInds = Memory_Alloc_Array_Unnamed( unsigned, grm.nDims );
-		for( n_i = 0; n_i < self->mesh->nodeLocalCount; n_i++ ) {
-			unsigned	gNodeInd = Mesh_NodeMapLocalToGlobal( self->mesh, n_i );
-			unsigned	d_i;
-
-			GRM_Lift( &grm, gNodeInd, dimInds );
-			for( d_i = 0; d_i < grm.nDims; d_i++ ) {
-				if( dimInds[d_i] == 0 || dimInds[d_i] == grm.nNodes[d_i] - 1 ) {
-					StiffRemesher_SetRestriction( self, n_i, d_i, True );
-
-					/* If on the top surface... */
-					if( d_i == 1 && dimInds[d_i] == grm.nNodes[d_i] - 1 ) {
-						unsigned	d_j;
-
-						/* Restrict in every dimension. */
-						for( d_j = 0; d_j < grm.nDims; d_j++ ) {
-							StiffRemesher_SetRestriction( self, n_i, d_j, True );
-						}
-					}
-				}
-			}
-		}
-
-		/* Free dimensional indices array. */
-		FreeArray( dimInds );
-	}
-	else {
-		assert( 0 );
-	}
-}
-
-
-void _StiffRemesher_Initialise( void* stiffRemesher, void* data ) {
-	StiffRemesher*	self = (StiffRemesher*)stiffRemesher;
-
-	assert( self );
-
-	/* Initialise parent. */
-	_Remesher_Initialise( self, data );
-
-	/* Initialise the system. */
-	StiffRemesher_BuildSystem( self );
-}
-
-
-void _StiffRemesher_Execute( void* stiffRemesher, void* data ) {
-	StiffRemesher*	self = (StiffRemesher*)stiffRemesher;
-	unsigned	nLNodes;
-	double*		solArray;
-	unsigned	n_i, d_i;
-
-	assert( self );
-	assert( self->mesh );
-	assert( self->mesh->layout );
-	assert( self->mesh->layout->elementLayout );
-	/* TODO: remaining asserts */
-
-	nLNodes = self->mesh->nodeLocalCount;
-
-	/* Evaluate the weights. */
-	_StiffRemesher_UpdateWeights( self );
-
-	/* Fill RHS. */
-	Matrix_Zero( self->stiffMat );
-	Vector_Zero( self->rhsVec );
-	Vector_Zero( self->solVec );
-	for( n_i = 0; n_i < nLNodes; n_i++ ) {
-		for( d_i = 0; d_i < self->nDims; d_i++ ) {
-			unsigned	eqNumI;
-			unsigned	nNbrs;
-			unsigned*	nbrs;
-			unsigned	nbr_i;
-
-			/* If restricted in this dimension, skip. */
-			if( self->rests[n_i][d_i] ) {
-				continue;
-			}
-
-			/* Collect neighbour info. */
-			nNbrs = self->mesh->nodeNeighbourCountTbl[n_i];
-			nbrs = self->mesh->nodeNeighbourTbl[n_i];
-
-			/* Calc equation number and coef. */
-			eqNumI = self->baseEqNum + self->eqNums[n_i][d_i];
-
-			/* Enter matrix values. */
-			Matrix_AddValue( self->stiffMat, eqNumI, eqNumI, 1.0 );
-			for( nbr_i = 0; nbr_i < nNbrs; nbr_i++ ) {
-				/* If this neighbour is not restricted, add to matrix. */
-				if( !self->rests[nbrs[nbr_i]][d_i] ) {
-					unsigned	eqNumJ;
-
-					eqNumJ = self->baseEqNum + self->eqNums[nbrs[nbr_i]][d_i];
-					Matrix_AddValue( self->stiffMat, eqNumI, eqNumJ, -self->weights[n_i][nbr_i][d_i] );
-				}
-			}
-
-			/* Enter RHS value. */
-			for( nbr_i = 0; nbr_i < nNbrs; nbr_i++ ) {
-				/* If this neighbour is restricted, add to RHS. */
-				if( self->rests[nbrs[nbr_i]][d_i] ) {
-					Vector_AddEntry( self->rhsVec, eqNumI, 
-							 self->weights[n_i][nbr_i][d_i] * self->mesh->nodeCoord[nbrs[nbr_i]][d_i] );
-				}
-			}
-		}
-	}
-
-	/* Assemble the system. */
-	Matrix_AssemblyBegin( self->stiffMat );
-	Vector_AssemblyBegin( self->solVec );
-	Vector_AssemblyBegin( self->rhsVec );
-	Matrix_AssemblyEnd( self->stiffMat );
-	Vector_AssemblyEnd( self->solVec );
-	Vector_AssemblyEnd( self->rhsVec );
-
-	/* Solve the system. */
-	MatrixSolver_Solve( self->matSolver, self->solVec, self->rhsVec );
-
-	/* Update mesh coordinates. */
-	Vector_Get( self->solVec, &solArray );
-	for( n_i = 0; n_i < nLNodes; n_i++ ) {
-		for( d_i = 0; d_i < self->nDims; d_i++ ) {
-			unsigned	eqNum;
-
-			if( self->rests[n_i][d_i] ) {
-				continue;
-			}
-
-			/* Copy the coordinate from the vector. */
-			eqNum = self->eqNums[n_i][d_i] - self->baseEqNum;
-			self->mesh->nodeCoord[n_i][d_i] = solArray[eqNum];
-		}
-	}
-	Vector_Restore( self->solVec, &solArray );
-}
-
-
-void _StiffRemesher_Destroy( void* stiffRemesher, void* data ) {
-	StiffRemesher*	self = (StiffRemesher*)stiffRemesher;
-
-	assert( self );
-
-	/* TODO: If delete deletes, what does destroy do? */
-}
-
-
-void _StiffRemesher_SetMesh( void* stiffRemesher, Mesh* mesh ) {
-	StiffRemesher*	self = (StiffRemesher*)stiffRemesher;
-
-	assert( self );
-	assert( self->mesh->layout );
-	assert( self->mesh->layout->decomp );
-
-	/* Kill all internals. */
-	_StiffRemesher_Free( self );
-
-	/* Store the mesh and communicator. */
-	self->mesh = mesh;
-	self->comm = mesh->layout->decomp->communicator;
-
-	/* Allocate for element volume approximations. */
-	_StiffRemesher_CalcWeights( self );
-}
-
-
-/*----------------------------------------------------------------------------------------------------------------------------------
-** Public Functions
-*/
-
-void StiffRemesher_SetRestriction( void* stiffRemesher, unsigned lNodeInd, unsigned dim, Bool state ) {
-	StiffRemesher*	self = (StiffRemesher*)stiffRemesher;
-
-	assert( self );
-	assert( self->mesh );
-	assert( lNodeInd < self->mesh->nodeLocalCount );
-	assert( self->mesh->layout );
-	assert( self->mesh->layout->elementLayout );
-	assert( dim < ((HexaEL*)self->mesh->layout->elementLayout)->dim );
-
-	/* If we this is the first restriction, allocate the arrays. */
-	if( !self->rests ) {
-		unsigned	nLNodes;
-		unsigned	n_i;
-
-		nLNodes = self->mesh->nodeLocalCount;
-
-		self->rests = Memory_Alloc_2DArray( unsigned, nLNodes, self->nDims, "StiffRemesher->rests" );
-		for( n_i = 0; n_i < nLNodes; n_i++ ) {
-			memset( self->rests[n_i], 0, sizeof(Bool) * self->nDims );
-		}
-	}
-
-	/* If the new state is different from existing state, destroy the current system. */
-	if( self->rests[lNodeInd][dim] != state ) {
-		_StiffRemesher_FreeSystem( self );
-	}
-
-	/* Set the restriction. */
-	self->rests[lNodeInd][dim] = state;
-}
-
-
-void StiffRemesher_BuildSystem( void* stiffRemesher ) {
-	const unsigned	eqNumTag = 1010;
-	StiffRemesher*	self = (StiffRemesher*)stiffRemesher;
-	unsigned	nRows = 0;
-	unsigned	nonZeros = 0;
-	unsigned	nLNodes;
-	unsigned	rank, nProcs;
-	unsigned	n_i, d_i;
-
-	assert( self );
-	assert( self->mesh );
-	assert( self->mesh->nodeNeighbourCountTbl );
-	assert( self->mesh->nodeNeighbourTbl );
-	assert( self->mesh->layout );
-	assert( self->mesh->layout->elementLayout );
-	/* TODO: remaining assertions */
-
-	MPI_Comm_rank( self->comm, (int*)&rank );
-	MPI_Comm_size( self->comm, (int*)&nProcs );
-
-	nLNodes = self->mesh->nodeLocalCount;
-
-	/* Determine the number of rows and build local equation number mappings. */
-	self->eqNums = Memory_Alloc_2DArray( unsigned, nLNodes, self->nDims, "StiffRemesher->eqNums" );
-	for( n_i = 0; n_i < nLNodes; n_i++ ) {
-		for( d_i = 0; d_i < self->nDims; d_i++ ) {
-			if( !self->rests[n_i][d_i] ) {
-				self->eqNums[n_i][d_i] = nRows++;
-			}
-			else {
-				self->eqNums[n_i][d_i] = (unsigned)-1;
-			}
-		}
-	}
-
-	/* Determine the average number of non-zeros per row. */
-	for( n_i = 0; n_i < nLNodes; n_i++ ) {
-		for( d_i = 0; d_i < self->nDims; d_i++ ) {
-			/* Skip if restricted in this dimension. */
-			if( !self->rests[n_i][d_i] ) {
-				/* Set the non-zero count to be the number of neighbours. */
-				nonZeros += self->mesh->nodeNeighbourCountTbl[n_i];
-			}
-		}
-	}
-	nonZeros /= nRows;
-
-	/* Send and receive base equation numbers. */
-	if( rank > 0 ) {
-		MPI_Status	status;
-
-		MPI_Recv( &self->baseEqNum, 1, MPI_UNSIGNED, rank - 1, eqNumTag, self->comm, &status );
-	}
-	else {
-		self->baseEqNum = 0;
-	}
-
-	if( rank < nProcs - 1 ) {
-		self->baseEqNum += nRows;
-		MPI_Send( &self->baseEqNum, 1, MPI_UNSIGNED, rank + 1, eqNumTag, self->comm );
-		self->baseEqNum -= nRows;
-	}
-
-	/* Create the system. */
-	self->stiffMat = Matrix_New( self->comm, nRows, nRows, nonZeros );
-	self->solVec = Vector_New_SpecifyLocalSize( self->comm, nRows );
-	self->rhsVec = Vector_New_SpecifyLocalSize( self->comm, nRows );
-	Matrix_Zero( self->stiffMat );
-	Vector_Zero( self->solVec );
-	Vector_Zero( self->rhsVec );
-
-	/* Create the matrix solver. */
-	self->matSolver = MatrixSolver_Build( self->comm, self->stiffMat );
-	MatrixSolver_Setup( self->matSolver, self->stiffMat );
-}
-
-
-/*----------------------------------------------------------------------------------------------------------------------------------
-** Private Functions
-*/
-
-void _StiffRemesher_Free( StiffRemesher* self ) {
-	assert( self );
-
-	KillArray( self->weights ); /* FIX */
-	KillArray( self->rests );
-	KillArray( self->eqNums );
-	_StiffRemesher_FreeSystem( self );
-}
-
-
-void _StiffRemesher_FreeSystem( StiffRemesher* self ) {
-	assert( self );
-
-	if(  self->stiffMat ) {
-		Matrix_Destroy( self->stiffMat );
-		self->stiffMat = NULL;
-	}
-
-	if( self->solVec ) {
-		Vector_Destroy( self->solVec );
-		self->solVec = NULL;
-	}
-
-	if( self->rhsVec ) {
-		Vector_Destroy( self->rhsVec );
-		self->rhsVec = NULL;
-	}
-
-	if( self->matSolver ) {
-		MatrixSolver_Destroy( self->matSolver );
-		self->matSolver = NULL;
-	}
-}
-
-
-void _StiffRemesher_UpdateWeights( StiffRemesher* self ) {
-	unsigned	nNodes;
-	Coord*		nodeCrds;
-	double*		dispSums;
-	unsigned	n_i;
-
-	assert( self );
-
-	nodeCrds = self->mesh->nodeCoord;
-	nNodes = self->mesh->nodeLocalCount;
-	dispSums = Memory_Alloc_Array_Unnamed( double, self->nDims );
-	for( n_i = 0; n_i < nNodes; n_i++ ) {
-		unsigned	nNbrs;
-		unsigned*	nbrs;
-		double*		crd = nodeCrds[n_i];
-		double**	disps;
-		unsigned	nbr_i, d_i;
-
-		/* Get neighbours. */
-		nNbrs = self->mesh->nodeNeighbourCountTbl[n_i];
-		nbrs = self->mesh->nodeNeighbourTbl[n_i];
-
-		/* Allocate some stuff. */
-		disps = Memory_Alloc_2DArray_Unnamed( double, nNbrs, self->nDims );
-
-		/* Calculate unit vectors'n'such. */
-		memset( dispSums, 0, self->nDims * sizeof(double) );
-		for( nbr_i = 0; nbr_i < nNbrs; nbr_i++ ) {
-			double	mag = 0.0;
-
-			for( d_i = 0; d_i < self->nDims; d_i++ ) {
-				/* Calculate dimensional influence. */
-				disps[nbr_i][d_i] = nodeCrds[nbrs[nbr_i]][d_i] - crd[d_i];
-				disps[nbr_i][d_i] *= (disps[nbr_i][d_i] < 0.0) ? -1.0 : 1.0;
-				mag += disps[nbr_i][d_i] * disps[nbr_i][d_i];
-			}
-			mag = 1.0 / sqrt( mag );
-			for( d_i = 0; d_i < self->nDims; d_i++ ) {
-				disps[nbr_i][d_i] *= mag;
-				dispSums[d_i] += disps[nbr_i][d_i];
-			}
-		}
-
-		/* Build the weights. */
-		for( d_i = 0; d_i < self->nDims; d_i++ ) {
-			double	inv = 1.0 / dispSums[d_i];
-
-			for( nbr_i = 0; nbr_i < nNbrs; nbr_i++ ) {
-				self->weights[n_i][nbr_i][d_i] = disps[nbr_i][d_i] * inv;
-			}
-		}
-
-		FreeArray( disps );
-	}
-
-	FreeArray( dispSums );
-}
-
-
-void _StiffRemesher_CalcWeights( StiffRemesher* self ) {
-	unsigned	n_i;
-
-	assert( self );
-
-	self->weights = Memory_Alloc_Array_Unnamed( double**, self->mesh->nodeLocalCount );
-	for( n_i = 0; n_i < self->mesh->nodeLocalCount; n_i++ ) {
-		unsigned	nNbrs;
-
-		nNbrs = self->mesh->nodeNeighbourCountTbl[n_i];
-		self->weights[n_i] = Memory_Alloc_2DArray_Unnamed( double, nNbrs, self->nDims );
-	}
-
-	_StiffRemesher_UpdateWeights( self );
-}
-
-
-#if 0
-void _StiffRemesher_CalcWeights( StiffRemesher* self ) {
-	unsigned	nEls, nNodes;
-	double*		volumes;
-	double		avgVol = 0.0;
-	unsigned	e_i, n_i;
-
-	assert( self );
-	assert( self->weights );
-	assert( self->mesh->type == FiniteElement_Mesh_Type );
-
-	nEls = self->mesh->elementLocalCount;
-	nNodes = self->mesh->nodeLocalCount;
-
-	/* Allocate for new volumes. */
-	volumes = Memory_Alloc_Array_Unnamed( double, nEls );
-
-	/* Calculate current volumes. */
-	for( e_i = 0; e_i < nEls; e_i++ ) {
-		ElementType*	elType;
-		unsigned	nElNodes;
-		unsigned	cellInd;
-		unsigned	nParticles;
-		double		vol = 0.0;
-		double**	gDerivs;
-		unsigned	p_i;
-
-		/* Get the element type. */
-		elType = FeMesh_ElementTypeAt( (FiniteElement_Mesh*)self->mesh, e_i );
-		nElNodes = elType->nodeCount;
-
-		/* Allocate for global derivatives. */
-		gDerivs = Memory_Alloc_2DArray_Unnamed( double, self->nDims, nElNodes );
-
-		/* Get particle info. */
-		cellInd = CellLayout_MapElementIdToCellId( self->swarm->cellLayout, e_i );
-		nParticles = self->swarm->cellParticleCountTbl[cellInd];
-
-		/* Integrate domain. */
-		for( p_i = 0; p_i < nParticles; p_i++ ) {
-			IntegrationPoint*	intPoint;
-			double			jacDet;
-
-			/* Get the current integration point. */
-			intPoint = (IntegrationPoint*)Swarm_ParticleInCellAt( self->swarm, cellInd, p_i );
-
-			/* Evaluate the jacobian. */
-			ElementType_ShapeFunctionsGlobalDerivs( elType, self->mesh, e_i, intPoint->xi, self->nDims, 
-								&jacDet, gDerivs );
-
-			/* Add to total. */
-			vol += intPoint->weight * jacDet;
-		}
-
-		/* Free global derivs. */
-		FreeArray( gDerivs );
-
-		/* Store the volume. */
-		volumes[e_i] = vol;
-		printf( "volume[%d]: \t%g\n", e_i, vol );
-
-		/* Calc average. */
-		avgVol += vol;
-	}
-
-	/* Finish average. */
-	avgVol /= (double)nEls;
-
-	/* Calculate nodal weights. */
-	avgVol = 1.0 / avgVol;
-	for( n_i = 0; n_i < nNodes; n_i++ ) {
-		unsigned	nIncEls = self->mesh->nodeElementCountTbl[n_i];
-		unsigned*	incEls = self->mesh->nodeElementTbl[n_i];
-		unsigned	nRealIncEls = 0;
-		unsigned	ne_i;
-
-		self->weights[n_i] = 0.0;
-		for( ne_i = 0; ne_i < nIncEls; ne_i++ ) {
-			if( incEls[ne_i] < nEls ) {
-				self->weights[n_i] += volumes[incEls[ne_i]] * avgVol;
-				nRealIncEls++;
-			}
-		}
-		self->weights[n_i] /= (double)nRealIncEls;
-	}
-
-	/* Free volumes array. */
-	FreeArray( volumes );
-}
-#endif

Deleted: long/3D/Gale/trunk/src/StgFEM/SLE/src/StiffRemesher.h
===================================================================
--- long/3D/Gale/trunk/src/StgFEM/SLE/src/StiffRemesher.h	2006-12-07 23:26:14 UTC (rev 5532)
+++ long/3D/Gale/trunk/src/StgFEM/SLE/src/StiffRemesher.h	2006-12-07 23:29:43 UTC (rev 5533)
@@ -1,136 +0,0 @@
-/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-**
-** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
-**	Melbourne, 3053, Australia.
-**
-** Primary Contributing Organisations:
-**	Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
-**	Australian Computational Earth Systems Simulator - http://www.access.edu.au
-**	Monash Cluster Computing - http://www.mcc.monash.edu.au
-**	Computational Infrastructure for Geodynamics - http://www.geodynamics.org
-**
-** Contributors:
-**	Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
-**	Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
-**	Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
-**	David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
-**	Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
-**	Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
-**	Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
-**	Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
-**	Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
-**	Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
-**
-**  This library is free software; you can redistribute it and/or
-**  modify it under the terms of the GNU Lesser General Public
-**  License as published by the Free Software Foundation; either
-**  version 2.1 of the License, or (at your option) any later version.
-**
-**  This library 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
-**  Lesser General Public License for more details.
-**
-**  You should have received a copy of the GNU Lesser General Public
-**  License along with this library; if not, write to the Free Software
-**  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-**
-*/
-/** \file
-**  Role:
-**
-** Assumptions:
-**
-** Invariants:
-**
-** Comments:
-**
-** $Id: StiffRemesher.h 2225 1970-01-02 13:48:23Z LukeHodkinson $
-**
-**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
-
-#ifndef __StgFEM_SLE_StiffRemesher_h__
-#define __StgFEM_SLE_StiffRemesher_h__
-
-	/* Textual name of this class. */
-	extern const Type StiffRemesher_Type;
-
-	/* Virtual function types. */
-
-	/* Class contents. */
-	#define __StiffRemesher					\
-		/* General info */				\
-		__Remesher					\
-								\
-		/* Virtual info */				\
-								\
-		/* StiffRemesher info ... */			\
-		unsigned		nDims;			\
-		Swarm*			swarm;			\
-		double***		weights;		\
-								\
-		Bool**			rests;			\
-		unsigned		baseEqNum;		\
-		unsigned**		eqNums;			\
-								\
-		Matrix*			stiffMat;		\
-		Vector*			solVec;			\
-		Vector*			rhsVec;			\
-		MatrixSolver*		matSolver;
-
-	struct StiffRemesher { __StiffRemesher };
-
-
-	/*-----------------------------------------------------------------------------------------------------------------------------
-	** Constructors
-	*/
-
-	/* Create a StiffRemesher */
-	StiffRemesher* StiffRemesher_New( Name name );
-
-	/* Creation implementation */
-	StiffRemesher* _StiffRemesher_New( CLASS_ARGS, 
-					   COMPONENT_ARGS, 
-					   REMESHER_ARGS );
-
-	/* Initialise a StiffRemesher */
-	void StiffRemesher_Init( StiffRemesher* self );
-
-	/* Initialisation implementation functions */
-	void _StiffRemesher_Init( StiffRemesher* self );
-
-
-	/*-----------------------------------------------------------------------------------------------------------------------------
-	** Virtual functions
-	*/
-
-	void _StiffRemesher_Delete( void* stiffRemesher );
-	void _StiffRemesher_Print( void* stiffRemesher, Stream* stream );
-	StiffRemesher* _StiffRemesher_DefaultNew( Name name );
-	void _StiffRemesher_Construct( void* stiffRemesher, Stg_ComponentFactory* cf, void* data );
-	void _StiffRemesher_Build( void* stiffRemesher, void* data );
-	void _StiffRemesher_Initialise( void* stiffRemesher, void* data );
-	void _StiffRemesher_Execute( void* stiffRemesher, void* data );
-	void _StiffRemesher_Destroy( void* stiffRemesher, void* data );
-
-	void _StiffRemesher_SetMesh( void* stiffRemesher, Mesh* mesh );
-
-
-	/*-----------------------------------------------------------------------------------------------------------------------------
-	** Public functions
-	*/
-
-	void StiffRemesher_SetRestriction( void* stiffRemesher, unsigned lNodeInd, unsigned dim, Bool state );
-	void StiffRemesher_BuildSystem( void* stiffRemesher );
-
-
-	/*-----------------------------------------------------------------------------------------------------------------------------
-	** Private Member functions
-	*/
-
-	void _StiffRemesher_Free( StiffRemesher* self );
-	void _StiffRemesher_FreeSystem( StiffRemesher* self );
-	void _StiffRemesher_UpdateWeights( StiffRemesher* self );
-	void _StiffRemesher_CalcWeights( StiffRemesher* self );
-
-#endif

Deleted: long/3D/Gale/trunk/src/StgFEM/SLE/src/StiffRemesher.meta
===================================================================
--- long/3D/Gale/trunk/src/StgFEM/SLE/src/StiffRemesher.meta	2006-12-07 23:26:14 UTC (rev 5532)
+++ long/3D/Gale/trunk/src/StgFEM/SLE/src/StiffRemesher.meta	2006-12-07 23:29:43 UTC (rev 5533)
@@ -1,27 +0,0 @@
-<?xml version="1.0"?>
-<!DOCTYPE StGermainData SYSTEM "stgermain.dtd">
-<StGermainData xmlns="http://www.vpac.org/StGermain/XML_IO_Handler/Jun2003">
-
-<param name="Name">StiffRemesher</param>
-<param name="Organisation">VPAC</param>
-<param name="Project">StgFEM</param>
-<param name="Location">./StgFEM/SLE/src/</param>
-<param name="Project Web">https://csd.vpac.org/twiki/bin/view/Stgfem/WebHome</param>
-<param name="Copyright">Copyright (C) 2004-2005 VPAC.</param>
-<param name="License">https://csd.vpac.org/twiki/bin/view/Stgermain/SoftwareLicense</param>
-<param name="Parent"></param>
-<param name="Description">...</param>
-
-<!--Now the interesting stuff-->
-
-
-<list name="Params">
-</list>
-
-<list name="Dependencies">
-
-</list>
-<!-- Add an exmaple XML if possible -->
-<param name="Example">...</param>
-
-</StGermainData>

Modified: long/3D/Gale/trunk/src/StgFEM/plugins/CompareFeVariableAgainstReferenceSolution/CompareFeVariableAgainstReferenceSolution.c
===================================================================
--- long/3D/Gale/trunk/src/StgFEM/plugins/CompareFeVariableAgainstReferenceSolution/CompareFeVariableAgainstReferenceSolution.c	2006-12-07 23:26:14 UTC (rev 5532)
+++ long/3D/Gale/trunk/src/StgFEM/plugins/CompareFeVariableAgainstReferenceSolution/CompareFeVariableAgainstReferenceSolution.c	2006-12-07 23:29:43 UTC (rev 5533)
@@ -278,13 +278,13 @@
 		referenceDataVariable = Variable_NewScalar(
 			tmpName,
 			Variable_DataType_Double,
-			&feVarToTest->feMesh->nodeDomainCount,
+			&feVarToTest->feMesh->topo->domains[MT_VERTEX]->nDomains, 
 			(void**)NULL,
 			variable_Register );
 		roundedDataVariable = Variable_NewScalar(
 			tmpName2,
 			Variable_DataType_Double,
-			&feVarToTest->feMesh->nodeDomainCount,
+			&feVarToTest->feMesh->topo->domains[MT_VERTEX]->nDomains, 
 			(void**)NULL,
 			variable_Register );
 	}
@@ -311,7 +311,7 @@
 				tmpName,
 				Variable_DataType_Double,
 				componentsCount,
-				&feVarToTest->feMesh->nodeDomainCount,
+				&feVarToTest->feMesh->topo->domains[MT_VERTEX]->nDomains, 
 				(void**)NULL,
 				variable_Register,
 				referenceVariableName[0],
@@ -327,7 +327,7 @@
 				tmpName2,
 				Variable_DataType_Double,
 				componentsCount,
-				&feVarToTest->feMesh->nodeDomainCount,
+				&feVarToTest->feMesh->topo->domains[MT_VERTEX]->nDomains, 
 				(void**)NULL,
 				variable_Register,
 				roundedVariableName[0],
@@ -354,8 +354,10 @@
 	/* Create Dof layout for this variable based on its own DataVariable */
 	tmpName = Stg_Object_AppendSuffix( feVarToTest, "Reference-DofLayout" );
 	tmpName2 = Stg_Object_AppendSuffix( feVarToTest, "Rounded-DofLayout" );
-	referenceDofLayout = DofLayout_New( tmpName, variable_Register, feVarToTest->feMesh->layout->decomp->nodeDomainCount );
-	roundedDofLayout = DofLayout_New( tmpName2, variable_Register, feVarToTest->feMesh->layout->decomp->nodeDomainCount );
+	referenceDofLayout = DofLayout_New( tmpName, variable_Register, 
+					    Mesh_GetDomainSize( feVarToTest->feMesh, MT_VERTEX ), NULL );
+	roundedDofLayout = DofLayout_New( tmpName2, variable_Register, 
+					  Mesh_GetDomainSize( feVarToTest->feMesh, MT_VERTEX ), NULL );
 	if ( scalar ) {
 		DofLayout_AddAllFromVariableArray( referenceDofLayout, 1, &referenceDataVariable );
 		DofLayout_AddAllFromVariableArray( roundedDofLayout, 1, &roundedDataVariable );
@@ -370,7 +372,7 @@
 			roundedVariable->arrayPtrPtr = &roundedDataVariable->arrayPtr;
 
 			/* Assign variable to each node */
-			for( dNode_I = 0; dNode_I < feVarToTest->feMesh->layout->decomp->nodeDomainCount ; dNode_I++ ) {
+			for( dNode_I = 0; dNode_I < Mesh_GetDomainSize( feVarToTest->feMesh, MT_VERTEX ); dNode_I++ ) {
 				DofLayout_AddDof_ByVarName( referenceDofLayout, referenceVariableName[variable_I], dNode_I );
 				DofLayout_AddDof_ByVarName( roundedDofLayout, roundedVariableName[variable_I], dNode_I );
 			}
@@ -431,7 +433,7 @@
 	}
 
 	/* now we need to round off the feVar we are testing, and copy the result to the roundedFeVar */
-	for( dNode_I = 0; dNode_I < feVarToTest->feMesh->nodeDomainCount; dNode_I++ ) {
+	for( dNode_I = 0; dNode_I < Mesh_GetDomainSize( feVarToTest->feMesh, MT_VERTEX ); dNode_I++ ) {
 		dofCountAtNode = feVarToTest->dofLayout->dofCounts[dNode_I];
 		
 		if ( dofCountAtNode != dofCountAtPrevNode ) {

Modified: long/3D/Gale/trunk/src/StgFEM/plugins/FeVariableImportExporters/FeVariable_ImportExport_ABAQUS/FeVariable_ImportExport_ABAQUS.c
===================================================================
--- long/3D/Gale/trunk/src/StgFEM/plugins/FeVariableImportExporters/FeVariable_ImportExport_ABAQUS/FeVariable_ImportExport_ABAQUS.c	2006-12-07 23:26:14 UTC (rev 5532)
+++ long/3D/Gale/trunk/src/StgFEM/plugins/FeVariableImportExporters/FeVariable_ImportExport_ABAQUS/FeVariable_ImportExport_ABAQUS.c	2006-12-07 23:29:43 UTC (rev 5533)
@@ -63,19 +63,25 @@
 	const unsigned int MAX_LINE_LENGTH = 1000;
 	Processor_Index    proc_I=0;
 	Dimension_Index    dim_I=0;
-	BlockGeometry*     geometry = (BlockGeometry*)feVariable->feMesh->layout->elementLayout->geometry;
 	char*              matchString;
 	Index              currentFileLine = 0;
 	Coord              localGeometryMin;
 	Coord              localGeometryMax;
 	Stream*            debugStream = Journal_Register( Debug_Type, StgFEM_FeVariable_ImportExport_ABAQUS_Type );
+	FeMesh*		mesh = feVariable->feMesh;
+	MPI_Comm	comm;
+	unsigned	rank, nProcs;
+	double		min[3], max[3];
+	unsigned	nDims;
 	
 	Journal_DPrintf( debugStream, "In %s(): for FeVariable \"%s\"\n", __func__, feVariable->name );
 	Stream_Indent( debugStream );
-	
-	/* Necessary for now since we need to update the geometry min and max - see comment below */
-	Stg_CheckType( geometry, BlockGeometry );
 
+	nDims = Mesh_GetDimSize( mesh );
+	comm = CommTopology_GetComm( Mesh_GetCommTopology( mesh, MT_VERTEX ) );
+	MPI_Comm_rank( comm, (int*)&rank );
+	MPI_Comm_size( comm, (int*)&nProcs );
+	
 	/*                                                prefix            feVariable->name        . 00000 .  dat \0 */
 	filename = Memory_Alloc_Array_Unnamed( char, strlen(prefixStr) + strlen(feVariable->name) + 1 + 5 + 1 + 3 + 1 );
 	sprintf( filename, "%s%s.%.5u.rpt", prefixStr, feVariable->name, timeStep );
@@ -84,9 +90,9 @@
 	
 	/* This loop used to stop 2 processors trying to open the file at the same time, which
 	  * seems to cause problems */
-	for ( proc_I = 0; proc_I < feVariable->feMesh->layout->decomp->nproc; proc_I++ ) {
-		MPI_Barrier( feVariable->feMesh->layout->decomp->communicator );
-		if ( proc_I == feVariable->feMesh->layout->decomp->rank ) {	
+	for ( proc_I = 0; proc_I < nProcs; proc_I++ ) {
+		MPI_Barrier( comm );
+		if ( proc_I == rank ) {	
 			inputFile = fopen( filename, "r" );
 		}
 	}
@@ -127,51 +133,45 @@
 	Journal_DPrintf( debugStream, "Processing Nodal Data...\n", currentFileLine );
 	Stream_Indent( debugStream );
 	/* Note: in ABAQUS, the number of lines of nodal values from hereon is always == the number of global nodes */
-	for ( gNodeCount_I = 0; gNodeCount_I < feVariable->feMesh->nodeGlobalCount; gNodeCount_I++ ) {
+	for ( gNodeCount_I = 0; gNodeCount_I < Mesh_GetGlobalSize( mesh, MT_VERTEX ); gNodeCount_I++ ) {
 		fscanf( inputFile, "%u ", &gNode_I );
 		/* Note: ABAQUS has same layout of global node indices as StgFEM, except it indexes starting from 1 - thus we
 		 * need to subtract 1 here */
 		gNode_I -= 1;
 		
-		lNode_I = Mesh_NodeMapGlobalToLocal( feVariable->feMesh, gNode_I );
-		Journal_DPrintfL( debugStream, 3, "Found info for global node %u, local node %u:\n", gNode_I, lNode_I );
-		Stream_Indent( debugStream );
+		if ( Mesh_GlobalToDomain( feVariable->feMesh, MT_VERTEX, gNode_I, &lNode_I ) ) {
+			Journal_DPrintfL( debugStream, 3, "Found info for global node %u, local node %u:\n", gNode_I, lNode_I );
+			Stream_Indent( debugStream );
 
-		if ( lNode_I != Mesh_Node_Invalid( feVariable->feMesh ) ) {
 			/* Note: until we have proper mesh geometry, topology etc checkpointing, we re-load the 
 			node co-ords from the feVariable file - and also update the geometry */
-			fscanf( inputFile, "%lg %lg ",
-				&feVariable->feMesh->nodeCoord[lNode_I][0],
-				&feVariable->feMesh->nodeCoord[lNode_I][1] );
-			if ( feVariable->fieldComponentCount == 3 ) {	
-				fscanf( inputFile, "%lg",
-					&feVariable->feMesh->nodeCoord[lNode_I][2] );
-			}	
-			else {
-				feVariable->feMesh->nodeCoord[lNode_I][2] = 0.0;
+			fscanf( inputFile, "%lg %lg ", Mesh_GetVertex( mesh, lNode_I ), 
+				Mesh_GetVertex( mesh, lNode_I ) + 1 );
+			if ( feVariable->fieldComponentCount == 3 ) {
+				fscanf( inputFile, "%lg", Mesh_GetVertex( mesh, lNode_I ) + 2 );
 			}
 
 			Journal_DPrintfL( debugStream, 3, "read coord (%.3f, %.3f, %.3f)\n", 
-				feVariable->feMesh->nodeCoord[lNode_I][0],
-				feVariable->feMesh->nodeCoord[lNode_I][1],
-				feVariable->feMesh->nodeCoord[lNode_I][2] );
+					  Mesh_GetVertex( mesh, lNode_I )[0],
+					  Mesh_GetVertex( mesh, lNode_I )[1],
+					  (nDims == 3) ? Mesh_GetVertex( mesh, lNode_I )[2] : 0.0 );
 
 			for ( dof_I = 0; dof_I < dofAtEachNodeCount; dof_I++ ) {
 				fscanf( inputFile, "%lg ", &variableVal );
 				DofLayout_SetValueDouble( feVariable->dofLayout, lNode_I, dof_I, variableVal );
 				Journal_DPrintfL( debugStream, 3, "read dof %u: %g\n", dof_I, variableVal ); 
 				/* TODO: Hack for now - ABAQUS only uses initial coords, so assume this is displacement and add */
-				feVariable->feMesh->nodeCoord[lNode_I][dof_I] += variableVal;
+				Mesh_GetVertex( mesh, lNode_I )[dof_I] += variableVal;
 				Journal_DPrintfL( debugStream, 3, "TODO: using HACK assumption of disp.:- updating nodeCoord[%u] to %.3f\n",
-					dof_I, feVariable->feMesh->nodeCoord[lNode_I][dof_I] );
+						  dof_I, Mesh_GetVertex( mesh, lNode_I )[dof_I] );
 			}
 
 			for ( dim_I = 0; dim_I < 3; dim_I++ ) {
-				if ( feVariable->feMesh->nodeCoord[lNode_I][dim_I] < localGeometryMin[dim_I] ) {
-					localGeometryMin[dim_I] = feVariable->feMesh->nodeCoord[lNode_I][dim_I];
+				if ( Mesh_GetVertex( mesh, lNode_I )[dim_I] < localGeometryMin[dim_I] ) {
+					localGeometryMin[dim_I] = Mesh_GetVertex( mesh, lNode_I )[dim_I];
 				}
-				else if ( feVariable->feMesh->nodeCoord[lNode_I][dim_I] > localGeometryMax[dim_I] ) {
-					localGeometryMax[dim_I] = feVariable->feMesh->nodeCoord[lNode_I][dim_I];
+				else if ( Mesh_GetVertex( mesh, lNode_I )[dim_I] > localGeometryMax[dim_I] ) {
+					localGeometryMax[dim_I] = Mesh_GetVertex( mesh, lNode_I )[dim_I];
 				}
 			}
 			
@@ -186,23 +186,16 @@
 	fclose( inputFile );
 	Stream_UnIndent( debugStream );
 
-	/* Since we could be loading in parallel, need to find global min and max of geometry */
-	for ( dim_I = 0; dim_I < 3; dim_I++ ) {
-		MPI_Allreduce( localGeometryMin, geometry->min, 3, MPI_DOUBLE, MPI_MIN, 
-			feVariable->feMesh->layout->decomp->communicator );
-		MPI_Allreduce( localGeometryMax, geometry->max, 3, MPI_DOUBLE, MPI_MAX, 
-			feVariable->feMesh->layout->decomp->communicator );
-	}
+	/* Resync the mesh and update deformation members. */
+	Mesh_Sync( mesh );
+	Mesh_DeformationUpdate( mesh );
 
+	Mesh_GetGlobalCoordRange( mesh, min, max );
 	Journal_DPrintf( debugStream, "Recalculated global field min coord as (%.3f, %.3f, %.3f)\n",
-		geometry->min[0], geometry->min[1], geometry->min[2] );
+			 min[0], min[1], (nDims == 3) ? min[2] : 0.0 );
 	Journal_DPrintf( debugStream, "Recalculated global field max coord as (%.3f, %.3f, %.3f)\n",
-		geometry->max[0], geometry->max[1], geometry->max[2] );
+			 max[0], max[1], (nDims == 3) ? max[2] : 0.0 );
 
-	if ( Stg_Class_IsInstance( feVariable->feMesh->layout->elementLayout, ParallelPipedHexaEL_Type ) ) {
-		ParallelPipedHexaEL_UpdateGeometryPartitionInfo( feVariable->feMesh->layout->elementLayout, feVariable->feMesh->layout->decomp );
-	}
-
 	Stream_UnIndent( debugStream );
 }			
 

Modified: long/3D/Gale/trunk/src/StgFEM/plugins/StandardConditionFunctions/StandardConditionFunctions.c
===================================================================
--- long/3D/Gale/trunk/src/StgFEM/plugins/StandardConditionFunctions/StandardConditionFunctions.c	2006-12-07 23:26:14 UTC (rev 5532)
+++ long/3D/Gale/trunk/src/StgFEM/plugins/StandardConditionFunctions/StandardConditionFunctions.c	2006-12-07 23:29:43 UTC (rev 5533)
@@ -139,7 +139,7 @@
 	DiscretisationContext*	context            = (DiscretisationContext*)_context;
 	Dictionary*             dictionary         = context->dictionary;
 	FeVariable*             feVariable         = NULL;
-	FiniteElement_Mesh*     mesh               = NULL;
+	FeMesh*			mesh               = NULL;
 	double*                 result             = (double*) _result;
 	double*                 coord;
 	Coord                   centre;
@@ -156,7 +156,7 @@
 	omega            = Dictionary_GetDouble_WithDefault( dictionary, "SolidBodyRotationOmega",   1.0 );
 
 	/* Find coordinate of node */
-	coord = Mesh_CoordAt( mesh, node_lI );
+	coord = Mesh_GetVertex( mesh, node_lI );
 
 	/* Find vector from centre to node */
 	StGermain_VectorSubtraction( vector, coord, centre, 2 );
@@ -170,7 +170,7 @@
 	DiscretisationContext*	context            = (DiscretisationContext*)_context;
 	Dictionary*             dictionary         = context->dictionary;
 	FeVariable*             feVariable         = NULL;
-	FiniteElement_Mesh*     mesh               = NULL;
+	FeMesh*			mesh               = NULL;
 	double*                 result             = (double*) _result;
 	double*                 coord;
 	Coord                   centre;
@@ -190,7 +190,7 @@
 	omega            = Dictionary_GetDouble_WithDefault( dictionary, "SolidBodyRotationOmega",   1.0 );
 
 	/* Find coordinate of node */
-	coord = Mesh_CoordAt( mesh, node_lI );
+	coord = Mesh_GetVertex( mesh, node_lI );
 
 	/* Find vector from centre to node */
 	StGermain_VectorSubtraction( vector, coord, centre, 2 );
@@ -208,7 +208,7 @@
 	DiscretisationContext*	context            = (DiscretisationContext*)_context;
 	Dictionary*             dictionary         = context->dictionary;
 	FeVariable*             feVariable         = NULL;
-	FiniteElement_Mesh*     mesh               = NULL;
+	FeMesh*			mesh               = NULL;
 	double*                 result             = (double*) _result;
 	double*                 coord;
 	Coord                   centre;
@@ -228,7 +228,7 @@
 	omega            = Dictionary_GetDouble_WithDefault( dictionary, "SolidBodyRotationOmega",   1.0 );
 
 	/* Find coordinate of node */
-	coord = Mesh_CoordAt( mesh, node_lI );
+	coord = Mesh_GetVertex( mesh, node_lI );
 
 	/* Find vector from centre to node */
 	StGermain_VectorSubtraction( vector, coord, centre, 2 );
@@ -247,7 +247,7 @@
 	DiscretisationContext*	context            = (DiscretisationContext*)_context;
 	Dictionary*             dictionary         = context->dictionary;
 	FeVariable*             feVariable         = NULL;
-	FiniteElement_Mesh*     mesh               = NULL;
+	FeMesh*			mesh               = NULL;
 	double*                 result             = (double*) _result;
 	double*                 coord;
 	double                  centre;
@@ -261,7 +261,7 @@
 	factor = Dictionary_GetDouble_WithDefault( dictionary, "SimpleShearFactor", 1.0 );
 
 	/* Find coordinate of node */
-	coord = Mesh_CoordAt( mesh, node_lI );
+	coord = Mesh_GetVertex( mesh, node_lI );
 
 	*result = factor * (coord[ J_AXIS ] - centre);
 }
@@ -270,7 +270,7 @@
 	DiscretisationContext*	context            = (DiscretisationContext*)_context;
 	Dictionary*             dictionary         = context->dictionary;
 	FeVariable*             feVariable         = NULL;
-	FiniteElement_Mesh*     mesh               = NULL;
+	FeMesh*			mesh               = NULL;
 	double*                 result             = (double*) _result;
 	double*                 coord;
 	double                  centre;
@@ -284,7 +284,7 @@
 	factor = Dictionary_GetDouble_WithDefault( dictionary, "ExtensionFactor", 1.0 );
 
 	/* Find coordinate of node */
-	coord = Mesh_CoordAt( mesh, node_lI );
+	coord = Mesh_GetVertex( mesh, node_lI );
 
 	*result = factor * (coord[ I_AXIS ] - centre);
 }
@@ -293,70 +293,66 @@
 void StgFEM_StandardConditionFunctions_PartialLid_TopLayer( Node_LocalIndex node_lI, Variable_Index var_I, void* _context, void* result ) {
 	DiscretisationContext*	context = (DiscretisationContext*)_context;
 	FeVariable*             velVar = NULL;
-	FiniteElement_Mesh*     mesh = NULL;
-	ParallelPipedHexaEL*    boxEL = NULL;
-	BlockGeometry*          geometry = NULL;
+	FeMesh*			mesh = NULL;
 	double*			velResult = (double*)result;
 	double                  margin = 0;
+	double			min[3], max[3];
 	
 	velVar = (FeVariable*)FieldVariable_Register_GetByName( context->fieldVariable_Register, "VelocityField" );
 	mesh = velVar->feMesh;
-	boxEL = (ParallelPipedHexaEL*)mesh->layout->elementLayout;
-	geometry = (BlockGeometry*)boxEL->geometry;
-	
-	margin = boxEL->elementLengthEachDim[I_AXIS] * 1.1;
-	if ( (mesh->nodeCoord[node_lI][I_AXIS] < (geometry->max[I_AXIS] - margin )) && 
-	     (mesh->nodeCoord[node_lI][I_AXIS] > (geometry->min[I_AXIS] + margin ))) {
+
+	Mesh_GetMinimumSeparation( mesh, &margin, NULL );
+	Mesh_GetGlobalCoordRange( mesh, min, max );
+	margin *= 1.1;
+	if( (Mesh_GetVertex( mesh, node_lI )[I_AXIS] < (max[I_AXIS] - margin )) && 
+	    (Mesh_GetVertex( mesh, node_lI )[I_AXIS] > (min[I_AXIS] + margin )))
+	{
 		(*velResult) = 1;
 	}
 	else {
 		(*velResult) = 0;
-	}	
+	}
 }
 
 
 void StgFEM_StandardConditionFunctions_LinearInterpolationLid( Node_LocalIndex node_lI, Variable_Index var_I, void* _context, void* result ) {
 	DiscretisationContext*	context = (DiscretisationContext*)_context;
 	FeVariable*             velVar = NULL;
-	FiniteElement_Mesh*     mesh = NULL;
-	ParallelPipedHexaEL*    boxEL = NULL;
-	BlockGeometry*          geometry = NULL;
+	FeMesh*			mesh = NULL;
 	double*			velResult = (double*)result;
 	double			boxLength = 0;
 	double			leftHandSideValue = 0;
 	double			rightHandSideValue = 0;
 	double			gradient = 0;
+	double			min[3], max[3];
 	
 	velVar = (FeVariable*)FieldVariable_Register_GetByName( context->fieldVariable_Register, "VelocityField" );
 	mesh = velVar->feMesh;
-	boxEL = (ParallelPipedHexaEL*)mesh->layout->elementLayout;
-	geometry = (BlockGeometry*)boxEL->geometry;
-	
-	boxLength = geometry->max[I_AXIS] - geometry->min[I_AXIS];
+
+	Mesh_GetGlobalCoordRange( mesh, min, max );
+	boxLength = max[I_AXIS] - min[I_AXIS];
 	leftHandSideValue = Dictionary_GetDouble_WithDefault( context->dictionary, "bcLeftHandSideValue", 0.0 );
 	rightHandSideValue = Dictionary_GetDouble_WithDefault( context->dictionary, "bcRightHandSideValue", 1.0 );
 	gradient = (rightHandSideValue - leftHandSideValue) / boxLength;
-	(*velResult) = leftHandSideValue + gradient * ( mesh->nodeCoord[node_lI][I_AXIS] - geometry->min[I_AXIS] );
+	(*velResult) = leftHandSideValue + gradient * (Mesh_GetVertex( mesh, node_lI )[I_AXIS] - min[I_AXIS] );
 }
 
 
 void StgFEM_StandardConditionFunctions_Lid_RampWithCentralMax( Node_LocalIndex node_lI, Variable_Index var_I, void* _context, void* result ) {
 	DiscretisationContext*	context = (DiscretisationContext*)_context;
 	FeVariable*             velVar = NULL;
-	FiniteElement_Mesh*     mesh = NULL;
-	ParallelPipedHexaEL*    boxEL = NULL;
-	BlockGeometry*          geometry = NULL;
+	FeMesh*			mesh = NULL;
 	double*			velResult = (double*)result;
 	double			boxLength = 0;
 	double			xPosRelativeToTopLeft = 0;
+	double			min[3], max[3];
 	
 	velVar = (FeVariable*)FieldVariable_Register_GetByName( context->fieldVariable_Register, "VelocityField" );
 	mesh = velVar->feMesh;
-	boxEL = (ParallelPipedHexaEL*)mesh->layout->elementLayout;
-	geometry = (BlockGeometry*)boxEL->geometry;
-	xPosRelativeToTopLeft = mesh->nodeCoord[node_lI][I_AXIS] - geometry->min[I_AXIS];
-	
-	boxLength = geometry->max[I_AXIS] - geometry->min[I_AXIS];
+
+	Mesh_GetGlobalCoordRange( mesh, min, max );
+	xPosRelativeToTopLeft = Mesh_GetVertex( mesh, node_lI )[I_AXIS] - min[I_AXIS];
+	boxLength = max[I_AXIS] - min[I_AXIS];
 	if ( xPosRelativeToTopLeft < boxLength / 2 ) {
 		(*velResult) =  2 * xPosRelativeToTopLeft / boxLength;
 	}
@@ -369,23 +365,21 @@
 void StgFEM_StandardConditionFunctions_SinusoidalLid( Node_LocalIndex node_lI, Variable_Index var_I, void* _context, void* result ) {
 	DiscretisationContext*	context = (DiscretisationContext*)_context;
 	FeVariable*             velVar = NULL;
-	FiniteElement_Mesh*     mesh = NULL;
-	ParallelPipedHexaEL*    boxEL = NULL;
-	BlockGeometry*          geometry = NULL;
+	FeMesh*			mesh = NULL;
 	double*			velResult = (double*)result;
 	double			boxLength = 0;
 	double			linearInterp = 0;
-	double          wavenumber;
+	double          	wavenumber;
+	double			min[3], max[3];
 
 	wavenumber = Dictionary_GetDouble_WithDefault( context->dictionary, "sinusoidalLidWavenumber", 1 );
 	
 	velVar = (FeVariable*)FieldVariable_Register_GetByName( context->fieldVariable_Register, "VelocityField" );
 	mesh = velVar->feMesh;
-	boxEL = (ParallelPipedHexaEL*)mesh->layout->elementLayout;
-	geometry = (BlockGeometry*)boxEL->geometry;
-	
-	boxLength = geometry->max[I_AXIS] - geometry->min[I_AXIS];
-	linearInterp = ( mesh->nodeCoord[node_lI][I_AXIS] - geometry->min[I_AXIS] ) / boxLength;
+
+	Mesh_GetGlobalCoordRange( mesh, min, max );
+	boxLength = max[I_AXIS] - min[I_AXIS];
+	linearInterp = (Mesh_GetVertex( mesh, node_lI )[I_AXIS] - min[I_AXIS] ) / boxLength;
 	(*velResult) = sin( linearInterp * M_PI * wavenumber );
 }
 
@@ -393,20 +387,21 @@
 void StgFEM_StandardConditionFunctions_CornerOnly( Node_LocalIndex node_lI, Variable_Index var_I, void* _context, void* result ) {
 	DiscretisationContext*	context = (DiscretisationContext*)_context;
 	FeVariable*             velVar = NULL;
-	FiniteElement_Mesh*     mesh = NULL;
-	ParallelPipedHexaEL*    boxEL = NULL;
+	FeMesh*			feMesh = NULL;
 	double*			velResult = (double*)result;
 	Node_GlobalIndex	node_gI = 0;
-	Index			iIndex, jIndex, kIndex;
-	
+	unsigned		inds[3];
+	Grid*			elGrid;
+
 	velVar = (FeVariable*)FieldVariable_Register_GetByName( context->fieldVariable_Register, "VelocityField" );
-	mesh = velVar->feMesh;
-	boxEL = (ParallelPipedHexaEL*)mesh->layout->elementLayout;
-	node_gI = mesh->nodeL2G[node_lI];
+	feMesh = velVar->feMesh;
+	elGrid = *(Grid**)ExtensionManager_Get( feMesh->info, feMesh, 
+						ExtensionManager_GetHandle( feMesh->info, "elGrid" ) );
+
+	node_gI = Mesh_DomainToGlobal( feMesh, MT_VERTEX, node_lI );
+	RegularMeshUtils_Node_1DTo3D( feMesh, node_gI, inds );
 	
-	RegularMeshUtils_Node_1DTo3D( ((HexaMD*)mesh->layout->decomp), node_gI, &iIndex, &jIndex, &kIndex );
-	
-	if ( iIndex == boxEL->elementSize[I_AXIS] ) {
+	if ( inds[0] == elGrid->sizes[I_AXIS] ) {
 		(*velResult) = 1;
 	}
 	else {
@@ -427,7 +422,7 @@
 	DiscretisationContext*	context            = (DiscretisationContext*)_context;
 	Dictionary*             dictionary         = context->dictionary;
 	FeVariable*             feVariable         = NULL;
-	FiniteElement_Mesh*     mesh               = NULL;
+	FeMesh*			feMesh               = NULL;
 	double*                 result             = (double*) _result;
 	Coord                   centre;
 	Coord                   rotationCentre;
@@ -436,7 +431,7 @@
 	double                  hillDiameter;
 	
 	feVariable = (FeVariable*)FieldVariable_Register_GetByName( context->fieldVariable_Register, "TemperatureField" );
-	mesh       = feVariable->feMesh;
+	feMesh       = feVariable->feMesh;
 
 	/* Read values from dictionary */
 	hillHeight       = Dictionary_GetDouble_WithDefault( dictionary, "CosineHillHeight"  , 1.0 );
@@ -457,7 +452,7 @@
 		StGermain_VectorAddition( centre, centre, rotationCentre, context->dim );
 	}
 
-	*result = StGermain_CosineHillValue( centre, Mesh_CoordAt( mesh, node_lI ), hillHeight, hillDiameter, context->dim );
+	*result = StGermain_CosineHillValue( centre, Mesh_GetVertex( feMesh, node_lI ), hillHeight, hillDiameter, context->dim );
 }
 
 
@@ -465,8 +460,7 @@
 	DiscretisationContext*	context = (DiscretisationContext*)_context;
 	Dictionary*             dictionary         = context->dictionary;
 	FeVariable*             feVariable = NULL;
-	FiniteElement_Mesh*     mesh = NULL;
-	BlockGeometry*          geometry = NULL;
+	FeMesh*			feMesh = NULL;
 	double*                 result = (double*) _result;
 	double                  topLayerBC;
 	double                  bottomLayerBC;
@@ -477,11 +471,13 @@
 	double*                 coord;
 	Dimension_Index         dim_I=0;
 	Coord                   relScaledCoord;
+	double			min[3], max[3];
 	
 	feVariable = (FeVariable*)FieldVariable_Register_GetByName( context->fieldVariable_Register, "TemperatureField" );
-	mesh       = feVariable->feMesh;
-	geometry = (BlockGeometry*)mesh->layout->elementLayout->geometry;
+	feMesh       = feVariable->feMesh;
 
+	Mesh_GetGlobalCoordRange( feMesh, min, max );
+
 	topLayerBC = Dictionary_GetDouble_WithDefault( dictionary, "SinusoidalTempIC_TopLayerBC", 0.0 );
 	bottomLayerBC = Dictionary_GetDouble_WithDefault( dictionary, "SinusoidalTempIC_BottomLayerBC", 1.0 );
 	scaleFactor = bottomLayerBC - topLayerBC;
@@ -491,11 +487,10 @@
 	horizontalWaveNumber = Dictionary_GetDouble_WithDefault( dictionary, "SinusoidalTempIC_HorizontalWaveNumber", 1.0 );
 	verticalWaveNumber = Dictionary_GetDouble_WithDefault( dictionary, "SinusoidalTempIC_VerticalWaveNumber", 1.0 );
 
-	coord = Mesh_CoordAt( mesh, node_lI );
+	coord = Mesh_GetVertex( feMesh, node_lI );
 	/* make coord relative to box bottom left corner, then scale from 0 to 1 between box min & max */
 	for ( dim_I = 0; dim_I < 3; dim_I++ ) {
-		relScaledCoord[dim_I] = ( coord[dim_I] - geometry->min[dim_I] )
-			/ (geometry->max[dim_I] - geometry->min[dim_I]);
+		relScaledCoord[dim_I] = (coord[dim_I] - min[dim_I]) / (max[dim_I] - min[dim_I]);
 	}
 
 	/* Note: ok to use the 1.0 below since we've already scaled the coord to somewhere between 0 to 1 */
@@ -507,20 +502,21 @@
 void StgFEM_StandardConditionFunctions_Trigonometry( Node_LocalIndex node_lI, Variable_Index var_I, void* _context, void* _result ) {
 	DiscretisationContext*	context            = (DiscretisationContext*)_context;
 	FeVariable*             feVariable         = NULL;
-	FiniteElement_Mesh*     mesh               = NULL;
-	BlockGeometry*          geometry;
+	FeMesh*			feMesh               = NULL;
 	double*                 result             = (double*) _result;
 	double*                 coord;
 	double                  height, width;
+	double			min[3], max[3];
 
 	feVariable = (FeVariable*)FieldVariable_Register_GetByName( context->fieldVariable_Register, "TemperatureField" );
-	mesh       = feVariable->feMesh;
-	geometry   = (BlockGeometry*) mesh->layout->elementLayout->geometry;
-	coord      = Mesh_CoordAt( mesh, node_lI );
+	feMesh       = feVariable->feMesh;
 
+	Mesh_GetGlobalCoordRange( feMesh, min, max );
+	coord = Mesh_GetVertex( feMesh, node_lI );
+
 	/* Get Aspect Ratio */
-	height = geometry->max[ J_AXIS ] - geometry->min[ J_AXIS ];
-	width  = geometry->max[ I_AXIS ] - geometry->min[ I_AXIS ];
+	height = max[ J_AXIS ] - min[ J_AXIS ];
+	width  = max[ I_AXIS ] - min[ I_AXIS ];
 	
 	*result = 1.0 - 0.5 * M_PI * coord[ J_AXIS ] * sin( M_PI * coord[ I_AXIS ]/width );
 }
@@ -529,8 +525,7 @@
 void Stg_FEM_VelicTemperatureIC( Node_LocalIndex node_lI, Variable_Index var_I, void* _context, void* _result ) {
 	DiscretisationContext*  context            = (DiscretisationContext*)_context;
 	FeVariable*             temperatureField   = (FeVariable*) FieldVariable_Register_GetByName( context->fieldVariable_Register, "TemperatureField" );
-	FiniteElement_Mesh*     mesh               = temperatureField->feMesh;
-	BlockGeometry*          geometry           = (BlockGeometry*) mesh->layout->elementLayout->geometry;
+	FeMesh*			feMesh               = temperatureField->feMesh;
 	Dictionary*             dictionary         = context->dictionary;
 	double*                 result             = (double*) _result;
 	double*                 coord;
@@ -542,16 +537,18 @@
 	double                  wavenumberY;
 	double                  sigma;
 	double                  Lx;
+	double			min[3], max[3];
 	
 	/* Find coordinate of node */
-	coord = Mesh_CoordAt( mesh, node_lI );
+	coord = Mesh_GetVertex( feMesh, node_lI );
+	Mesh_GetGlobalCoordRange( feMesh, min, max );
 
 	/* Make sure that the box has right dimensions */
-	assert( ( geometry->max[ J_AXIS ] - geometry->min[ J_AXIS ] - 1.0 ) < SMALL );
-	Lx = geometry->max[ I_AXIS ] - geometry->min[ I_AXIS ];
+	assert( ( max[ J_AXIS ] - min[ J_AXIS ] - 1.0 ) < SMALL );
+	Lx = max[ I_AXIS ] - min[ I_AXIS ];
 
-	x = coord[ I_AXIS ] - geometry->min[ I_AXIS ];
-	y = coord[ J_AXIS ] - geometry->min[ J_AXIS ];
+	x = coord[ I_AXIS ] - min[ I_AXIS ];
+	y = coord[ J_AXIS ] - min[ J_AXIS ];
 
 	wavenumberX = Dictionary_GetInt_WithDefault( dictionary, "wavenumberX", 1 );
 	wavenumberY = Dictionary_GetDouble_WithDefault( dictionary, "wavenumberY", 1.0 );
@@ -571,8 +568,7 @@
 void Stg_FEM_VelicTemperatureIC_SolB( Node_LocalIndex node_lI, Variable_Index var_I, void* _context, void* _result ) {
 	DiscretisationContext*  context            = (DiscretisationContext*)_context;
 	FeVariable*             temperatureField   = (FeVariable*) FieldVariable_Register_GetByName( context->fieldVariable_Register, "TemperatureField" );
-	FiniteElement_Mesh*     mesh               = temperatureField->feMesh;
-	BlockGeometry*          geometry           = (BlockGeometry*) mesh->layout->elementLayout->geometry;
+	FeMesh*			feMesh               = temperatureField->feMesh;
 	Dictionary*             dictionary         = context->dictionary;
 	double*                 result             = (double*) _result;
 	double*                 coord;
@@ -584,16 +580,18 @@
 	double                  wavenumberY;
 	double                  L;
 	double                  sigma;
+	double			min[3], max[3];
 	
 	/* Find coordinate of node */
-	coord = Mesh_CoordAt( mesh, node_lI );
+	coord = Mesh_GetVertex( feMesh, node_lI );
+	Mesh_GetGlobalCoordRange( feMesh, min, max );
 
 	/* Make sure that the box has right dimensions */
-	assert( ( geometry->max[ J_AXIS ] - geometry->min[ J_AXIS ] - 1.0 ) < SMALL );
-	L = geometry->max[ I_AXIS ] - geometry->min[ I_AXIS ];
+	assert( (max[ J_AXIS ] - min[ J_AXIS ] - 1.0 ) < SMALL );
+	L = max[ I_AXIS ] - min[ I_AXIS ];
 
-	x = coord[ I_AXIS ] - geometry->min[ I_AXIS ];
-	y = coord[ J_AXIS ] - geometry->min[ J_AXIS ];
+	x = coord[ I_AXIS ] - min[ I_AXIS ];
+	y = coord[ J_AXIS ] - min[ J_AXIS ];
 
 	wavenumberX = Dictionary_GetInt_WithDefault( dictionary, "wavenumberX", 1 );
 	wavenumberY = Dictionary_GetDouble_WithDefault( dictionary, "wavenumberY", 2.0 );
@@ -613,8 +611,7 @@
 void StgFEM_StandardConditionFunctions_AnalyticalTemperatureIC( Node_LocalIndex node_lI, Variable_Index var_I, void* _context, void* _result ) {
 	DiscretisationContext*	context            = (DiscretisationContext*)_context;
 	FeVariable*             feVariable         = NULL;
-	FiniteElement_Mesh*     mesh               = NULL;
-	BlockGeometry*          geometry;
+	FeMesh*			feMesh               = NULL;
 	Dictionary*             dictionary         = context->dictionary;
 	double*                 result             = (double*) _result;
 	double*                 coord;
@@ -623,23 +620,25 @@
 	double                  Ra;
 	double                  lambda, height, width;
 	double                  Tu, Tl, Tr, Ts;
+	double			min[3], max[3];
 
 #ifdef NO_ERF
         printf("StG_FEM_StandardConditionFunctions_AnalyticalTemperatureIC does not work\nbecause erf is not defined.\n");
         exit(1);
 #else
 	feVariable = (FeVariable*)FieldVariable_Register_GetByName( context->fieldVariable_Register, "TemperatureField" );
-	mesh       = feVariable->feMesh;
-	geometry   = (BlockGeometry*) mesh->layout->elementLayout->geometry;
-	coord      = Mesh_CoordAt( mesh, node_lI );
+	feMesh       = feVariable->feMesh;
 
+	coord      = Mesh_GetVertex( feMesh, node_lI );
+	Mesh_GetGlobalCoordRange( feMesh, min, max );
+
 	/* Get Aspect Ratio */
-	height = geometry->max[ J_AXIS ] - geometry->min[ J_AXIS ];
-	width  = geometry->max[ I_AXIS ] - geometry->min[ I_AXIS ];
+	height = max[ J_AXIS ] - min[ J_AXIS ];
+	width  = max[ I_AXIS ] - min[ I_AXIS ];
 	lambda = width/height;
 	
-	x = coord[ I_AXIS ] - geometry->min[ I_AXIS ];
-	y = coord[ J_AXIS ] - geometry->min[ J_AXIS ];
+	x = coord[ I_AXIS ] - min[ I_AXIS ];
+	y = coord[ J_AXIS ] - min[ J_AXIS ];
 	
 	/* Get thermal Rayleigh Number from Dictionary */
 	Ra = Dictionary_GetDouble( dictionary, "Ra" );
@@ -690,7 +689,7 @@
 void StgFEM_StandardConditionFunctions_StepFunction( Node_LocalIndex node_lI, Variable_Index var_I, void* _context, void* _result ) {
 	FiniteElementContext *	context            = (FiniteElementContext*)_context;
 	FeVariable*             feVariable         = NULL;
-	FiniteElement_Mesh*     mesh               = NULL;
+	FeMesh*			feMesh               = NULL;
 	Dictionary*             dictionary         = context->dictionary;
 	double*                 result             = (double*) _result;
         double*                 coord;
@@ -700,8 +699,8 @@
 	Bool			less;
 
 	feVariable = (FeVariable*)FieldVariable_Register_GetByName( context->fieldVariable_Register, "VelocityField" );
-	mesh       = feVariable->feMesh;
-	coord      = Mesh_CoordAt( mesh, node_lI );
+	feMesh       = feVariable->feMesh;
+	coord      = Mesh_GetVertex( feMesh, node_lI );
 
 	lower_offset = Dictionary_GetDouble_WithDefault( dictionary, "StepFunctionLowerOffset", 0.0 );
 	upper_offset = Dictionary_GetDouble_WithDefault( dictionary, "StepFunctionUpperOffset", lower_offset );

Modified: long/3D/Gale/trunk/src/StgFEM/plugins/VelicAnalyticSolutions/Velic_solA/solA.c
===================================================================
--- long/3D/Gale/trunk/src/StgFEM/plugins/VelicAnalyticSolutions/Velic_solA/solA.c	2006-12-07 23:26:14 UTC (rev 5532)
+++ long/3D/Gale/trunk/src/StgFEM/plugins/VelicAnalyticSolutions/Velic_solA/solA.c	2006-12-07 23:29:43 UTC (rev 5533)
@@ -311,43 +311,48 @@
 
 void _Velic_solA_Construct( void* analyticSolution, Stg_ComponentFactory* cf, void* data ) {
 	Velic_solA* self = (Velic_solA*) analyticSolution;
-	FeVariable*              velocityField;
-	FeVariable*              pressureField;
-	FeVariable*              stressField;
-	FeVariable*              strainRateField;
-	FeVariable*              recoverdStrainRateField;
-	FeVariable*              recoveredStressField;
 
 	/* Construct Parent */
 	_AnalyticSolution_Construct( self, cf, data );
 
 	/* Create Analytic Fields */
-	velocityField = Stg_ComponentFactory_ConstructByName( cf, "VelocityField", FeVariable, True, data ); 
-	AnalyticSolution_CreateAnalyticVectorField( self, velocityField, Velic_solA_VelocityFunction );
+	self->velocityField = Stg_ComponentFactory_ConstructByName( cf, "VelocityField", FeVariable, True, data ); 
+	self->pressureField = Stg_ComponentFactory_ConstructByName( cf, "PressureField", FeVariable, True, data ); 
+	self->stressField = Stg_ComponentFactory_ConstructByName( cf, "StressField", FeVariable, False, data ); 
+	self->strainRateField = Stg_ComponentFactory_ConstructByName( cf, "StrainRateField", FeVariable, False, data ); 
+	self->recoveredStrainRateField = Stg_ComponentFactory_ConstructByName( cf, "recoveredStrainRate", FeVariable, False, data ); 
+	self->recoveredStressField = Stg_ComponentFactory_ConstructByName( cf, "recoveredStress", FeVariable, False, data );
 
-	pressureField = Stg_ComponentFactory_ConstructByName( cf, "PressureField", FeVariable, True, data ); 
-	AnalyticSolution_CreateAnalyticField( self, pressureField, Velic_solA_PressureFunction );
+	self->sigma = Stg_ComponentFactory_GetRootDictDouble( cf, "sigma", 1.0 );
+	self->Z = Stg_ComponentFactory_GetRootDictDouble( cf, "Z", 1.0 );
+}
 
-	stressField = Stg_ComponentFactory_ConstructByName( cf, "StressField", FeVariable, False, data ); 
-	if ( stressField )
-		AnalyticSolution_CreateAnalyticSymmetricTensorField( self, stressField, Velic_solA_StressFunction );
+void _Velic_solA_Build( void* analyticSolution, void* data ) {
+	Velic_solA* self = (Velic_solA*) analyticSolution;
 
-	strainRateField = Stg_ComponentFactory_ConstructByName( cf, "StrainRateField", FeVariable, False, data ); 
-	if ( strainRateField  ) {
-		AnalyticSolution_CreateAnalyticSymmetricTensorField( self, strainRateField, Velic_solA_StrainRateFunction );
+	Build( self->velocityField, data, False );
+	Build( self->pressureField, data, False );
+
+	AnalyticSolution_CreateAnalyticVectorField( self, self->velocityField, Velic_solA_VelocityFunction );
+	AnalyticSolution_CreateAnalyticField( self, self->pressureField, Velic_solA_PressureFunction );
+	if ( self->stressField ) {
+		Build( self->stressField, data, False );
+		AnalyticSolution_CreateAnalyticSymmetricTensorField( self, self->stressField, Velic_solA_StressFunction );
 	}
+	if ( self->strainRateField  ) {
+		Build( self->strainRateField, data, False );
+		AnalyticSolution_CreateAnalyticSymmetricTensorField( self, self->strainRateField, Velic_solA_StrainRateFunction );
+	}
+	if ( self->recoveredStrainRateField ) {
+		Build( self->recoveredStrainRateField, data, False );
+		AnalyticSolution_CreateAnalyticSymmetricTensorField( self, self->recoveredStrainRateField, Velic_solA_StrainRateFunction );
+	}
+	if ( self->recoveredStressField ) {
+		Build( self->recoveredStressField, data, False );
+		AnalyticSolution_CreateAnalyticSymmetricTensorField( self, self->recoveredStressField, Velic_solA_StressFunction );
+	}
 
-	recoverdStrainRateField = Stg_ComponentFactory_ConstructByName( cf, "recoveredStrainRate", FeVariable, False, data ); 
-	if ( recoverdStrainRateField )
-		AnalyticSolution_CreateAnalyticSymmetricTensorField( self, recoverdStrainRateField, Velic_solA_StrainRateFunction );
-
-	recoveredStressField = Stg_ComponentFactory_ConstructByName( cf, "recoveredStress", FeVariable, False, data );
-	if ( recoveredStressField )
-		AnalyticSolution_CreateAnalyticSymmetricTensorField( self, recoveredStressField, Velic_solA_StressFunction );
-	
-
-	self->sigma = Stg_ComponentFactory_GetRootDictDouble( cf, "sigma", 1.0 );
-	self->Z = Stg_ComponentFactory_GetRootDictDouble( cf, "Z", 1.0 );
+	_AnalyticSolution_Build( self, data );
 }
 
 void* _Velic_solA_DefaultNew( Name name ) {
@@ -359,7 +364,7 @@
 			_AnalyticSolution_Copy,
 			_Velic_solA_DefaultNew,
 			_Velic_solA_Construct,
-			_AnalyticSolution_Build,
+			_Velic_solA_Build, 
 			_AnalyticSolution_Initialise,
 			_AnalyticSolution_Execute,
 			_AnalyticSolution_Destroy,

Modified: long/3D/Gale/trunk/src/StgFEM/plugins/VelicAnalyticSolutions/Velic_solA/solA.h
===================================================================
--- long/3D/Gale/trunk/src/StgFEM/plugins/VelicAnalyticSolutions/Velic_solA/solA.h	2006-12-07 23:26:14 UTC (rev 5532)
+++ long/3D/Gale/trunk/src/StgFEM/plugins/VelicAnalyticSolutions/Velic_solA/solA.h	2006-12-07 23:29:43 UTC (rev 5533)
@@ -7,6 +7,12 @@
 		__AnalyticSolution
 		double sigma;
 		double Z;
+		FeVariable* velocityField;
+		FeVariable* pressureField;
+		FeVariable* stressField;
+		FeVariable* strainRateField;
+		FeVariable* recoveredStrainRateField;
+		FeVariable* recoveredStressField;
 	} Velic_solA;
 
 	void Velic_solA_PressureFunction( void* analyticSolution, FeVariable* analyticFeVariable, double* coord, double* pressure );

Modified: long/3D/Gale/trunk/src/StgFEM/src/main.c
===================================================================
--- long/3D/Gale/trunk/src/StgFEM/src/main.c	2006-12-07 23:26:14 UTC (rev 5532)
+++ long/3D/Gale/trunk/src/StgFEM/src/main.c	2006-12-07 23:29:43 UTC (rev 5533)
@@ -80,7 +80,7 @@
 	MPI_Comm_dup( MPI_COMM_WORLD, &CommWorld );
 	MPI_Comm_size( CommWorld, &numProcessors );
 	MPI_Comm_rank( CommWorld, &rank );
-	
+
 	StGermain_Init( &argc, &argv );
 	StgFEM_Init( &argc, &argv );
 	#ifdef HAVE_PYTHON



More information about the cig-commits mailing list