[cig-commits] r19040 - in long/3D/SNAC/trunk/Snac/plugins: . remesher_BI

echoi at geodynamics.org echoi at geodynamics.org
Fri Oct 7 09:18:20 PDT 2011


Author: echoi
Date: 2011-10-07 09:18:20 -0700 (Fri, 07 Oct 2011)
New Revision: 19040

Added:
   long/3D/SNAC/trunk/Snac/plugins/remesher_BI/
   long/3D/SNAC/trunk/Snac/plugins/remesher_BI/Build.c
   long/3D/SNAC/trunk/Snac/plugins/remesher_BI/Build.h
   long/3D/SNAC/trunk/Snac/plugins/remesher_BI/ConstructExtensions.c
   long/3D/SNAC/trunk/Snac/plugins/remesher_BI/ConstructExtensions.h
   long/3D/SNAC/trunk/Snac/plugins/remesher_BI/Context.c
   long/3D/SNAC/trunk/Snac/plugins/remesher_BI/Context.h
   long/3D/SNAC/trunk/Snac/plugins/remesher_BI/DeleteExtensions.c
   long/3D/SNAC/trunk/Snac/plugins/remesher_BI/DeleteExtensions.h
   long/3D/SNAC/trunk/Snac/plugins/remesher_BI/EntryPoint.c
   long/3D/SNAC/trunk/Snac/plugins/remesher_BI/EntryPoint.h
   long/3D/SNAC/trunk/Snac/plugins/remesher_BI/InitialConditions.c
   long/3D/SNAC/trunk/Snac/plugins/remesher_BI/InitialConditions.h
   long/3D/SNAC/trunk/Snac/plugins/remesher_BI/Make.mm
   long/3D/SNAC/trunk/Snac/plugins/remesher_BI/Makefile.def
   long/3D/SNAC/trunk/Snac/plugins/remesher_BI/Mesh.c
   long/3D/SNAC/trunk/Snac/plugins/remesher_BI/Mesh.h
   long/3D/SNAC/trunk/Snac/plugins/remesher_BI/Output.c
   long/3D/SNAC/trunk/Snac/plugins/remesher_BI/Output.h
   long/3D/SNAC/trunk/Snac/plugins/remesher_BI/Register.c
   long/3D/SNAC/trunk/Snac/plugins/remesher_BI/Register.h
   long/3D/SNAC/trunk/Snac/plugins/remesher_BI/Remesh.c
   long/3D/SNAC/trunk/Snac/plugins/remesher_BI/Remesh.h
   long/3D/SNAC/trunk/Snac/plugins/remesher_BI/RemeshCoords.c
   long/3D/SNAC/trunk/Snac/plugins/remesher_BI/RemeshElements.c
   long/3D/SNAC/trunk/Snac/plugins/remesher_BI/RemeshNodes.c
   long/3D/SNAC/trunk/Snac/plugins/remesher_BI/Remesher.h
   long/3D/SNAC/trunk/Snac/plugins/remesher_BI/TestCondFunc.c
   long/3D/SNAC/trunk/Snac/plugins/remesher_BI/TestCondFunc.h
   long/3D/SNAC/trunk/Snac/plugins/remesher_BI/Utils.c
   long/3D/SNAC/trunk/Snac/plugins/remesher_BI/Utils.h
   long/3D/SNAC/trunk/Snac/plugins/remesher_BI/makefile
   long/3D/SNAC/trunk/Snac/plugins/remesher_BI/types.h
Log:
A new scheme of remeshing implemented.
  1. Grids of barycenters of new and old hex meshes are created. Tet elements become topological nodes of these grids.
  2. Barycentric coordinates of a node of the new barycenter grid are computed within
     a containing tet in the old barycenter grid. 
  3. Tet elements of a regridded mesh takes surrounding elements' values weighted by the barycentric coordinates.



Added: long/3D/SNAC/trunk/Snac/plugins/remesher_BI/Build.c
===================================================================
--- long/3D/SNAC/trunk/Snac/plugins/remesher_BI/Build.c	                        (rev 0)
+++ long/3D/SNAC/trunk/Snac/plugins/remesher_BI/Build.c	2011-10-07 16:18:20 UTC (rev 19040)
@@ -0,0 +1,154 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+**
+** Copyright (C), 2003,
+**	Steve Quenette, 110 Victoria Street, Melbourne, Victoria, 3053, Australia.
+**	Californian Institute of Technology, 1200 East California Boulevard, Pasadena, California, 91125, USA.
+**	University of Texas, 1 University Station, Austin, Texas, 78712, USA.
+**
+** Authors:
+**	Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
+**	Stevan M. Quenette, Visitor in Geophysics, Caltech.
+**	Luc Lavier, Research Scientist, The University of Texas. (luc at utig.ug.utexas.edu)
+**	Luc Lavier, Research Scientist, Caltech.
+**
+** This program is free software; you can redistribute it and/or modify it
+** under the terms of the GNU General Public License as published by the
+** Free Software Foundation; either version 2, or (at your option) any
+** later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+**
+** $Id: Build.c 3095 2005-07-13 09:50:46Z LukeHodkinson $
+**
+**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#include <mpi.h>
+#include <StGermain/StGermain.h>
+#include <StGermain/FD/FD.h>
+#include "Snac/Snac.h"
+#include "types.h"
+#include "Mesh.h"
+#include "Context.h"
+#include "Register.h"
+#include "Build.h"
+
+
+void _SnacRemesher_Build( void* _context, void* data ) {
+	Snac_Context*		context = (Snac_Context*)_context;
+	Mesh*			mesh = context->mesh;
+	SnacRemesher_Mesh*	meshExt = ExtensionManager_Get(
+						context->meshExtensionMgr,
+						mesh,
+						SnacRemesher_MeshHandle );
+	
+
+	Journal_Printf( context->debug, "In: %s\n", __func__ );
+	
+	/* Alloc space for the remeshed node coords. */
+	meshExt->newNodeCoords = Memory_Alloc_Array( Coord, mesh->nodeLocalCount, "SnacRemesher" );
+	
+	/* Set all else to empty values. */
+	meshExt->newNodes = NULL;
+	meshExt->newElements = NULL;
+	meshExt->nExternalNodes = 0;
+	meshExt->externalNodes = NULL;
+	meshExt->nExternalElements = 0;
+	meshExt->externalElements = NULL;
+	meshExt->nTopInternNodes = 0;
+	meshExt->topInternToLocal = NULL;
+	meshExt->nBotInternNodes = 0;
+	meshExt->botInternToLocal = NULL;
+	meshExt->nTopTriNodes = 0;
+	meshExt->topTriToDomain = NULL;
+	meshExt->nBotTriNodes = 0;
+	meshExt->botTriToDomain = NULL;
+	meshExt->nYLines = 0;
+	meshExt->yLineLTerm = NULL;
+	meshExt->yLineUTerm = NULL;
+	meshExt->yLineNYInds = NULL;
+	meshExt->yLineYInds = NULL;
+	meshExt->yLineLocalInds = NULL;
+}
+
+
+
+#if 0
+
+void _SnacRemesher_Build( void* _context, void* data ) {
+	Snac_Context*		context = (Snac_Context*)_context;
+	Mesh*			mesh = context->mesh;
+	SnacRemesher_Mesh*	meshExt = ExtensionManager_Get(
+						context->meshExtensionMgr,
+						mesh,
+						SnacRemesher_MeshHandle );
+
+	Journal_Printf( context->debug, "In: %s\n", __func__ );
+
+	/* Keep local copies of the node count info */
+	meshExt->nodeLocalCount = mesh->nodeLocalCount;
+	meshExt->nodeDomainCount = mesh->nodeDomainCount;
+	meshExt->nodeGlobalCount = mesh->nodeGlobalCount;
+	meshExt->elementLocalCount = mesh->elementLocalCount;
+	meshExt->elementDomainCount = mesh->elementDomainCount;
+	meshExt->elementGlobalCount = mesh->elementGlobalCount;
+	Journal_Printf(
+		context->snacDebug,
+		"Remesher is being told: nodeLocalCount: %u, nodeDomainCount: %u, nodeGlobalCount: %u\n",
+		meshExt->nodeLocalCount,
+		meshExt->nodeDomainCount,
+		meshExt->nodeGlobalCount );
+	Journal_Printf(
+		context->snacDebug,
+		"Remesher is being told:  elementLocalCount: %u, elementDomainCount %u, elementGlobalCount: %u\n",
+		meshExt->elementLocalCount,
+		meshExt->elementDomainCount,
+		meshExt->elementGlobalCount );
+
+	/* Alloc mem for initial coordinates array. We need only local coordinates here */
+	meshExt->initialNodeCoord = (Coord*)malloc( sizeof(Coord) * meshExt->nodeLocalCount );
+
+	/* Alloc mem for scratch space for calculating new interpolated nodes and elements. Include shadow nodes too.
+	   TODO: node and element mem allocation SHOULD be a function provided by the Mesh class */
+	meshExt->newNodeCoord = (Coord*)malloc( sizeof(Coord) * meshExt->nodeDomainCount );
+	meshExt->newNode = (Snac_Node*)ExtensionManager_Malloc( context->mesh->nodeExtensionMgr, meshExt->nodeDomainCount );
+	meshExt->newElement = (Snac_Element*)ExtensionManager_Malloc( context->mesh->elementExtensionMgr, meshExt->elementDomainCount );
+
+	/* Alloc mem for knowing who our neighbour ranks are */
+	meshExt->neighbourRankCount = _HexaMD_Shadow_ProcCount( (HexaMD*)mesh->layout->decomp );
+	meshExt->neighbourRank = (Partition_Index*)malloc( sizeof(Partition_Index) * meshExt->neighbourRankCount );
+
+	/* Top surface shadowing */
+	meshExt->shadowNodeLocalCount = 0;
+	meshExt->shadowNodeLocalArray = 0;
+	meshExt->shadowNodeRemoteCount = 0;
+	meshExt->shadowNodeRemoteArray = 0;
+	meshExt->shadowNodeRemoteCoord = 0;
+	meshExt->shadowNodeRemote = 0;
+	meshExt->shadowElementLocalCount = 0;
+	meshExt->shadowElementLocalArray = 0;
+	meshExt->shadowElementRemoteCount = 0;
+	meshExt->shadowElementRemoteArray = 0;
+	meshExt->shadowElementRemote = 0;
+
+	meshExt->topInternalSet = IndexSet_New( meshExt->nodeLocalCount );
+	meshExt->bottomInternalSet = IndexSet_New( meshExt->nodeLocalCount );
+	meshExt->wallSet = IndexSet_New( meshExt->nodeLocalCount );
+	meshExt->internalSet = IndexSet_New( meshExt->nodeLocalCount );
+	meshExt->topInternalCount = 0;
+	meshExt->bottomInternalCount = 0;
+	meshExt->wallCount = 0;
+	meshExt->internalCount = 0;
+	meshExt->topInternalArray = 0;
+	meshExt->bottomInternalArray = 0;
+	meshExt->wallArray = 0;
+	meshExt->internalArray = 0;
+}
+
+#endif

Added: long/3D/SNAC/trunk/Snac/plugins/remesher_BI/Build.h
===================================================================
--- long/3D/SNAC/trunk/Snac/plugins/remesher_BI/Build.h	                        (rev 0)
+++ long/3D/SNAC/trunk/Snac/plugins/remesher_BI/Build.h	2011-10-07 16:18:20 UTC (rev 19040)
@@ -0,0 +1,47 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+**
+** Copyright (C), 2003, 
+**	Steve Quenette, 110 Victoria Street, Melbourne, Victoria, 3053, Australia.
+**	Californian Institute of Technology, 1200 East California Boulevard, Pasadena, California, 91125, USA.
+**	University of Texas, 1 University Station, Austin, Texas, 78712, USA.
+**
+** Authors:
+**	Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
+**	Stevan M. Quenette, Visitor in Geophysics, Caltech.
+**	Luc Lavier, Research Scientist, The University of Texas. (luc at utig.ug.utexas.edu)
+**	Luc Lavier, Research Scientist, Caltech.
+**
+** This program is free software; you can redistribute it and/or modify it
+** under the terms of the GNU General Public License as published by the
+** Free Software Foundation; either version 2, or (at your option) any
+** later version.
+** 
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+** GNU General Public License for more details.
+** 
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+**
+*/
+/** \file
+** Role:
+**
+** Assumptions:
+**
+** Comments:
+**
+** $Id: Build.h 3095 2005-07-13 09:50:46Z LukeHodkinson $
+**
+**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#ifndef __SnacRemesher_Build_h__
+#define __SnacRemesher_Build_h__
+	
+	
+	void _SnacRemesher_Build( void* _context, void* data );
+	
+	
+#endif /* __SnacRemesher_Build_h__ */

Added: long/3D/SNAC/trunk/Snac/plugins/remesher_BI/ConstructExtensions.c
===================================================================
--- long/3D/SNAC/trunk/Snac/plugins/remesher_BI/ConstructExtensions.c	                        (rev 0)
+++ long/3D/SNAC/trunk/Snac/plugins/remesher_BI/ConstructExtensions.c	2011-10-07 16:18:20 UTC (rev 19040)
@@ -0,0 +1,228 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+**
+** Copyright (C), 2003,
+**	Steve Quenette, 110 Victoria Street, Melbourne, Victoria, 3053, Australia.
+**	Californian Institute of Technology, 1200 East California Boulevard, Pasadena, California, 91125, USA.
+**	University of Texas, 1 University Station, Austin, Texas, 78712, USA.
+**
+** Authors:
+**	Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
+**	Stevan M. Quenette, Visitor in Geophysics, Caltech.
+**	Luc Lavier, Research Scientist, The University of Texas. (luc at utig.ug.utexas.edu)
+**	Luc Lavier, Research Scientist, Caltech.
+**
+** This program is free software; you can redistribute it and/or modify it
+** under the terms of the GNU General Public License as published by the
+** Free Software Foundation; either version 2, or (at your option) any
+** later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+**
+** $Id: ConstructExtensions.c 3066 2005-07-06 22:17:29Z EunseoChoi $
+**
+**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#include <mpi.h>
+#include <StGermain/StGermain.h>
+#include <StGermain/FD/FD.h>
+#include "Snac/Snac.h"
+#include "types.h"
+#include "Mesh.h"
+#include "Context.h"
+#include "Register.h"
+#include "TestCondFunc.h"
+#include "ConstructExtensions.h"
+#include <assert.h>
+#include <limits.h>
+#include <string.h>
+
+static char CONDITION_STR[] = "remeshCondition";
+static char TIMESTEPCRITERION_STR[] = "remeshTimeStepCriterion";
+static char LENGTHCRITERION_STR[] = "remeshLengthCriterion";
+static char OFF_STR[] = "off";
+static char ON_STR[] = "on";
+static char ONTIMESTEP_STR[] = "onTimeStep";
+static char ONMINLENGTHSCALE_STR[] = "onMinLengthScale";
+static char ONBOTHTIMESTEPLENGTH_STR[] = "onBothTimeStepLength";
+static char MESH_STR[] = "mesh";
+static char MESHTYPE_STR[] = "meshType";
+static char SPHERICAL_STR[] = "spherical";
+static char CARTESIAN_STR[] = "cartesian";
+#ifndef PATH_MAX
+	#define PATH_MAX 1024
+#endif
+
+void _SnacRemesher_ConstructExtensions( void* _context, void* data ) {
+	Snac_Context*				context = (Snac_Context*)_context;
+	SnacRemesher_Context*			contextExt = ExtensionManager_Get(
+							context->extensionMgr,
+							context,
+							SnacRemesher_ContextHandle );
+	Mesh*					mesh = context->mesh;
+	SnacRemesher_Mesh*			meshExt = ExtensionManager_Get(
+							context->meshExtensionMgr,
+							mesh,
+							SnacRemesher_MeshHandle );
+	char*					conditionStr;
+	Dictionary_Entry_Value*			conditionCriterion;
+	Dictionary* 				meshDict;
+	Stream*					error = Journal_Register( Error_Type, "Remesher" );
+	char					tmpBuf[PATH_MAX];
+
+	Journal_Printf( context->debug, "In: %s\n", __func__ );
+	
+	contextExt->debugIC = Journal_Register( Debug_Type, "Remesher-ICs" );
+	contextExt->debugCoords = Journal_Register( Debug_Type, "Remesher-Coords" );
+	contextExt->debugNodes = Journal_Register( Debug_Type, "Remesher-Nodes" );
+	contextExt->debugElements = Journal_Register( Debug_Type, "Remesher-Elements" );
+	contextExt->debugSync = Journal_Register( Debug_Type, "Remesher-Sync" );
+	
+	/* Additional tables required over the nodeElementTbl already required by core Snac */
+	Mesh_ActivateNodeNeighbourTbl( mesh );
+	Mesh_ActivateElementNeighbourTbl( mesh );
+	
+	/* Work out condition to remesh on */
+	if( !Dictionary_Get( context->dictionary, CONDITION_STR ) ) {
+		Journal_Printf( 
+			error,
+			"Warning: No \"%s\" entry in dictionary... will default to \"%s\"\n", 
+			CONDITION_STR,
+			OFF_STR );
+	}
+	
+	conditionStr = Dictionary_Entry_Value_AsString( 
+		Dictionary_GetDefault( context->dictionary, CONDITION_STR, Dictionary_Entry_Value_FromString( OFF_STR ) ) );
+	
+	contextExt->OnTimeStep = 0;
+	contextExt->onMinLengthScale = 0;
+	if( !strcmp( conditionStr, OFF_STR ) ) {
+		contextExt->condition = SnacRemesher_Off;
+		Journal_Printf( context->snacInfo, "Remesher is off\n" );
+	}
+	else if( !strcmp( conditionStr, ONTIMESTEP_STR ) ) {
+		contextExt->condition = SnacRemesher_OnTimeStep;
+		conditionCriterion = Dictionary_Get( context->dictionary, TIMESTEPCRITERION_STR );
+		Journal_Printf( context->snacInfo, "Remesher is on... activated based on timeStep\n" );
+		
+		if( conditionCriterion ) {
+			contextExt->OnTimeStep = Dictionary_Entry_Value_AsUnsignedInt( conditionCriterion );
+		}
+		else {
+		}
+		Journal_Printf( context->snacInfo, "Remeshing every %u timeSteps\n", contextExt->OnTimeStep );
+	}
+	else if( !strcmp( conditionStr, ONMINLENGTHSCALE_STR ) ) {
+		contextExt->condition = SnacRemesher_OnMinLengthScale;
+		conditionCriterion = Dictionary_Get( context->dictionary, LENGTHCRITERION_STR );
+		Journal_Printf( context->snacInfo, "Remesher is on... activated by minLengthScale\n" );
+		
+		if( conditionCriterion ) {
+			contextExt->onMinLengthScale = Dictionary_Entry_Value_AsDouble( conditionCriterion );
+		}
+		else {
+		}
+		Journal_Printf( context->snacInfo, "Remesh when minLengthScale < %g\n", contextExt->onMinLengthScale );
+	}
+	else if( !strcmp( conditionStr, ONBOTHTIMESTEPLENGTH_STR ) ) {
+		contextExt->condition = SnacRemesher_OnBothTimeStepLength;
+		conditionCriterion = Dictionary_Get( context->dictionary, TIMESTEPCRITERION_STR );
+		Journal_Printf( context->snacInfo, "Remesher is on... activated by both timeStep and minLengthScale\n" );
+		
+		if( conditionCriterion ) {
+			contextExt->OnTimeStep = Dictionary_Entry_Value_AsUnsignedInt( conditionCriterion );
+			conditionCriterion = Dictionary_Get( context->dictionary, LENGTHCRITERION_STR );
+			contextExt->onMinLengthScale = Dictionary_Entry_Value_AsDouble( conditionCriterion );
+		}
+		else {
+		}
+		Journal_Printf( context->snacInfo, "Remesh every %u timeSteps or wheen minLengthScale < %g\n", contextExt->OnTimeStep, contextExt->onMinLengthScale );
+	}
+	else {
+		contextExt->condition = SnacRemesher_Off;
+		Journal_Printf( context->snacInfo, "Remesher is defaulting to off\n" );
+		Journal_Printf( error, "Provided remesh condition \"%s\" unrecognised\n", conditionStr );
+	}
+	
+	
+	/* Work out the mesh type */
+	meshDict = Dictionary_Entry_Value_AsDictionary( Dictionary_Get( context->dictionary, MESH_STR ) );
+	if( meshDict ) {
+		char* 					meshTypeStr;
+		
+		if( !Dictionary_Get( meshDict, MESHTYPE_STR ) ) {
+			Journal_Printf( 
+				error,
+				"Warning: No \"%s\" entry in \"%s\"... will default to \"%s\"\n", 
+				MESHTYPE_STR, 
+				MESH_STR, 
+				CARTESIAN_STR );
+		}
+		
+		meshTypeStr = Dictionary_Entry_Value_AsString( 
+			Dictionary_GetDefault( meshDict, MESHTYPE_STR, Dictionary_Entry_Value_FromString( CARTESIAN_STR ) ) );
+		
+		if( !strcmp( meshTypeStr, SPHERICAL_STR ) ) {
+			meshExt->meshType = SnacRemesher_Spherical;
+			Journal_Printf( context->snacInfo, "Remesher knows mesh as a spherical mesh\n" );
+		}
+		else if( !strcmp( meshTypeStr, CARTESIAN_STR ) ) {
+			meshExt->meshType = SnacRemesher_Cartesian;
+			Journal_Printf( context->snacInfo, "Remesher knows mesh as a cartesian mesh\n" );
+		}
+		else {
+			meshExt->meshType = SnacRemesher_Cartesian;
+			Journal_Printf( context->snacInfo, "Remesher assuming mesh as a cartesian mesh\n" );
+			Journal_Printf( error, "Provided mesh type \"%s\" unrecognised!\n", meshTypeStr );
+		}
+	}
+	else {
+		meshExt->meshType = SnacRemesher_Cartesian;
+		Journal_Printf( context->snacInfo, "Remesher assuming mesh as a cartesian mesh\n" );
+		Journal_Printf( error, "No \"%s\" entry in dictionary!\n", MESH_STR );
+	}
+	/* Decide whether to restore the bottom surface */
+	contextExt->bottomRestore = 0;
+	if( !strcmp( Dictionary_Entry_Value_AsString( Dictionary_GetDefault( context->dictionary, "bottomRestore", Dictionary_Entry_Value_FromString( OFF_STR ) ) ), ON_STR) )
+		contextExt->bottomRestore = 1;
+	
+	
+	/* Register these functions for use in VCs */
+	ConditionFunction_Register_Add(
+		context->condFunc_Register,
+		ConditionFunction_New( _SnacRemesher_TestCondFunc, "SnacRemesher_TestCondFunc" ) );
+	
+	/* Register these functions for use in VCs */
+	ConditionFunction_Register_Add(
+		context->condFunc_Register,
+		ConditionFunction_New( _SnacRemesher_XFunc, "SnacRemesher_XFunc" ) );
+	
+	/* Register these functions for use in VCs */
+	ConditionFunction_Register_Add(
+		context->condFunc_Register,
+		ConditionFunction_New( _SnacRemesher_YFunc, "SnacRemesher_YFunc" ) );
+	
+	/* Obtain the keys for the our new entry points... having the keys saves doing a string compare at run time */
+	contextExt->interpolateNodeK = EntryPoint_Register_GetHandle( 
+		context->entryPoint_Register, 
+		SnacRemesher_EP_InterpolateNode );
+	contextExt->interpolateElementK = EntryPoint_Register_GetHandle( 
+		context->entryPoint_Register, 
+		SnacRemesher_EP_InterpolateElement );
+
+	/* Prepare the dump file */
+	if( context->rank == 0) {
+		sprintf( tmpBuf, "%s/remeshInfo.%u", context->outputPath, context->rank );
+		if( (contextExt->remesherOut = fopen( tmpBuf, "w+" )) == NULL ) {
+			assert( contextExt->remesherOut /* failed to open file for writing */ );
+		}
+	}
+	/* initialize remeshing counter */
+	contextExt->remeshingCount = 0;
+}

Added: long/3D/SNAC/trunk/Snac/plugins/remesher_BI/ConstructExtensions.h
===================================================================
--- long/3D/SNAC/trunk/Snac/plugins/remesher_BI/ConstructExtensions.h	                        (rev 0)
+++ long/3D/SNAC/trunk/Snac/plugins/remesher_BI/ConstructExtensions.h	2011-10-07 16:18:20 UTC (rev 19040)
@@ -0,0 +1,45 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+**
+** Copyright (C), 2003, 
+**	Steve Quenette, 110 Victoria Street, Melbourne, Victoria, 3053, Australia.
+**	Californian Institute of Technology, 1200 East California Boulevard, Pasadena, California, 91125, USA.
+**	University of Texas, 1 University Station, Austin, Texas, 78712, USA.
+**
+** Authors:
+**	Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
+**	Stevan M. Quenette, Visitor in Geophysics, Caltech.
+**	Luc Lavier, Research Scientist, The University of Texas. (luc at utig.ug.utexas.edu)
+**	Luc Lavier, Research Scientist, Caltech.
+**
+** This program is free software; you can redistribute it and/or modify it
+** under the terms of the GNU General Public License as published by the
+** Free Software Foundation; either version 2, or (at your option) any
+** later version.
+** 
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+** GNU General Public License for more details.
+** 
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+**
+*/
+/** \file
+** Role:
+**
+** Assumptions:
+**
+** Comments:
+**
+** $Id: ConstructExtensions.h 1396 2004-05-14 02:32:55Z SteveQuenette $
+**
+**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#ifndef __SnacRemesher_ConstructExtensions_h__
+#define __SnacRemesher_ConstructExtensions_h__
+	
+	void _SnacRemesher_ConstructExtensions( void* _context, void* data );
+	
+#endif /* __SnacRemesher_ConstructExtensions_h__ */

Added: long/3D/SNAC/trunk/Snac/plugins/remesher_BI/Context.c
===================================================================
--- long/3D/SNAC/trunk/Snac/plugins/remesher_BI/Context.c	                        (rev 0)
+++ long/3D/SNAC/trunk/Snac/plugins/remesher_BI/Context.c	2011-10-07 16:18:20 UTC (rev 19040)
@@ -0,0 +1,90 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+**
+** Copyright (C), 2003, 
+**	Steve Quenette, 110 Victoria Street, Melbourne, Victoria, 3053, Australia.
+**	Californian Institute of Technology, 1200 East California Boulevard, Pasadena, California, 91125, USA.
+**	University of Texas, 1 University Station, Austin, Texas, 78712, USA.
+**
+** Authors:
+**	Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
+**	Stevan M. Quenette, Visitor in Geophysics, Caltech.
+**	Luc Lavier, Research Scientist, The University of Texas. (luc at utig.ug.utexas.edu)
+**	Luc Lavier, Research Scientist, Caltech.
+**
+** This program is free software; you can redistribute it and/or modify it
+** under the terms of the GNU General Public License as published by the
+** Free Software Foundation; either version 2, or (at your option) any
+** later version.
+** 
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+** GNU General Public License for more details.
+** 
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+**
+** $Id: Context.c 3250 2006-10-23 06:15:18Z LukeHodkinson $
+**
+**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#include <mpi.h>
+#include <StGermain/StGermain.h>
+#include <StGermain/FD/FD.h>
+#include "Snac/Snac.h"
+#include "types.h"
+#include "EntryPoint.h"
+#include "Context.h"
+#include <stdio.h>
+
+void SnacRemesher_Context_Print( void* _context ) {
+	SnacRemesher_Context*		self = (SnacRemesher_Context*)_context;
+	
+	printf( "SnacRemesher_Context:\n" );
+	printf( 
+		"\tcondition: %s\n", 
+		self->condition == SnacRemesher_Off ? "off" : 
+			self->condition == SnacRemesher_OnTimeStep ? "OnTimeStep" :
+			self->condition == SnacRemesher_OnMinLengthScale ? "onMinLengthScale" : "Invalid value!" );
+	
+	printf( "\tOnTimeStep: %u", self->OnTimeStep );
+	printf( "\tonMinLengthScale: %g\n", self->onMinLengthScale );
+	
+	printf( "\tinterpolateNodeK: %u\n", self->interpolateNodeK );
+	printf( "\tinterpolateElementK: %u\n", self->interpolateElementK );
+}
+
+void SnacRemesher_InterpolateNodeFunction( void* _context, SnacRemesher_Context* self, 
+					   unsigned nodeInd, unsigned elementInd, unsigned tetInd, 
+					   unsigned* tetNodeInds, double* weights, 
+					   Snac_Node* dstNodes )
+{
+	Snac_Context*			context = (Snac_Context*)_context;
+	
+	SnacRemesher_InterpolateNodeMacro( context, self, 
+					   nodeInd, elementInd, tetInd, 
+					   tetNodeInds, weights, 
+					   dstNodes );
+}
+
+void SnacRemesher_InterpolateElementFunction( 
+		void*			_context, 
+		SnacRemesher_Context*	self, 
+		Element_LocalIndex	dstEltInd, 
+		Tetrahedra_Index	dstTetInd, 
+		Snac_Element*		dstEltArray, 
+		Element_DomainIndex	srcEltInd, 
+		Tetrahedra_Index	srcTetInd )
+{
+	Snac_Context*			context = (Snac_Context*)_context;
+		
+	SnacRemesher_InterpolateElementMacro( 
+		context,
+		self,
+		dstEltInd, 
+		dstTetInd, 
+		dstEltArray, 
+		srcEltInd, 
+		srcTetInd );
+}

Added: long/3D/SNAC/trunk/Snac/plugins/remesher_BI/Context.h
===================================================================
--- long/3D/SNAC/trunk/Snac/plugins/remesher_BI/Context.h	                        (rev 0)
+++ long/3D/SNAC/trunk/Snac/plugins/remesher_BI/Context.h	2011-10-07 16:18:20 UTC (rev 19040)
@@ -0,0 +1,127 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+**
+** Copyright (C), 2003,
+**	Steve Quenette, 110 Victoria Street, Melbourne, Victoria, 3053, Australia.
+**	Californian Institute of Technology, 1200 East California Boulevard, Pasadena, California, 91125, USA.
+**	University of Texas, 1 University Station, Austin, Texas, 78712, USA.
+**
+** Authors:
+**	Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
+**	Stevan M. Quenette, Visitor in Geophysics, Caltech.
+**	Luc Lavier, Research Scientist, The University of Texas. (luc at utig.ug.utexas.edu)
+**	Luc Lavier, Research Scientist, Caltech.
+**
+** This program is free software; you can redistribute it and/or modify it
+** under the terms of the GNU General Public License as published by the
+** Free Software Foundation; either version 2, or (at your option) any
+** later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+**
+*/
+/** \file
+** Role:
+**
+** Assumptions:
+**
+** Comments:
+**
+** $Id: Context.h 3250 2006-10-23 06:15:18Z LukeHodkinson $
+**
+**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#ifndef __SnacRemesher_Context_h__
+#define __SnacRemesher_Context_h__
+
+
+	typedef enum {
+		SnacRemesher_Off, 
+		SnacRemesher_OnTimeStep, 
+		SnacRemesher_OnMinLengthScale, 
+		SnacRemesher_OnBothTimeStepLength, 
+		SnacRemesher_ConditionMax
+	} SnacRemesher_Condition;
+	
+
+	/* Context Information */
+	struct _SnacRemesher_Context {
+		SnacRemesher_Condition	condition;	/* Type of remeshing criterion condition */
+		unsigned				bottomRestore;	/* Type of remeshing criterion condition */
+		Index 				OnTimeStep;	/* Time step multiple to remesh on */
+		double 				onMinLengthScale;	/* Min length scale to remesh on */
+		
+		EntryPoint_Index		interpolateNodeK;	/* Key to node interpolation entry point (for speed) */
+		EntryPoint_Index		interpolateElementK;	/* Key to element interpolation entry point (for speed) */
+
+		Stream*				debugIC;
+		Stream*				debugCoords;
+		Stream*				debugNodes;
+		Stream*				debugElements;
+		Stream*				debugSync;
+
+		/* Dumping */
+		FILE*               remesherOut;
+		Index               remeshingCount;
+	};
+
+	/* Print the contents of the context extension */
+	void SnacRemesher_Context_Print( void* _context );
+
+	/* Run the interpolate node entry point */
+	#define SnacRemesher_InterpolateNodeMacro( context, self, \
+						   nodeInd, elementInd, tetInd, \
+						   tetNodeInds, weights, \
+						   dstNodes ) \
+		( KeyCall( context, self->interpolateNodeK, SnacRemesher_InterpolateNode_CallCast* ) ( \
+			KeyHandle( context, self->interpolateNodeK ), \
+			context, \
+			nodeInd, elementInd, tetInd, \
+			tetNodeInds, weights, \
+			dstNodes ) )
+
+	void SnacRemesher_InterpolateNodeFunction( void* context, SnacRemesher_Context* self, 
+						   unsigned nodeInd, unsigned elementInd, unsigned tetInd, 
+						   unsigned* tetNodeInds, double* weights, 
+						   Snac_Node* dstNodes );
+
+	#ifdef MACRO_AS_FUNC
+		#define SnacRemesher_InterpolateNode SnacRemesher_InterpolateNodeFunction
+	#else
+		#define SnacRemesher_InterpolateNode SnacRemesher_InterpolateNodeMacro
+	#endif
+
+	/* Run the interpolate element entry point */
+	#define SnacRemesher_InterpolateElementMacro( context, self, \
+						      dstElementInd, dstTetInd, \
+						      elementArray, \
+						      srcElementInd, srcTetInd ) \
+		( KeyCall( context, self->interpolateElementK, SnacRemesher_InterpolateElement_CallCast* ) ( \
+			KeyHandle( context, self->interpolateElementK ), \
+			context, \
+			dstElementInd, \
+			dstTetInd, \
+			elementArray, \
+			srcElementInd, \
+			srcTetInd ) )
+	void SnacRemesher_InterpolateElementFunction( void*			_context, 
+						      SnacRemesher_Context*	self, 
+						      Element_LocalIndex	dstEltInd, 
+						      Tetrahedra_Index		dstTetInd, 
+						      Snac_Element*		dstEltArray, 
+						      Element_DomainIndex	srcEltInd, 
+						      Tetrahedra_Index		srcTetInd );
+
+	#ifdef MACRO_AS_FUNC
+		#define SnacRemesher_InterpolateElement SnacRemesher_InterpolateElementFunction
+	#else
+		#define SnacRemesher_InterpolateElement SnacRemesher_InterpolateElementMacro
+	#endif
+
+#endif /* __SnacRemesher_Context_h__ */

Added: long/3D/SNAC/trunk/Snac/plugins/remesher_BI/DeleteExtensions.c
===================================================================
--- long/3D/SNAC/trunk/Snac/plugins/remesher_BI/DeleteExtensions.c	                        (rev 0)
+++ long/3D/SNAC/trunk/Snac/plugins/remesher_BI/DeleteExtensions.c	2011-10-07 16:18:20 UTC (rev 19040)
@@ -0,0 +1,83 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+**
+** Copyright (C), 2003,
+**	Steve Quenette, 110 Victoria Street, Melbourne, Victoria, 3053, Australia.
+**	Californian Institute of Technology, 1200 East California Boulevard, Pasadena, California, 91125, USA.
+**	University of Texas, 1 University Station, Austin, Texas, 78712, USA.
+**
+** Authors:
+**	Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
+**	Stevan M. Quenette, Visitor in Geophysics, Caltech.
+**	Luc Lavier, Research Scientist, The University of Texas. (luc at utig.ug.utexas.edu)
+**	Luc Lavier, Research Scientist, Caltech.
+**
+** This program is free software; you can redistribute it and/or modify it
+** under the terms of the GNU General Public License as published by the
+** Free Software Foundation; either version 2, or (at your option) any
+** later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+**
+** $Id: DeleteExtensions.c 3095 2005-07-13 09:50:46Z LukeHodkinson $
+**
+**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#include <mpi.h>
+#include <StGermain/StGermain.h>
+#include <StGermain/FD/FD.h>
+#include "Snac/Snac.h"
+#include "types.h"
+#include "Mesh.h"
+#include "Context.h"
+#include "Register.h"
+#include "DeleteExtensions.h"
+
+
+void _SnacRemesher_DeleteExtensions( void* _context, void* data ) {
+	Snac_Context*				context = (Snac_Context*)_context;
+	Mesh*					mesh = context->mesh;
+	SnacRemesher_Mesh*			meshExt = ExtensionManager_Get(
+							context->meshExtensionMgr,
+							mesh,
+							SnacRemesher_MeshHandle );
+	
+	Journal_Printf( context->debug, "In: %s\n", __func__ );
+	
+	
+	/*
+	** Probably will not need to do this.
+	*/
+	
+	if( meshExt->newNodes ) {
+		ExtensionManager_Free( mesh->nodeExtensionMgr, meshExt->newNodes );
+	}
+	
+	if( meshExt->newElements ) {
+		ExtensionManager_Free( mesh->nodeExtensionMgr, meshExt->newElements );
+	}
+	
+	
+	/*
+	** Kill the mesh extension.
+	*/
+	
+	KillArray( meshExt->newNodeCoords );
+	KillArray( meshExt->externalNodes );
+	KillArray( meshExt->externalElements );
+	KillArray( meshExt->topInternToLocal );
+	KillArray( meshExt->botInternToLocal );
+	KillArray( meshExt->topTriToDomain );
+	KillArray( meshExt->botTriToDomain );
+	KillArray( meshExt->yLineLTerm );
+	KillArray( meshExt->yLineUTerm );
+	KillArray( meshExt->yLineNYInds );
+	KillArray2D( meshExt->nYLines, meshExt->yLineYInds );
+	KillArray2D( meshExt->nYLines, meshExt->yLineLocalInds );
+}

Added: long/3D/SNAC/trunk/Snac/plugins/remesher_BI/DeleteExtensions.h
===================================================================
--- long/3D/SNAC/trunk/Snac/plugins/remesher_BI/DeleteExtensions.h	                        (rev 0)
+++ long/3D/SNAC/trunk/Snac/plugins/remesher_BI/DeleteExtensions.h	2011-10-07 16:18:20 UTC (rev 19040)
@@ -0,0 +1,45 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+**
+** Copyright (C), 2003, 
+**	Steve Quenette, 110 Victoria Street, Melbourne, Victoria, 3053, Australia.
+**	Californian Institute of Technology, 1200 East California Boulevard, Pasadena, California, 91125, USA.
+**	University of Texas, 1 University Station, Austin, Texas, 78712, USA.
+**
+** Authors:
+**	Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
+**	Stevan M. Quenette, Visitor in Geophysics, Caltech.
+**	Luc Lavier, Research Scientist, The University of Texas. (luc at utig.ug.utexas.edu)
+**	Luc Lavier, Research Scientist, Caltech.
+**
+** This program is free software; you can redistribute it and/or modify it
+** under the terms of the GNU General Public License as published by the
+** Free Software Foundation; either version 2, or (at your option) any
+** later version.
+** 
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+** GNU General Public License for more details.
+** 
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+**
+*/
+/** \file
+** Role:
+**
+** Assumptions:
+**
+** Comments:
+**
+** $Id: DeleteExtensions.h 1396 2004-05-14 02:32:55Z SteveQuenette $
+**
+**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#ifndef __SnacRemesher_DeleteExtensions_h__
+#define __SnacRemesher_DeleteExtensions_h__
+	
+	void _SnacRemesher_DeleteExtensions( void* _context, void* data );
+	
+#endif /* __SnacRemesher_DeleteExtensions_h__ */

Added: long/3D/SNAC/trunk/Snac/plugins/remesher_BI/EntryPoint.c
===================================================================
--- long/3D/SNAC/trunk/Snac/plugins/remesher_BI/EntryPoint.c	                        (rev 0)
+++ long/3D/SNAC/trunk/Snac/plugins/remesher_BI/EntryPoint.c	2011-10-07 16:18:20 UTC (rev 19040)
@@ -0,0 +1,192 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+**
+** Copyright (C), 2003, 
+**	Steve Quenette, 110 Victoria Street, Melbourne, Victoria, 3053, Australia.
+**	Californian Institute of Technology, 1200 East California Boulevard, Pasadena, California, 91125, USA.
+**	University of Texas, 1 University Station, Austin, Texas, 78712, USA.
+**
+** Authors:
+**	Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
+**	Stevan M. Quenette, Visitor in Geophysics, Caltech.
+**	Luc Lavier, Research Scientist, The University of Texas. (luc at utig.ug.utexas.edu)
+**	Luc Lavier, Research Scientist, Caltech.
+**
+** This program is free software; you can redistribute it and/or modify it
+** under the terms of the GNU General Public License as published by the
+** Free Software Foundation; either version 2, or (at your option) any
+** later version.
+** 
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+** GNU General Public License for more details.
+** 
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+**
+** $Id: EntryPoint.c 3250 2006-10-23 06:15:18Z LukeHodkinson $
+**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <string.h>
+#include <stdarg.h>
+
+#include <mpi.h>
+#include <StGermain/StGermain.h>
+#include <StGermain/FD/FD.h>
+#include "Snac/Snac.h"
+#include "types.h"
+#include "EntryPoint.h"
+
+/* Textual name of this class */
+const Type SnacRemesher_EntryPoint_Type = "SnacRemesher_EntryPoint";
+
+
+SnacRemesher_EntryPoint* SnacRemesher_EntryPoint_New( const Name name, unsigned int castType ) {
+	return _SnacRemesher_EntryPoint_New( 
+		sizeof(SnacRemesher_EntryPoint), 
+		SnacRemesher_EntryPoint_Type, 
+		_EntryPoint_Delete, 
+		_EntryPoint_Print, 
+		NULL, 
+		_SnacRemesher_EntryPoint_GetRun, 
+		name, 
+		castType );
+}
+
+void SnacRemesher_EntryPoint_Init( void* snac_EntryPoint, const Name name, unsigned int castType ) {
+	SnacRemesher_EntryPoint* self = (SnacRemesher_EntryPoint*)snac_EntryPoint;
+	
+	/* General info */
+	self->type = SnacRemesher_EntryPoint_Type;
+	self->_sizeOfSelf = sizeof(SnacRemesher_EntryPoint);
+	self->_deleteSelf = False;
+	
+	/* Virtual info */
+	self->_delete = _EntryPoint_Delete;
+	self->_print = _EntryPoint_Print;
+	self->_copy = NULL;
+	self->_getRun = _SnacRemesher_EntryPoint_GetRun;
+	_Stg_Class_Init( (Stg_Class*)self );
+	_Stg_Object_Init( (Stg_Object*)self, name, NON_GLOBAL );
+	_EntryPoint_Init( (EntryPoint*)self, castType );
+	_ContextEntryPoint_Init( (ContextEntryPoint*)self );
+	_Snac_EntryPoint_Init( (Snac_EntryPoint*)self );
+	
+	/* SnacRemesher_EntryPoint info */
+	_SnacRemesher_EntryPoint_Init( self );
+}
+
+SnacRemesher_EntryPoint* _SnacRemesher_EntryPoint_New( 
+		SizeT					_sizeOfSelf,
+		Type					type,
+		Stg_Class_DeleteFunction*			_delete,
+		Stg_Class_PrintFunction*			_print,
+		Stg_Class_CopyFunction*			_copy, 
+		EntryPoint_GetRunFunction*		_getRun,
+		Name					name,
+		unsigned int				castType )
+{
+	SnacRemesher_EntryPoint* self;
+	
+	/* Allocate memory */
+	assert( _sizeOfSelf >= sizeof(SnacRemesher_EntryPoint) );
+	self = (SnacRemesher_EntryPoint*)_Snac_EntryPoint_New( 
+		_sizeOfSelf, 
+		type, 
+		_delete, 
+		_print, 
+		_copy, 
+		_getRun, 
+		name, 
+		castType );
+	
+	/* General info */
+	
+	/* Virtual info */
+	
+	/* SnacRemesher_EntryPoint info */
+	_SnacRemesher_EntryPoint_Init( self );
+	
+	return self;
+}
+
+void _SnacRemesher_EntryPoint_Init( SnacRemesher_EntryPoint* self ) {
+	/* General and Virtual info should already be set */
+	
+	/* SnacRemesher_EntryPoint info */
+}
+
+
+Func_Ptr _SnacRemesher_EntryPoint_GetRun( void* snac_EntryPoint ) {
+	SnacRemesher_EntryPoint* self = (SnacRemesher_EntryPoint*)snac_EntryPoint;
+	
+	switch( self->castType ) {
+		case SnacRemesher_InterpolateNode_CastType:
+			return _SnacRemesher_EntryPoint_Run_InterpolateNode;
+		
+		case SnacRemesher_InterpolateElement_CastType:
+			return _SnacRemesher_EntryPoint_Run_InterpolateElement;
+		default:
+			return _Snac_EntryPoint_GetRun( self );
+	}
+}
+
+
+void _SnacRemesher_EntryPoint_Run_InterpolateNode( void* entryPoint, void* context, 
+						   unsigned nodeInd, unsigned elementInd, unsigned tetInd, 
+						   unsigned* tetNodeInds, double* weights, 
+						   Snac_Node* dstNodes )
+{
+	SnacRemesher_EntryPoint* self = (SnacRemesher_EntryPoint*)entryPoint;
+	Hook_Index hookIndex;
+	
+	#ifdef USE_PROFILE
+		Stg_CallGraph_Push( stgCallGraph, _SnacRemesher_EntryPoint_Run_InterpolateNode, self->name );
+	#endif
+
+	for( hookIndex = 0; hookIndex < self->hooks->count; hookIndex++ ) {
+		void*	funcPtr;
+
+		funcPtr = ((Hook*)self->hooks->data[hookIndex])->funcPtr;
+		(*(SnacRemesher_InterpolateNode_Cast*)funcPtr)( context, 
+								nodeInd, elementInd, tetInd, 
+								tetNodeInds, weights, 
+								dstNodes );
+	}
+
+	#ifdef USE_PROFILE
+		Stg_CallGraph_Pop( stgCallGraph );
+	#endif
+}
+
+void _SnacRemesher_EntryPoint_Run_InterpolateElement( void* entryPoint, void* context, 
+						      unsigned dstElementInd, unsigned dstTetInd, 
+						      Snac_Element* elementArray, 
+						      unsigned srcElementInd, unsigned srcTetInd )
+{
+	SnacRemesher_EntryPoint* self = (SnacRemesher_EntryPoint*)entryPoint;
+	Hook_Index hookIndex;
+	
+	#ifdef USE_PROFILE
+		Stg_CallGraph_Push( stgCallGraph, _SnacRemesher_EntryPoint_Run_InterpolateElement, self->name );
+	#endif
+
+	for( hookIndex = 0; hookIndex < self->hooks->count; hookIndex++ ) {
+		void*	funcPtr;
+
+		funcPtr = ((Hook*)self->hooks->data[hookIndex])->funcPtr;
+		(*(SnacRemesher_InterpolateElement_Cast*)funcPtr)( context, 
+								   dstElementInd, dstTetInd, 
+								   elementArray, 
+								   srcElementInd, srcTetInd );
+	}
+
+	#ifdef USE_PROFILE
+		Stg_CallGraph_Pop( stgCallGraph );
+	#endif
+}
+

Added: long/3D/SNAC/trunk/Snac/plugins/remesher_BI/EntryPoint.h
===================================================================
--- long/3D/SNAC/trunk/Snac/plugins/remesher_BI/EntryPoint.h	                        (rev 0)
+++ long/3D/SNAC/trunk/Snac/plugins/remesher_BI/EntryPoint.h	2011-10-07 16:18:20 UTC (rev 19040)
@@ -0,0 +1,109 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+**
+** Copyright (C), 2003,
+**	Steve Quenette, 110 Victoria Street, Melbourne, Victoria, 3053, Australia.
+**	Californian Institute of Technology, 1200 East California Boulevard, Pasadena, California, 91125, USA.
+**	University of Texas, 1 University Station, Austin, Texas, 78712, USA.
+**
+** Authors:
+**	Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
+**	Stevan M. Quenette, Visitor in Geophysics, Caltech.
+**	Luc Lavier, Research Scientist, The University of Texas. (luc at utig.ug.utexas.edu)
+**	Luc Lavier, Research Scientist, Caltech.
+**
+** This program is free software; you can redistribute it and/or modify it
+** under the terms of the GNU General Public License as published by the
+** Free Software Foundation; either version 2, or (at your option) any
+** later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+**
+** $Id: EntryPoint.h 3250 2006-10-23 06:15:18Z LukeHodkinson $
+**
+**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#ifndef __SnacRemesher_EntryPoint_h__
+#define __SnacRemesher_EntryPoint_h__
+
+	/* Templates for default entry point type */
+	typedef void (SnacRemesher_InterpolateNode_Cast)( void* context, 
+							  unsigned nodeInd, unsigned elementInd, unsigned tetInd, 
+							  unsigned* tetNodeInds, double* weights, 
+							  Snac_Node* dstNodes );
+
+	typedef void (SnacRemesher_InterpolateElement_Cast)( void* context, 
+							     unsigned dstElementInd, unsigned dstTetInd, 
+							     Snac_Element* elementArray, 
+							     unsigned srcElementInd, unsigned srcTetInd );
+
+	typedef void (SnacRemesher_InterpolateNode_CallCast)( void* entryPoint, void* context, 
+							      unsigned nodeInd, unsigned elementInd, unsigned tetInd, 
+							      unsigned* tetNodeInds, double* weights, 
+							      Snac_Node* dstNodes );
+
+	typedef void (SnacRemesher_InterpolateElement_CallCast)( void* entryPoint, void* context, 
+								 unsigned dstElementInd, unsigned dstTetInd, 
+								 Snac_Element* elementArray, 
+								 unsigned srcElementInd, unsigned srcTetInd );
+
+	#define SnacRemesher_InterpolateNode_CastType		(Snac_CastType_MAX + 1)
+	#define SnacRemesher_InterpolateElement_CastType	(SnacRemesher_InterpolateNode_CastType + 1)
+	#define SnacRemesher_CastType_MAX			(SnacRemesher_InterpolateElement_CastType + 1)
+
+	/** Textual name of this class */
+	extern const Type SnacRemesher_EntryPoint_Type;
+
+	/** SnacRemesher_EntryPoint info */
+	#define __SnacRemesher_EntryPoint \
+		/* General info */ \
+		__Snac_EntryPoint \
+		\
+		/* Virtual info */ \
+		\
+		/* SnacRemesher_EntryPoint info */
+
+	struct _SnacRemesher_EntryPoint { __SnacRemesher_EntryPoint };
+
+	/* Create a new SnacRemesher_EntryPoint */
+	SnacRemesher_EntryPoint* SnacRemesher_EntryPoint_New( const Name name, unsigned int castType );
+
+	/* Initialise an SnacRemesher_EntryPoint */
+	void SnacRemesher_EntryPoint_Init( void* snac_EntryPoint, const Name name, unsigned int castType );
+
+	/* Creation implementation */
+	SnacRemesher_EntryPoint* _SnacRemesher_EntryPoint_New(
+		SizeT					_sizeOfSelf,
+		Type					type,
+		Stg_Class_DeleteFunction*			_delete,
+		Stg_Class_PrintFunction*			_print,
+		Stg_Class_CopyFunction*			_copy, 
+		EntryPoint_GetRunFunction*		_getRun,
+		const Name				name,
+		unsigned int				castType);
+
+	/* Initialisation implementation */
+	void _SnacRemesher_EntryPoint_Init( SnacRemesher_EntryPoint* self );
+
+	/* Default GetRun implementation */
+	Func_Ptr _SnacRemesher_EntryPoint_GetRun( void* snac_EntryPoint );
+
+	/* Snac remesher entry point run... for interpolating a node */
+	void _SnacRemesher_EntryPoint_Run_InterpolateNode( void* entryPoint, void* context, 
+							   unsigned nodeInd, unsigned elementInd, unsigned tetInd, 
+							   unsigned* tetNodeInds, double* weights, 
+							   Snac_Node* dstNodes );
+	
+	/* Snac remesher entry point run... for interpolating an element */
+	void _SnacRemesher_EntryPoint_Run_InterpolateElement( void* entryPoint, void* context, 
+							      unsigned dstElementInd, unsigned dstTetInd, 
+							      Snac_Element* elementArray, 
+							      unsigned srcElementInd, unsigned srcTetInd );
+
+#endif /* __SnacRemesher_EntryPoint_h__ */

Added: long/3D/SNAC/trunk/Snac/plugins/remesher_BI/InitialConditions.c
===================================================================
--- long/3D/SNAC/trunk/Snac/plugins/remesher_BI/InitialConditions.c	                        (rev 0)
+++ long/3D/SNAC/trunk/Snac/plugins/remesher_BI/InitialConditions.c	2011-10-07 16:18:20 UTC (rev 19040)
@@ -0,0 +1,1048 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+**
+** Copyright (C), 2003,
+**	Steve Quenette, 110 Victoria Street, Melbourne, Victoria, 3053, Australia.
+**	Californian Institute of Technology, 1200 East California Boulevard, Pasadena, California, 91125, USA.
+**	University of Texas, 1 University Station, Austin, Texas, 78712, USA.
+**
+** Authors:
+**	Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
+**	Stevan M. Quenette, Visitor in Geophysics, Caltech.
+**	Luc Lavier, Research Scientist, The University of Texas. (luc at utig.ug.utexas.edu)
+**	Luc Lavier, Research Scientist, Caltech.
+**
+** This program is free software; you can redistribute it and/or modify it
+** under the terms of the GNU General Public License as published by the
+** Free Software Foundation; either version 2, or (at your option) any
+** later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+**
+** Comments:
+** 	Not sure ShadowElementSetLocal is needed as I think it now has the same values as ShadowElementSetCurrent.
+**
+** $Id: InitialConditions.c 3254 2006-10-26 08:25:11Z EunseoChoi $
+**
+**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#include <mpi.h>
+#include <StGermain/StGermain.h>
+#include <StGermain/FD/FD.h>
+
+#include "Snac/Snac.h"
+#include "types.h"
+#include "Mesh.h"
+#include "Context.h"
+#include "Register.h"
+#include "InitialConditions.h"
+#include "Utils.h"
+
+#include <string.h>
+#include <math.h>
+#include <assert.h>
+
+#ifndef PATH_MAX
+	#define PATH_MAX 1024
+#endif
+
+void _SnacRemesher_InitialConditions( void* _context, void* data ) {
+	Snac_Context*		context = (Snac_Context*)_context;
+	Mesh*			mesh = context->mesh;
+	HexaMD*			decomp = (HexaMD*)mesh->layout->decomp;
+	SnacRemesher_Mesh*	meshExt = ExtensionManager_Get(
+						context->meshExtensionMgr,
+						mesh,
+						SnacRemesher_MeshHandle );
+	unsigned			lNode_i;
+	IndexSet*			walls[6];
+	IndexSet*			bulk;
+	IndexSet*			topIntern;
+	IndexSet*			botIntern;
+	
+	void _SnacRemesher_TriangulateXZPlane(
+		void*		_context, 
+		IndexSet*		planeNodes, 
+		unsigned		gYInd, 
+		unsigned*		nTriNodes, 
+		unsigned**	triToDomain );
+	
+	
+	/*
+	** Firstly, backup all coords into the 'newNodeCoords' coord block.
+	*/
+	if( context->restartTimestep > 0 ) {
+		FILE *fp;
+		char path[PATH_MAX];
+		double	x,y,z;
+
+		sprintf(path, "%s/snac.initCoord.%d.%06d.restart",context->outputPath,context->rank,context->restartTimestep);
+		Journal_Firewall( ( (fp=fopen(path,"r")) != NULL), context->snacError, "Can't find %s\n", path );
+		for( lNode_i = 0; lNode_i < mesh->nodeLocalCount; lNode_i++ ) {
+			fscanf( fp, "%le %le %le", &x,&y,&z);
+			meshExt->newNodeCoords[lNode_i][0] = x;
+			meshExt->newNodeCoords[lNode_i][1] = y;
+			meshExt->newNodeCoords[lNode_i][2] = z;
+		}
+	}
+	else {
+		if( meshExt->meshType == SnacRemesher_Cartesian ) {
+			for( lNode_i = 0; lNode_i < mesh->nodeLocalCount; lNode_i++ ) {
+				Vector_Set( meshExt->newNodeCoords[lNode_i], mesh->nodeCoord[lNode_i] );
+			}
+		}
+		else {
+			/* Convert cartesian coordinates to spherical coordinates and store. */
+			for( lNode_i = 0; lNode_i < mesh->nodeLocalCount; lNode_i++ ) {
+				double	x = mesh->nodeCoord[lNode_i][0];
+				double	y = mesh->nodeCoord[lNode_i][1];
+				double	z = mesh->nodeCoord[lNode_i][2];
+				
+				meshExt->newNodeCoords[lNode_i][0] = SnacArcTan( y, x );
+				meshExt->newNodeCoords[lNode_i][1] = sqrt( x * x + y * y + z * z );
+				meshExt->newNodeCoords[lNode_i][2] = acos( z / meshExt->newNodeCoords[lNode_i][1] );
+			}
+		}
+	}
+	
+	
+	/*
+	** Generate index arrays into local coordinate space for top and bottom (internal) walls.
+	*/
+	
+	walls[0] = RegularMeshUtils_CreateGlobalLeftSet( mesh );
+	walls[1] = RegularMeshUtils_CreateGlobalRightSet( mesh );
+	walls[2] = RegularMeshUtils_CreateGlobalFrontSet( mesh );
+	walls[3] = RegularMeshUtils_CreateGlobalBackSet( mesh );
+	walls[4] = RegularMeshUtils_CreateGlobalTopSet( mesh );
+	walls[5] = RegularMeshUtils_CreateGlobalBottomSet( mesh );
+	bulk = IndexSet_New( mesh->nodeLocalCount );
+	
+	topIntern = IndexSet_New( mesh->nodeLocalCount );
+	botIntern = IndexSet_New( mesh->nodeLocalCount );
+	
+	for( lNode_i = 0; lNode_i < mesh->nodeLocalCount; lNode_i++ ) {
+		if( IndexSet_IsMember( walls[4], lNode_i ) ) {
+			IndexSet_Add( topIntern, lNode_i );
+		}
+		else if( IndexSet_IsMember( walls[5], lNode_i ) )
+		{
+			IndexSet_Add( botIntern, lNode_i );
+		}
+		else {
+			/* Also generate the bulk indices while we're at it. */
+			IndexSet_Add( bulk, lNode_i );
+		}
+	}
+	
+	IndexSet_GetMembers( topIntern, &meshExt->nTopInternNodes, &meshExt->topInternToLocal );
+	IndexSet_GetMembers( botIntern, &meshExt->nBotInternNodes, &meshExt->botInternToLocal );
+	
+	/* These walls aren't needed any more. */
+	Stg_Class_Delete( walls[0] );
+	Stg_Class_Delete( walls[1] );
+	Stg_Class_Delete( walls[2] );
+	Stg_Class_Delete( walls[3] );
+	
+	
+	/*
+	** Create triangulations for the top and bottom walls using domain indices.
+	*/
+	
+	if( walls[4]->membersCount > 0 ) {
+		_SnacRemesher_TriangulateXZPlane( 
+			context, 
+			walls[4], 
+			decomp->nodeGlobal3DCounts[1] - 1, 
+			&meshExt->nTopTriNodes, 
+			&meshExt->topTriToDomain );
+	}
+	else {
+		meshExt->nTopTriNodes = 0;
+		meshExt->topTriToDomain = NULL;
+	}
+	
+	if( walls[5]->membersCount > 0 ) {
+		_SnacRemesher_TriangulateXZPlane( context, walls[5], 0, &meshExt->nBotTriNodes, &meshExt->botTriToDomain );
+	}
+	else {
+		meshExt->nBotTriNodes = 0;
+		meshExt->botTriToDomain = NULL;
+	}
+	
+	/* Walls are no longer required. */
+	Stg_Class_Delete( walls[4] );
+	Stg_Class_Delete( walls[5] );
+	
+	
+	/*
+	** Build lists of y-lines for interpolating bulk nodes efficiently.
+	*/
+	
+	{
+		unsigned			nBulkNodes;
+		Node_LocalIndex*	bulkNodes;
+		unsigned			bulk_i;
+		unsigned			nYLines;
+		unsigned*			yLineX;
+		unsigned*			yLineZ;
+		
+		/*
+		** First, extract the number of y-lines and their x,z offsets.
+		*/
+		
+		/* Extract the bulk local node indices and destroy the set. */
+		IndexSet_GetMembers( bulk, &nBulkNodes, &bulkNodes );
+		Stg_Class_Delete( bulk );
+		
+		/* Setup yLine info. */
+		nYLines = 0;
+		yLineX = Memory_Alloc_Array( unsigned, 1, "SnacRemesher" );
+		yLineZ = Memory_Alloc_Array( unsigned, 1, "SnacRemesher" );
+		
+		/* Calculate the number of unique y-lines and their x, z offsets. */
+		for( bulk_i = 0; bulk_i < nBulkNodes; bulk_i++ ) {
+			Node_GlobalIndex	gNodeInd;
+			IJK				ijk;
+			unsigned			yLine_i;
+			
+			gNodeInd = Mesh_NodeMapLocalToGlobal( mesh, bulkNodes[bulk_i] );
+			RegularMeshUtils_Node_1DTo3D( decomp, gNodeInd, &ijk[0], &ijk[1], &ijk[2] );
+			
+			/* Is this one unique? */
+			for( yLine_i = 0; yLine_i < nYLines; yLine_i++ ) {
+				if( yLineX[yLine_i] == ijk[0] && yLineZ[yLine_i] == ijk[2] ) {
+					break;
+				}
+			}
+			
+			/* If not, skip. */
+			if( yLine_i < nYLines ) {
+				continue;
+			}
+			
+			/* If so, add it to the list. */
+			yLineX = Memory_Realloc_Array( yLineX, unsigned, nYLines + 1 );
+			yLineZ = Memory_Realloc_Array( yLineZ, unsigned, nYLines + 1 );
+			yLineX[nYLines] = ijk[0];
+			yLineZ[nYLines] = ijk[2];
+			nYLines++;
+		}
+		
+		/* If there were none, then fix the arrays. */
+		if( nYLines == 0 ) {
+			Memory_Free( yLineX );
+			yLineX = NULL;
+			Memory_Free( yLineZ );
+			yLineZ = NULL;
+		}
+		else {
+			IndexSet*	locals;
+			unsigned	yLine_i;
+			
+			/* If we're here, then there are local y-lines and we need to fill incident local nodes. Start
+			   by setting up the arrays. */
+			meshExt->nYLines = nYLines;
+			meshExt->yLineLTerm = Memory_Alloc_Array( unsigned, nYLines, "SnacRemesher" );
+			meshExt->yLineUTerm = Memory_Alloc_Array( unsigned, nYLines, "SnacRemesher" );
+			meshExt->yLineNYInds = Memory_Alloc_Array( unsigned, nYLines, "SnacRemesher" );
+			meshExt->yLineYInds = Memory_Alloc_Array( unsigned*, nYLines, "SnacRemesher" );
+			meshExt->yLineLocalInds = Memory_Alloc_Array( unsigned*, nYLines, "SnacRemesher" );
+			
+			locals = IndexSet_New( mesh->nodeLocalCount );
+			
+			/* Loop over y-lines */
+			for( yLine_i = 0; yLine_i < nYLines; yLine_i++ ) {
+				IndexSet_RemoveAll( locals );
+				
+				/* Loop over local bulk nodes. */
+				for( bulk_i = 0; bulk_i < nBulkNodes; bulk_i++ ) {
+					Node_GlobalIndex	gNodeInd;
+					IJK				ijk;
+					
+					gNodeInd = Mesh_NodeMapLocalToGlobal( mesh, bulkNodes[bulk_i] );
+					RegularMeshUtils_Node_1DTo3D( decomp, gNodeInd, &ijk[0], &ijk[1], &ijk[2] );
+					
+					if( ijk[0] == yLineX[yLine_i] && ijk[2] == yLineZ[yLine_i] ) {
+						IndexSet_Add( locals, bulkNodes[bulk_i] );
+					}
+				}
+				
+				/* Add them to the master arrays. */
+				{
+					unsigned	yLine_j;
+					IJK		ijk;
+					
+					IndexSet_GetMembers( locals, &meshExt->yLineNYInds[yLine_i], &meshExt->yLineLocalInds[yLine_i] );
+					meshExt->yLineYInds[yLine_i] = Memory_Alloc_Array( unsigned, 
+						meshExt->yLineNYInds[yLine_i], 
+						"SnacRemesher" );
+					
+					/* Extract the global y-index for each local index. */
+					for( yLine_j = 0; yLine_j < meshExt->yLineNYInds[yLine_i]; yLine_j++ ) {
+						Node_GlobalIndex	gNodeInd;
+						
+						gNodeInd = Mesh_NodeMapLocalToGlobal( mesh, meshExt->yLineLocalInds[yLine_i][yLine_j] );
+						RegularMeshUtils_Node_1DTo3D( decomp, gNodeInd, &ijk[0], &ijk[1], &ijk[2] );
+						
+						meshExt->yLineYInds[yLine_i][yLine_j] = ijk[1];
+					}
+					
+					/* Set up the terminals. */
+					meshExt->yLineLTerm[yLine_i] = RegularMeshUtils_Node_Global3DToGlobal1D( decomp, 
+						ijk[0], 
+						0, 
+						ijk[2] );
+					meshExt->yLineUTerm[yLine_i] = RegularMeshUtils_Node_Global3DToGlobal1D( decomp, 
+						ijk[0], 
+						decomp->nodeGlobal3DCounts[1] - 1, 
+						ijk[2] );
+				}
+			}
+			
+			Stg_Class_Delete( locals );
+		}
+		
+		if( yLineX ) {
+			Memory_Free( yLineX );
+		}
+		
+		if( yLineZ ) {
+			Memory_Free( yLineZ );
+		}
+	}
+	
+	
+	/*
+	** Currently, the terminals are stored in global index format.  We need to determine if the terminals are
+	** actually locally stored or remotely.  If locally, then convert the global index to a local one.  If remotely, 
+	** then add it to the 'sync' class and modify the global index to look in the right sync'ed place.
+	*/
+	
+	{
+		unsigned	yLine_i;
+		SnacSync*	sync;
+		unsigned	nLocals = 0;
+		unsigned*	locals;
+		unsigned	nRequired = 0;
+		unsigned*	required;
+		unsigned	z_i;
+		unsigned*	srcMap;
+		
+		/* Create a new sync class. */
+		sync = SnacSync_New( "SnacRemesher_SnacSync" );
+		
+		/* Initialise the required array. */
+		required = Memory_Alloc_Array( unsigned, 1, "SnacSync" );
+		
+		for( yLine_i = 0; yLine_i < meshExt->nYLines; yLine_i++ ) {
+			unsigned	term;
+			
+			/* Check the lower terminal. */
+			term = Mesh_NodeMapGlobalToLocal( mesh, meshExt->yLineLTerm[yLine_i] );
+			if( term < mesh->nodeLocalCount ) {
+				/* Store local index. */
+				meshExt->yLineLTerm[yLine_i] = term;
+			}
+			else {
+				/* Add this terminal to the sync-remote array and modify its index to be:
+					nodeLocalCount + remote-index */
+				required = Memory_Realloc_Array( required, unsigned, nRequired + 1 );
+				required[nRequired] = meshExt->yLineLTerm[yLine_i];
+				meshExt->yLineLTerm[yLine_i] = mesh->nodeLocalCount + nRequired;
+				nRequired++;
+			}
+			
+			/* Check the upper terminal. */
+			term = Mesh_NodeMapGlobalToLocal( mesh, meshExt->yLineUTerm[yLine_i] );
+			if( term < mesh->nodeLocalCount ) {
+				/* Store local index. */
+				meshExt->yLineUTerm[yLine_i] = term;
+			}
+			else {
+				/* Add this terminal to the sync-remote array and modify its index to be:
+					nodeLocalCount + remote-index */
+				required = Memory_Realloc_Array( required, unsigned, nRequired + 1 );
+				required[nRequired] = meshExt->yLineUTerm[yLine_i];
+				meshExt->yLineUTerm[yLine_i] = mesh->nodeLocalCount + nRequired;
+				nRequired++;
+			}
+		}
+		
+		/* Fix up the required array. */
+		if( nRequired == 0 ) {
+			KillArray( required );
+		}
+		
+		/* Begin the local array. */
+		locals = Memory_Alloc_Array( unsigned, 1, "SnacSync" );
+		
+		/* Add local terminals. */
+		for( z_i = 0; z_i < decomp->nodeGlobal3DCounts[2]; z_i++ ) {
+			unsigned	x_i;
+			
+			for( x_i = 0; x_i < decomp->nodeGlobal3DCounts[0]; x_i++ ) {
+				Node_GlobalIndex	gLower;
+				Node_GlobalIndex	gUpper;
+				Node_LocalIndex	lLower;
+				Node_LocalIndex	lUpper;
+				
+				gLower = RegularMeshUtils_Node_Global3DToGlobal1D( decomp, x_i, 0, z_i );
+				gUpper = RegularMeshUtils_Node_Global3DToGlobal1D( decomp, x_i, decomp->nodeGlobal3DCounts[1] - 1, z_i );
+				lLower = Mesh_NodeMapGlobalToLocal( mesh, gLower );
+				lUpper = Mesh_NodeMapGlobalToLocal( mesh, gUpper );
+				
+				if( lLower < mesh->nodeLocalCount ) {
+					locals = Memory_Realloc_Array( locals, unsigned, nLocals + 1 );
+					locals[nLocals] = gLower;
+					nLocals++;
+				}
+				
+				if( lUpper < mesh->nodeLocalCount ) {
+					locals = Memory_Realloc_Array( locals, unsigned, nLocals + 1 );
+					locals[nLocals] = gUpper;
+					nLocals++;
+				}
+			}
+		}
+		
+		/* If no locals, fix array. */
+		if( nLocals == 0 ) {
+			KillArray( locals );
+		}
+		
+		/* Negotiate minimum comms. */
+		SnacSync_Negotiate( sync, mesh->nodeGlobalCount, nLocals, locals, nRequired, required, decomp->communicator );
+		
+		/* Store the sync class. */
+		meshExt->sync = sync;
+		
+		
+		/*
+		** Build a map to move source values from the received order (which is essentially anything) to the order
+		** specified in 'required'.
+		*/
+		
+		if( sync->netSource ) {
+			unsigned	proc_i;
+			unsigned	srcInd = 0;
+			
+			/* Alloc memory. */
+			srcMap = Memory_Alloc_Array( unsigned, sync->netSource, "SnacSync" );
+			
+			/* Map 'em. */
+			for( proc_i = 0; proc_i < sync->nProcs; proc_i++ ) {
+				unsigned	src_i;
+				
+				for( src_i = 0; src_i < sync->nSource[proc_i]; src_i++ ) {
+					unsigned	req_i;
+					
+					for( req_i = 0; req_i < nRequired; req_i++ ) {
+						if( sync->source[proc_i][src_i] == required[req_i] ) {
+							srcMap[srcInd] = req_i;
+							break;
+						}
+					}
+					
+					srcInd++;
+				}
+			}
+		}
+		else {
+			srcMap = NULL;
+		}
+
+		
+		/*
+		** Build a mapping from sink indices to local indices and initialise the send/recv component of the sync class.
+		*/
+		
+		{
+			unsigned*	snkMap;
+			
+			if( sync->netSink ) {
+				unsigned	proc_i;
+				unsigned	snkInd = 0;
+				
+				snkMap = Memory_Alloc_Array( unsigned, sync->netSink, "SnacRemesher" );
+				
+				for( proc_i = 0; proc_i < sync->nProcs; proc_i++ ) {
+					unsigned	snk_i;
+					
+					for( snk_i = 0; snk_i < sync->nSink[proc_i]; snk_i++ ) {
+						snkMap[snkInd] = Mesh_NodeMapGlobalToLocal( mesh, sync->sink[proc_i][snk_i] );
+						snkInd++;
+					}
+				}
+			}
+			else {
+				snkMap = NULL;
+			}
+			
+			/* Initialise. */
+			SnacSync_SendRecvInitialise( sync, sizeof(double), snkMap, sizeof(Coord), srcMap, sizeof(double) );
+			
+			/* Free resources. */
+			FreeArray( snkMap );
+			FreeArray( srcMap );
+		}
+		
+		/* Free other arrays. */
+		FreeArray( locals );
+		FreeArray( required );
+	}
+}
+
+
+void _SnacRemesher_TriangulateXZPlane(
+	void*		_context, 
+	IndexSet*		planeNodes, 
+	unsigned		gYInd, 
+	unsigned*		nTriNodes, 
+	unsigned**	triToDomain )
+{
+	Snac_Context*		context = (Snac_Context*)_context;
+	Mesh*			mesh = context->mesh;
+	HexaMD*			decomp = (HexaMD*)mesh->layout->decomp;
+	IJK				gSize;
+	IJK				dSize;
+	IJK				pos;
+	
+	
+	/*
+	** Definitley not the fastest way of doing this, but it should work none-the-less.
+	*/
+	
+	gSize[0] = decomp->nodeGlobal3DCounts[0];
+	gSize[1] = decomp->nodeGlobal3DCounts[1];
+	gSize[2] = decomp->nodeGlobal3DCounts[2];
+	pos[1] = gYInd;
+	
+	/* Calculate the domain x size. */
+	for( pos[2] = 0; pos[2] < gSize[2]; pos[2]++ ) {
+		unsigned	xMin, xMax;
+		Bool		found = False;
+		
+		xMax = 0;
+		
+		for( pos[0] = 0; pos[0] < gSize[0]; pos[0]++ ) {
+			Node_GlobalIndex	gNodeInd;
+			Node_DomainIndex	dNodeInd;
+			
+			gNodeInd = RegularMeshUtils_Node_Global3DToGlobal1D( decomp, pos[0], pos[1], pos[2] );
+			dNodeInd = Mesh_NodeMapGlobalToDomain( mesh, gNodeInd );
+			
+			if( !found && dNodeInd < mesh->nodeDomainCount ) {
+				xMin = pos[0];
+				found = True;
+			}
+			else if( found && dNodeInd >= mesh->nodeDomainCount ) {
+				xMax = pos[0];
+				break;
+			}
+		}
+		
+		if( found ) {
+			if( xMax == 0 ) {
+				dSize[0] = gSize[0] - xMin;
+			}
+			else {
+				dSize[0] = xMax - xMin;
+			}
+			break;
+		}
+	}
+	
+	/* Calculate the domain z size. */
+	for( pos[0] = 0; pos[0] < gSize[0]; pos[0]++ ) {
+		unsigned	zMin, zMax;
+		Bool		found = False;
+		
+		zMax = 0;
+		
+		for( pos[2] = 0; pos[2] < gSize[2]; pos[2]++ ) {
+			Node_GlobalIndex	gNodeInd;
+			Node_DomainIndex	dNodeInd;
+			
+			gNodeInd = RegularMeshUtils_Node_Global3DToGlobal1D( decomp, pos[0], pos[1], pos[2] );
+			dNodeInd = Mesh_NodeMapGlobalToDomain( mesh, gNodeInd );
+			
+			if( !found && dNodeInd < mesh->nodeDomainCount ) {
+				zMin = pos[2];
+				found = True;
+			}
+			else if( found && dNodeInd >= mesh->nodeDomainCount ) {
+				zMax = pos[2];
+				break;
+			}
+		}
+		
+		if( found ) {
+			if( zMax == 0 ) {
+				dSize[2] = gSize[2] - zMin;
+			}
+			else {
+				dSize[2] = zMax - zMin;
+			}
+			break;
+		}
+	}
+	
+	
+	/*
+	** Set up the destination values/arrays.
+	*/
+	
+	*nTriNodes = (dSize[0] - 1) * (dSize[2] - 1) * 6;
+	*triToDomain = Memory_Alloc_Array( Node_DomainIndex, *nTriNodes, "SnacRemesher" );
+	
+	
+	/*
+	** Do the triangulation.
+	*/
+	
+	{
+		unsigned	curTri = 0;
+		
+		for( pos[2] = 0; pos[2] < gSize[2] - 1; pos[2]++ ) {
+			for( pos[0] = 0; pos[0] < gSize[0] - 1; pos[0]++ ) {
+				Node_GlobalIndex	gNodeInd;
+				Node_DomainIndex	dNodeInd[4];
+				
+				gNodeInd = RegularMeshUtils_Node_Global3DToGlobal1D( decomp, pos[0], pos[1], pos[2] );
+				dNodeInd[0] = Mesh_NodeMapGlobalToDomain( mesh, gNodeInd );
+				gNodeInd = RegularMeshUtils_Node_Global3DToGlobal1D( decomp, pos[0] + 1, pos[1], pos[2] );
+				dNodeInd[1] = Mesh_NodeMapGlobalToDomain( mesh, gNodeInd );
+				gNodeInd = RegularMeshUtils_Node_Global3DToGlobal1D( decomp, pos[0] + 1, pos[1], pos[2] + 1 );
+				dNodeInd[2] = Mesh_NodeMapGlobalToDomain( mesh, gNodeInd );
+				gNodeInd = RegularMeshUtils_Node_Global3DToGlobal1D( decomp, pos[0], pos[1], pos[2] + 1 );
+				dNodeInd[3] = Mesh_NodeMapGlobalToDomain( mesh, gNodeInd );
+				
+				if( dNodeInd[0] < mesh->nodeDomainCount && dNodeInd[1] < mesh->nodeDomainCount && 
+				    dNodeInd[2] < mesh->nodeDomainCount && dNodeInd[3] < mesh->nodeDomainCount )
+				{
+					/* If we are here then we've found a valid planar element and can proceed to triangulate it. */
+					(*triToDomain)[(curTri * 3) + 0] = dNodeInd[0];
+					(*triToDomain)[(curTri * 3) + 1] = dNodeInd[1];
+					(*triToDomain)[(curTri * 3) + 2] = dNodeInd[3];
+					curTri++;
+					
+					(*triToDomain)[(curTri * 3) + 0] = dNodeInd[1];
+					(*triToDomain)[(curTri * 3) + 1] = dNodeInd[2];
+					(*triToDomain)[(curTri * 3) + 2] = dNodeInd[3];
+					curTri++;
+				}
+			}
+		}
+	}
+}
+
+
+
+
+
+#if 0
+/*
+** Removed for a rewrite.  Luke - 02/07/2005
+*/
+
+
+/*
+static void _SnacRemesher_CheckForShadowNode(
+		Snac_Context*			context,
+		SnacRemesher_Context*		contextExt,
+		Node_GlobalIndex		node_gI,
+		Node_LocalIndex			node_lI,
+		IndexSet**			ShadowNodeSetCurrent,
+		IndexSet**			ShadowNodeSetLocal,
+		IndexSet**			ShadowNodeSetRemote );
+
+static void _SnacRemesher_CheckForShadowElement(
+		Snac_Context*			context,
+		SnacRemesher_Context*		contextExt,
+		Element_GlobalIndex		element_gI,
+		Element_LocalIndex		element_lI,
+		IndexSet**			ShadowElementSetCurrent,
+		IndexSet**			ShadowElementSetLocal,
+		IndexSet**			ShadowElementSetRemote );
+*/
+
+
+void _SnacRemesher_InitialConditions( void* _context, void* data ) {
+	Snac_Context*				context = (Snac_Context*)_context;
+	Mesh*					mesh = context->mesh;
+	MeshLayout*				layout = mesh->layout;
+	Topology*				eTopology = layout->elementLayout->topology;
+	HexaMD*					decomp = (HexaMD*)layout->decomp;
+	SnacRemesher_Mesh*			meshExt = ExtensionManager_Get(
+							context->meshExtensionMgr,
+							mesh,
+							SnacRemesher_MeshHandle );
+	IndexSet**				gWallSet;
+	Partition_Index				rn_I;
+	Partition_Index				rnCount = meshExt->neighbourRankCount;
+	IndexSet**				shadowNodeSetLocal;
+	IndexSet**				shadowNodeSetRemote;
+	IndexSet**				shadowElementSetLocal;
+	IndexSet**				shadowElementSetRemote;
+	Node_GlobalIndex			node_gI;
+	Element_GlobalIndex			element_gI;
+	
+	Journal_Printf( context->debug, "In: %s\n", __func__ );
+	
+	/* If cartesion mesh, merely make a copy of initial node coordinates */
+	if( meshExt->meshType == SnacRemesher_Cartesian || meshExt->meshType == SnacRemesher_Spherical ) {
+		memcpy( meshExt->initialNodeCoord, mesh->nodeCoord, sizeof(Coord) * meshExt->nodeLocalCount );
+	}
+	/* Else, it is a spherical mesh (construct extensions prevents otherwise), convert each one */
+	else {
+		Node_LocalIndex				node_lI;
+		
+		for( node_lI = 0; node_lI < meshExt->nodeLocalCount; node_lI++ ) {
+			Coord*					spherical = &meshExt->initialNodeCoord[node_lI];
+			Coord*					cartesian = &mesh->nodeCoord[node_lI];
+			double 					sqXsqY =
+									(*cartesian)[0] * (*cartesian)[0] +
+									(*cartesian)[1] * (*cartesian)[1];
+			
+			/* At this point in time, spehrical coordinates are kept as radians, not degress as it evaluates faster */
+			
+			/* r = sqrt( sq( x ) + sq( y ) + sq( z ) ) */
+			(*spherical)[1] = sqrt( sqXsqY + (*cartesian)[2] * (*cartesian)[2] );
+			
+			/* phi = arcsin( sqrt( sq( x ) + sq( y ) ) / z ) */
+			(*spherical)[2] = asin( (*cartesian)[1] / (*spherical)[1] );
+			
+			/* theta = arctan( y / x ) */
+			(*spherical)[0] = atan( (*cartesian)[0] / (*cartesian)[2] );
+			
+			if( (*cartesian)[2] < 0.0 ) {
+				(*spherical)[0] += M_PI;
+			}
+			else if( (*cartesian)[0] < 0.0 ) {
+				(*spherical)[0] += 2 * M_PI;
+			}
+			
+			if( (*spherical)[0] > M_PI )
+				(*spherical)[0] = -2.0 * M_PI + (*spherical)[0];
+		}
+	}
+	
+	/* Obtain neighbour rank info */
+	_HexaMD_Shadow_BuildProcs( decomp, meshExt->neighbourRank );
+	
+	/* Build local temporary sets of the global walls and top-internal shadow nodes */
+	gWallSet = (IndexSet**)malloc( sizeof(IndexSet*) * 6 );
+	gWallSet[0] = RegularMeshUtils_CreateGlobalLeftSet( mesh );
+	gWallSet[1] = RegularMeshUtils_CreateGlobalRightSet( mesh );
+	gWallSet[2] = RegularMeshUtils_CreateGlobalBottomSet( mesh );
+	gWallSet[3] = RegularMeshUtils_CreateGlobalBackSet( mesh );
+	gWallSet[4] = RegularMeshUtils_CreateGlobalFrontSet( mesh );
+	gWallSet[5] = RegularMeshUtils_CreateGlobalTopSet( mesh ); /* TODO: positive radial dir for cartesian */
+	shadowNodeSetLocal = (IndexSet**)malloc( sizeof(IndexSet*) * rnCount );
+	shadowNodeSetRemote = (IndexSet**)malloc( sizeof(IndexSet*) * rnCount );
+	shadowElementSetLocal = (IndexSet**)malloc( sizeof(IndexSet*) * rnCount );
+	shadowElementSetRemote = (IndexSet**)malloc( sizeof(IndexSet*) * rnCount );
+	for( rn_I = 0; rn_I < rnCount; rn_I++ ) {
+		shadowNodeSetLocal[rn_I] = IndexSet_New( mesh->nodeLocalCount );
+		shadowNodeSetRemote[rn_I] = IndexSet_New( mesh->nodeGlobalCount );
+		shadowElementSetLocal[rn_I] = IndexSet_New( mesh->elementLocalCount );
+		shadowElementSetRemote[rn_I] = IndexSet_New( mesh->elementGlobalCount );
+	}
+	
+	/* Build the "wall", "topInternal" and "internal" local node sets, and the node shadow sets */
+	for( node_gI = 0; node_gI < meshExt->nodeGlobalCount; node_gI++ ) {
+		Node_LocalIndex				node_lI;
+		
+		node_lI = Mesh_NodeMapGlobalToLocal( mesh, node_gI );
+		if( node_lI < meshExt->nodeLocalCount ) {
+			if( IndexSet_IsMember( gWallSet[5], node_lI ) ) {
+				IndexSet_Add( meshExt->topInternalSet, node_lI );
+				/*dbPrint3(); fflush( stdout );
+
+				_SnacRemesher_CheckForShadowNode(
+					context,
+					contextExt,
+					node_gI,
+					node_lI,
+					ShadowNodeSetCurrent,
+					ShadowNodeSetLocal,
+					ShadowNodeSetRemote );*/
+			}
+			else if( IndexSet_IsMember( gWallSet[2], node_lI ) ) {
+				IndexSet_Add( meshExt->bottomInternalSet, node_lI );
+				/*dbPrint3_2(); fflush( stdout );
+
+				_SnacRemesher_CheckForShadowNode(
+					context,
+					contextExt,
+					node_gI,
+					node_lI,
+					ShadowNodeSetCurrent,
+					ShadowNodeSetLocal,
+					ShadowNodeSetRemote );*/
+			}
+			/* The walls (except for positive radial dir) remesh back to initial positions...
+			   maintain as one local set */
+			else if(
+				IndexSet_IsMember( gWallSet[0], node_lI ) ||
+				IndexSet_IsMember( gWallSet[1], node_lI ) ||
+				IndexSet_IsMember( gWallSet[3], node_lI ) ||
+				IndexSet_IsMember( gWallSet[4], node_lI ) )
+			{
+				IndexSet_Add( meshExt->wallSet, node_lI );
+				/*dbPrint2();
+
+				_SnacRemesher_CheckForShadowNode(
+					context,
+					contextExt,
+					node_gI,
+					node_lI,
+					ShadowNodeSetCurrent,
+					ShadowNodeSetLocal,
+					ShadowNodeSetRemote );*/
+			}
+			/* The positive radial dir wall internal nodes are free...
+			   maintain as one local set */
+
+			/* Internal nodes are interpolated in the radial dir...
+			   maintain as one set */
+			else {
+				IndexSet_Add( meshExt->internalSet, node_lI );
+			}
+		}
+		else Journal_DPrintf( context->debug, "node_gI: %3u node_lI: %3u, not local\n", node_gI, node_lI );
+	}
+	
+	/* Build the element shadow sets */
+	for( element_gI = 0; element_gI < meshExt->elementGlobalCount; element_gI++ ) {
+		Element_LocalIndex			element_lI;
+		Element_GlobalIndex			en_I;
+
+		element_lI = decomp->elementMapGlobalToLocal( decomp, element_gI );
+		if( element_lI < meshExt->elementLocalCount ) {
+			Element_GlobalIndex			eNbrCnt;
+			eNbrCnt = eTopology->neighbourCount( eTopology, element_gI );
+			if( eNbrCnt ) {
+				Element_GlobalIndex*			eNbrs;
+
+				eNbrs = (Element_GlobalIndex*)malloc( sizeof(Element_GlobalIndex) * eNbrCnt );
+				eTopology->buildNeighbours( eTopology, element_gI, eNbrs );
+				
+				for( rn_I = 0; rn_I < meshExt->neighbourRankCount; rn_I++ ) {
+					Partition_Index		rank;
+
+					rank = meshExt->neighbourRank[rn_I];
+
+					for( en_I = 0; en_I < eNbrCnt; en_I++ ) {
+						if( eNbrs[en_I] < meshExt->elementGlobalCount &&
+							IndexSet_IsMember( decomp->localElementSets[rank], eNbrs[en_I] ) &&
+							!IndexSet_IsMember(
+								decomp->localElementSets[context->rank],
+								eNbrs[en_I] ) )
+						{
+							IndexSet_Add( shadowElementSetRemote[rn_I], eNbrs[en_I] );
+						}
+					}
+				}
+
+				if( eNbrs )
+					free( eNbrs );
+			}
+		}
+	}
+	
+	/* Resolve the "wall", "topInternal" and "internal" sets into array of indices (for speed) */
+	IndexSet_GetMembers( meshExt->wallSet, &meshExt->wallCount, &meshExt->wallArray );
+	IndexSet_GetMembers( meshExt->topInternalSet, &meshExt->topInternalCount, &meshExt->topInternalArray );
+	IndexSet_GetMembers( meshExt->bottomInternalSet, &meshExt->bottomInternalCount, &meshExt->bottomInternalArray );
+	IndexSet_GetMembers( meshExt->internalSet, &meshExt->internalCount, &meshExt->internalArray );
+	
+	/* Build shadow tables and arrays */
+	meshExt->shadowNodeLocalCount = (Node_LocalIndex*)malloc( sizeof(Node_LocalIndex) * rnCount );
+	meshExt->shadowNodeLocalArray = (Node_LocalIndex**)malloc( sizeof(Node_LocalIndex*) * rnCount );
+	meshExt->shadowNodeRemoteCount = (Node_ShadowIndex*)malloc( sizeof(Node_ShadowIndex) * rnCount );
+	meshExt->shadowNodeRemoteArray = (Node_GlobalIndex**)malloc( sizeof(Node_GlobalIndex*) * rnCount );
+	meshExt->shadowNodeRemoteCoord = (Coord**)malloc( sizeof(Coord*) * rnCount );
+	meshExt->shadowNodeRemote = (Snac_Node**)malloc( sizeof(Snac_Node*) * rnCount );
+	meshExt->shadowElementLocalCount = (Element_LocalIndex*)malloc( sizeof(Element_LocalIndex) * rnCount );
+	meshExt->shadowElementLocalArray = (Element_LocalIndex**)malloc( sizeof(Element_LocalIndex*) * rnCount );
+	meshExt->shadowElementRemoteCount = (Element_ShadowIndex*)malloc( sizeof(Element_ShadowIndex) * rnCount );
+	meshExt->shadowElementRemoteArray = (Element_GlobalIndex**)malloc( sizeof(Element_GlobalIndex*) * rnCount );
+	meshExt->shadowElementRemote = (Snac_Element**)malloc( sizeof(Snac_Element*) * rnCount );
+	for( rn_I = 0; rn_I < rnCount; rn_I++ ) {
+		Element_LocalIndex		e_lI;
+		Node_LocalIndex			n_lI;
+		MPI_Status			status;
+		Element_ShadowIndex		se_I;
+
+		/* temp */
+		meshExt->shadowNodeLocalCount[rn_I] = 0;
+		meshExt->shadowNodeRemoteCount[rn_I] = 0;
+		
+		/* convert shadow elements to arrays */
+		IndexSet_GetMembers(
+			shadowElementSetRemote[rn_I],
+			&meshExt->shadowElementRemoteCount[rn_I],
+			&meshExt->shadowElementRemoteArray[rn_I] );
+		/* transfer to neighbours - send size */
+		MPI_Send(
+			&meshExt->shadowElementRemoteCount[rn_I],
+			1,
+			MPI_INT,
+			meshExt->neighbourRank[rn_I],
+			0,
+			decomp->communicator );
+		/* send data */
+		MPI_Send(
+			meshExt->shadowElementRemoteArray[rn_I],
+			meshExt->shadowElementRemoteCount[rn_I],
+			MPI_INT,
+			meshExt->neighbourRank[rn_I],
+			7,
+			decomp->communicator );
+		/* recv size */
+		MPI_Recv(
+			&meshExt->shadowElementLocalCount[rn_I],
+			1,
+			MPI_INT,
+			meshExt->neighbourRank[rn_I],
+			0,
+			decomp->communicator,
+			&status );
+		meshExt->shadowElementLocalArray[rn_I] = (Index*)malloc(
+			sizeof(Element_LocalIndex) * meshExt->shadowElementLocalCount[rn_I] );
+		/* recv data */
+		MPI_Recv(
+			meshExt->shadowElementLocalArray[rn_I],
+			meshExt->shadowElementLocalCount[rn_I],
+			MPI_INT,
+			meshExt->neighbourRank[rn_I],
+			7,
+			decomp->communicator,
+			&status );
+		/* loop over data and convert to local indices */
+		for( e_lI = 0; e_lI < meshExt->shadowElementLocalCount[rn_I]; e_lI++ ) {
+			Index   element_lI = Mesh_ElementMapGlobalToLocal( mesh, meshExt->shadowElementLocalArray[rn_I][e_lI] );
+
+			if( element_lI >= meshExt->elementLocalCount )
+				assert( 0 ); /* Big trouble */
+			
+			meshExt->shadowElementLocalArray[rn_I][e_lI] = element_lI;
+		}
+		/* setup the remaining element info */
+		meshExt->shadowElementRemote[rn_I] = (Snac_Element*)ExtensionManager_Malloc(
+			mesh->elementExtensionMgr,
+			meshExt->shadowElementRemoteCount[rn_I] );
+		ExtensionManager_Memset(
+			mesh->elementExtensionMgr,
+			meshExt->shadowElementRemote[rn_I],
+			0,
+			meshExt->shadowElementRemoteCount[rn_I] );
+		
+		/* Loop over shadow elements to calculate node info */
+		for( se_I = 0; se_I < meshExt->shadowElementRemoteCount[rn_I]; se_I++ ) {
+			NodeLayout*     nodeLayout = mesh->layout->nodeLayout;
+			Index		sen_I, seNodeCnt;
+			Index*		seNodes;
+
+			/* extract nodes */
+			seNodeCnt = nodeLayout->elementNodeCount( nodeLayout, meshExt->shadowElementRemoteArray[rn_I][se_I] );
+			seNodes = (Index*)malloc( sizeof(Index) * seNodeCnt );
+			nodeLayout->buildElementNodes( nodeLayout, meshExt->shadowElementRemoteArray[rn_I][se_I], seNodes );
+
+			for( sen_I = 0; sen_I < seNodeCnt; sen_I++ ) {
+				Index localNode = Mesh_NodeMapGlobalToLocal( mesh, seNodes[sen_I] );
+
+				if( localNode >= meshExt->nodeLocalCount ) {
+					IndexSet_Add( shadowNodeSetRemote[rn_I], seNodes[sen_I] );
+				}
+			}
+
+			if( seNodes )
+				free( seNodes );
+		}
+		/* convert to array */
+		IndexSet_GetMembers(
+			shadowNodeSetRemote[rn_I],
+			&meshExt->shadowNodeRemoteCount[rn_I],
+			&meshExt->shadowNodeRemoteArray[rn_I] );
+		/* transfer to neighbours - send size */
+		MPI_Send(
+			&meshExt->shadowNodeRemoteCount[rn_I],
+			1,
+			MPI_INT,
+			meshExt->neighbourRank[rn_I],
+			0,
+			decomp->communicator );
+		/* send data */
+		MPI_Send(
+			meshExt->shadowNodeRemoteArray[rn_I],
+			meshExt->shadowNodeRemoteCount[rn_I],
+			MPI_INT,
+			meshExt->neighbourRank[rn_I],
+			7,
+			decomp->communicator );
+		/* recv size */
+		MPI_Recv(
+			&meshExt->shadowNodeLocalCount[rn_I],
+			1,
+			MPI_INT,
+			meshExt->neighbourRank[rn_I],
+			0,
+			decomp->communicator,
+			&status );
+		meshExt->shadowNodeLocalArray[rn_I] = (Index*)malloc( sizeof(Index) * meshExt->shadowNodeLocalCount[rn_I] );
+		/* recv data */
+		MPI_Recv(
+			meshExt->shadowNodeLocalArray[rn_I],
+			meshExt->shadowNodeLocalCount[rn_I],
+			MPI_INT,
+			meshExt->neighbourRank[rn_I],
+			7,
+			decomp->communicator,
+			&status );
+		/* loop over data and convert to local indices */
+		for( n_lI = 0; n_lI < meshExt->shadowNodeLocalCount[rn_I]; n_lI++ ) {
+			Index   node_lI = Mesh_NodeMapGlobalToLocal( mesh, meshExt->shadowNodeLocalArray[rn_I][n_lI] );
+
+			if( node_lI >= meshExt->nodeLocalCount )
+				assert( 0 ); /* something is terribly wrong */
+			
+			meshExt->shadowNodeLocalArray[rn_I][n_lI] = node_lI;
+		}
+		/* setup remaining node info */
+		meshExt->shadowNodeRemoteCoord[rn_I] = (Coord*)malloc( sizeof(Coord) * meshExt->shadowNodeRemoteCount[rn_I] );
+		memset( meshExt->shadowNodeRemoteCoord[rn_I], 0, sizeof(Coord) * meshExt->shadowNodeRemoteCount[rn_I] );
+		meshExt->shadowNodeRemote[rn_I] = (Snac_Node*)ExtensionManager_Malloc(
+			mesh->nodeExtensionMgr,
+			meshExt->shadowNodeRemoteCount[rn_I] );
+		ExtensionManager_Memset( mesh->nodeExtensionMgr,  meshExt->shadowNodeRemote[rn_I], 0, meshExt->shadowNodeRemoteCount[rn_I] );
+	}
+	
+	/* Delete temporary sets */
+	for( rn_I = 0; rn_I < rnCount; rn_I++ ) {
+		Stg_Class_Delete( shadowElementSetRemote[rn_I]  );
+		Stg_Class_Delete( shadowElementSetLocal[rn_I]  );
+		Stg_Class_Delete( shadowNodeSetRemote[rn_I]  );
+		Stg_Class_Delete( shadowNodeSetLocal[rn_I]  );
+	}
+	free( shadowElementSetRemote );
+	free( shadowElementSetLocal );
+	free( shadowNodeSetRemote );
+	free( shadowNodeSetLocal );
+	Stg_Class_Delete( gWallSet[5] );
+	Stg_Class_Delete( gWallSet[4] );
+	Stg_Class_Delete( gWallSet[3] );
+	Stg_Class_Delete( gWallSet[2] );
+	Stg_Class_Delete( gWallSet[1] );
+	Stg_Class_Delete( gWallSet[0] );
+	free( gWallSet );
+}
+#endif

Added: long/3D/SNAC/trunk/Snac/plugins/remesher_BI/InitialConditions.h
===================================================================
--- long/3D/SNAC/trunk/Snac/plugins/remesher_BI/InitialConditions.h	                        (rev 0)
+++ long/3D/SNAC/trunk/Snac/plugins/remesher_BI/InitialConditions.h	2011-10-07 16:18:20 UTC (rev 19040)
@@ -0,0 +1,47 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+**
+** Copyright (C), 2003, 
+**	Steve Quenette, 110 Victoria Street, Melbourne, Victoria, 3053, Australia.
+**	Californian Institute of Technology, 1200 East California Boulevard, Pasadena, California, 91125, USA.
+**	University of Texas, 1 University Station, Austin, Texas, 78712, USA.
+**
+** Authors:
+**	Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
+**	Stevan M. Quenette, Visitor in Geophysics, Caltech.
+**	Luc Lavier, Research Scientist, The University of Texas. (luc at utig.ug.utexas.edu)
+**	Luc Lavier, Research Scientist, Caltech.
+**
+** This program is free software; you can redistribute it and/or modify it
+** under the terms of the GNU General Public License as published by the
+** Free Software Foundation; either version 2, or (at your option) any
+** later version.
+** 
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+** GNU General Public License for more details.
+** 
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+**
+*/
+/** \file
+** Role:
+**
+** Assumptions:
+**
+** Comments:
+**
+** $Id: InitialConditions.h 3095 2005-07-13 09:50:46Z LukeHodkinson $
+**
+**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#ifndef __SnacRemesher_InitialConditions_h__
+#define __SnacRemesher_InitialConditions_h__
+	
+	
+	void _SnacRemesher_InitialConditions( void* _context, void* data );
+	
+	
+#endif /* __SnacRemesher_InitialConditions_h__ */

Added: long/3D/SNAC/trunk/Snac/plugins/remesher_BI/Make.mm
===================================================================
--- long/3D/SNAC/trunk/Snac/plugins/remesher_BI/Make.mm	                        (rev 0)
+++ long/3D/SNAC/trunk/Snac/plugins/remesher_BI/Make.mm	2011-10-07 16:18:20 UTC (rev 19040)
@@ -0,0 +1,67 @@
+##~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+##
+## Copyright (C), 2003, 
+##	Steve Quenette, 110 Victoria Street, Melbourne, Victoria, 3053, Australia.
+##	Californian Institute of Technology, 1200 East California Boulevard, Pasadena, California, 91125, USA.
+##	University of Texas, 1 University Station, Austin, Texas, 78712, USA.
+##
+## Authors:
+##	Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
+##	Stevan M. Quenette, Visitor in Geophysics, Caltech.
+##	Luc Lavier, Research Scientist, The University of Texas. (luc at utig.ug.utexas.edu)
+##	Luc Lavier, Research Scientist, Caltech.
+##
+## This program is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by the
+## Free Software Foundation; either version 2, or (at your option) any
+## later version.
+## 
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+## GNU General Public License for more details.
+## 
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+##
+## $Id: Make.mm 2921 2005-05-10 06:44:06Z EunseoChoi $
+##
+##~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+include Makefile.def
+
+PROJECT = Snac
+PACKAGE = ${def_mod}module
+
+PROJ_LIB = $(BLD_LIBDIR)/$(PACKAGE).a
+PROJ_DLL = $(BLD_LIBDIR)/$(PACKAGE).$(EXT_SO)
+PROJ_TMPDIR = $(BLD_TMPDIR)/$(PROJECT)/$(PACKAGE)
+PROJ_CLEAN += $(PROJ_LIB) $(PROJ_DLL)
+PROJ_INCDIR = $(BLD_INCDIR)/${def_inc}
+
+PROJ_SRCS = ${def_srcs}
+PROJ_CC_FLAGS += -I$(BLD_INCDIR)/$(PROJECT) -I$(BLD_INCDIR)/Snac -I$(BLD_INCDIR)/StGermain -I$(STGERMAIN_INCDIR)/ -I$(STGERMAIN_INCDIR)/StGermain `xml2-config --cflags` -DCURR_MODULE_NAME=\"${def_mod}\"
+PROJ_LIBRARIES = -L$(BLD_LIBDIR) -L$(STGERMAIN_LIBDIR)/ -lSnac -lStGermain `xml2-config --libs` $(MPI_LIBPATH) $(MPI_LIBS)
+LCCFLAGS = 
+
+# I keep file lists to build a monolith .so from a set of .a's
+PROJ_OBJS_IN_TMP = ${addprefix $(PROJECT)/$(PACKAGE)/, ${addsuffix .o, ${basename $(PROJ_SRCS)}}}
+PROJ_OBJLIST = $(BLD_TMPDIR)/$(PROJECT).$(PACKAGE).objlist
+
+all: $(PROJ_LIB) DLL createObjList export
+
+DLL: product_dirs $(PROJ_OBJS)
+	$(CC) -o $(PROJ_DLL) $(PROJ_OBJS) $(COMPILER_LCC_SOFLAGS) $(LCCFLAGS) $(PROJ_LIBRARIES) $(EXTERNAL_LIBPATH) $(EXTERNAL_LIBS)
+
+
+
+createObjList:: 
+	@echo ${PROJ_OBJS_IN_TMP} | cat > ${PROJ_OBJLIST}
+
+#export:: export-headers
+export:: export-headers export-libraries
+EXPORT_HEADERS = ${def_hdrs}
+EXPORT_LIBS = $(PROJ_LIB) $(PROJ_DLL)
+
+check::

Added: long/3D/SNAC/trunk/Snac/plugins/remesher_BI/Makefile.def
===================================================================
--- long/3D/SNAC/trunk/Snac/plugins/remesher_BI/Makefile.def	                        (rev 0)
+++ long/3D/SNAC/trunk/Snac/plugins/remesher_BI/Makefile.def	2011-10-07 16:18:20 UTC (rev 19040)
@@ -0,0 +1,68 @@
+##~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+##
+## Copyright (C), 2003, 
+##	Steve Quenette, 110 Victoria Street, Melbourne, Victoria, 3053, Australia.
+##	Californian Institute of Technology, 1200 East California Boulevard, Pasadena, California, 91125, USA.
+##	University of Texas, 1 University Station, Austin, Texas, 78712, USA.
+##
+## Authors:
+##	Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
+##	Stevan M. Quenette, Visitor in Geophysics, Caltech.
+##	Luc Lavier, Research Scientist, The University of Texas. (luc at utig.ug.utexas.edu)
+##	Luc Lavier, Research Scientist, Caltech.
+##	Luc Lavier, Caltech.
+##
+## This program is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by the
+## Free Software Foundation; either version 2, or (at your option) any
+## later version.
+## 
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+## GNU General Public License for more details.
+## 
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+##
+## $Id: Makefile.def 3095 2005-07-13 09:50:46Z LukeHodkinson $
+##
+##~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ 
+def_mod = SnacRemesher
+def_inc = Snac/Remesher
+
+def_srcs = \
+	Utils.c \
+	EntryPoint.c \
+	Context.c \
+	Mesh.c \
+	Register.c \
+	ConstructExtensions.c \
+	Build.c \
+	InitialConditions.c \
+	Output.c \
+	TestCondFunc.c \
+	Remesh.c \
+	RemeshCoords.c \
+	RemeshNodes.c \
+	RemeshElements.c \
+	DeleteExtensions.c
+
+def_hdrs = \
+	types.h \
+	Utils.h \
+	Context.h \
+	EntryPoint.h \
+	Mesh.h \
+	Register.h \
+	ConstructExtensions.h \
+	Build.h \
+	InitialConditions.h \
+	Output.h \
+	TestCondFunc.h \
+	Remesh.h \
+	DeleteExtensions.h \
+	Remesher.h
+

Added: long/3D/SNAC/trunk/Snac/plugins/remesher_BI/Mesh.c
===================================================================
--- long/3D/SNAC/trunk/Snac/plugins/remesher_BI/Mesh.c	                        (rev 0)
+++ long/3D/SNAC/trunk/Snac/plugins/remesher_BI/Mesh.c	2011-10-07 16:18:20 UTC (rev 19040)
@@ -0,0 +1,228 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+**
+** Copyright (C), 2003,
+**	Steve Quenette, 110 Victoria Street, Melbourne, Victoria, 3053, Australia.
+**	Californian Institute of Technology, 1200 East California Boulevard, Pasadena, California, 91125, USA.
+**	University of Texas, 1 University Station, Austin, Texas, 78712, USA.
+**
+** Authors:
+**	Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
+**	Stevan M. Quenette, Visitor in Geophysics, Caltech.
+**	Luc Lavier, Research Scientist, The University of Texas. (luc at utig.ug.utexas.edu)
+**	Luc Lavier, Research Scientist, Caltech.
+**
+** This program is free software; you can redistribute it and/or modify it
+** under the terms of the GNU General Public License as published by the
+** Free Software Foundation; either version 2, or (at your option) any
+** later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+**
+** $Id: Mesh.c 3095 2005-07-13 09:50:46Z LukeHodkinson $
+**
+**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#include <mpi.h>
+#include <StGermain/StGermain.h>
+#include <StGermain/FD/FD.h>
+
+#include "Snac/Snac.h"
+#include "types.h"
+#include "Mesh.h"
+
+#include <stdio.h>
+
+
+/*
+** Due to the rewrite this func is severely useless.  Need to fix it.
+*/
+
+void SnacRemesher_Mesh_Print( void* mesh, Stream* stream ) {
+	SnacRemesher_Mesh*	self = (SnacRemesher_Mesh*)mesh;
+/*	Node_LocalIndex		node_lI; */
+/*	Node_LocalIndex		index; */
+
+	Journal_Printf( stream, "SnacRemesher_Mesh:\n" );
+
+#if 0
+	Journal_Printf( stream, "\tnodeLocalCount: %u\n", self->nodeLocalCount );
+	Journal_Printf( stream, "\tnodeDomainCount: %u\n", self->nodeDomainCount );
+	Journal_Printf( stream, "\tnodeGlobalCount: %u\n", self->nodeGlobalCount );
+	Journal_Printf( stream, "\telementLocalCount: %u\n", self->elementLocalCount );
+	Journal_Printf( stream, "\telementDomainCount: %u\n", self->elementDomainCount );
+	Journal_Printf( stream, "\telementGlobalCount: %u\n", self->elementGlobalCount );
+	Journal_Printf( stream, "\tinitialNodeCoord[0-%u]: { ", self->nodeLocalCount );
+	for( node_lI = 0; node_lI < self->nodeLocalCount; node_lI++ ) {
+		Journal_Printf( stream,
+			"{ %g, %g, %g } ",
+			self->initialNodeCoord[node_lI][0],
+			self->initialNodeCoord[node_lI][1],
+			self->initialNodeCoord[node_lI][2] );
+	}
+	Journal_Printf( stream, "}\n" );
+	Journal_Printf( stream, "\tnewNodeCoord[0-%u]: { ", self->nodeLocalCount );
+	for( node_lI = 0; node_lI < self->nodeLocalCount; node_lI++ ) {
+		Journal_Printf( stream,
+			"{ %g, %g, %g } ",
+			self->newNodeCoord[node_lI][0],
+			self->newNodeCoord[node_lI][1],
+			self->newNodeCoord[node_lI][2] );
+	}
+	Journal_Printf( stream, "}\n" );
+	Journal_Printf( stream, "\tnewNode[0-%u]: { ... TODO: Print nodes nicely... }\n", self->nodeLocalCount );
+
+	Journal_Printf( stream,
+		"\tmeshType: %s\n",
+		self->meshType == SnacRemesher_Spherical ? "Spherical" :
+			self->meshType == SnacRemesher_Cartesian ? "Cartesian" : "Invalid value!" );
+
+	Journal_Printf( stream, "\tneighbourRankCount: %u\n", self->neighbourRankCount );
+	Journal_Printf( stream, "\tneighbourRank[0-%u]: {", self->neighbourRankCount );
+	for( index = 0; index < self->neighbourRankCount; index++ ) {
+		Journal_Printf( stream, "%i ", self->neighbourRank[index] );
+	}
+	Journal_Printf( stream, "}\n" );
+
+	Journal_Printf( stream, "\ttopInternalSet: " ); Print( self->topInternalSet, stream );
+	Journal_Printf( stream, "\tbottomInternalSet: " ); Print( self->bottomInternalSet, stream );
+	Journal_Printf( stream, "\twallSet: " ); Print( self->wallSet, stream );
+	Journal_Printf( stream, "\tinternalSet: " ); Print( self->internalSet, stream );
+
+	Journal_Printf( stream, "\ttopInternalCount: %u\n", self->topInternalCount );
+	Journal_Printf( stream, "\tbottomInternalCount: %u\n", self->bottomInternalCount );
+	Journal_Printf( stream, "\twalllCount: %u\n", self->wallCount );
+	Journal_Printf( stream, "\tinternalCount: %u\n", self->internalCount );
+
+	Journal_Printf( stream, "\ttopInternalArray[0-%u]: { ", self->topInternalCount );
+	for( index = 0; index < self->topInternalCount; index++ ) {
+		Journal_Printf( stream, "%u ", self->topInternalArray[index] );
+	}
+	Journal_Printf( stream, "}\n" );
+	Journal_Printf( stream, "\tbottomInternalArray[0-%u]: { ", self->bottomInternalCount );
+	for( index = 0; index < self->bottomInternalCount; index++ ) {
+		Journal_Printf( stream, "%u ", self->bottomInternalArray[index] );
+	}
+	Journal_Printf( stream, "}\n" );
+	Journal_Printf( stream, "\twallSet[0-%u]: { ", self->wallCount );
+	for( index = 0; index < self->wallCount; index++ ) {
+		Journal_Printf( stream, "%u ", self->wallArray[index] );
+	}
+	Journal_Printf( stream, "}\n" );
+	Journal_Printf( stream, "\tinternalArray[0-%u]: { ", self->internalCount );
+	for( index = 0; index < self->internalCount; index++ ) {
+		Journal_Printf( stream, "%u ", self->internalArray[index] );
+	}
+	Journal_Printf( stream, "}\n" );
+
+	/* Shadow */
+	Journal_Printf( stream, "\tshadowNodeLocalCount[0-%u]: { ", self->neighbourRankCount );
+	for( index = 0; index < self->neighbourRankCount; index++ ) {
+		Journal_Printf( stream, "%u ", self->shadowNodeLocalCount[index] );
+	}
+	Journal_Printf( stream, "}\n" );
+	Journal_Printf( stream, "\tshadowNodeLocalArray[0-%u]: {\n", self->neighbourRankCount );
+	for( index = 0; index < self->neighbourRankCount; index++ ) {
+		Index					index2;
+
+		Journal_Printf( stream, "\t\tshadowNodeLocalArray[%u][0-%u]: { ", index, self->shadowNodeLocalCount[index] );
+		for( index2 = 0; index2 < self->shadowNodeLocalCount[index]; index2++ ) {
+			Journal_Printf( stream, "%u ", self->shadowNodeLocalArray[index][index2] );
+		}
+		Journal_Printf( stream, "}\n" );
+	}
+	Journal_Printf( stream, "}\n" );
+	Journal_Printf( stream, "\tshadowNodeRemoteCount[0-%u]: { ", self->neighbourRankCount );
+	for( index = 0; index < self->neighbourRankCount; index++ ) {
+		Journal_Printf( stream, "%u ", self->shadowNodeRemoteCount[index] );
+	}
+	Journal_Printf( stream, "}\n" );
+	Journal_Printf( stream, "\tshadowNodeRemoteArray[0-%u]: {\n", self->neighbourRankCount );
+	for( index = 0; index < self->neighbourRankCount; index++ ) {
+		Index					index2;
+
+		Journal_Printf( stream, "\t\tshadowNodeRemoteArray[%u][0-%u]: { ", index, self->shadowNodeRemoteCount[index] );
+		for( index2 = 0; index2 < self->shadowNodeRemoteCount[index]; index2++ ) {
+			Journal_Printf( stream, "%u ", self->shadowNodeRemoteArray[index][index2] );
+		}
+		Journal_Printf( stream, "}\n" );
+	}
+	Journal_Printf( stream, "}\n" );
+	Journal_Printf( stream, "\tshadowNodeRemoteCoord[0-%u]: {\n", self->neighbourRankCount );
+	for( index = 0; index < self->neighbourRankCount; index++ ) {
+		Index					index2;
+
+		Journal_Printf( stream, "\t\tshadowNodeRemoteCoord[%u][0-%u]: { ", index, self->shadowNodeRemoteCount[index] );
+		for( index2 = 0; index2 < self->shadowNodeRemoteCount[index]; index2++ ) {
+			Journal_Printf( stream,
+				"{ %g, %g, %g }, ",
+				self->shadowNodeRemoteCoord[index][index2][0],
+				self->shadowNodeRemoteCoord[index][index2][1],
+				self->shadowNodeRemoteCoord[index][index2][2] );
+		}
+		Journal_Printf( stream, "}\n" );
+	}
+	Journal_Printf( stream, "}\n" );
+	Journal_Printf( stream, "\tshadowNodeRemote[0-%u]: {\n", self->neighbourRankCount );
+	for( index = 0; index < self->neighbourRankCount; index++ ) {
+		Index					index2;
+
+		Journal_Printf( stream, "\t\tshadowNodeRemote[%u][0-%u]: { ", index, self->shadowNodeRemoteCount[index] );
+		for( index2 = 0; index2 < self->shadowNodeRemoteCount[index]; index2++ ) {
+			Snac_Node_Print( &self->shadowNodeRemote[index][index2] );
+		}
+		Journal_Printf( stream, "}\n" );
+	}
+	Journal_Printf( stream, "}\n" );
+
+	/* Shadow Elements*/
+	Journal_Printf( stream, "\tshadowElementLocalCount[0-%u]: { ", self->neighbourRankCount );
+	for( index = 0; index < self->neighbourRankCount; index++ ) {
+		Journal_Printf( stream, "%u ", self->shadowElementLocalCount[index] );
+	}
+	Journal_Printf( stream, "}\n" );
+	Journal_Printf( stream, "\tshadowElementLocalArray[0-%u]: {\n", self->neighbourRankCount );
+	for( index = 0; index < self->neighbourRankCount; index++ ) {
+		Index					index2;
+
+		Journal_Printf( stream, "\t\tshadowElementLocalArray[%u][0-%u]: { ", index, self->shadowElementLocalCount[index] );
+		for( index2 = 0; index2 < self->shadowElementLocalCount[index]; index2++ ) {
+			Journal_Printf( stream, "%u ", self->shadowElementLocalArray[index][index2] );
+		}
+		Journal_Printf( stream, "}\n" );
+	}
+	Journal_Printf( stream, "}\n" );
+	Journal_Printf( stream, "\tshadowElementRemoteCount[0-%u]: { ", self->neighbourRankCount );
+	for( index = 0; index < self->neighbourRankCount; index++ ) {
+		Journal_Printf( stream, "%u ", self->shadowElementRemoteCount[index] );
+	}
+	Journal_Printf( stream, "}\n" );
+	Journal_Printf( stream, "\tshadowElementRemoteArray[0-%u]: {\n", self->neighbourRankCount );
+	for( index = 0; index < self->neighbourRankCount; index++ ) {
+		Index					index2;
+
+		Journal_Printf( stream, "\t\tshadowElementRemoteArray[%u][0-%u]: { ", index, self->shadowElementRemoteCount[index] );
+		for( index2 = 0; index2 < self->shadowElementRemoteCount[index]; index2++ ) {
+			Journal_Printf( stream, "%u ", self->shadowElementRemoteArray[index][index2] );
+		}
+		Journal_Printf( stream, "}\n" );
+	}
+	Journal_Printf( stream, "}\n" );
+	for( index = 0; index < self->neighbourRankCount; index++ ) {
+		Index					index2;
+
+		Journal_Printf( stream, "\t\tshadowElementRemote[%u][0-%u]: { ", index, self->shadowElementRemoteCount[index] );
+		for( index2 = 0; index2 < self->shadowElementRemoteCount[index]; index2++ ) {
+			Snac_Element_Print( &self->shadowElementRemote[index][index2], stream );
+		}
+		Journal_Printf( stream, "}\n" );
+	}
+	Journal_Printf( stream, "}\n" );
+#endif
+}

Added: long/3D/SNAC/trunk/Snac/plugins/remesher_BI/Mesh.h
===================================================================
--- long/3D/SNAC/trunk/Snac/plugins/remesher_BI/Mesh.h	                        (rev 0)
+++ long/3D/SNAC/trunk/Snac/plugins/remesher_BI/Mesh.h	2011-10-07 16:18:20 UTC (rev 19040)
@@ -0,0 +1,173 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+**
+** Copyright (C), 2003,
+**	Steve Quenette, 110 Victoria Street, Melbourne, Victoria, 3053, Australia.
+**	Californian Institute of Technology, 1200 East California Boulevard, Pasadena, California, 91125, USA.
+**	University of Texas, 1 University Station, Austin, Texas, 78712, USA.
+**
+** Authors:
+**	Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
+**	Stevan M. Quenette, Visitor in Geophysics, Caltech.
+**	Luc Lavier, Research Scientist, The University of Texas. (luc at utig.ug.utexas.edu)
+**	Luc Lavier, Research Scientist, Caltech.
+**
+** This program is free software; you can redistribute it and/or modify it
+** under the terms of the GNU General Public License as published by the
+** Free Software Foundation; either version 2, or (at your option) any
+** later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+**
+*/
+/** \file
+** Role:
+**	Snac exchanger properties extensions to the mesh construct.
+**
+** Assumptions:
+**
+** Comments:
+**
+** $Id: Mesh.h 3173 2005-11-21 23:47:09Z LukeHodkinson $
+**
+**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#ifndef __SnacRemesher_Mesh_h__
+#define __SnacRemesher_Mesh_h__
+
+
+	typedef enum {
+		SnacRemesher_Spherical, 
+		SnacRemesher_Cartesian, 
+		SnacRemesher_MeshTypeMax
+	} SnacRemesher_MeshType;
+
+	struct _SnacRemesher_ElementBarcord {
+		double				L[4];
+		Element_DomainIndex	elnum;
+		Tetrahedra_Index	tetnum;
+	};	
+	typedef struct _SnacRemesher_ElementBarcord SnacRemesher_ElementBarcord;
+
+	struct _SnacRemesher_ElementBarcoef {
+		/* Each of 5 tet has 4 shape functions (i.e., 4 nodes), 
+		   each of which needs 4 coefficients. */
+		double				coef[5][4][4]; 
+	};	
+	typedef struct _SnacRemesher_ElementBarcoef SnacRemesher_ElementBarcoef;
+	
+	/* Mesh Information */
+	struct _SnacRemesher_Mesh {
+		SnacRemesher_MeshType	meshType;
+		
+		/* A placeholder for new coords, and stores static node coords. */
+		Coord*		newNodeCoords;
+		Snac_Node*	newNodes;
+		Coord*		oldBarycenters;
+		Coord*		newBarycenters;
+		SnacRemesher_ElementBarcord*	barcord;	
+		SnacRemesher_ElementBarcoef*	barcoef;	
+
+		Snac_Element*	newElements;
+		
+		/* If during the remesh nodes are found outside the old mesh they will be stored here. */
+		unsigned			nExternalNodes;
+		Node_LocalIndex*	externalNodes;
+		unsigned			nExternalElements;
+		Element_LocalIndex*	externalElements;
+		
+		/* Used for interpolating top/bottom internal nodes. */
+		unsigned			nTopInternNodes;
+		Node_LocalIndex*	topInternToLocal;
+		unsigned			nBotInternNodes;
+		Node_LocalIndex*	botInternToLocal;
+		
+		unsigned			nTopTriNodes;
+		Node_DomainIndex*	topTriToDomain;
+		unsigned			nBotTriNodes;
+		Node_DomainIndex*	botTriToDomain;
+		
+		/* Used for interpolating bulk nodes. */
+		unsigned			nYLines;
+		unsigned*			yLineLTerm;
+		unsigned*			yLineUTerm;
+		unsigned*			yLineNYInds;
+		unsigned**		yLineYInds;
+		Node_LocalIndex**	yLineLocalInds;
+		
+		/* The sync class provides remote terminals for interpolating bulk nodes. */
+		SnacSync*	sync;
+	};
+	
+
+#if 0
+	/* Mesh Information */
+	struct _SnacRemesher_Mesh {
+		
+		Coord*		initialNodeCoord;	/* Array of initial node coordinates */
+		Coord*		newNodeCoord;	/* Array of new/temporary node coordinates */
+		Snac_Node*	newNode;	/* Array of new/temporary node values */
+		Snac_Element*	newElement;	/* Array of new Elements */
+
+		/* Node count... may not otherwise be directly available from this structure, so we keep a copy here */
+		Node_LocalIndex		nodeLocalCount;
+		Node_DomainIndex		nodeDomainCount;
+		Node_GlobalIndex		nodeGlobalCount;
+		Element_LocalIndex		elementLocalCount;
+		Element_DomainIndex		elementDomainCount;
+		Element_GlobalIndex		elementGlobalCount;
+
+		/* Mesh type */
+		SnacRemesher_MeshType		meshType;
+
+		/* Rank neighbour info */
+		Partition_Index	neighbourRankCount;
+		Partition_Index*	neighbourRank;
+
+		/* The walls (except for positive radial dir) remesh back to initial positions... maintain as one local set */
+		IndexSet*		wallSet;
+		Index 		wallCount;
+		Index*		wallArray; /* content is local indices */
+
+		/* The positive radial dir wall internal nodes are free... maintain as one local set */
+		IndexSet*		topInternalSet;
+		Index 		topInternalCount;
+		Index*		topInternalArray;
+
+		/* The positive radial dir wall internal nodes are free... maintain as one local set */
+		IndexSet*		bottomInternalSet;
+		Index 		bottomInternalCount;
+		Index*		bottomInternalArray;
+
+		/* Internal nodes are interpolated in the radial dir... maintain as one set */
+		IndexSet*		internalSet;
+		Index 		internalCount;
+		Index*		internalArray; /* content is local indices */
+
+		/* Shadow node tables */
+		Node_LocalIndex*		shadowNodeLocalCount;
+		Node_LocalIndex**		shadowNodeLocalArray;
+		Node_ShadowIndex*		shadowNodeRemoteCount;
+		Node_LocalIndex**		shadowNodeRemoteArray;
+		Coord**				shadowNodeRemoteCoord;
+		Snac_Node**			shadowNodeRemote;
+		Element_LocalIndex*		shadowElementLocalCount;
+		Element_LocalIndex**	shadowElementLocalArray;
+		Element_ShadowIndex*	shadowElementRemoteCount;
+		Element_GlobalIndex**	shadowElementRemoteArray;
+		Snac_Element**			shadowElementRemote;
+	};
+#endif
+
+	/* Print the contents of a mesh */
+	void SnacRemesher_Mesh_Print( void* mesh, Stream* stream );
+	
+
+#endif /* __SnacRemesher_Mesh_h__ */
+

Added: long/3D/SNAC/trunk/Snac/plugins/remesher_BI/Output.c
===================================================================
--- long/3D/SNAC/trunk/Snac/plugins/remesher_BI/Output.c	                        (rev 0)
+++ long/3D/SNAC/trunk/Snac/plugins/remesher_BI/Output.c	2011-10-07 16:18:20 UTC (rev 19040)
@@ -0,0 +1,79 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+**
+** Copyright (C), 2003,
+**	Steve Quenette, 110 Victoria Street, Melbourne, Victoria, 3053, Australia.
+**	Californian Institute of Technology, 1200 East California Boulevard, Pasadena, California, 91125, USA.
+**	University of Texas, 1 University Station, Austin, Texas, 78712, USA.
+**
+** Authors:
+**	Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
+**	Stevan M. Quenette, Visitor in Geophysics, Caltech.
+**	Luc Lavier, Research Scientist, The University of Texas. (luc at utig.ug.utexas.edu)
+**	Luc Lavier, Research Scientist, Caltech.
+**
+** This program is free software; you can redistribute it and/or modify it
+** under the terms of the GNU General Public License as published by the
+** Free Software Foundation; either version 2, or (at your option) any
+** later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+**
+** $Id: Output.c 1095 2004-03-28 00:51:42Z SteveQuenette $
+**
+**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#include <mpi.h>
+#include <StGermain/StGermain.h>
+#include <StGermain/FD/FD.h>
+#include "Snac/Snac.h"
+#include "types.h"
+#include "Output.h"
+#include "Context.h"
+#include "Register.h"
+#include <stdio.h>
+
+void _SnacRemesher_DumpInfo( void* _context ) {
+	Snac_Context*				context = (Snac_Context*) _context;
+	SnacRemesher_Context*		contextExt = ExtensionManager_Get(
+							context->extensionMgr,
+							context,
+							SnacRemesher_ContextHandle );
+	char                    cr[255];
+
+	if( context->rank != 0)
+		return;
+
+	switch( contextExt->condition ) {
+	case SnacRemesher_OnTimeStep:
+		sprintf(cr,"OnTimeStep");
+		break;
+	case SnacRemesher_OnMinLengthScale:
+		sprintf(cr,"OnMinLengthScale");
+		break;
+	case SnacRemesher_OnBothTimeStepLength:
+		sprintf(cr,"OnBothTimeStepLength");
+		break;
+	case SnacRemesher_Off:
+		sprintf(cr,"Off");
+		break;
+	}
+
+	fprintf( contextExt->remesherOut, "%6u: %s %6d %6u %12g %12g %12g %12g\n",
+			 (long unsigned int)contextExt->remeshingCount,
+			 cr,
+			 context->timeStep,
+			 (long unsigned int)contextExt->OnTimeStep,
+			 contextExt->onMinLengthScale,
+			 context->minLengthScale/context->initMinLengthScale,
+			 context->minLengthScale,context->initMinLengthScale);
+	fflush( contextExt->remesherOut );
+
+}
+

Added: long/3D/SNAC/trunk/Snac/plugins/remesher_BI/Output.h
===================================================================
--- long/3D/SNAC/trunk/Snac/plugins/remesher_BI/Output.h	                        (rev 0)
+++ long/3D/SNAC/trunk/Snac/plugins/remesher_BI/Output.h	2011-10-07 16:18:20 UTC (rev 19040)
@@ -0,0 +1,37 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+**
+** Copyright (C), 2003,
+**	Steve Quenette, 110 Victoria Street, Melbourne, Victoria, 3053, Australia.
+**	Californian Institute of Technology, 1200 East California Boulevard, Pasadena, California, 91125, USA.
+**	University of Texas, 1 University Station, Austin, Texas, 78712, USA.
+**
+** Authors:
+**	Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
+**	Stevan M. Quenette, Visitor in Geophysics, Caltech.
+**	Luc Lavier, Research Scientist, The University of Texas. (luc at utig.ug.utexas.edu)
+**	Luc Lavier, Research Scientist, Caltech.
+**
+** This program is free software; you can redistribute it and/or modify it
+** under the terms of the GNU General Public License as published by the
+** Free Software Foundation; either version 2, or (at your option) any
+** later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+**
+** $Id: Output.h 1095 2004-03-28 00:51:42Z SteveQuenette $
+**
+**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#ifndef _SnacRemesher_Output_
+#define _SnacRemesher_Output_
+
+	void _SnacRemesher_DumpInfo( void* _context );
+
+#endif

Added: long/3D/SNAC/trunk/Snac/plugins/remesher_BI/Register.c
===================================================================
--- long/3D/SNAC/trunk/Snac/plugins/remesher_BI/Register.c	                        (rev 0)
+++ long/3D/SNAC/trunk/Snac/plugins/remesher_BI/Register.c	2011-10-07 16:18:20 UTC (rev 19040)
@@ -0,0 +1,145 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+**
+** Copyright (C), 2003,
+**	Steve Quenette, 110 Victoria Street, Melbourne, Victoria, 3053, Australia.
+**	Californian Institute of Technology, 1200 East California Boulevard, Pasadena, California, 91125, USA.
+**	University of Texas, 1 University Station, Austin, Texas, 78712, USA.
+**
+** Authors:
+**	Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
+**	Stevan M. Quenette, Visitor in Geophysics, Caltech.
+**	Luc Lavier, Research Scientist, The University of Texas. (luc at utig.ug.utexas.edu)
+**	Luc Lavier, Research Scientist, Caltech.
+**
+** This program is free software; you can redistribute it and/or modify it
+** under the terms of the GNU General Public License as published by the
+** Free Software Foundation; either version 2, or (at your option) any
+** later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+**
+** $Id: Register.c 3243 2006-10-12 09:04:00Z SteveQuenette $
+**
+**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#include <mpi.h>
+#include <StGermain/StGermain.h>
+#include <StGermain/FD/FD.h>
+#include "Snac/Snac.h"
+#include "types.h"
+#include "EntryPoint.h"
+#include "Context.h"
+#include "Mesh.h"
+#include "ConstructExtensions.h"
+#include "Build.h"
+#include "InitialConditions.h"
+#include "Remesh.h"
+#include "DeleteExtensions.h"
+#include "Register.h"
+#include <stdio.h>
+
+/* Textual name of this class */
+const Type SnacRemesher_Type = "SnacRemesher";
+
+ExtensionInfo_Index SnacRemesher_ContextHandle;
+ExtensionInfo_Index SnacRemesher_MeshHandle;
+
+const Name SnacRemesher_EP_InterpolateNode =		"SnacRemesher_EP_InterpolateNode";
+const Name SnacRemesher_EP_InterpolateElement =		"SnacRemesher_EP_InterpolateElement";
+
+
+Index _SnacRemesher_Register( PluginsManager* pluginsMgr ) {
+	return PluginsManager_Submit( pluginsMgr, 
+				      SnacRemesher_Type, 
+				      "0", 
+				      _SnacRemesher_DefaultNew );
+}
+
+
+void* _SnacRemesher_DefaultNew( Name name ) {
+	return _Codelet_New( sizeof(Codelet), 
+			     SnacRemesher_Type, 
+			     _Codelet_Delete, 
+			     _Codelet_Print, 
+			     _Codelet_Copy, 
+			     _SnacRemesher_DefaultNew, 
+			     _SnacRemesher_Construct, 
+			     _Codelet_Build, 
+			     _Codelet_Initialise, 
+			     _Codelet_Execute, 
+			     _Codelet_Destroy, 
+			     name );
+}
+
+
+void _SnacRemesher_Construct( void* component, Stg_ComponentFactory* cf, void* data ) {
+	Snac_Context*	context;
+
+	/* Retrieve context. */
+	context = (Snac_Context*)Stg_ComponentFactory_ConstructByName( cf, "context", Snac_Context, True, data ); 
+	
+	Journal_Printf( context->debug, "In: %s\n", __func__ );
+
+	/* Add extensions to nodes, elements and the context */
+	SnacRemesher_ContextHandle = ExtensionManager_Add(
+		context->extensionMgr,
+		SnacRemesher_Type,
+		sizeof(SnacRemesher_Context) );
+	SnacRemesher_MeshHandle = ExtensionManager_Add(
+		context->meshExtensionMgr,
+		SnacRemesher_Type,
+		sizeof(SnacRemesher_Mesh) );
+
+	Journal_Printf( context->debug, "\tcontext extension handle: %u\n", SnacRemesher_ContextHandle );
+	Journal_Printf( context->debug, "\tmesh extension handle: %u\n", SnacRemesher_MeshHandle );
+
+	/* Register new entry points to the context (which manages them) */
+	Context_AddEntryPoint(
+		context,
+		SnacRemesher_EntryPoint_New( SnacRemesher_EP_InterpolateNode, SnacRemesher_InterpolateNode_CastType ) );
+	Context_AddEntryPoint(
+		context,
+		SnacRemesher_EntryPoint_New( SnacRemesher_EP_InterpolateElement, SnacRemesher_InterpolateElement_CastType ) );
+
+	/* Add extensions to the entry points */
+	EntryPoint_Append(
+		Context_GetEntryPoint( context, AbstractContext_EP_Build ),
+		SnacRemesher_Type,
+		_SnacRemesher_Build,
+		SnacRemesher_Type );
+	EntryPoint_Append(
+		Context_GetEntryPoint( context, AbstractContext_EP_Initialise ),
+		SnacRemesher_Type,
+		_SnacRemesher_InitialConditions,
+		SnacRemesher_Type );
+	EntryPoint_Append(
+		Context_GetEntryPoint( context, AbstractContext_EP_Sync ),
+		SnacRemesher_Type,
+		_SnacRemesher_Remesh,
+		SnacRemesher_Type );
+	EntryPoint_Append(
+		Context_GetEntryPoint( context, SnacRemesher_EP_InterpolateNode ),
+		SnacRemesher_Type,
+		_SnacRemesher_InterpolateNode,
+		SnacRemesher_Type );
+	EntryPoint_Append(
+		Context_GetEntryPoint( context, SnacRemesher_EP_InterpolateElement ),
+		SnacRemesher_Type,
+		_SnacRemesher_InterpolateElement,
+		SnacRemesher_Type );
+	EntryPoint_Append(
+		Context_GetEntryPoint( context, AbstractContext_EP_DestroyExtensions ),
+		SnacRemesher_Type,
+		_SnacRemesher_DeleteExtensions,
+		SnacRemesher_Type );
+
+	/* Construct. */
+	_SnacRemesher_ConstructExtensions( context, data );
+}

Added: long/3D/SNAC/trunk/Snac/plugins/remesher_BI/Register.h
===================================================================
--- long/3D/SNAC/trunk/Snac/plugins/remesher_BI/Register.h	                        (rev 0)
+++ long/3D/SNAC/trunk/Snac/plugins/remesher_BI/Register.h	2011-10-07 16:18:20 UTC (rev 19040)
@@ -0,0 +1,60 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+**
+** Copyright (C), 2003, 
+**	Steve Quenette, 110 Victoria Street, Melbourne, Victoria, 3053, Australia.
+**	Californian Institute of Technology, 1200 East California Boulevard, Pasadena, California, 91125, USA.
+**	University of Texas, 1 University Station, Austin, Texas, 78712, USA.
+**
+** Authors:
+**	Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
+**	Stevan M. Quenette, Visitor in Geophysics, Caltech.
+**	Luc Lavier, Research Scientist, The University of Texas. (luc at utig.ug.utexas.edu)
+**	Luc Lavier, Research Scientist, Caltech.
+**
+** This program is free software; you can redistribute it and/or modify it
+** under the terms of the GNU General Public License as published by the
+** Free Software Foundation; either version 2, or (at your option) any
+** later version.
+** 
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+** GNU General Public License for more details.
+** 
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+**
+*/
+/** \file
+** Role:
+**
+** Assumptions:
+**
+** Comments:
+**
+** $Id: Register.h 3243 2006-10-12 09:04:00Z SteveQuenette $
+**
+**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#ifndef __SnacRemesher_Register_h__
+#define __SnacRemesher_Register_h__
+	
+	/* Textual name of this class */
+	extern const Type SnacRemesher_Type;
+	
+	/* Handles to extensions for quicker access */
+	extern ExtensionInfo_Index SnacRemesher_ContextHandle;
+	extern ExtensionInfo_Index SnacRemesher_MeshHandle;
+	
+	/* Names to new entry points */
+	extern const Name SnacRemesher_EP_InterpolateNode;
+	extern const Name SnacRemesher_EP_InterpolateElement;
+
+	Index _SnacRemesher_Register( PluginsManager* pluginsMgr );
+
+	void* _SnacRemesher_DefaultNew( Name name );
+
+	void _SnacRemesher_Construct( void* component, Stg_ComponentFactory* cf, void* data );
+	
+#endif /* __SnacRemesher_Register_h__ */

Added: long/3D/SNAC/trunk/Snac/plugins/remesher_BI/Remesh.c
===================================================================
--- long/3D/SNAC/trunk/Snac/plugins/remesher_BI/Remesh.c	                        (rev 0)
+++ long/3D/SNAC/trunk/Snac/plugins/remesher_BI/Remesh.c	2011-10-07 16:18:20 UTC (rev 19040)
@@ -0,0 +1,326 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+**
+** Copyright (C), 2003,
+**	Pururav Thoutireddy,
+**	Californian Institute of Technology, 1200 East California Boulevard, Pasadena, California, 91125, USA.
+**	110 Victoria Street, Melbourne, Victoria, 3053, Australia.
+**	University of Texas, 1 University Station, Austin, Texas, 78712, USA.
+**
+** Authors:
+**	Pururav Thoutireddy, Staff Scientist, Caltech
+**	Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
+**	Stevan M. Quenette, Visitor in Geophysics, Caltech.
+**	Luc Lavier, Research Scientist, The University of Texas. (luc at utig.ug.utexas.edu)
+**	Luc Lavier, Research Scientist, Caltech.
+**
+** This program is free software; you can redistribute it and/or modify it
+** under the terms of the GNU General Public License as published by the
+** Free Software Foundation; either version 2, or (at your option) any
+** later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+**
+** $Id: Remesh.c 3096 2005-07-13 23:51:01Z EunseoChoi $
+**
+**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#include <mpi.h>
+#include <StGermain/StGermain.h>
+#include <StGermain/FD/FD.h>
+#include "Snac/Snac.h"
+#include "types.h"
+#include "Mesh.h"
+#include "Context.h"
+#include "Remesh.h"
+#include "Register.h"
+#include "Utils.h"
+#include "Output.h"
+
+#include <string.h>
+#include <assert.h>
+
+
+void _SnacRemesher_Remesh( void* _context, void* data ) {
+	Snac_Context*				context = (Snac_Context*)_context;
+	SnacRemesher_Context*			contextExt = ExtensionManager_Get(
+							context->extensionMgr,
+							context,
+							SnacRemesher_ContextHandle );
+	Bool 					remesh;
+
+	Journal_DPrintf( context->debug, "In: %s\n", __func__ );
+
+	switch( contextExt->condition ) {
+		case SnacRemesher_OnTimeStep:
+			/* Remeshing on multiples of "OnTimeStep", but don't remesh on loop 0. */
+			Journal_Firewall( contextExt->OnTimeStep, context->snacError, 
+					  "Invalid remesh timestep criterion." );
+			remesh = (context->timeStep <= 1) ? False : 
+				(context->timeStep % contextExt->OnTimeStep == 0) ? True : False;
+			break;
+
+		case SnacRemesher_OnMinLengthScale:
+			remesh = (context->minLengthScale/context->initMinLengthScale < 
+				  contextExt->onMinLengthScale) ? True : False;
+			break;
+
+		case SnacRemesher_OnBothTimeStepLength:
+			Journal_Firewall( contextExt->OnTimeStep, context->snacError, 
+					  "Invalid remesh timestep criterion." );
+			remesh = (context->timeStep <= 1) ? False : 
+			  (context->timeStep % contextExt->OnTimeStep == 0) ? True : False;
+			remesh = remesh ? True : (context->minLengthScale/context->initMinLengthScale < 
+						  contextExt->onMinLengthScale) ? True : False;
+			break;
+
+		case SnacRemesher_Off:
+		default:
+			remesh = False;
+			break;
+	}
+
+	if( remesh ) {
+		Mesh*					mesh = context->mesh;
+		SnacRemesher_Mesh*			meshExt = ExtensionManager_Get(
+								context->meshExtensionMgr,
+								mesh,
+								SnacRemesher_MeshHandle );
+		Node_LocalIndex		newNode_i;
+
+		Journal_Printf( context->snacInfo, "Remeshing!\n" );
+		
+		/*
+		** If spherical coordinates are being used, 
+		** then we'll need to convert the current mesh's cartesian coordinates 
+		** to spherical coordinates first.
+		*/
+		
+		if( meshExt->meshType == SnacRemesher_Spherical ) {
+			Node_LocalIndex	lNode_i;
+			
+			for( lNode_i = 0; lNode_i < mesh->nodeLocalCount; lNode_i++ ) {
+				double	x = mesh->nodeCoord[lNode_i][0];
+				double	y = mesh->nodeCoord[lNode_i][1];
+				double	z = mesh->nodeCoord[lNode_i][2];
+				
+				mesh->nodeCoord[lNode_i][0] = SnacArcTan( y, x );
+				mesh->nodeCoord[lNode_i][1] = sqrt( x * x + y * y + z * z );
+				mesh->nodeCoord[lNode_i][2] = acos( z / meshExt->newNodeCoords[lNode_i][1] );
+			}
+		}
+		
+		/* Sync the mesh. */
+		if( mesh->layout->decomp->procsInUse > 1 ) {
+			Mesh_Sync( mesh );
+		}
+		
+		/* Remesh the coordinates. */
+		_SnacRemesher_NewCoords( context );
+		
+		/* Interpolate current nodal values onto new coordinates. */
+		meshExt->newNodes = (Snac_Node*)ExtensionManager_Malloc( mesh->nodeExtensionMgr, mesh->nodeLocalCount );
+		_SnacRemesher_InterpolateNodes( context );
+
+		/* Don't forget the residualFr/Ft: This simple copy works because bottoms nodes are always bottom and remeshing doesn't change the node number. */
+		for( newNode_i = 0; newNode_i < mesh->nodeLocalCount; newNode_i++ ) {
+			Snac_Node* dstNode = 
+				(Snac_Node*)ExtensionManager_At( context->mesh->nodeExtensionMgr,
+												 meshExt->newNodes,
+												 newNode_i );
+
+			Snac_Node* srcNode = 
+				Snac_Node_At( context, newNode_i );
+
+			dstNode->residualFr = srcNode->residualFr;
+			dstNode->residualFt = srcNode->residualFt;
+		}
+		
+		/* Interpolate current elemental values onto new coordinates. */
+		meshExt->oldBarycenters = Memory_Alloc_Array( Coord, mesh->elementDomainCount, "SnacRemesher" );
+		meshExt->newBarycenters = Memory_Alloc_Array( Coord, mesh->elementLocalCount, "SnacRemesher" );
+		meshExt->barcoef =  Memory_Alloc_Array( SnacRemesher_ElementBarcoef, mesh->elementDomainCount, "SnacRemesher" );
+		meshExt->barcord =  Memory_Alloc_Array( SnacRemesher_ElementBarcord, mesh->elementLocalCount, "SnacRemesher" );
+		meshExt->newElements = (Snac_Element*)ExtensionManager_Malloc( mesh->elementExtensionMgr, mesh->elementLocalCount );
+
+		/* Do the linear interpolation between grids of barycenters. */
+		_SnacRemesher_InterpolateElements( context );
+
+		/* Copy accross the new coord, node & element information to the current arrays. */
+		memcpy( mesh->nodeCoord, meshExt->newNodeCoords, mesh->nodeLocalCount * sizeof(Coord) );
+		memcpy( mesh->node, meshExt->newNodes, mesh->nodeExtensionMgr->finalSize * mesh->nodeLocalCount );
+		memcpy( mesh->element, meshExt->newElements, mesh->elementExtensionMgr->finalSize * mesh->elementLocalCount );
+		
+		/* Update element attributes based on the new coordinates and the transferred variables. */
+		_SnacRemesher_UpdateElements( context );
+		
+		/* Free some space, as it won't be needed until the next remesh. */
+		Memory_Free( meshExt->oldBarycenters );
+		Memory_Free( meshExt->newBarycenters ); 
+		Memory_Free( meshExt->barcoef );
+		Memory_Free( meshExt->barcoef );
+		ExtensionManager_Free( mesh->nodeExtensionMgr, meshExt->newNodes );
+		ExtensionManager_Free( mesh->elementExtensionMgr, meshExt->newElements );
+		meshExt->newNodes = NULL;
+		meshExt->newElements = NULL;
+		
+		/*
+		** If in spherical mode, convert back to cartesian coordinates.
+		*/
+		
+		if( meshExt->meshType == SnacRemesher_Spherical ) {
+			unsigned	lNode_i;
+			
+			for( lNode_i = 0; lNode_i < mesh->nodeLocalCount; lNode_i++ ) {
+				double	theta = mesh->nodeCoord[lNode_i][0];
+				double	r = mesh->nodeCoord[lNode_i][1];
+				double	phi = mesh->nodeCoord[lNode_i][2];
+				
+				mesh->nodeCoord[lNode_i][0] = r * sin( phi ) * cos( theta );
+				mesh->nodeCoord[lNode_i][1] = r * sin( phi ) * sin( theta );
+				mesh->nodeCoord[lNode_i][2] = r * cos( phi );
+			}
+		}
+		
+		/* Sync the mesh. */
+		if( mesh->layout->decomp->procsInUse > 1 ) {
+			Mesh_Sync( mesh );
+		}
+		
+		/* dump info such as remeshing frequency, criterion, and the current time step */
+		contextExt->remeshingCount++;
+		_SnacRemesher_DumpInfo( context );
+	}
+}
+
+#if 0
+void _SnacRemesher_Sync( void* _context ) {
+	Snac_Context*				context = (Snac_Context*)_context;
+	Mesh*					mesh = context->mesh;
+	SnacRemesher_Mesh*			meshExt = ExtensionManager_Get(
+							context->meshExtensionMgr,
+							mesh,
+							SnacRemesher_MeshHandle );
+	Partition_Index				i;
+
+	SnacRemesher_Context*			contextExt = ExtensionManager_Get(
+							context->extensionMgr,
+							context,
+							SnacRemesher_ContextHandle );
+
+	Journal_DPrintf( context->debug, "In: %s\n", __func__ );
+
+	/* Pack (local) shadows required to send to neighbour and send them, for each neighbour */
+	Journal_DPrintf( contextExt->debugSync, "Top nodes shadow syncing starting.\n" );
+	for( i = 0; i < meshExt->neighbourRankCount; i++ ) {
+		Node_ShadowIndex			nCount = meshExt->shadowNodeLocalCount[i];
+		Element_ShadowIndex			eCount = meshExt->shadowElementLocalCount[i];
+		Node_ShadowIndex			node_sI;
+		Element_ShadowIndex			element_sI;
+		Coord					coordLocal[nCount];
+		Snac_Node*				nodeLocal = (Snac_Node*)ExtensionManager_Malloc( mesh->nodeExtensionMgr, nCount );
+
+		Journal_DPrintf( contextExt->debugSync, "Sending node %u coordinates to rank: %u; {", nCount, meshExt->neighbourRank[i] );
+		for( node_sI = 0; node_sI < nCount; node_sI++ ) {
+			coordLocal[node_sI][0] = mesh->nodeCoord[meshExt->shadowNodeLocalArray[i][node_sI]][0];
+			coordLocal[node_sI][1] = mesh->nodeCoord[meshExt->shadowNodeLocalArray[i][node_sI]][1];
+			coordLocal[node_sI][2] = mesh->nodeCoord[meshExt->shadowNodeLocalArray[i][node_sI]][2];
+			Journal_DPrintf( contextExt->debugSync, "{ %g, %g, %g }, ", coordLocal[node_sI][0], coordLocal[node_sI][1], coordLocal[node_sI][2] );
+		}
+		Journal_DPrintf( contextExt->debugSync, "}\n" );
+
+		MPI_Send(
+			coordLocal,
+			nCount * 3,
+			MPI_DOUBLE,
+			meshExt->neighbourRank[i],
+			0,
+			context->communicator );
+
+		Journal_DPrintf( contextExt->debugSync, "Sending node %u to rank: %u\n", nCount, meshExt->neighbourRank[i] );
+		for( node_sI = 0; node_sI < nCount; node_sI++ ) {
+			memcpy(
+				ExtensionManager_At( mesh->nodeExtensionMgr, nodeLocal, node_sI ),
+				Mesh_NodeAt( mesh, meshExt->shadowNodeLocalArray[i][node_sI] ),
+				mesh->nodeExtensionMgr->finalSize );
+		}
+
+		MPI_Send(
+			nodeLocal,
+			nCount * mesh->nodeExtensionMgr->finalSize,
+			MPI_CHAR,
+			meshExt->neighbourRank[i],
+			1668,
+			context->communicator );
+
+		Journal_DPrintf( contextExt->debugSync, "Sending element %u to rank: %u\n", eCount, meshExt->neighbourRank[i] );
+		for( element_sI = 0; element_sI < eCount; element_sI++ ) {
+			MPI_Send(
+				Mesh_ElementAt( mesh, meshExt->shadowElementLocalArray[i][element_sI] ),
+				mesh->elementExtensionMgr->finalSize,
+				MPI_CHAR,
+				meshExt->neighbourRank[i],
+				1669+element_sI,
+				context->communicator );
+		}
+
+		ExtensionManager_Free( mesh->nodeExtensionMgr, nodeLocal );
+	}
+
+	/* Receive the associated shadows from each neighbour */
+	for( i = 0; i < meshExt->neighbourRankCount; i++ ) {
+		MPI_Status				status;
+		Node_ShadowIndex			nCount = meshExt->shadowNodeRemoteCount[i];
+		Element_ShadowIndex			eCount = meshExt->shadowElementRemoteCount[i];
+		Node_ShadowIndex			node_sI;
+		Element_ShadowIndex			element_sI;
+
+		MPI_Recv(
+			meshExt->shadowNodeRemoteCoord[i],
+			nCount * 3,
+			MPI_DOUBLE,
+			meshExt->neighbourRank[i],
+			0,
+			context->communicator,
+			&status );
+		Journal_DPrintf( contextExt->debugSync, "Received node %u coordinates from rank: %u; {", nCount, meshExt->neighbourRank[i] );
+		for( node_sI = 0; node_sI < nCount; node_sI++ ) {
+			Journal_DPrintf( contextExt->debugSync,
+				"{ %g, %g, %g }, ",
+				meshExt->shadowNodeRemoteCoord[i][node_sI][0],
+				meshExt->shadowNodeRemoteCoord[i][node_sI][1],
+				meshExt->shadowNodeRemoteCoord[i][node_sI][2] );
+		}
+		Journal_DPrintf( contextExt->debugSync, "}\n" );
+
+		MPI_Recv(
+			meshExt->shadowNodeRemote[i],
+			nCount * mesh->nodeExtensionMgr->finalSize,
+			MPI_CHAR,
+			meshExt->neighbourRank[i],
+			1668,
+			context->communicator,
+			&status );
+		Journal_DPrintf( contextExt->debugSync, "Received node %u from rank: %u\n", nCount, meshExt->neighbourRank[i] );
+
+		for( element_sI = 0; element_sI < eCount; element_sI++ ) {
+			MPI_Recv(
+				ExtensionManager_At( mesh->elementExtensionMgr, meshExt->shadowElementRemote[i], element_sI ),
+				mesh->elementExtensionMgr->finalSize,
+				MPI_CHAR,
+				meshExt->neighbourRank[i],
+				1669+element_sI,
+				context->communicator,
+				&status );
+		}
+		Journal_DPrintf( contextExt->debugSync, "Received element %u from rank: %u\n", eCount, meshExt->neighbourRank[i] );
+	}
+	Journal_DPrintf( contextExt->debugSync, "Top nodes shadow syncing done.\n" );
+}
+#endif

Added: long/3D/SNAC/trunk/Snac/plugins/remesher_BI/Remesh.h
===================================================================
--- long/3D/SNAC/trunk/Snac/plugins/remesher_BI/Remesh.h	                        (rev 0)
+++ long/3D/SNAC/trunk/Snac/plugins/remesher_BI/Remesh.h	2011-10-07 16:18:20 UTC (rev 19040)
@@ -0,0 +1,65 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+**
+** Copyright (C), 2003,
+**	Steve Quenette, 110 Victoria Street, Melbourne, Victoria, 3053, Australia.
+**	Californian Institute of Technology, 1200 East California Boulevard, Pasadena, California, 91125, USA.
+**	University of Texas, 1 University Station, Austin, Texas, 78712, USA.
+**
+** Authors:
+**	Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
+**	Stevan M. Quenette, Visitor in Geophysics, Caltech.
+**	Luc Lavier, Research Scientist, The University of Texas. (luc at utig.ug.utexas.edu)
+**	Luc Lavier, Research Scientist, Caltech.
+**
+** This program is free software; you can redistribute it and/or modify it
+** under the terms of the GNU General Public License as published by the
+** Free Software Foundation; either version 2, or (at your option) any
+** later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+**
+*/
+/** \file
+** Role:
+**
+** Assumptions:
+**
+** Comments:
+**
+** $Id: Remesh.h 3250 2006-10-23 06:15:18Z LukeHodkinson $
+**
+**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#ifndef __SnacRemesher_Remesh_h__
+#define __SnacRemesher_Remesh_h__
+
+	void _SnacRemesher_Remesh( void* _context, void* data );
+
+/*	void _SnacRemesher_Sync( void* _context ); */
+	void _SnacRemesher_NewCoords( void* _context );
+
+	void _SnacRemesher_InterpolateNodes( void* _context );
+	void _SnacRemesher_InterpolateNode( void* context,
+					    unsigned nodeInd, unsigned elementInd, unsigned tetInd, 
+					    unsigned* tetNodeInds, double* weights, 
+					    Snac_Node* dstNodes );
+
+	void _SnacRemesher_InterpolateElements( void* context );
+	void _SnacRemesher_UpdateElements( void* context );
+	void _SnacRemesher_InterpolateElement(
+		void*			_context,
+		Element_LocalIndex	dstEltInd, 
+		Tetrahedra_Index	dstTetInd, 
+		Snac_Element*		dstEltArray, 
+		Element_DomainIndex	srcEltInd, 
+		Tetrahedra_Index	srcTetInd );
+
+
+#endif /* __SnacRemesher_Remesh_h__ */

Added: long/3D/SNAC/trunk/Snac/plugins/remesher_BI/RemeshCoords.c
===================================================================
--- long/3D/SNAC/trunk/Snac/plugins/remesher_BI/RemeshCoords.c	                        (rev 0)
+++ long/3D/SNAC/trunk/Snac/plugins/remesher_BI/RemeshCoords.c	2011-10-07 16:18:20 UTC (rev 19040)
@@ -0,0 +1,2131 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+**
+** Copyright (C), 2003,
+**	Pururav Thoutireddy,
+**	Californian Institute of Technology, 1200 East California Boulevard, Pasadena, California, 91125, USA.
+**	110 Victoria Street, Melbourne, Victoria, 3053, Australia.
+**	University of Texas, 1 University Station, Austin, Texas, 78712, USA.
+**
+** Authors:
+**	Pururav Thoutireddy, Staff Scientist, Caltech
+**	Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
+**	Stevan M. Quenette, Visitor in Geophysics, Caltech.
+**	Luc Lavier, Research Scientist, The University of Texas. (luc at utig.ug.utexas.edu)
+**	Luc Lavier, Research Scientist, Caltech.
+**
+** This program is free software; you can redistribute it and/or modify it
+** under the terms of the GNU General Public License as published by the
+** Free Software Foundation; either version 2, or (at your option) any
+** later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+**
+** $Id: RemeshCoords.c 3173 2005-11-21 23:47:09Z LukeHodkinson $
+**
+**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#include <mpi.h>
+#include <StGermain/StGermain.h>
+#include <StGermain/FD/FD.h>
+#include "Snac/Snac.h"
+#include "types.h"
+#include "Mesh.h"
+#include "Context.h"
+#include "Remesh.h"
+#include "Register.h"
+
+#include <math.h>
+#include <assert.h>
+#include <string.h>
+#include <float.h>
+
+
+void _SnacRemesher_NewCoords( void* _context ) {
+	Snac_Context*			context = (Snac_Context*)_context;
+	SnacRemesher_Context*	contextExt = ExtensionManager_Get(
+							context->extensionMgr,
+							context,
+							SnacRemesher_ContextHandle );
+	Mesh*				mesh = context->mesh;
+	SnacRemesher_Mesh*		meshExt = ExtensionManager_Get(
+							context->meshExtensionMgr,
+							mesh,
+							SnacRemesher_MeshHandle );
+	HexaMD*				decomp = (HexaMD*)mesh->layout->decomp;
+
+	void _SnacRemesher_RemapSurface( void*				_context,
+							   unsigned			nSurfNodes,
+							   Node_LocalIndex*		surfNodeMap,
+							   unsigned			nTris,
+							   Node_DomainIndex*	triNodeMap );
+
+
+	/*
+	** This rewrite is based on the following assumptions:
+	**	1. Only the top and bottom internal nodes are free, the rest will be restored to their initial positions.
+	**	2. ... that's it for now.
+	*/
+
+
+	/*
+	** The left, right, front and back wall nodes will already be stored.  Also, the x and z components of the bulk,
+	** top and bottom nodes will also be pre-calculated.  So all that remains is to calculate the y components.
+	*/
+
+
+	/*
+	** Performing a bottom surface remap is only necessary if bottomRestore is false.  This is because the newNodeCoords
+	** array in meshExt will already have the correct bottom values in there by default.
+	*/
+
+	if( contextExt->bottomRestore == False ) {
+		_SnacRemesher_RemapSurface( context,
+							   meshExt->nBotInternNodes,
+							   meshExt->botInternToLocal,
+							   meshExt->nBotTriNodes,
+							   meshExt->botTriToDomain );
+	}
+
+
+	/*
+	** Remap the top surface.
+	*/
+
+	_SnacRemesher_RemapSurface( context,
+						   meshExt->nTopInternNodes,
+						   meshExt->topInternToLocal,
+						   meshExt->nTopTriNodes,
+						   meshExt->topTriToDomain );
+
+
+	/*
+	** The bulk of the mesh requires some communication, it needs to know both the terminals of
+	** the y-axis for each y-oriented line.
+	*/
+
+	{
+		double*	remoteYCoords;
+		SnacSync*	sync = meshExt->sync;
+		unsigned	yLine_i;
+
+		/* Prepare an array to receive any y coords we need. */
+		if( sync->netSource > 0 ) {
+			remoteYCoords = Memory_Alloc_Array( double, sync->netSource, "SnacRemesher" );
+		}
+		else {
+			remoteYCoords = NULL;
+		}
+
+		/* Send and receive. */
+		SnacSync_SendRecv( sync,
+				   &meshExt->newNodeCoords[0][1],
+				   remoteYCoords );
+
+		/* Now that we have any required remote y coords, interpolate the local bulk nodes. */
+		for( yLine_i = 0; yLine_i < meshExt->nYLines; yLine_i++ ) {
+			double	top;
+			double	bot;
+			double	h;
+			unsigned	ylNode_i;
+
+			/* Find the top coordinate. */
+			if( meshExt->yLineUTerm[yLine_i] < mesh->nodeLocalCount ) {
+				Node_LocalIndex	lNodeInd = meshExt->yLineUTerm[yLine_i];
+
+				top = meshExt->newNodeCoords[lNodeInd][1];
+			}
+			else {
+				unsigned	remInd = meshExt->yLineUTerm[yLine_i] - mesh->nodeLocalCount;
+
+				top = remoteYCoords[remInd];
+			}
+
+			/* Find the bottom coordinate. */
+			if( meshExt->yLineLTerm[yLine_i] < mesh->nodeLocalCount ) {
+				Node_LocalIndex	lNodeInd = meshExt->yLineLTerm[yLine_i];
+
+				bot = meshExt->newNodeCoords[lNodeInd][1];
+			}
+			else {
+				unsigned	remInd = meshExt->yLineLTerm[yLine_i] - mesh->nodeLocalCount;
+
+				bot = remoteYCoords[remInd];
+			}
+
+			/* Calculate the interval. */
+			h = (top - bot) / (double)(decomp->nodeGlobal3DCounts[1] - 1);
+
+			/* Interpolate all the local nodes in this y-line. */
+			for( ylNode_i = 0; ylNode_i < meshExt->yLineNYInds[yLine_i]; ylNode_i++ ) {
+				Node_LocalIndex	lNodeInd = meshExt->yLineLocalInds[yLine_i][ylNode_i];
+				unsigned			yInd = meshExt->yLineYInds[yLine_i][ylNode_i];
+
+				meshExt->newNodeCoords[lNodeInd][1] = bot + h * (double)yInd;
+			}
+		}
+
+		/* Free up resources. */
+		FreeArray( remoteYCoords );
+	}
+}
+
+
+void _SnacRemesher_RemapSurface( void*				_context,
+						   unsigned			nSurfNodes,
+						   Node_LocalIndex*		surfNodeMap,
+						   unsigned			nTriNodes,
+						   Node_DomainIndex*	triNodeMap )
+{
+	Snac_Context*			context = (Snac_Context*)_context;
+	Mesh*				mesh = context->mesh;
+	SnacRemesher_Mesh*		meshExt = ExtensionManager_Get(
+							context->meshExtensionMgr,
+							mesh,
+							SnacRemesher_MeshHandle );
+	unsigned				surfNode_i;
+
+	Bool _SnacRemesher_PointInTri( Coord pnt, Coord a, Coord b, Coord c );
+	void _SnacRemesher_TriBarycenter( Coord tri[3], Coord pnt, Coord dst );
+
+
+	if( nSurfNodes == 0 ) {
+		return;
+	}
+
+
+	/*
+	** Loop over the nodes to be mapped (nodeInds) and determine which surface element of the old
+	** mesh it falls in.  Then, interpolate the position there using barycentric coordinates.
+	*/
+
+	for( surfNode_i = 0; surfNode_i < nSurfNodes; surfNode_i++ ) {
+		Node_LocalIndex	lNodeInd = surfNodeMap[surfNode_i];
+		Coord			newCoord;
+		unsigned			triNode_i;
+
+		/* Grab the new x and z coords. */
+		newCoord[0] = meshExt->newNodeCoords[lNodeInd][0];
+		newCoord[1] = 0.0;
+		newCoord[2] = meshExt->newNodeCoords[lNodeInd][2];
+
+		/* Find the triangle it's in and interpolate. */
+		for( triNode_i = 0; triNode_i < nTriNodes; triNode_i += 3 ) {
+			Coord	tri[3];
+
+			/* Collect the coords of the tri and clear the y component. */
+			Vector_Set( tri[0], mesh->nodeCoord[triNodeMap[triNode_i + 0]] );
+			tri[0][1] = 0.0;
+			Vector_Set( tri[1], mesh->nodeCoord[triNodeMap[triNode_i + 1]] );
+			tri[1][1] = 0.0;
+			Vector_Set( tri[2], mesh->nodeCoord[triNodeMap[triNode_i + 2]] );
+			tri[2][1] = 0.0;
+
+			if( _SnacRemesher_PointInTri( newCoord, tri[0], tri[1], tri[2] ) == True ) {
+				Coord	center;
+
+				/* Calculate the barycentric coords of the new point in the triangle, then
+				   interpolate. */
+				_SnacRemesher_TriBarycenter( tri, newCoord, center );
+				newCoord[1] = center[0] * mesh->nodeCoord[triNodeMap[triNode_i + 0]][1] +
+						    center[1] * mesh->nodeCoord[triNodeMap[triNode_i + 1]][1] +
+						    center[2] * mesh->nodeCoord[triNodeMap[triNode_i + 2]][1];
+
+				/* Update the y-axis of the new node coords. */
+				meshExt->newNodeCoords[lNodeInd][1] = newCoord[1];
+
+				break;
+			}
+		}
+
+		/* Note that if the new coord couldn't be projected onto the triangulated surface (the mesh has either
+		   contracted too far, drifted too far or there is not enough shadow depth), then the current y coord will
+		   be left as is. */
+	}
+}
+
+
+/*
+** Two functions for determining whether a point is inside a triangle.  Probably not the fastest
+** way of doing this but it is independant of triangle winding so can be used without a whole lot
+** of extra consideration.  Additionally, it may be better to use a 'winding' style solution so that
+** if the surface to be projected onto has folded then we can know if we are projecting onto an
+** unreachable triangle.
+*/
+
+Bool _SnacRemesher_PointInTri( Coord pnt, Coord a, Coord b, Coord c ) {
+	Bool _SnacRemesher_SameSide( Coord pnt, Coord ref, Coord from, Coord to );
+
+	if( _SnacRemesher_SameSide( pnt, a, b, c ) &&
+	    _SnacRemesher_SameSide( pnt, b, a, c ) &&
+	    _SnacRemesher_SameSide( pnt, c, a, b ) )
+	{
+		return True;
+	}
+	else {
+		return False;
+	}
+}
+
+
+Bool _SnacRemesher_SameSide( Coord pnt, Coord ref, Coord from, Coord to ) {
+	Coord	line;
+	Coord	cp[2];
+
+	Vector_Sub( line, to, from );
+	Vector_Sub( cp[0], pnt, from );
+	Vector_Sub( cp[1], ref, from );
+	Vector_Cross( cp[0], line, cp[0] );
+	Vector_Cross( cp[1], line, cp[1] );
+
+	return (Vector_Dot( cp[0], cp[1] ) >= -1.0e-16) ? True : False;
+}
+
+
+/*
+** Calculates the barycenter of a triangle with respect to some point.
+*/
+
+void _SnacRemesher_TriBarycenter( Coord tri[3], Coord pnt, Coord dst ) {
+	double	a = tri[0][0] - tri[2][0];
+	double	b = tri[1][0] - tri[2][0];
+	double	c = tri[2][0] - pnt[0];
+	double	d = tri[0][1] - tri[2][1];
+	double	e = tri[1][1] - tri[2][1];
+	double	f = tri[2][1] - pnt[1];
+	double	g = tri[0][2] - tri[2][2];
+	double	h = tri[1][2] - tri[2][2];
+	double	i = tri[2][2] - pnt[2];
+
+	dst[0] = (b * (f + i) - c * (e + h)) / (a * (e + h) - b * (d + g));
+	dst[1] = (a * (f + i) - c * (d + g)) / (b * (d + g) - a * (e + h));
+	dst[2] = 1.0 - dst[0] - dst[1];
+}
+
+
+
+
+
+
+
+#if 0
+/*
+** Removed but not deleted while rewriting the whole damn thing.
+**	Luke, 31/06/2005
+*/
+
+
+
+#define DIM 3
+#define NODES_PER_ELEMENT 8
+
+#ifndef MAX
+	#define MAX(a,b) ((a) > (b) ? (a) : (b))
+#endif
+#ifndef MIN
+	#define MIN(a,b) ((a) < (b) ? (a) : (b))
+#endif
+
+double isLargerThanZero( double, double );
+double isLargerThanZero2( double, double, double );
+double getSignedArea( Coord );
+void xyz2tprCoord( Coord, Coord* );
+void tpr2xyzCoord( Coord, Coord* );
+void xyz2tprVel( Coord, Coord, Coord* );
+void tpr2xyzVel( Coord, Coord, Coord* );
+
+
+
+void _SnacRemesher_NewCoords_Cartesian( void* _context ) {
+	Snac_Context*			context = (Snac_Context*)_context;
+	SnacRemesher_Context*			contextExt = ExtensionManager_Get(
+                                                                      context->extensionMgr,
+                                                                      context,
+                                                                      SnacRemesher_ContextHandle );
+	Mesh*				mesh = context->mesh;
+	SnacRemesher_Mesh*		meshExt = ExtensionManager_Get(
+                                                           context->meshExtensionMgr,
+                                                           mesh,
+                                                           SnacRemesher_MeshHandle );
+	HexaMD*				decomp = (HexaMD*)mesh->layout->decomp;
+	Node_LocalIndex			index;
+	int*				ind;
+	Index				d;
+	Element_LocalIndex      element_lK,element_lI,element_lN;
+	Node_LocalIndex         node_lK,node_lI,node_lII,node_lN;
+	Element_LocalIndex		nElementX=decomp->elementLocal3DCounts[decomp->rank][0];
+	Element_LocalIndex		nElementY=decomp->elementLocal3DCounts[decomp->rank][1];
+	Element_LocalIndex		nElementZ=decomp->elementLocal3DCounts[decomp->rank][2];
+	Node_LocalIndex		    nNodeX=decomp->nodeLocal3DCounts[decomp->rank][0];
+	Node_LocalIndex		    nNodeY=decomp->nodeLocal3DCounts[decomp->rank][1];
+	Node_LocalIndex		    nNodeZ=decomp->nodeLocal3DCounts[decomp->rank][2];
+	Element_NodeIndex		elementNodeCount;
+	double				xc[DIM*NODES_PER_ELEMENT];
+	PartitionIndex			rn_I;
+	int                             count;
+	int			        en_II[4] = { 3, 2, 6, 7};
+	int			        nn[2][3] = { {3, 7, 2}, {2, 7, 6} };
+	unsigned int                       All_passed = 0;
+	double                             TOL = 0.0f;
+    const int                          shadowDepth = ( decomp->shadowDepth > 3) ? decomp->shadowDepth : 3;
+	const int                          numSearchElement = 2*shadowDepth-1;
+	const int                          numSearchDepth = shadowDepth-1;
+
+	Journal_DPrintf( context->debug, "In: %s\n", __func__ );
+
+	ind = (int*)malloc( sizeof(int) * nNodeX * nNodeZ );
+	memset( ind, 0, sizeof(int) * nNodeX * nNodeZ );
+
+	while(!All_passed) {
+		/* Calculate the new node coordintates for the top-internal nodes. */
+		for( node_lK = 0; node_lK < nNodeZ; node_lK++ )
+			for( node_lII = 0; node_lII < nNodeX; node_lII++ ) {
+				Element_NodeIndex		en_N;
+				double				elembbox[2][DIM];
+				Node_LocalIndex**		elementNodeTbl = context->mesh->elementNodeTbl;
+				Tetrahedra_Index		tetra_I;
+				Coord				initialNodeCoord;
+				Element_LocalIndex      searchElement_lI,searchElement_lK;
+				IJK                             ijk;
+
+				node_lI = node_lII + (nNodeY-1)*nNodeX + node_lK*nNodeX*nNodeY;
+				RegularMeshUtils_Node_Local1DTo3D( decomp, node_lI, &ijk[0], &ijk[1], &ijk[2] );
+				element_lI = (ijk[0] <= 1)? 0 : (ijk[0]-1);
+				element_lK = (ijk[2] <= 1)? 0 : (ijk[2]-1);
+
+				if( ind[ijk[0]+ijk[2]*nNodeX] ) {
+					continue;
+				}
+
+				initialNodeCoord[0] = meshExt->initialNodeCoord[node_lI][0];
+				initialNodeCoord[1] = 0.0f;
+				initialNodeCoord[2] = meshExt->initialNodeCoord[node_lI][2];
+
+				for(searchElement_lK=0;searchElement_lK<numSearchElement;searchElement_lK++) {
+					if( (element_lK+searchElement_lK-numSearchDepth) < 0 || (element_lK+searchElement_lK-numSearchDepth) >= nElementZ )
+						continue;
+					for(searchElement_lI=0;searchElement_lI<numSearchElement;searchElement_lI++) {
+						if( (element_lI+searchElement_lI-numSearchDepth) < 0 || (element_lI+searchElement_lI-numSearchDepth) >= nElementX )
+							continue;
+						element_lN = (element_lI+searchElement_lI-numSearchDepth) + (nElementY-1)*nElementX +
+							(element_lK+searchElement_lK-numSearchDepth)*nElementY*nElementX;
+
+						elementNodeCount = context->mesh->elementNodeCountTbl[element_lN];
+						if( elementNodeCount != (unsigned)NODES_PER_ELEMENT ) {
+							printf( "elementNodeCount != NODES_PER_ELEMENT  element_lN = %d", element_lN );
+							assert( 0 );
+						}
+
+						if( ind[ijk[0]+ijk[2]*nNodeX] )
+							break;
+
+						/* create a local copy of the veocity and coords for each of the element's nodes of the old mesh */
+						for( en_N = 0; en_N < 4; en_N++) {
+							node_lN = elementNodeTbl[element_lN][en_II[en_N]];
+							for( d = 0; d < DIM; d++ ) {
+								xc[en_II[en_N]*DIM+d] = Mesh_CoordAt( context->mesh, node_lN )[d];
+							}
+						}
+
+						/* Calculate element's bounding box */
+						for( d = 0; d < DIM; d++ ) {
+							elembbox[0][d] = DBL_MAX;
+							elembbox[1][d] = DBL_MIN;
+						}
+						for( en_N = 0; en_N < 4; en_N++ ) {
+							for( d = 0; d < DIM; ++d ) {
+								elembbox[0][d] = MIN( elembbox[0][d], xc[en_II[en_N]*DIM+d] );
+								elembbox[1][d] = MAX( elembbox[1][d], xc[en_II[en_N]*DIM+d] );
+							}
+						}
+
+						/* If new mesh's current node is outside the bounding box, next loop */
+						if( initialNodeCoord[0] < elembbox[0][0]-0.5f*(elembbox[1][0]-elembbox[0][0]) ||
+							initialNodeCoord[0] > elembbox[1][0]+0.5f*(elembbox[1][0]-elembbox[0][0]) ||
+							initialNodeCoord[2] < elembbox[0][2]-0.5f*(elembbox[1][2]-elembbox[0][2]) ||
+							initialNodeCoord[2] > elembbox[1][2]+0.5f*(elembbox[1][2]-elembbox[0][2]) )
+							{
+								//assert(0);
+								continue;
+							}
+						/* if the current coord is very close to the initial ones, just copy those initial values rather than bothering to compute determinents and adding error */
+						if( ( meshExt->initialNodeCoord[node_lI][0] >= mesh->nodeCoord[node_lI][0] - TOL*(elembbox[1][0]-elembbox[0][0]) && meshExt->initialNodeCoord[node_lI][0] <= mesh->nodeCoord[node_lI][0] + TOL*(elembbox[1][0]-elembbox[0][0]) ) &&
+							( meshExt->initialNodeCoord[node_lI][1] >= mesh->nodeCoord[node_lI][1] - TOL*(elembbox[1][1]-elembbox[0][1]) && meshExt->initialNodeCoord[node_lI][1] <= mesh->nodeCoord[node_lI][1] + TOL*(elembbox[1][1]-elembbox[0][1]) ) &&
+							( meshExt->initialNodeCoord[node_lI][2] >= mesh->nodeCoord[node_lI][2] - TOL*(elembbox[1][2]-elembbox[0][2]) && meshExt->initialNodeCoord[node_lI][2] <= mesh->nodeCoord[node_lI][2] + TOL*(elembbox[1][2]-elembbox[0][2]) ) ) {
+							meshExt->newNodeCoord[node_lI][0] = meshExt->initialNodeCoord[node_lI][0];
+							meshExt->newNodeCoord[node_lI][1] = Mesh_CoordAt( context->mesh, node_lI )[1];
+							meshExt->newNodeCoord[node_lI][2] = meshExt->initialNodeCoord[node_lI][2];
+							ind[ijk[0]+ijk[2]*nNodeX] = 1;
+							continue;
+						}
+
+						/* if the current coordinate is far enough from the initial position,
+						   try to interpolate surface topo. */
+						/* loop over 2 sub triangles in a rectangular element, work out the triangle it is in, and then interpolate */
+						for( tetra_I = 0; tetra_I < 2; tetra_I++ ) {
+							double				x1[DIM];
+							double				x2[DIM];
+							double				x3[DIM];
+							double				y1,y2,y3;
+							double				dett;
+							double				det[3];
+							Coord				axisA,axisB,axisC;
+							unsigned int		found=0;
+
+							for( d = 0; d < DIM; d++ ) {
+								x1[d] = xc[nn[tetra_I][0]*DIM+d];
+								x2[d] = xc[nn[tetra_I][1]*DIM+d];
+								x3[d] = xc[nn[tetra_I][2]*DIM+d];
+							}
+							y1 = x1[1];
+							y2 = x2[1];
+							y3 = x3[1];
+
+							x1[1] = x2[1] = x3[1] = 0.0f;
+							Vector_Sub( axisA, x2, x1 );
+							Vector_Sub( axisB, x3, x1 );
+							Vector_Cross( axisC, axisA, axisB );
+							dett = 0.5*getSignedArea( axisC );
+							dett = isLargerThanZero2(dett, dett, TOL);
+
+							Vector_Sub( axisA, x2, initialNodeCoord );
+							Vector_Sub( axisB, x3, initialNodeCoord );
+							Vector_Cross( axisC, axisA, axisB );
+							det[0] = 0.5*getSignedArea( axisC );
+							det[0] = isLargerThanZero2(det[0], dett, TOL);
+							Vector_Sub( axisA, x3, initialNodeCoord );
+							Vector_Sub( axisB, x1, initialNodeCoord );
+							Vector_Cross( axisC, axisA, axisB );
+							det[1] = 0.5*getSignedArea( axisC );
+							det[1] = isLargerThanZero2(det[1], dett, TOL);
+							Vector_Sub( axisA, x1, initialNodeCoord );
+							Vector_Sub( axisB, x2, initialNodeCoord );
+							Vector_Cross( axisC, axisA, axisB );
+							det[2] = 0.5*getSignedArea( axisC );
+							det[2] = isLargerThanZero2(det[2], dett, TOL);
+							dett = det[0] + det[1] + det[2];
+							//if( dett <= -1.0e-10 || dett == 0.0)
+							//    fprintf(stderr,"me=%d element_lI=%d node_lI=%d TOL=%e det=%e %e %e %e\ninitialCoord=%e %e %e x1=%e %e %e x2=%e %e %e x3=%e %e %e\n",
+							//            context->rank,element_lI,node_lI,TOL,det[0],det[1],det[2],dett,initialNodeCoord[0],initialNodeCoord[1],initialNodeCoord[2],
+							//            x1[0],x1[1],x1[2],x2[0],x2[1],x2[2],x3[0],x3[1],x3[2]);
+							//assert( dett > -1.0e-10 && dett != 0.0);
+							//fprintf(stderr,"Top coord: element_lI=%d node_lI=%d tetra_I=%d det's=%e %e %e %e\n",
+							//element_lI,node_lI,tetra_I,dett,det[0],det[1],det[2]);
+							//fprintf(stderr,"tetra_I=%d dett=%e det0=%e det1=%e det2=%e\n",tetra_I,dett,det[0],det[1],det[2]);
+
+
+							if( dett < 0 )	{
+								//assert(0);
+								continue;
+							}
+							/* found if all det are greater than zero */
+							if( det[0] >= 0.0f && det[1] >= 0.0f && det[2] >= 0.0f ) {
+								found = 1;
+							}
+							if( found ) {
+								double				shape[3];
+								Index				tNode_I;
+
+								/* mark, such that we dont do it again */
+								ind[ijk[0]+ijk[2]*nNodeX] = 1;
+
+								/* Calculate the shape funcs */
+
+								for( tNode_I = 0; tNode_I < 3; tNode_I++ ) {
+									shape[tNode_I] = det[tNode_I] / dett;
+								}
+								//fprintf(stderr,"dett=%e det0=%e det1=%e det2=%e shape=%e %e %e\n",dett,det[0],det[1],det[2],shape[0],shape[1],shape[2]);
+
+								/* Assign proper values of velocities and temperatures from old mesh to new mesh */
+								meshExt->newNodeCoord[node_lI][0] = initialNodeCoord[0];
+								meshExt->newNodeCoord[node_lI][1] = y1*shape[0] + y2*shape[1] + y3*shape[2];
+								//meshExt->newNodeCoord[node_lI][1] -= TOL*fabs(meshExt->newNodeCoord[node_lI][1]);
+								meshExt->newNodeCoord[node_lI][2] = initialNodeCoord[2];
+
+								break;
+							}
+#if 0
+							if(node_lII==0 && node_lK==0)
+								fprintf(stderr,"Found? %d timeStep=%d me=%d element_lI=%d node_lI=%d tetra_I=%d\nxc=(%e %e %e) (%e %e %e)(%e %e %e) initialX=%e %e %e\nbbox=(%e %e) (%e %e)\ndett=%e %e %e %e\n\n",
+										found,context->timeStep,context->rank,element_lN,node_lI,tetra_I,
+										x1[0],x1[1],x1[2],x2[0],x2[1],x2[2],x3[0],x3[1],x3[2],
+                                            initialNodeCoord[0],initialNodeCoord[1],initialNodeCoord[2],
+                                            elembbox[0][0],elembbox[1][0],elembbox[0][2],elembbox[1][2],
+										det[0],det[1],det[2],dett);
+#endif
+						}
+					}
+				}
+				/*
+				** Loop over shadow elements
+				*/
+				for( rn_I = 0; rn_I < meshExt->neighbourRankCount; rn_I++ ) {
+					Element_ShadowIndex		element_sN;
+
+                    /* Loop over all the shadow elements to find one including node_lI */
+                    for( element_sN = 0; element_sN < meshExt->shadowElementRemoteCount[rn_I]; element_sN++ ) {
+                        Element_GlobalIndex		gElement_N = meshExt->shadowElementRemoteArray[rn_I][element_sN];
+                        Node_Index*			shadowElementNodesN = (Node_Index*)malloc( sizeof(Node_Index) * NODES_PER_ELEMENT );
+                        Index				en_N;
+                        double				elembbox[2][DIM];
+                        Node_GlobalIndex	elementNodeN[8];
+                        IJK                 eijkN;
+
+                        /* skip irrelevant elements or exit the loop once the interpolation is done (ind == 1). */
+                        RegularMeshUtils_Element_1DTo3D( decomp, gElement_N, &eijkN[0], &eijkN[1], &eijkN[2] );
+                        if(eijkN[1] != decomp->elementGlobal3DCounts[1]-1)
+                            continue;
+                        if(ind[ijk[0]+ijk[2]*nNodeX] == 1)
+                            break;
+
+                        /* Figure out node index */
+                        _HexaEL_BuildCornerIndices( context->mesh->layout->elementLayout, gElement_N, elementNodeN );
+                        for( en_N = 0; en_N < 8; en_N++ ) {
+                            Node_GlobalIndex	node_gN = elementNodeN[en_N];
+                            Index			    node_lN = Mesh_NodeMapGlobalToLocal( context->mesh, node_gN );
+                            unsigned int		found = 0;
+                            if( node_lN < meshExt->nodeLocalCount ) {
+                                shadowElementNodesN[en_N] = node_lN;
+                                found = 1;
+                                elementNodeN[en_N] = node_lN;
+                            }
+                            else {
+                                Node_ShadowIndex		node_sI;
+                                for( node_sI = 0; node_sI < meshExt->shadowNodeRemoteCount[rn_I]; node_sI++ ) {
+                                    if( node_gN == meshExt->shadowNodeRemoteArray[rn_I][node_sI] ) {
+                                        shadowElementNodesN[en_N] =
+                                            context->mesh->nodeGlobalCount +
+                                            node_sI;
+                                        found = 1;
+                                        break;
+                                    }
+                                }
+                            }
+                            assert( found ); /* we expected this to be a shadow node, but wasn't in list! */
+                        }
+
+                        elementNodeCount = (unsigned)NODES_PER_ELEMENT; /* Assume all shadow elements have 8 nodes per el */
+                        if( elementNodeCount != (unsigned)NODES_PER_ELEMENT ) {
+                            printf( "elementNodeCount != NODES_PER_ELEMENT  element_sN = %d", element_sN );
+                            assert( 0 );
+                        }
+
+                        /* create a local copy of the veocity and coords for each of the element's nodes of the old mesh */
+                        for( en_N = 0; en_N < 4; en_N++) {
+                            node_lN = shadowElementNodesN[en_II[en_N]];
+                            if( node_lN < context->mesh->nodeDomainCount ) {
+                                for( d = 0; d < DIM; d++ ) {
+                                    xc[en_II[en_N]*DIM+d] = Mesh_CoordAt( context->mesh, node_lN )[d];
+                                }
+                            }
+                            else {
+                                node_lN -= context->mesh->nodeGlobalCount;
+                                for( d = 0; d < DIM; d++ ) {
+                                    xc[en_II[en_N]*DIM+d] = meshExt->shadowNodeRemoteCoord[rn_I][node_lN][d];
+                                }
+                            }
+                        }
+
+                        /* Calculate element's bounding box */
+                        for( d = 0; d < DIM; d++ ) {
+                            elembbox[0][d] = DBL_MAX;
+                            elembbox[1][d] = DBL_MIN;
+                        }
+                        for( en_N = 0; en_N < 4; en_N++ ) {
+                            for( d = 0; d < DIM; ++d ) {
+                                elembbox[0][d] = MIN( elembbox[0][d], xc[en_II[en_N]*DIM+d] );
+                                elembbox[1][d] = MAX( elembbox[1][d], xc[en_II[en_N]*DIM+d] );
+                            }
+                        }
+
+                        /* If new mesh's current node is outside the bounding box, next loop */
+                        if( initialNodeCoord[0] < elembbox[0][0]-0.5f*(elembbox[1][0]-elembbox[0][0]) ||
+                            initialNodeCoord[0] > elembbox[1][0]+0.5f*(elembbox[1][0]-elembbox[0][0]) ||
+                            initialNodeCoord[2] < elembbox[0][2]-0.5f*(elembbox[1][2]-elembbox[0][2]) ||
+                            initialNodeCoord[2] > elembbox[1][2]+0.5f*(elembbox[1][2]-elembbox[0][2]) )
+                            {
+                                //assert(0);
+                                continue;
+                            }
+
+                        /* if the current coordinate is far enough fromt the initial position,
+                           try to interpolate surface topo. */
+                        /* loop over 2 sub triangles in a rectangular element, work out the triangle it is in, and then interpolate */
+                        for( tetra_I = 0; tetra_I < 2; tetra_I++ ) {
+                            double				x1[DIM];
+                            double				x2[DIM];
+                            double				x3[DIM];
+                            double				y1,y2,y3;
+                            double				dett;
+                            double				det[3];
+							Coord				axisA,axisB,axisC;
+							unsigned int		found=0;
+
+                            for( d = 0; d < DIM; d++ ) {
+                                x1[d] = xc[nn[tetra_I][0]*DIM+d];
+                                x2[d] = xc[nn[tetra_I][1]*DIM+d];
+                                x3[d] = xc[nn[tetra_I][2]*DIM+d];
+                            }
+                            y1 = x1[1];
+                            y2 = x2[1];
+                            y3 = x3[1];
+                            x1[1] = x2[1] = x3[1] = 0.0f;
+
+                            Vector_Sub( axisA, x2, x1 );
+                            Vector_Sub( axisB, x3, x1 );
+                            Vector_Cross( axisC, axisA, axisB );
+                            dett = 0.5*getSignedArea( axisC );
+                            dett = isLargerThanZero2(dett, dett, TOL);
+
+
+                            Vector_Sub( axisA, x2, initialNodeCoord );
+                            Vector_Sub( axisB, x3, initialNodeCoord );
+                            Vector_Cross( axisC, axisA, axisB );
+                            det[0] = 0.5*getSignedArea( axisC );
+                            det[0] = isLargerThanZero2(det[0], dett, TOL);
+                            Vector_Sub( axisA, x3, initialNodeCoord );
+                            Vector_Sub( axisB, x1, initialNodeCoord );
+                            Vector_Cross( axisC, axisA, axisB );
+                            det[1] = 0.5*getSignedArea( axisC );
+                            det[1] = isLargerThanZero2(det[1], dett, TOL);
+                            Vector_Sub( axisA, x1, initialNodeCoord );
+                            Vector_Sub( axisB, x2, initialNodeCoord );
+                            Vector_Cross( axisC, axisA, axisB );
+                            det[2] = 0.5*getSignedArea( axisC );
+                            det[2] = isLargerThanZero2(det[2], dett, TOL);
+                            dett = det[0] + det[1] + det[2];
+
+                            if( dett < 0 )	{
+                                printf( "Determinant evaluation is wrong node=%d\t xt[0]=%g \t xt[1]=%g \t xt[t]=%g\n",
+                                        node_lI,
+                                        initialNodeCoord[0],
+                                        initialNodeCoord[1],
+                                        initialNodeCoord[2]);
+                                continue;
+                                //assert(0);
+                            }
+                            /* found if all det are greater than zero */
+                            if( det[0] >= 0.0f && det[1] >= 0.0f && det[2] >= 0.0f ) {
+                                found = 1;
+                            }
+                            if( found ) {
+                                double				shape[3];
+                                Index				tNode_I;
+
+                                /* mark, such that we dont do it again */
+                                ind[ijk[0]+ijk[2]*nNodeX] = 1;
+
+                                /* Calculate the shape funcs */
+                                for( tNode_I = 0; tNode_I < 3; tNode_I++ ) {
+                                    shape[tNode_I] = det[tNode_I] / dett;
+                                }
+
+                                /* Assign proper values of velocities and temperatures from old mesh to new mesh */
+                                meshExt->newNodeCoord[node_lI][0] = initialNodeCoord[0];
+                                meshExt->newNodeCoord[node_lI][1] = y1*shape[0] + y2*shape[1] + y3*shape[2];
+                                meshExt->newNodeCoord[node_lI][2] = initialNodeCoord[2];
+
+								break;
+                            }
+#if 0
+                            if(context->rank==1 && node_lI==44)
+                                fprintf(stderr,"Shadow Found? %d ind=%d timeStep=%d me=%d gElment_N=%d node_lI=%d tetra_I=%d\nxc=(%e %e %e) (%e %e %e)(%e %e %e) initialX=%e %e %e\nbbox=(%e %e) (%e %e)\ndett=%e %e %e %e\n\n",
+                                        found,ind[ijk[0]+ijk[2]*nNodeX],context->timeStep,context->rank,gElement_N,node_lI,tetra_I,
+                                        x1[0],x1[1],x1[2],x2[0],x2[1],x2[2],x3[0],x3[1],x3[2],
+                                        initialNodeCoord[0],initialNodeCoord[1],initialNodeCoord[2],
+                                        elembbox[0][0],elembbox[1][0],elembbox[0][2],elembbox[1][2],
+                                        det[0],det[1],det[2],dett);
+#endif
+                        }
+                    }
+                }
+            }
+		All_passed = 1;
+		count = 0;
+		for( node_lK = 0; node_lK < nNodeZ; node_lK++ )
+			for( node_lII = 0; node_lII < nNodeX; node_lII++ ) {
+				node_lI=node_lII+(nNodeY-1)*nNodeX+node_lK*nNodeX*nNodeY;
+				if( ind[node_lII+node_lK*nNodeX] == 0 ) {
+					count++;
+					All_passed = 0;
+					fprintf(stderr,"me=%d TOP failed node_lI=%d TOL=%e\n",context->rank,node_lI,TOL);
+				}
+			}
+		if(TOL==0.0)TOL = 1.0e-10;
+		else TOL *= 10.0;
+        Journal_Firewall( TOL <= 1.0e-03, context->snacError," In: %s, timeStep=%d rank=%d Increased tolerance for Top: %e count=%d\n", __func__, context->timeStep, context->rank, TOL,count );
+		Journal_DPrintf( context->debug, " In: %s, rank=%d Increased tolerance for Top: %e count=%d\n", __func__, context->rank, TOL,count );
+	}
+	/* Calculate the new node coordintates for the bottom-internal nodes. */
+    if(contextExt->bottomRestore) {
+        for( index = 0; index < meshExt->bottomInternalCount; index++ ) {
+			node_lI = meshExt->bottomInternalArray[index];
+			meshExt->newNodeCoord[node_lI][0] = meshExt->initialNodeCoord[node_lI][0];
+			meshExt->newNodeCoord[node_lI][1] = meshExt->initialNodeCoord[node_lI][1];
+			meshExt->newNodeCoord[node_lI][2] = meshExt->initialNodeCoord[node_lI][2];
+        }
+    }
+    else {
+        en_II[0] = 0;	en_II[1] = 1;	en_II[2] = 5;	en_II[3] = 4;
+        nn[0][0] = 0; nn[0][1] = 4; nn[0][2] = 1;
+        nn[1][0] = 1; nn[1][1] = 4; nn[1][2] = 5;
+        count = 0;
+        memset( ind, 0, sizeof( int ) * nNodeX * nNodeZ );
+
+        All_passed = 0;
+        TOL= 0.0f;
+        while(!All_passed) {
+			for( node_lK = 0; node_lK < nNodeZ; node_lK++ )
+				for( node_lII = 0; node_lII < nNodeX; node_lII++ ) {
+                    Element_NodeIndex		en_N;
+                    double				elembbox[2][DIM];
+					Coord               initialNodeCoord;
+					Node_LocalIndex**		elementNodeTbl = context->mesh->elementNodeTbl;
+					Tetrahedra_Index		tetra_I;
+                    Element_LocalIndex      searchElement_lI,searchElement_lK;
+					IJK                             ijk;
+
+					node_lI = node_lII + node_lK*nNodeX*nNodeY;
+					RegularMeshUtils_Node_Local1DTo3D( decomp, node_lI, &ijk[0], &ijk[1], &ijk[2] );
+					element_lI = (ijk[0] <= 1)? 0 : (ijk[0]-1);
+					element_lK = (ijk[2] <= 1)? 0 : (ijk[2]-1);
+
+					if( ind[ijk[0]+ijk[2]*nNodeX] ) {
+						continue;
+					}
+
+					initialNodeCoord[0] = meshExt->initialNodeCoord[node_lI][0];
+					initialNodeCoord[1] = 0.0f;
+					initialNodeCoord[2] = meshExt->initialNodeCoord[node_lI][2];
+
+					for(searchElement_lK=0;searchElement_lK<numSearchElement;searchElement_lK++) {
+						if( (element_lK+searchElement_lK-numSearchDepth) < 0 || (element_lK+searchElement_lK-numSearchDepth) >= nElementZ )
+							continue;
+						for(searchElement_lI=0;searchElement_lI<numSearchElement;searchElement_lI++) {
+							if( (element_lI+searchElement_lI-numSearchDepth) < 0 || (element_lI+searchElement_lI-numSearchDepth) >= nElementX )
+								continue;
+							element_lN = (element_lI+searchElement_lI-numSearchDepth) + (element_lK+searchElement_lK-numSearchDepth)*nElementY*nElementX;
+
+							elementNodeCount = context->mesh->elementNodeCountTbl[element_lN];
+							if( elementNodeCount != (unsigned)NODES_PER_ELEMENT ) {
+								printf( "elementNodeCount != NODES_PER_ELEMENT  element_lN = %d", element_lN );
+								assert( 0 );
+							}
+
+							if( ind[ijk[0]+ijk[2]*nNodeX] )
+								break;
+
+							/* create a local copy of the veocity and coords for each of the element's nodes of the old mesh */
+							for( en_N = 0; en_N < 4; en_N++) {
+								node_lN = elementNodeTbl[element_lN][en_II[en_N]];
+								for( d = 0; d < DIM; d++ ) {
+									xc[en_II[en_N]*DIM+d] = Mesh_CoordAt( context->mesh, node_lN )[d];
+								}
+							}
+
+							/* Calculate element's bounding box */
+							for( d = 0; d < DIM; d++ ) {
+								elembbox[0][d] = DBL_MAX;
+								elembbox[1][d] = DBL_MIN;
+							}
+							for( en_N = 0; en_N < 4; en_N++ ) {
+								for( d = 0; d < DIM; ++d ) {
+									elembbox[0][d] = MIN( elembbox[0][d], xc[en_II[en_N]*DIM+d] );
+									elembbox[1][d] = MAX( elembbox[1][d], xc[en_II[en_N]*DIM+d] );
+								}
+							}
+							/* If new mesh's current node is outside the bounding box, next loop */
+							if( initialNodeCoord[0] < elembbox[0][0]-0.5f*(elembbox[1][0]-elembbox[0][0]) ||
+								initialNodeCoord[0] > elembbox[1][0]+0.5f*(elembbox[1][0]-elembbox[0][0]) ||
+								initialNodeCoord[2] < elembbox[0][2]-0.5f*(elembbox[1][2]-elembbox[0][2]) ||
+								initialNodeCoord[2] > elembbox[1][2]+0.5f*(elembbox[1][2]-elembbox[0][2]) )
+								{
+									//assert(0);
+									continue;
+								}
+
+							/* if the current coordinate is far enough fromt the initial position,
+							   try to interpolate surface topo. */
+							/* loop over 2 sub triangles in a rectangular element, work out the triangle it is in, and then interpolate */
+							for( tetra_I = 0; tetra_I < 2; tetra_I++ ) {
+								double				x1[DIM];
+								double				x2[DIM];
+								double				x3[DIM];
+								double				y1,y2,y3;
+								double				dett;
+								double				det[3];
+								Coord				axisA,axisB,axisC;
+								unsigned int		found=0;
+
+								for( d = 0; d < DIM; d++ ) {
+									x1[d] = xc[nn[tetra_I][0]*DIM+d];
+									x2[d] = xc[nn[tetra_I][1]*DIM+d];
+									x3[d] = xc[nn[tetra_I][2]*DIM+d];
+								}
+								y1 = x1[1];
+								y2 = x2[1];
+								y3 = x3[1];
+
+								x1[1] = x2[1] = x3[1] = 0.0f;
+								Vector_Sub( axisA, x2, x1 );
+								Vector_Sub( axisB, x3, x1 );
+								Vector_Cross( axisC, axisA, axisB );
+								dett = 0.5*getSignedArea( axisC );
+								dett = isLargerThanZero2(dett, dett, TOL);
+
+								Vector_Sub( axisA, x2, initialNodeCoord );
+								Vector_Sub( axisB, x3, initialNodeCoord );
+								Vector_Cross( axisC, axisA, axisB );
+								det[0] = 0.5*getSignedArea( axisC );
+								det[0] = isLargerThanZero2(det[0], dett, TOL);
+								Vector_Sub( axisA, x3, initialNodeCoord );
+								Vector_Sub( axisB, x1, initialNodeCoord );
+								Vector_Cross( axisC, axisA, axisB );
+								det[1] = 0.5*getSignedArea( axisC );
+								det[1] = isLargerThanZero2(det[1], dett, TOL);
+								Vector_Sub( axisA, x1, initialNodeCoord );
+								Vector_Sub( axisB, x2, initialNodeCoord );
+								Vector_Cross( axisC, axisA, axisB );
+								det[2] = 0.5*getSignedArea( axisC );
+								det[2] = isLargerThanZero2(det[2], dett, TOL);
+								assert( dett > -1.0e-10 && dett != 0.0);
+								dett = det[0] + det[1] + det[2];
+
+								if( dett < 0 )	{
+									continue;
+									//assert(0);
+								}
+								/* found if all det are greater than zero */
+								if( det[0] >= 0.0f && det[1] >= 0.0f && det[2] >= 0.0f ) {
+									found = 1;
+								}
+								if( found ) {
+									double				shape[3];
+									Index				tNode_I;
+
+									/* mark, such that we dont do it again */
+									RegularMeshUtils_Node_Local1DTo3D( decomp, node_lI, &ijk[0], &ijk[1], &ijk[2] );
+									ind[ijk[0]+ijk[2]*nNodeX] = 1;
+
+									/* Calculate the shape funcs */
+									for( tNode_I = 0; tNode_I < 3; tNode_I++ ) {
+										shape[tNode_I] = det[tNode_I] / dett;
+									}
+
+									/* Assign proper values of velocities and temperatures from old mesh to new mesh */
+									meshExt->newNodeCoord[node_lI][0] = initialNodeCoord[0];
+									meshExt->newNodeCoord[node_lI][1] = y1*shape[0] + y2*shape[1] + y3*shape[2];
+									meshExt->newNodeCoord[node_lI][2] = initialNodeCoord[2];
+
+									break;
+								}
+#if 0
+								fprintf(stderr,"Found? %d timeStep=%d me=%d element_lI=%d node_lI=%d tetra_I=%d\nxc=(%e %e %e) (%e %e %e)(%e %e %e) initialX=%e %e %e\nbbox=(%e %e) (%e %e)\ndett=%e %e %e %e\n\n",
+										found,context->timeStep,context->rank,element_lN,node_lI,tetra_I,
+										x1[0],x1[1],x1[2],x2[0],x2[1],x2[2],x3[0],x3[1],x3[2],
+										initialNodeCoord[0],initialNodeCoord[1],initialNodeCoord[2],
+										elembbox[0][0],elembbox[1][0],elembbox[0][2],elembbox[1][2],
+										det[0],det[1],det[2],dett);
+#endif
+							}
+						}
+					}
+					/*
+					** Loop over shadow elements
+					*/
+					for( rn_I = 0; rn_I < meshExt->neighbourRankCount; rn_I++ ) {
+						Element_ShadowIndex		element_sN;
+
+                        /* Loop over all the shadow elements to find one including node_lI */
+                        for( element_sN = 0; element_sN < meshExt->shadowElementRemoteCount[rn_I]; element_sN++ ) {
+                            Element_GlobalIndex		gElement_N = meshExt->shadowElementRemoteArray[rn_I][element_sN];
+                            Node_Index*			shadowElementNodesN = (Node_Index*)malloc( sizeof(Node_Index) * NODES_PER_ELEMENT );
+                            Index				en_N;
+                            double				elembbox[2][DIM];
+                            Node_GlobalIndex	elementNodeN[8];
+                            IJK                 eijkN;
+
+                            /* skip irrelevant elements or exit the loop once the interpolation is done (ind == 1). */
+                            RegularMeshUtils_Element_1DTo3D( decomp, gElement_N, &eijkN[0], &eijkN[1], &eijkN[2] );
+                            if(eijkN[1] != 0)
+                                continue;
+                            if(ind[ijk[0]+ijk[2]*nNodeX] == 1)
+                                break;
+
+                            /* Figure out node index */
+                            _HexaEL_BuildCornerIndices( context->mesh->layout->elementLayout, gElement_N, elementNodeN );
+                            for( en_N = 0; en_N < 8; en_N++ ) {
+                                Node_GlobalIndex     node_gN = elementNodeN[en_N];
+                                Node_LocalIndex      node_lN = Mesh_NodeMapGlobalToLocal( context->mesh, node_gN );
+                                unsigned int         found = 0;
+                                if( node_lN < meshExt->nodeLocalCount ) {
+                                    shadowElementNodesN[en_N] = node_lN;
+                                    found = 1;
+                                    elementNodeN[en_N] = node_lN;
+                                }
+                                else {
+                                    Node_ShadowIndex		node_sI;
+                                    for( node_sI = 0; node_sI < meshExt->shadowNodeRemoteCount[rn_I]; node_sI++ ) {
+                                        if( node_gN == meshExt->shadowNodeRemoteArray[rn_I][node_sI] ) {
+                                            shadowElementNodesN[en_N] =
+                                                context->mesh->nodeGlobalCount +
+                                                node_sI;
+                                            found = 1;
+                                            break;
+                                        }
+                                    }
+                                }
+                                assert( found ); /* we expected this to be a shadow node, but wasn't in list! */
+                            }
+
+                            elementNodeCount = (unsigned)NODES_PER_ELEMENT; /* Assume all shadow elements have 8 nodes per el */
+                            if( elementNodeCount != (unsigned)NODES_PER_ELEMENT ) {
+                                printf( "elementNodeCount != NODES_PER_ELEMENT  element_sN = %d", element_sN );
+                                assert( 0 );
+                            }
+
+                            /* create a local copy of the veocity and coords for each of the element's nodes of the old mesh */
+                            for( en_N = 0; en_N < 4; en_N++) {
+                                node_lN = shadowElementNodesN[en_II[en_N]];
+                                if( node_lN < context->mesh->nodeDomainCount ) {
+                                    for( d = 0; d < DIM; d++ ) {
+                                        xc[en_II[en_N]*DIM+d] = Mesh_CoordAt( context->mesh, node_lN )[d];
+                                    }
+                                }
+                                else {
+                                    node_lN -= context->mesh->nodeGlobalCount;
+                                    for( d = 0; d < DIM; d++ ) {
+                                        xc[en_II[en_N]*DIM+d] = meshExt->shadowNodeRemoteCoord[rn_I][node_lN][d];
+                                    }
+                                }
+                            }
+
+                            /* Calculate element's bounding box */
+                            for( d = 0; d < DIM; d++ ) {
+                                elembbox[0][d] = DBL_MAX;
+                                elembbox[1][d] = DBL_MIN;
+                            }
+                            for( en_N = 0; en_N < 4; en_N++ ) {
+                                for( d = 0; d < DIM; ++d ) {
+                                    elembbox[0][d] = MIN( elembbox[0][d], xc[en_II[en_N]*DIM+d] );
+                                    elembbox[1][d] = MAX( elembbox[1][d], xc[en_II[en_N]*DIM+d] );
+                                }
+                            }
+                            /* If new mesh's current node is outside the bounding box, next loop */
+                            if( initialNodeCoord[0] < elembbox[0][0]-0.5f*(elembbox[1][0]-elembbox[0][0]) ||
+                                initialNodeCoord[0] > elembbox[1][0]+0.5f*(elembbox[1][0]-elembbox[0][0]) ||
+                                initialNodeCoord[2] < elembbox[0][2]-0.5f*(elembbox[1][2]-elembbox[0][2]) ||
+                                initialNodeCoord[2] > elembbox[1][2]+0.5f*(elembbox[1][2]-elembbox[0][2]) )
+                                {
+                                    //assert(0);
+                                    continue;
+                                }
+
+                            /* if the current coord is very close to the initial ones, just copy those initial values rather than bothering to compute determinents and adding error */
+                            if( ( initialNodeCoord[0] >= Mesh_CoordAt( context->mesh, node_lI )[0] - TOL*(elembbox[1][0]-elembbox[0][0]) && initialNodeCoord[0] <= Mesh_CoordAt( context->mesh, node_lI )[0] + TOL*(elembbox[1][0]-elembbox[0][0]) ) &&
+                                ( initialNodeCoord[1] >= Mesh_CoordAt( context->mesh, node_lI )[1] - TOL*(elembbox[1][1]-elembbox[0][1]) && initialNodeCoord[1] <= Mesh_CoordAt( context->mesh, node_lI )[1] + TOL*(elembbox[1][1]-elembbox[0][1]) ) &&
+                                ( initialNodeCoord[2] >= Mesh_CoordAt( context->mesh, node_lI )[2] - TOL*(elembbox[1][2]-elembbox[0][2]) && initialNodeCoord[2] <= Mesh_CoordAt( context->mesh, node_lI )[2] + TOL*(elembbox[1][2]-elembbox[0][2]) ) ) {
+                                meshExt->newNodeCoord[node_lI][0] = initialNodeCoord[0];
+                                meshExt->newNodeCoord[node_lI][1] = Mesh_CoordAt( context->mesh, node_lI )[1];
+                                meshExt->newNodeCoord[node_lI][2] = initialNodeCoord[2];
+                                ind[ijk[0]+ijk[2]*nNodeX] = 1;
+                                continue;
+                            }
+
+                            /* if the current coordinate is far enough fromt the initial position,
+                               try to interpolate surface topo. */
+                            /* loop over 2 sub triangles in a rectangular element, work out the triangle it is in, and then interpolate */
+                            for( tetra_I = 0; tetra_I < 2; tetra_I++ ) {
+                                double				x1[DIM];
+                                double				x2[DIM];
+                                double				x3[DIM];
+                                double				y1,y2,y3;
+                                double				dett;
+                                double				det[3];
+								Coord				axisA,axisB,axisC;
+								unsigned int		found=0;
+
+                                for( d = 0; d < DIM; d++ ) {
+                                    x1[d] = xc[nn[tetra_I][0]*DIM+d];
+                                    x2[d] = xc[nn[tetra_I][1]*DIM+d];
+                                    x3[d] = xc[nn[tetra_I][2]*DIM+d];
+                                }
+                                y1 = x1[1];
+                                y2 = x2[1];
+                                y3 = x3[1];
+                                x1[1] = x2[1] = x3[1] = 0.0f;
+
+                                Vector_Sub( axisA, x2, x1 );
+                                Vector_Sub( axisB, x3, x1 );
+                                Vector_Cross( axisC, axisA, axisB );
+                                dett = 0.5*getSignedArea( axisC );
+                                dett = isLargerThanZero2(dett, dett, TOL);
+
+
+                                Vector_Sub( axisA, x2, initialNodeCoord );
+                                Vector_Sub( axisB, x3, initialNodeCoord );
+                                Vector_Cross( axisC, axisA, axisB );
+                                det[0] = 0.5*getSignedArea( axisC );
+                                det[0] = isLargerThanZero2(det[0], dett, TOL);
+                                Vector_Sub( axisA, x3, initialNodeCoord );
+                                Vector_Sub( axisB, x1, initialNodeCoord );
+                                Vector_Cross( axisC, axisA, axisB );
+                                det[1] = 0.5*getSignedArea( axisC );
+                                det[1] = isLargerThanZero2(det[1], dett, TOL);
+                                Vector_Sub( axisA, x1, initialNodeCoord );
+                                Vector_Sub( axisB, x2, initialNodeCoord );
+                                Vector_Cross( axisC, axisA, axisB );
+                                det[2] = 0.5*getSignedArea( axisC );
+                                det[2] = isLargerThanZero2(det[2], dett, TOL);
+                                dett = det[0] + det[1] + det[2];
+
+                                if( dett < 0 )	{
+                                    continue;
+                                }
+
+                                /* found if all det are greater than zero */
+                                if( det[0] >= 0.0f && det[1] >= 0.0f && det[2] >= 0.0f ) {
+                                    found = 1;
+                                }
+                                if( found ) {
+                                    double				shape[3];
+                                    Index				tNode_I;
+
+                                    /* mark, such that we dont do it again */
+                                    ind[ijk[0]+ijk[2]*nNodeX] = 1;
+                                    count++;
+
+                                    /* Calculate the shape funcs */
+                                    for( tNode_I = 0; tNode_I < 3; tNode_I++ ) {
+                                        shape[tNode_I] = det[tNode_I] / dett;
+                                    }
+
+                                    /* Assign proper values of velocities and temperatures from old mesh to new mesh */
+                                    meshExt->newNodeCoord[node_lI][0] = initialNodeCoord[0];
+                                    meshExt->newNodeCoord[node_lI][1] = y1*shape[0] + y2*shape[1] + y3*shape[2];
+                                    meshExt->newNodeCoord[node_lI][2] = initialNodeCoord[2];
+
+									break;
+                                }
+                            }
+                        }
+                    }
+                }
+			All_passed = 1;
+			count = 0;
+			for( node_lK = 0; node_lK < nNodeZ; node_lK++ )
+				for( node_lII = 0; node_lII < nNodeX; node_lII++ ) {
+					node_lI=node_lII+(nNodeY-1)*nNodeX+node_lK*nNodeX*nNodeY;
+					if( ind[node_lII+node_lK*nNodeX] == 0 ) {
+						All_passed = 0;
+						count++;
+						fprintf(stderr,"me=%d BOT failed node_lI=%d TOL=%e\n",context->rank,node_lI,TOL);
+					}
+				}
+			if(TOL==0.0)TOL = 1.0e-10;
+			else TOL *= 10.0;
+			Journal_Firewall( TOL <= 1.0e-03, context->snacError," In: %s, timeStep=%d rank=%d Increased tolerance for Bottom: %e count=%d\n", __func__, context->timeStep, context->rank, TOL,count );
+			Journal_DPrintf( context->debug, " In: %s, rank=%d Increased tolerance for Bottom: %e count=%d\n", __func__, context->rank, TOL, count );
+		}
+	}
+	free( ind );
+
+	/* Calculate the new node coordintates for the wall nodes. */
+	if( meshExt->meshType == -1 ) {
+		assert( 0 );
+	}
+	else { /* SnacRemesher_Cartesian */
+		for( index = 0; index < meshExt->wallCount; index++ ) {
+			Node_LocalIndex				node_lI;
+			IJK					ijk;
+			Node_LocalIndex				nodeTop_lI, nodeBottom_lI;
+			const Index 				topI = decomp->nodeLocal3DCounts[decomp->rank][1];
+
+			node_lI = meshExt->wallArray[index];
+			RegularMeshUtils_Node_Local1DTo3D( decomp, node_lI, &ijk[0], &ijk[1], &ijk[2] );
+
+			/* The wall node positions revert to the initial position */
+			meshExt->newNodeCoord[node_lI][0] = meshExt->initialNodeCoord[node_lI][0];
+			meshExt->newNodeCoord[node_lI][2] = meshExt->initialNodeCoord[node_lI][2];
+			nodeBottom_lI = RegularMeshUtils_Node_Local3DTo1D( decomp, ijk[0], 0, ijk[2] );
+			nodeTop_lI = RegularMeshUtils_Node_Local3DTo1D( decomp, ijk[0], topI - 1, ijk[2] );
+			meshExt->newNodeCoord[node_lI][1] =
+				meshExt->newNodeCoord[nodeBottom_lI][1] +
+				( meshExt->newNodeCoord[nodeTop_lI][1] - meshExt->newNodeCoord[nodeBottom_lI][1] ) /
+				(topI - 1 ) *
+				ijk[1];
+		}
+	}
+
+	for( index = 0; index < meshExt->internalCount; index++ ) {
+		Node_LocalIndex				node_lI;
+		IJK					ijk;
+		Node_LocalIndex				nodeBottom_lI;
+		Node_LocalIndex				nodeTop_lI;
+		HexaMD*					decomp = (HexaMD*)mesh->layout->decomp;
+		const Index 				topI = decomp->nodeLocal3DCounts[decomp->rank][1];
+
+		/* TODO... parallel version! */
+		node_lI = meshExt->internalArray[index];
+		RegularMeshUtils_Node_Local1DTo3D( decomp, node_lI, &ijk[0], &ijk[1], &ijk[2] );
+		/* TODO... Local? where's the global equivalent? */
+		nodeBottom_lI = RegularMeshUtils_Node_Local3DTo1D( decomp, ijk[0], 0, ijk[2] );
+		nodeTop_lI = RegularMeshUtils_Node_Local3DTo1D( decomp, ijk[0], topI - 1, ijk[2] );
+
+		meshExt->newNodeCoord[node_lI][0] = meshExt->initialNodeCoord[node_lI][0];
+		meshExt->newNodeCoord[node_lI][1] =
+			meshExt->newNodeCoord[nodeBottom_lI][1] +
+			( meshExt->newNodeCoord[nodeTop_lI][1] - meshExt->newNodeCoord[nodeBottom_lI][1] ) /
+			(topI - 1 ) *
+			ijk[1];
+		meshExt->newNodeCoord[node_lI][2] = meshExt->initialNodeCoord[node_lI][2];
+	}
+}
+
+void _SnacRemesher_NewCoords_Spherical( void* _context ) {
+	Snac_Context*			context = (Snac_Context*)_context;
+	SnacRemesher_Context*			contextExt = ExtensionManager_Get(
+							context->extensionMgr,
+							context,
+							SnacRemesher_ContextHandle );
+	Mesh*				mesh = context->mesh;
+	SnacRemesher_Mesh*		meshExt = ExtensionManager_Get(
+						context->meshExtensionMgr,
+						mesh,
+						SnacRemesher_MeshHandle );
+	HexaMD*				decomp = (HexaMD*)mesh->layout->decomp;
+	Node_LocalIndex			index;
+	Node_LocalIndex			node_lI,node_lII,node_lK,node_lN;
+	int*				ind;
+	Index				d;
+	Element_LocalIndex		element_lK,element_lJ,element_lI,element_lN;
+	Element_LocalIndex		nElementX=decomp->elementLocal3DCounts[decomp->rank][0];
+	Element_LocalIndex		nElementY=decomp->elementLocal3DCounts[decomp->rank][1];
+	Element_LocalIndex		nElementZ=decomp->elementLocal3DCounts[decomp->rank][2];
+	Node_LocalIndex		        nNodeX=decomp->nodeLocal3DCounts[decomp->rank][0];
+	Node_LocalIndex		        nNodeY=decomp->nodeLocal3DCounts[decomp->rank][1];
+	Node_LocalIndex		        nNodeZ=decomp->nodeLocal3DCounts[decomp->rank][2];
+	Element_NodeIndex		elementNodeCount;
+	double				xc[DIM*NODES_PER_ELEMENT];
+	double				xcs[DIM*NODES_PER_ELEMENT];
+	PartitionIndex			rn_I;
+	int                             count;
+	int			        en_II[4] = { 3, 2, 6, 7};
+	int			        nn[2][3] = { {3, 7, 2}, {2, 7, 6} };
+	unsigned int                    All_passed = 0;
+	double                          TOL = 0.0f;
+    const int                          shadowDepth = ( decomp->shadowDepth > 3) ? decomp->shadowDepth : 3;
+	const int                          numSearchElement = 2*shadowDepth-1;
+	const int                          numSearchDepth = shadowDepth-1;
+
+	Journal_DPrintf( context->debug, "In: %s\n", __func__ );
+
+	ind = (int*)malloc( sizeof( int ) * nNodeX * nNodeZ );
+	memset( ind, 0, sizeof( int ) * nNodeX * nNodeZ );
+
+	while(!All_passed) {
+		/* Calculate the new node coordintates for the top-internal nodes. */
+		for( node_lK = 0; node_lK < nNodeZ; node_lK++ )
+			for( node_lII = 0; node_lII < nNodeX; node_lII++ ) {
+
+				Element_NodeIndex		en_N;
+				double				elembbox[2][DIM];
+				Coord                           temp1,temp2;
+				Node_LocalIndex**		elementNodeTbl = context->mesh->elementNodeTbl;
+				Tetrahedra_Index		tetra_I;
+				Coord				initialNodeCoord;
+				Coord				initialNodeCoordS;
+                Element_LocalIndex      searchElement_lI,searchElement_lK;
+				IJK                             ijk;
+
+				/* Ensure we haven't already done this node */
+				node_lI = node_lII + (nNodeY-1)*nNodeX + node_lK*nNodeX*nNodeY;
+				RegularMeshUtils_Node_Local1DTo3D( decomp, node_lI, &ijk[0], &ijk[1], &ijk[2] );
+				element_lI = (ijk[0] <= 1)? 0 : (ijk[0]-1);
+				element_lK = (ijk[2] <= 1)? 0 : (ijk[2]-1);
+
+				if( ind[ijk[0]+ijk[2]*nNodeX] ) {
+					continue;
+				}
+
+				initialNodeCoord[0] = meshExt->initialNodeCoord[node_lI][0];
+				initialNodeCoord[1] = meshExt->initialNodeCoord[node_lI][1];
+				initialNodeCoord[2] = meshExt->initialNodeCoord[node_lI][2];
+				xyz2tprCoord( initialNodeCoord, &initialNodeCoordS );
+				initialNodeCoordS[1] = 0.0f;
+
+				for(searchElement_lK=0;searchElement_lK<numSearchElement;searchElement_lK++) {
+					if( (element_lK+searchElement_lK-numSearchDepth) < 0 || (element_lK+searchElement_lK-numSearchDepth) >= nElementZ )
+						continue;
+					for(searchElement_lI=0;searchElement_lI<numSearchElement;searchElement_lI++) {
+						if( (element_lI+searchElement_lI-numSearchDepth) < 0 || (element_lI+searchElement_lI-numSearchDepth) >= nElementX )
+							continue;
+						element_lN = (element_lI+searchElement_lI-numSearchDepth) + (nElementY-1)*nElementX +
+							(element_lK+searchElement_lK-numSearchDepth)*nElementY*nElementX;
+
+						elementNodeCount = context->mesh->elementNodeCountTbl[element_lN];
+						if( elementNodeCount != (unsigned)NODES_PER_ELEMENT ) {
+							printf( "elementNodeCount != NODES_PER_ELEMENT  element_lN = %d", element_lN );
+							assert( 0 );
+						}
+
+						if( ind[ijk[0]+ijk[2]*nNodeX] )
+							break;
+
+						/* create a local copy of the veocity and coords for each of the element's nodes of the old mesh */
+						for( en_N = 0; en_N < 4; en_N++) {
+							node_lN = elementNodeTbl[element_lN][en_II[en_N]];
+							for( d = 0; d < DIM; d++ ) {
+								xc[en_II[en_N]*DIM+d] = Mesh_CoordAt( context->mesh, node_lN )[d];
+							}
+							// (0,1,2) <=> (x,y,z) <=> (fi,r,theta)
+							temp1[0] = xc[en_II[en_N]*DIM+0];
+							temp1[1] = xc[en_II[en_N]*DIM+1];
+							temp1[2] = xc[en_II[en_N]*DIM+2];
+							xyz2tprCoord( temp1, &temp2 );
+							xcs[en_II[en_N]*DIM+0] = temp2[0];
+							xcs[en_II[en_N]*DIM+1] = temp2[1];
+							xcs[en_II[en_N]*DIM+2] = temp2[2];
+						}
+
+						/* Calculate element's bounding box */
+						for( d = 0; d < DIM; d++ ) {
+							elembbox[0][d] = DBL_MAX;
+							elembbox[1][d] = DBL_MIN;
+						}
+						for( en_N = 0; en_N < 4; en_N++ ) {
+							for( d = 0; d < DIM; ++d ) {
+								elembbox[0][d] = MIN( elembbox[0][d], xcs[en_II[en_N]*DIM+d] );
+								elembbox[1][d] = MAX( elembbox[1][d], xcs[en_II[en_N]*DIM+d] );
+							}
+						}
+						/* If new mesh's current node is outside the bounding box, next loop */
+						if( initialNodeCoordS[0] < elembbox[0][0]-0.5f*(elembbox[1][0]-elembbox[0][0]) ||
+							initialNodeCoordS[0] > elembbox[1][0]+0.5f*(elembbox[1][0]-elembbox[0][0]) ||
+							initialNodeCoordS[2] < elembbox[0][2]-0.5f*(elembbox[1][2]-elembbox[0][2]) ||
+							initialNodeCoordS[2] > elembbox[1][2]+0.5f*(elembbox[1][2]-elembbox[0][2]) )
+							{
+								//assert(0);
+								continue;
+							}
+
+						/* if the current coordinate is far enough from the initial position,
+						   try to interpolate surface topo. */
+						/* loop over 2 sub triangles in a rectangular element, work out the triangle it is in, and then interpolate */
+						for( tetra_I = 0; tetra_I < 2; tetra_I++ ) {
+							double				x1[DIM];
+							double				x2[DIM];
+							double				x3[DIM];
+							double				y1,y2,y3;
+							double				dett;
+							double				det[3];
+							Coord				axisA,axisB,axisC;
+							unsigned int		found=0;
+
+							for( d = 0; d < DIM; d++ ) {
+								x1[d] = xcs[nn[tetra_I][0]*DIM+d];
+								x2[d] = xcs[nn[tetra_I][1]*DIM+d];
+								x3[d] = xcs[nn[tetra_I][2]*DIM+d];
+							}
+							y1 = x1[1];
+							y2 = x2[1];
+							y3 = x3[1];
+							x1[1] = x2[1] = x3[1] = 0.0f;
+
+							Vector_Sub( axisA, x2, x1 );
+							Vector_Sub( axisB, x3, x1 );
+							Vector_Cross( axisC, axisA, axisB );
+							dett = 0.5*getSignedArea( axisC );
+							dett = isLargerThanZero2(dett, dett, TOL);
+
+							Vector_Sub( axisA, x2, initialNodeCoordS );
+							Vector_Sub( axisB, x3, initialNodeCoordS );
+							Vector_Cross( axisC, axisA, axisB );
+							det[0] = 0.5*getSignedArea( axisC );
+							det[0] = isLargerThanZero2(det[0], dett, TOL);
+							Vector_Sub( axisA, x3, initialNodeCoordS );
+							Vector_Sub( axisB, x1, initialNodeCoordS );
+							Vector_Cross( axisC, axisA, axisB );
+							det[1] = 0.5*getSignedArea( axisC );
+							det[1] = isLargerThanZero2(det[1], dett, TOL);
+							Vector_Sub( axisA, x1, initialNodeCoordS );
+							Vector_Sub( axisB, x2, initialNodeCoordS );
+							Vector_Cross( axisC, axisA, axisB );
+							det[2] = 0.5*getSignedArea( axisC );
+							det[2] = isLargerThanZero2(det[2], dett, TOL);
+							dett = det[0] + det[1] + det[2];
+
+							if( dett < 0 )	{
+								continue;
+							}
+							/* found if all det are greater than zero */
+							if( det[0] >= 0.0f && det[1] >= 0.0f && det[2] >= 0.0f ) {
+								found = 1;
+							}
+							if( found ) {
+								double				shape[3];
+								Index				tNode_I;
+								/* mark, such that we dont do it again */
+								ind[ijk[0]+ijk[2]*nNodeX] = 1;
+
+								/* Calculate the shape funcs */
+
+								for( tNode_I = 0; tNode_I < 3; tNode_I++ ) {
+									shape[tNode_I] = det[tNode_I] / dett;
+								}
+
+								/* Assign proper values of velocities and temperatures from old mesh to new mesh */
+								x1[0] = initialNodeCoordS[0];
+								x1[1] = y1*shape[0] + y2*shape[1] + y3*shape[2];
+								x1[2] = initialNodeCoordS[2];
+								tpr2xyzCoord( x1,&meshExt->newNodeCoord[node_lI] );
+
+								break;
+							}
+#if 0
+							if(context->rank==0 && node_lI==0 && TOL <= 1.0e-7)
+								fprintf(stderr,"Found? %d TOL=%e timeStep=%d me=%d element_lI=%d node_lI=%d tetra_I=%d\nxc=(%e %e %e) (%e %e %e)(%e %e %e) initialX=%e %e %e\nbbox=(%e %e) (%e %e)\ndett=%e %e %e %e min=%e max=%e result=%e\n\n",
+										found,TOL,context->timeStep,context->rank,element_lN,node_lI,tetra_I,
+										x1[0],x1[1],x1[2],x2[0],x2[1],x2[2],x3[0],x3[1],x3[2],
+										initialNodeCoordS[0],initialNodeCoordS[1],initialNodeCoordS[2],
+										elembbox[0][0],elembbox[1][0],elembbox[0][2],elembbox[1][2],
+										det[0],det[1],det[2],dett,-1.0*fabs(dett)*TOL,fabs(dett)*TOL,
+										isLargerThanZero2(det[0],dett,TOL));
+#endif
+						}
+					}
+				}
+				/*
+				** Loop over shadow elements
+				*/
+				for( rn_I = 0; rn_I < meshExt->neighbourRankCount; rn_I++ ) {
+					Element_ShadowIndex		element_sN;
+
+                    /* Loop over all the shadow elements to find one including node_lI */
+                    for( element_sN = 0; element_sN < meshExt->shadowElementRemoteCount[rn_I]; element_sN++ ) {
+                        Element_GlobalIndex		gElement_N = meshExt->shadowElementRemoteArray[rn_I][element_sN];
+                        Node_Index*			shadowElementNodesN = (Node_Index*)malloc( sizeof(Node_Index) * NODES_PER_ELEMENT );
+                        Index				en_N;
+                        double				elembbox[2][DIM];
+                        Node_GlobalIndex	elementNodeN[8];
+                        IJK                 eijkN;
+
+                        /* skip irrelevant elements or exit the loop once the interpolation is done (ind == 1). */
+                        RegularMeshUtils_Element_1DTo3D( decomp, gElement_N, &eijkN[0], &eijkN[1], &eijkN[2] );
+                        if(eijkN[1] != decomp->elementGlobal3DCounts[1]-1)
+                            continue;
+                        if(ind[ijk[0]+ijk[2]*nNodeX] == 1)
+                            break;
+
+                        /* Figure out node index */
+                        _HexaEL_BuildCornerIndices( context->mesh->layout->elementLayout, gElement_N, elementNodeN );
+                        for( en_N = 0; en_N < 8; en_N++ ) {
+                            Node_GlobalIndex	node_gN = elementNodeN[en_N];
+                            unsigned int		found = 0;
+                            node_lN = Mesh_NodeMapGlobalToLocal( context->mesh, node_gN );
+                            if( node_lN < meshExt->nodeLocalCount ) {
+                                shadowElementNodesN[en_N] = node_lN;
+                                found = 1;
+                                elementNodeN[en_N] = node_lN;
+                            }
+                            else {
+                                Node_ShadowIndex		node_sI;
+                                for( node_sI = 0; node_sI < meshExt->shadowNodeRemoteCount[rn_I]; node_sI++ ) {
+                                    if( node_gN == meshExt->shadowNodeRemoteArray[rn_I][node_sI] ) {
+                                        shadowElementNodesN[en_N] =
+                                            context->mesh->nodeGlobalCount +
+                                            node_sI;
+                                        found = 1;
+                                        break;
+                                    }
+                                }
+                            }
+                            assert( found ); /* we expected this to be a shadow node, but wasn't in list! */
+                        }
+
+                        elementNodeCount = (unsigned)NODES_PER_ELEMENT; /* Assume all shadow elements have 8 nodes per el */
+                        if( elementNodeCount != (unsigned)NODES_PER_ELEMENT ) {
+                            printf( "elementNodeCount != NODES_PER_ELEMENT  element_sN = %d", element_sN );
+                            assert( 0 );
+                        }
+
+                        /* create a local copy of the veocity and coords for each of the element's nodes of the old mesh */
+                        for( en_N = 0; en_N < 4; en_N++) {
+                            node_lN = shadowElementNodesN[en_II[en_N]];
+                            if( node_lN < context->mesh->nodeDomainCount ) {
+                                for( d = 0; d < DIM; d++ ) {
+                                    xc[en_II[en_N]*DIM+d] = Mesh_CoordAt( context->mesh, node_lN )[d];
+                                }
+                            }
+                            else {
+                                node_lN -= context->mesh->nodeGlobalCount;
+                                for( d = 0; d < DIM; d++ ) {
+                                    xc[en_II[en_N]*DIM+d] = meshExt->shadowNodeRemoteCoord[rn_I][node_lN][d];
+                                }
+                            }
+                            // (0,1,2) <=> (x,y,z) <=> (fi,r,theta)
+                            temp1[0] = xc[en_II[en_N]*DIM+0];
+                            temp1[1] = xc[en_II[en_N]*DIM+1];
+                            temp1[2] = xc[en_II[en_N]*DIM+2];
+                            xyz2tprCoord( temp1, &temp2 );
+                            xcs[en_II[en_N]*DIM+0] = temp2[0];
+                            xcs[en_II[en_N]*DIM+1] = temp2[1];
+                            xcs[en_II[en_N]*DIM+2] = temp2[2];
+                        }
+
+                        /* Calculate element's bounding box */
+                        for( d = 0; d < DIM; d++ ) {
+                            elembbox[0][d] = DBL_MAX;
+                            elembbox[1][d] = DBL_MIN;
+                        }
+                        for( en_N = 0; en_N < 4; en_N++ ) {
+                            for( d = 0; d < DIM; ++d ) {
+                                elembbox[0][d] = MIN( elembbox[0][d], xcs[en_II[en_N]*DIM+d] );
+                                elembbox[1][d] = MAX( elembbox[1][d], xcs[en_II[en_N]*DIM+d] );
+                            }
+                        }
+
+                        /* If new mesh's current node is outside the bounding box, next loop */
+                        if( initialNodeCoordS[0] < elembbox[0][0]-0.5f*(elembbox[1][0]-elembbox[0][0]) ||
+                            initialNodeCoordS[0] > elembbox[1][0]+0.5f*(elembbox[1][0]-elembbox[0][0]) ||
+                            initialNodeCoordS[2] < elembbox[0][2]-0.5f*(elembbox[1][2]-elembbox[0][2]) ||
+                            initialNodeCoordS[2] > elembbox[1][2]+0.5f*(elembbox[1][2]-elembbox[0][2]) )
+                            {
+                                continue;
+                            }
+
+                        /* if the current coord is very close to the initial ones, just copy those initial values rather than bothering to compute determinents and adding error */
+                        if( ( initialNodeCoord[0] >= Mesh_CoordAt( context->mesh, node_lI )[0] - TOL*(elembbox[1][0]-elembbox[0][0]) && initialNodeCoord[0] <= Mesh_CoordAt( context->mesh, node_lI )[0] + TOL*(elembbox[1][0]-elembbox[0][0]) ) &&
+                            ( initialNodeCoord[1] >= Mesh_CoordAt( context->mesh, node_lI )[1] - TOL*(elembbox[1][1]-elembbox[0][1]) && initialNodeCoord[1] <= Mesh_CoordAt( context->mesh, node_lI )[1] + TOL*(elembbox[1][1]-elembbox[0][1]) ) &&
+                            ( initialNodeCoord[2] >= Mesh_CoordAt( context->mesh, node_lI )[2] - TOL*(elembbox[1][2]-elembbox[0][2]) && initialNodeCoord[2] <= Mesh_CoordAt( context->mesh, node_lI )[2] + TOL*(elembbox[1][2]-elembbox[0][2]) ) ) {
+                            meshExt->newNodeCoord[node_lI][0] = initialNodeCoord[0];
+                            meshExt->newNodeCoord[node_lI][1] = Mesh_CoordAt( context->mesh, node_lI )[1];
+                            meshExt->newNodeCoord[node_lI][2] = initialNodeCoord[2];
+                            ind[ijk[0]+ijk[2]*nNodeX] = 1;
+                            continue;
+                        }
+
+                        /* if the current coordinate is far enough fromt the initial position,
+                           try to interpolate surface topo. */
+                        /* loop over 2 sub triangles in a rectangular element, work out the triangle it is in, and then interpolate */
+                        for( tetra_I = 0; tetra_I < 2; tetra_I++ ) {
+                            double				x1[DIM];
+                            double				x2[DIM];
+                            double				x3[DIM];
+                            double				y1,y2,y3;
+                            double				dett;
+                            double				det[3];
+							Coord				axisA,axisB,axisC;
+							unsigned int		found=0;
+
+                            for( d = 0; d < DIM; d++ ) {
+                                x1[d] = xcs[nn[tetra_I][0]*DIM+d];
+                                x2[d] = xcs[nn[tetra_I][1]*DIM+d];
+                                x3[d] = xcs[nn[tetra_I][2]*DIM+d];
+                            }
+                            y1 = x1[1];
+                            y2 = x2[1];
+                            y3 = x3[1];
+                            x1[1] = x2[1] = x3[1] = 0.0f;
+
+                            Vector_Sub( axisA, x2, x1 );
+                            Vector_Sub( axisB, x3, x1 );
+                            Vector_Cross( axisC, axisA, axisB );
+                            dett = 0.5*getSignedArea( axisC );
+                            dett = isLargerThanZero2(dett, dett, TOL);
+
+
+                            Vector_Sub( axisA, x2, initialNodeCoordS );
+                            Vector_Sub( axisB, x3, initialNodeCoordS );
+                            Vector_Cross( axisC, axisA, axisB );
+                            det[0] = 0.5*getSignedArea( axisC );
+                            det[0] = isLargerThanZero2(det[0], dett, TOL);
+                            Vector_Sub( axisA, x3, initialNodeCoordS );
+                            Vector_Sub( axisB, x1, initialNodeCoordS );
+                            Vector_Cross( axisC, axisA, axisB );
+                            det[1] = 0.5*getSignedArea( axisC );
+                            det[1] = isLargerThanZero2(det[1], dett, TOL);
+                            Vector_Sub( axisA, x1, initialNodeCoordS );
+                            Vector_Sub( axisB, x2, initialNodeCoordS );
+                            Vector_Cross( axisC, axisA, axisB );
+                            det[2] = 0.5*getSignedArea( axisC );
+                            det[2] = isLargerThanZero2(det[2], dett, TOL);
+                            dett = det[0] + det[1] + det[2];
+                            assert( dett > -1.0e-10 && dett != 0.0);
+
+                            if( dett < 0 )	{
+                                continue;
+                            }
+                            /* found if all det are greater than zero */
+                            if( det[0] >= 0.0f && det[1] >= 0.0f && det[2] >= 0.0f ) {
+                                found = 1;
+                            }
+                            if( found ) {
+                                double				shape[3];
+                                Index				tNode_I;
+
+                                /* mark, such that we dont do it again */
+                                ind[ijk[0]+ijk[2]*nNodeX] = 1;
+
+                                /* Calculate the shape funcs */
+                                for( tNode_I = 0; tNode_I < 3; tNode_I++ ) {
+                                    shape[tNode_I] = det[tNode_I] / dett;
+                                }
+
+                                /* Assign proper values of velocities and temperatures from old mesh to new mesh */
+                                x1[0] = initialNodeCoordS[0];
+                                x1[1] = y1*shape[0] + y2*shape[1] + y3*shape[2];
+                                x1[2] = initialNodeCoordS[2];
+                                tpr2xyzCoord( x1, &meshExt->newNodeCoord[node_lI] );
+                            }
+#if 0
+                            if(context->rank==2 && node_lI==594)
+                                fprintf(stderr,"Shadow Found? %d TOL=%e timeStep=%d me=%d element_lI=%d node_lI=%d tetra_I=%d\nxc=(%e %e %e) (%e %e %e)(%e %e %e) initialX=%e %e %e\nbbox=(%e %e) (%e %e)\ndett=%e %e %e %e\n\n",
+                                        found,TOL,context->timeStep,context->rank,element_lN,node_lI,tetra_I,
+                                        x1[0],x1[1],x1[2],x2[0],x2[1],x2[2],x3[0],x3[1],x3[2],
+                                        initialNodeCoordS[0],initialNodeCoordS[1],initialNodeCoordS[2],
+                                        elembbox[0][0],elembbox[1][0],elembbox[0][2],elembbox[1][2],
+                                        det[0],det[1],det[2],dett);
+#endif
+                        }
+                    }
+                }
+			}
+		All_passed = 1;
+		count = 0;
+		for( node_lK = 0; node_lK < nNodeZ; node_lK++ )
+			for( node_lII = 0; node_lII < nNodeX; node_lII++ ) {
+				node_lI=node_lII+(nNodeY-1)*nNodeX+node_lK*nNodeX*nNodeY;
+				if( ind[node_lII+node_lK*nNodeX] == 0 ) {
+					count++;
+					All_passed = 0;
+				}
+			}
+		if(TOL==0.0) TOL = 1.0e-10;
+		else TOL *= 10.0;
+		Journal_DPrintf( context->debug," In: %s, rank=%d Increased tolerance for Top: %e count=%d\n", __func__, context->rank, TOL,count );
+        Journal_Firewall( TOL <= 1.0e-03, context->snacError," In: %s, timeStep=%d rank=%d Increased tolerance for Top: %e count=%d\n", __func__, context->timeStep, context->rank, TOL,count );
+	}
+
+	/* Calculate the new node coordintates for the bottom-internal nodes. */
+    if(contextExt->bottomRestore) {
+        for( index = 0; index < meshExt->bottomInternalCount; index++ ) {
+			node_lI = meshExt->bottomInternalArray[index];
+			meshExt->newNodeCoord[node_lI][0] = meshExt->initialNodeCoord[node_lI][0];
+			meshExt->newNodeCoord[node_lI][1] = meshExt->initialNodeCoord[node_lI][1];
+			meshExt->newNodeCoord[node_lI][2] = meshExt->initialNodeCoord[node_lI][2];
+        }
+    }
+    else {
+        en_II[0] = 0;	en_II[1] = 1;	en_II[2] = 5;	en_II[3] = 4;
+        nn[0][0] = 0; nn[0][1] = 4; nn[0][2] = 1;
+        nn[1][0] = 1; nn[1][1] = 4; nn[1][2] = 5;
+        memset( ind, 0, sizeof( int ) * nNodeX * nNodeZ );
+
+        All_passed = 0;
+        TOL= 0.0f;
+        while(!All_passed) {
+			for( node_lK = 0; node_lK < nNodeZ; node_lK++ )
+				for( node_lII = 0; node_lII < nNodeX; node_lII++ ) {
+                    Element_NodeIndex		en_N;
+                    double				elembbox[2][DIM];
+                    Coord                           temp1,temp2;
+                    Node_LocalIndex**		elementNodeTbl = context->mesh->elementNodeTbl;
+                    Element_LocalIndex      searchElement_lI,searchElement_lK;
+					Tetrahedra_Index		tetra_I;
+					Coord				initialNodeCoord;
+					Coord				initialNodeCoordS;
+					IJK                             ijk;
+
+					node_lI = node_lII + node_lK*nNodeX*nNodeY;
+					RegularMeshUtils_Node_Local1DTo3D( decomp, node_lI, &ijk[0], &ijk[1], &ijk[2] );
+					element_lI = (ijk[0] <= 1)? 0 : (ijk[0]-1);
+					element_lK = (ijk[2] <= 1)? 0 : (ijk[2]-1);
+
+					if( ind[ijk[0]+ijk[2]*nNodeX] ) {
+						continue;
+					}
+
+					initialNodeCoord[0] = meshExt->initialNodeCoord[node_lI][0];
+					initialNodeCoord[1] = meshExt->initialNodeCoord[node_lI][1];
+					initialNodeCoord[2] = meshExt->initialNodeCoord[node_lI][2];
+					xyz2tprCoord( initialNodeCoord, &initialNodeCoordS );
+					initialNodeCoordS[1] = 0.0f;
+
+					for(searchElement_lK=0;searchElement_lK<numSearchElement;searchElement_lK++) {
+						if( (element_lK+searchElement_lK-numSearchDepth) < 0 || (element_lK+searchElement_lK-numSearchDepth) >= nElementZ )
+							continue;
+						for(searchElement_lI=0;searchElement_lI<numSearchElement;searchElement_lI++) {
+							if( (element_lI+searchElement_lI-numSearchDepth) < 0 || (element_lI+searchElement_lI-numSearchDepth) >= nElementX )
+								continue;
+							element_lN = (element_lI+searchElement_lI-numSearchDepth) + (element_lK+searchElement_lK-numSearchDepth)*nElementY*nElementX;
+
+							elementNodeCount = context->mesh->elementNodeCountTbl[element_lN];
+							if( elementNodeCount != (unsigned)NODES_PER_ELEMENT ) {
+								printf( "elementNodeCount != NODES_PER_ELEMENT  element_lN = %d", element_lN );
+								assert( 0 );
+							}
+
+							if( ind[ijk[0]+ijk[2]*nNodeX] )
+								break;
+
+							for( en_N = 0; en_N < 4; en_N++ ) {
+								node_lN = elementNodeTbl[element_lN][en_II[en_N]];
+								for( d = 0; d < DIM; d++ ) {
+									xc[en_II[en_N]*DIM+d] = Mesh_CoordAt( context->mesh, node_lN )[d];
+								}
+								// (0,1,2) <=> (x,y,z) <=> (fi,r,theta)
+								temp1[0] = xc[en_II[en_N]*DIM+0];
+								temp1[1] = xc[en_II[en_N]*DIM+1];
+								temp1[2] = xc[en_II[en_N]*DIM+2];
+								xyz2tprCoord( temp1, &temp2 );
+								xcs[en_II[en_N]*DIM+0] = temp2[0];
+								xcs[en_II[en_N]*DIM+1] = temp2[1];
+								xcs[en_II[en_N]*DIM+2] = temp2[2];
+							}
+
+							/* Calculate element's bounding box */
+							for( d = 0; d < DIM; d++ ) {
+								elembbox[0][d] = DBL_MAX;
+								elembbox[1][d] = DBL_MIN;
+							}
+							for( en_N = 0; en_N < 4; en_N++ ) {
+								for( d = 0; d < DIM; ++d ) {
+									elembbox[0][d] = MIN( elembbox[0][d], xcs[en_II[en_N]*DIM+d] );
+									elembbox[1][d] = MAX( elembbox[1][d], xcs[en_II[en_N]*DIM+d] );
+								}
+							}
+							/* If new mesh's current node is outside the bounding box, next loop */
+							if( initialNodeCoordS[0] < elembbox[0][0]-0.5f*(elembbox[1][0]-elembbox[0][0]) ||
+								initialNodeCoordS[0] > elembbox[1][0]+0.5f*(elembbox[1][0]-elembbox[0][0]) ||
+								initialNodeCoordS[2] < elembbox[0][2]-0.5f*(elembbox[1][2]-elembbox[0][2]) ||
+								initialNodeCoordS[2] > elembbox[1][2]+0.5f*(elembbox[1][2]-elembbox[0][2]) )
+								{
+									continue;
+								}
+
+							/* if the current coordinate is far enough fromt the initial position,
+							   try to interpolate surface topo. */
+							/* loop over 2 sub triangles in a rectangular element, work out the triangle it is in, and then interpolate */
+							for( tetra_I = 0; tetra_I < 2; tetra_I++ ) {
+								double				x1[DIM];
+								double				x2[DIM];
+								double				x3[DIM];
+								double				y1,y2,y3;
+								double				dett;
+								double				det[3];
+								Coord				axisA,axisB,axisC;
+								unsigned int		found=0;
+
+								for( d = 0; d < DIM; d++ ) {
+									x1[d] = xcs[nn[tetra_I][0]*DIM+d];
+									x2[d] = xcs[nn[tetra_I][1]*DIM+d];
+									x3[d] = xcs[nn[tetra_I][2]*DIM+d];
+								}
+								y1 = x1[1];
+								y2 = x2[1];
+								y3 = x3[1];
+								x1[1] = x2[1] = x3[1] = 0.0f;
+
+								Vector_Sub( axisA, x2, x1 );
+								Vector_Sub( axisB, x3, x1 );
+								Vector_Cross( axisC, axisA, axisB );
+								dett = 0.5*getSignedArea( axisC );
+								dett = isLargerThanZero2(dett, dett, TOL);
+
+								Vector_Sub( axisA, x2, initialNodeCoordS );
+								Vector_Sub( axisB, x3, initialNodeCoordS );
+
+								Vector_Cross( axisC, axisA, axisB );
+								det[0] = 0.5*getSignedArea( axisC );
+								det[0] = isLargerThanZero2(det[0], dett, TOL);
+								Vector_Sub( axisA, x3, initialNodeCoordS );
+								Vector_Sub( axisB, x1, initialNodeCoordS );
+								Vector_Cross( axisC, axisA, axisB );
+								det[1] = 0.5*getSignedArea( axisC );
+								det[1] = isLargerThanZero2(det[1], dett, TOL);
+								Vector_Sub( axisA, x1, initialNodeCoordS );
+								Vector_Sub( axisB, x2, initialNodeCoordS );
+								Vector_Cross( axisC, axisA, axisB );
+								det[2] = 0.5*getSignedArea( axisC );
+								det[2] = isLargerThanZero2(det[2], dett, TOL);
+								dett = det[0] + det[1] + det[2];
+
+								if( dett <= 0 )	{
+									printf( "Determinant evaluation is wrong node=%d\t xt[0]=%g \t xt[1]=%g \t xt[t]=%g\n",
+											en_N,
+											initialNodeCoordS[0],
+											initialNodeCoordS[1],
+											initialNodeCoordS[2]);
+									//assert(0);
+									continue;
+								}
+								/* found if all det are greater than zero */
+								if( det[0] >= 0.0f && det[1] >= 0.0f && det[2] >= 0.0f ) {
+									found = 1;
+								}
+								if( found ) {
+									double				shape[3];
+									Index				tNode_I;
+
+									/* mark, such that we dont do it again */
+									ind[ijk[0]+ijk[2]*nNodeX] = 1;
+
+									/* Calculate the shape funcs */
+									for( tNode_I = 0; tNode_I < 3; tNode_I++ ) {
+										shape[tNode_I] = det[tNode_I] / dett;
+									}
+
+									/* Assign proper values of velocities and temperatures from old mesh to new mesh */
+									x1[0] = initialNodeCoordS[0];
+									x1[1] = y1*shape[0] + y2*shape[1] + y3*shape[2];
+									x1[2] = initialNodeCoordS[2];
+									tpr2xyzCoord( x1, &meshExt->newNodeCoord[node_lI] );
+
+									break;
+								}
+#if 0
+								if(context->rank==0 && node_lI==0)
+									fprintf(stderr,"Found? %d timeStep=%d me=%d element_lI=%d node_lI=%d tetra_I=%d\nxc=(%e %e %e) (%e %e %e)(%e %e %e) initialX=%e %e %e\nbbox=(%e %e) (%e %e)\ndett=%e %e %e %e\n\n",
+											found,context->timeStep,context->rank,element_lN,node_lI,tetra_I,
+											x1[0],x1[1],x1[2],x2[0],x2[1],x2[2],x3[0],x3[1],x3[2],
+											initialNodeCoordS[0],initialNodeCoordS[1],initialNodeCoordS[2],
+											elembbox[0][0],elembbox[1][0],elembbox[0][2],elembbox[1][2],
+											det[0],det[1],det[2],dett);
+#endif
+							}
+						}
+					}
+					/*
+					** Loop over shadow elements
+					*/
+					for( rn_I = 0; rn_I < meshExt->neighbourRankCount; rn_I++ ) {
+						Element_ShadowIndex		element_sN;
+
+                        /* Loop over all the shadow elements to find one including node_lI */
+                        for( element_sN = 0; element_sN < meshExt->shadowElementRemoteCount[rn_I]; element_sN++ ) {
+                            Element_GlobalIndex		gElement_N = meshExt->shadowElementRemoteArray[rn_I][element_sN];
+                            Node_Index*			shadowElementNodesN = (Node_Index*)malloc( sizeof(Node_Index) * NODES_PER_ELEMENT );
+                            Index				en_N;
+                            double				elembbox[2][DIM];
+                            Node_GlobalIndex	elementNodeN[8];
+                            IJK                 eijkN;
+
+                            /* skip irrelevant elements or exit the loop once the interpolation is done (ind == 1). */
+                            RegularMeshUtils_Element_1DTo3D( decomp, gElement_N, &eijkN[0], &eijkN[1], &eijkN[2] );
+                            if(eijkN[1] != 0)
+                                continue;
+                            if(ind[ijk[0]+ijk[2]*nNodeX] == 1)
+                                break;
+
+                            /* Figure out node index */
+                            _HexaEL_BuildCornerIndices( context->mesh->layout->elementLayout, gElement_N, elementNodeN );
+                            for( en_N = 0; en_N < 8; en_N++ ) {
+                                Node_GlobalIndex	node_gN = elementNodeN[en_N];
+                                unsigned int		found = 0;
+                                node_lN = Mesh_NodeMapGlobalToLocal( context->mesh, node_gN );
+                                if( node_lN < meshExt->nodeLocalCount ) {
+                                    shadowElementNodesN[en_N] = node_lN;
+                                    found = 1;
+                                    elementNodeN[en_N] = node_lN;
+                                }
+                                else {
+                                    Node_ShadowIndex		node_sI;
+                                    for( node_sI = 0; node_sI < meshExt->shadowNodeRemoteCount[rn_I]; node_sI++ ) {
+                                        if( node_gN == meshExt->shadowNodeRemoteArray[rn_I][node_sI] ) {
+                                            shadowElementNodesN[en_N] =
+                                                context->mesh->nodeGlobalCount +
+                                                node_sI;
+                                            found = 1;
+                                            break;
+                                        }
+                                    }
+                                }
+                                assert( found ); /* we expected this to be a shadow node, but wasn't in list! */
+                            }
+
+                            elementNodeCount = (unsigned)NODES_PER_ELEMENT; /* Assume all shadow elements have 8 nodes per el */
+                            if( elementNodeCount != (unsigned)NODES_PER_ELEMENT ) {
+                                printf( "elementNodeCount != NODES_PER_ELEMENT  element_sN = %d", element_sN );
+                                assert( 0 );
+                            }
+
+
+                            /* create a local copy of the veocity and coords for each of the element's nodes of the old mesh */
+                            for( en_N = 0; en_N < 4; en_N++) {
+                                node_lN = shadowElementNodesN[en_II[en_N]];
+                                if( node_lN < context->mesh->nodeDomainCount ) {
+                                    for( d = 0; d < DIM; d++ ) {
+                                        xc[en_II[en_N]*DIM+d] = Mesh_CoordAt( context->mesh, node_lN )[d];
+                                    }
+                                }
+                                else {
+                                    node_lN -= context->mesh->nodeGlobalCount;
+                                    for( d = 0; d < DIM; d++ ) {
+                                        xc[en_II[en_N]*DIM+d] = meshExt->shadowNodeRemoteCoord[rn_I][node_lN][d];
+                                    }
+                                }
+                                // (0,1,2) <=> (x,y,z) <=> (fi,r,theta)
+                                temp1[0] = xc[en_II[en_N]*DIM+0];
+                                temp1[1] = xc[en_II[en_N]*DIM+1];
+                                temp1[2] = xc[en_II[en_N]*DIM+2];
+                                xyz2tprCoord( temp1, &temp2 );
+                                xcs[en_II[en_N]*DIM+0] = temp2[0];
+                                xcs[en_II[en_N]*DIM+1] = temp2[1];
+                                xcs[en_II[en_N]*DIM+2] = temp2[2];
+                            }
+
+                            /* Calculate element's bounding box */
+                            for( d = 0; d < DIM; d++ ) {
+                                elembbox[0][d] = DBL_MAX;
+                                elembbox[1][d] = DBL_MIN;
+                            }
+                            for( en_N = 0; en_N < 4; en_N++ ) {
+                                for( d = 0; d < DIM; ++d ) {
+                                    elembbox[0][d] = MIN( elembbox[0][d], xcs[en_II[en_N]*DIM+d] );
+                                    elembbox[1][d] = MAX( elembbox[1][d], xcs[en_II[en_N]*DIM+d] );
+                                }
+                            }
+                            /* If new mesh's current node is outside the bounding box, next loop */
+                            if( initialNodeCoordS[0] < elembbox[0][0]-0.5f*(elembbox[1][0]-elembbox[0][0]) ||
+                                initialNodeCoordS[0] > elembbox[1][0]+0.5f*(elembbox[1][0]-elembbox[0][0]) ||
+                                initialNodeCoordS[2] < elembbox[0][2]-0.5f*(elembbox[1][2]-elembbox[0][2]) ||
+                                initialNodeCoordS[2] > elembbox[1][2]+0.5f*(elembbox[1][2]-elembbox[0][2]) )
+                                {
+                                    continue;
+                                }
+
+                            /* if the current coord is very close to the initial ones, just copy those initial values rather than bothering to compute determinents and adding error */
+                            if( ( initialNodeCoord[0] >= Mesh_CoordAt( context->mesh, node_lI )[0] - TOL*(elembbox[1][0]-elembbox[0][0]) && initialNodeCoord[0] <= Mesh_CoordAt( context->mesh, node_lI )[0] + TOL*(elembbox[1][0]-elembbox[0][0]) ) &&
+                                ( initialNodeCoord[1] >= Mesh_CoordAt( context->mesh, node_lI )[1] - TOL*(elembbox[1][1]-elembbox[0][1]) && initialNodeCoord[1] <= Mesh_CoordAt( context->mesh, node_lI )[1] + TOL*(elembbox[1][1]-elembbox[0][1]) ) &&
+                                ( initialNodeCoord[2] >= Mesh_CoordAt( context->mesh, node_lI )[2] - TOL*(elembbox[1][2]-elembbox[0][2]) && initialNodeCoord[2] <= Mesh_CoordAt( context->mesh, node_lI )[2] + TOL*(elembbox[1][2]-elembbox[0][2]) ) ) {
+                                meshExt->newNodeCoord[node_lI][0] = initialNodeCoord[0];
+                                meshExt->newNodeCoord[node_lI][1] = Mesh_CoordAt( context->mesh, node_lI )[1];
+                                meshExt->newNodeCoord[node_lI][2] = initialNodeCoord[2];
+                                ind[ijk[0]+ijk[2]*nNodeX] = 1;
+                                continue;
+                            }
+
+                            /* if the current coordinate is far enough fromt the initial position,
+                               try to interpolate surface topo. */
+                            /* loop over 2 sub triangles in a rectangular element, work out the triangle it is in, and then interpolate */
+                            for( tetra_I = 0; tetra_I < 2; tetra_I++ ) {
+                                double				x1[DIM];
+                                double				x2[DIM];
+                                double				x3[DIM];
+                                double				y1,y2,y3;
+                                double				dett;
+                                double				det[3];
+								Coord				axisA,axisB,axisC;
+								unsigned int		found=0;
+
+                                for( d = 0; d < DIM; d++ ) {
+                                    x1[d] = xcs[nn[tetra_I][0]*DIM+d];
+                                    x2[d] = xcs[nn[tetra_I][1]*DIM+d];
+                                    x3[d] = xcs[nn[tetra_I][2]*DIM+d];
+                                }
+                                y1 = x1[1];
+                                y2 = x2[1];
+                                y3 = x3[1];
+                                x1[1] = x2[1] = x3[1] = 0.0f;
+
+                                Vector_Sub( axisA, x2, x1 );
+                                Vector_Sub( axisB, x3, x1 );
+                                Vector_Cross( axisC, axisA, axisB );
+                                dett = 0.5*getSignedArea( axisC );
+                                dett = isLargerThanZero2(dett, dett, TOL);
+
+                                Vector_Sub( axisA, x2, initialNodeCoordS );
+                                Vector_Sub( axisB, x3, initialNodeCoordS );
+                                Vector_Cross( axisC, axisA, axisB );
+                                det[0] = 0.5*getSignedArea( axisC );
+                                det[0] = isLargerThanZero2(det[0], dett, TOL);
+                                Vector_Sub( axisA, x3, initialNodeCoordS );
+                                Vector_Sub( axisB, x1, initialNodeCoordS );
+                                Vector_Cross( axisC, axisA, axisB );
+                                det[1] = 0.5*getSignedArea( axisC );
+                                det[1] = isLargerThanZero2(det[1], dett, TOL);
+                                Vector_Sub( axisA, x1, initialNodeCoordS );
+                                Vector_Sub( axisB, x2, initialNodeCoordS );
+                                Vector_Cross( axisC, axisA, axisB );
+                                det[2] = 0.5*getSignedArea( axisC );
+                                det[2] = isLargerThanZero2(det[2], dett, TOL);
+                                dett = det[0] + det[1] + det[2];
+
+                                assert( dett > 0.0);
+                                if( dett <= 0 )	{
+									continue;
+                                }
+                                /* found if all det are greater than zero */
+                                if( det[0] >= 0.0f && det[1] >= 0.0f && det[2] >= 0.0f ) {
+                                    found = 1;
+                                }
+                                if( found ) {
+                                    double				shape[3];
+                                    Index				tNode_I;
+
+                                    /* mark, such that we dont do it again */
+                                    RegularMeshUtils_Node_Local1DTo3D( decomp, node_lI, &ijk[0], &ijk[1], &ijk[2] );
+                                    ind[ijk[0]+ijk[2]*nNodeX] = 1;
+
+                                    /* Calculate the shape funcs */
+                                    for( tNode_I = 0; tNode_I < 3; tNode_I++ ) {
+                                        shape[tNode_I] = det[tNode_I] / dett;
+                                    }
+
+                                    /* Assign proper values of velocities and temperatures from old mesh to new mesh */
+                                    x1[0] = initialNodeCoordS[0];
+                                    x1[1] = y1*shape[0] + y2*shape[1] + y3*shape[2];
+                                    x1[2] = initialNodeCoordS[2];
+                                    tpr2xyzCoord( x1, &meshExt->newNodeCoord[node_lI] );
+                                }
+#if 0
+                                if(context->rank==0 && node_lI==0)
+                                    fprintf(stderr,"Shadow Found? %d timeStep=%d me=%d element_lI=%d node_lI=%d tetra_I=%d\nxc=(%e %e %e) (%e %e %e)(%e %e %e) initialX=%e %e %e\nbbox=(%e %e) (%e %e)\ndett=%e %e %e %e\n\n",
+                                            found,context->timeStep,context->rank,element_lN,node_lI,tetra_I,
+                                            x1[0],x1[1],x1[2],x2[0],x2[1],x2[2],x3[0],x3[1],x3[2],
+                                            initialNodeCoordS[0],initialNodeCoordS[1],initialNodeCoordS[2],
+                                            elembbox[0][0],elembbox[1][0],elembbox[0][2],elembbox[1][2],
+                                            det[0],det[1],det[2],dett);
+#endif
+                            }
+                        }
+                    }
+                }
+			All_passed = 1;
+			count = 0;
+			for( node_lK = 0; node_lK < nNodeZ; node_lK++ )
+				for( node_lII = 0; node_lII < nNodeX; node_lII++ ) {
+					node_lI=node_lII+(nNodeY-1)*nNodeX+node_lK*nNodeX*nNodeY;
+					if( ind[node_lII+node_lK*nNodeX] == 0 ) {
+						All_passed = 0;
+						count++;
+						//fprintf(stderr,"me=%d failed Bottom nodes=%d\n",context->rank,node_lI);
+					}
+				}
+			if(TOL==0.0)TOL = 1.0e-10;
+			else TOL *= 10.0;
+			Journal_DPrintf( context->debug," In: %s, rank=%d Increased tolerance for Bottom: %e count=%d\n", __func__, context->rank, TOL, count );
+			Journal_Firewall( TOL <= 1.0e-03, context->snacError," In: %s, timeStep=%d rank=%d Increased tolerance for Bottom: %e count=%d\n", __func__, context->timeStep, context->rank, TOL,count );
+		}
+	}
+	free( ind );
+
+	/* Calculate the new node coordintates for the wall nodes. */
+	if( meshExt->meshType == -1 ) {
+		assert( 0 );
+	}
+	else {
+		for( index = 0; index < meshExt->wallCount; index++ ) {
+			Node_LocalIndex				node_lI;
+			IJK					ijk;
+			Node_LocalIndex				nodeTop_lI, nodeBottom_lI;
+			const Index 				topI = decomp->nodeLocal3DCounts[decomp->rank][1];
+			Coord                                   temp,tempTop,tempBottom;
+			node_lI = meshExt->wallArray[index];
+			RegularMeshUtils_Node_Local1DTo3D( decomp, node_lI, &ijk[0], &ijk[1], &ijk[2] );
+
+			/* The wall node positions revert to the initial position */
+			nodeBottom_lI = RegularMeshUtils_Node_Local3DTo1D( decomp, ijk[0], 0, ijk[2] );
+			nodeTop_lI = RegularMeshUtils_Node_Local3DTo1D( decomp, ijk[0], topI - 1, ijk[2] );
+
+			xyz2tprCoord( meshExt->initialNodeCoord[node_lI], &temp );
+			xyz2tprCoord( meshExt->newNodeCoord[nodeTop_lI], &tempTop );
+			xyz2tprCoord( meshExt->newNodeCoord[nodeBottom_lI], &tempBottom );
+
+			temp[1] = tempBottom[1] + (tempTop[1] - tempBottom[1])/(topI - 1 )*ijk[1];
+
+			tpr2xyzCoord( temp, &meshExt->newNodeCoord[node_lI] );
+		}
+	}
+
+	/* Calculate the new node coordintates for the internal nodes. */
+	for( index = 0; index < meshExt->internalCount; index++ ) {
+		Node_LocalIndex				node_lI;
+		IJK					ijk;
+		Node_LocalIndex				nodeBottom_lI, nodeLeft_lI, nodeFront_lI;
+		Node_LocalIndex				nodeTop_lI, nodeRight_lI, nodeBack_lI;
+		const Index 				topI = decomp->nodeLocal3DCounts[decomp->rank][1];
+		const Index				rightI = decomp->nodeLocal3DCounts[decomp->rank][0];
+		const Index				frontI = decomp->nodeLocal3DCounts[decomp->rank][2];
+		Coord                                   temp,tempTop,tempBottom,tempLeft,tempRight,tempBack,tempFront;
+
+		/* TODO... parallel version! */
+		node_lI = meshExt->internalArray[index];
+		RegularMeshUtils_Node_Local1DTo3D( decomp, node_lI, &ijk[0], &ijk[1], &ijk[2] );
+		/* TODO... Local? where's the global equivalent? */
+		nodeBottom_lI = RegularMeshUtils_Node_Local3DTo1D( decomp, ijk[0], 0, ijk[2] );
+		nodeTop_lI = RegularMeshUtils_Node_Local3DTo1D( decomp, ijk[0], topI - 1, ijk[2] );
+		nodeLeft_lI = RegularMeshUtils_Node_Local3DTo1D( decomp, 0, ijk[1], ijk[2] );
+		nodeRight_lI = RegularMeshUtils_Node_Local3DTo1D( decomp, rightI - 1, ijk[1], ijk[2] );
+		nodeBack_lI = RegularMeshUtils_Node_Local3DTo1D( decomp, ijk[0], ijk[1], 0 );
+		nodeFront_lI = RegularMeshUtils_Node_Local3DTo1D( decomp, ijk[0], ijk[1], frontI - 1 );
+		xyz2tprCoord( meshExt->newNodeCoord[nodeTop_lI], &tempTop );
+		xyz2tprCoord( meshExt->newNodeCoord[nodeBottom_lI], &tempBottom );
+		xyz2tprCoord( meshExt->initialNodeCoord[nodeLeft_lI], &tempLeft );
+		xyz2tprCoord( meshExt->initialNodeCoord[nodeRight_lI], &tempRight );
+		xyz2tprCoord( meshExt->initialNodeCoord[nodeBack_lI], &tempBack );
+		xyz2tprCoord( meshExt->initialNodeCoord[nodeFront_lI], &tempFront );
+
+		temp[0] = tempLeft[0] + (tempRight[0] - tempLeft[0])/(rightI - 1 )*ijk[0];
+		temp[1] = tempBottom[1] + (tempTop[1] - tempBottom[1])/(topI - 1 )*ijk[1];
+		temp[2] = tempBack[2] + (tempFront[2] - tempBack[2])/(frontI - 1 )*ijk[2];
+
+		tpr2xyzCoord( temp, &meshExt->newNodeCoord[node_lI] );
+	}
+}
+
+double isLargerThanZero(double a, double TOL)
+{
+	if(a>=-1.0*TOL && a<=TOL)
+		return 0.0f;
+	else
+		return a;
+}
+double isLargerThanZero2(double a, double refval, double TOL)
+{
+	if(a>=-1.0*fabs(refval)*TOL && a<=fabs(refval)*TOL)
+		return 0.0f;
+	else
+		return a;
+}
+double getSignedArea( Coord a )
+{
+	if(a[1] >= 0.0)
+		return Vector_Mag(a);
+	else
+		return -1.0f*Vector_Mag(a);
+}
+void xyz2tprCoord( Coord x, Coord* dest )
+{
+	(*dest)[0] = atan2(x[1],x[0]);
+	(*dest)[1] = sqrt(x[0]*x[0]+x[1]*x[1]+x[2]*x[2]);
+	(*dest)[2] = acos(x[2]/(*dest)[1]);
+}
+void tpr2xyzCoord( Coord s, Coord* dest )
+{
+	(*dest)[0] = s[1]*sin(s[2])*cos(s[0]);
+	(*dest)[1] = s[1]*sin(s[2])*sin(s[0]);
+	(*dest)[2] = s[1]*cos(s[2]);
+}
+void xyz2tprVel( Coord x, Coord vx, Coord* dest )
+{
+	Coord s;
+	xyz2tprCoord( x, &s );
+	(*dest)[0] = -1.0f*vx[0]*sin(s[0])+vx[1]*cos(s[0]);
+	(*dest)[1] = vx[0]*sin(s[2])*cos(s[0])+vx[1]*sin(s[2])*sin(s[0])+vx[2]*cos(s[2]);
+	(*dest)[2] = vx[0]*cos(s[2])*cos(s[0])+vx[1]*cos(s[2])*sin(s[0])-vx[2]*sin(s[2]);
+}
+void tpr2xyzVel( Coord s, Coord vs, Coord* dest )
+{
+	(*dest)[0] = vs[1]*sin(s[2])*cos(s[0])+vs[2]*cos(s[2])*cos(s[0])-vs[0]*sin(s[0]);
+	(*dest)[1] = vs[1]*sin(s[2])*sin(s[0])+vs[2]*cos(s[2])*sin(s[0])+vs[0]*cos(s[0]);
+	(*dest)[2] = vs[1]*cos(s[2])-vs[2]*sin(s[2]);
+}
+#endif

Added: long/3D/SNAC/trunk/Snac/plugins/remesher_BI/RemeshElements.c
===================================================================
--- long/3D/SNAC/trunk/Snac/plugins/remesher_BI/RemeshElements.c	                        (rev 0)
+++ long/3D/SNAC/trunk/Snac/plugins/remesher_BI/RemeshElements.c	2011-10-07 16:18:20 UTC (rev 19040)
@@ -0,0 +1,886 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+**
+** Copyright (C), 2003,
+**	Pururav Thoutireddy,
+**	Californian Institute of Technology, 1200 East California Boulevard, Pasadena, California, 91125, USA.
+**	110 Victoria Street, Melbourne, Victoria, 3053, Australia.
+**	University of Texas, 1 University Station, Austin, Texas, 78712, USA.
+**
+** Authors:
+**	Pururav Thoutireddy, Staff Scientist, Caltech
+**	Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
+**	Stevan M. Quenette, Visitor in Geophysics, Caltech.
+**	Luc Lavier, Research Scientist, The University of Texas. (luc at utig.ug.utexas.edu)
+**	Luc Lavier, Research Scientist, Caltech.
+**
+** This program is free software; you can redistribute it and/or modify it
+** under the terms of the GNU General Public License as published by the
+** Free Software Foundation; either version 2, or (at your option) any
+** later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+**
+** $Id: RemeshElements.c 3259 2006-11-09 20:06:31Z EunseoChoi $
+**
+**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#include <mpi.h>
+#include <StGermain/StGermain.h>
+#include <StGermain/FD/FD.h>
+#include "Snac/Snac.h"
+#include "types.h"
+#include "EntryPoint.h"
+#include "Mesh.h"
+#include "Context.h"
+#include "Remesh.h"
+#include "Register.h"
+#include "Utils.h"
+
+#include <string.h>
+#include <math.h>
+#include <assert.h>
+#include <float.h>
+
+
+void _SnacRemesher_InterpolateElements( void* _context ) {
+	Snac_Context*			context = (Snac_Context*)_context;
+	SnacRemesher_Context*	contextExt = ExtensionManager_Get( context->extensionMgr, 
+															   context, 
+															   SnacRemesher_ContextHandle );
+	Mesh*					mesh = context->mesh;
+	SnacRemesher_Mesh*		meshExt = ExtensionManager_Get( context->meshExtensionMgr,
+															mesh, 
+															SnacRemesher_MeshHandle );
+	HexaMD*					decomp = (HexaMD*)mesh->layout->decomp;
+	Element_LocalIndex		element_lI;
+	Element_DomainIndex		element_dI;
+	Tetrahedra_Index		tet_I;
+
+	Element_DomainIndex		ellI,ellJ,ellK; 
+	Element_DomainIndex		nellI = decomp->elementLocal3DCounts[decomp->rank][0];
+	Element_DomainIndex		nellJ = decomp->elementLocal3DCounts[decomp->rank][1];
+	Element_DomainIndex		nellK = decomp->elementLocal3DCounts[decomp->rank][2];
+	Element_DomainIndex		eldI,eldJ,eldK; 
+	Element_DomainIndex		neldI =  decomp->elementDomain3DCounts[0];
+	Element_DomainIndex		neldJ =  decomp->elementDomain3DCounts[1];
+	Element_DomainIndex		neldK =  decomp->elementDomain3DCounts[2];
+	
+	void Tet_Barycenter( Coord tetCrds[4], Coord center );
+	void createBarycenterGrids( void* _context );
+
+	struct dist_elem_pair { double dist; unsigned int id; };
+	int dist_compare( const void* dist1, const void* dist2 ) {
+		/* double v1 = *(double *)dist1; */
+		/* double v2 = *(double *)dist2; */
+		double v1 = ((struct dist_elem_pair *)dist1)->dist;
+		double v2 = ((struct dist_elem_pair *)dist2)->dist;
+		//return (dist1<dist2) ? -1 : (dist1>dist2) ? 1 : 0;
+		return (v1<v2) ? -1 : (v1>v2) ? 1 : 0;
+	};
+	
+	/* Create old and new grids of barycenters */
+	createBarycenterGrids( context );
+	
+	/*
+	** Free any owned arrays that may still exist from the last node interpolation.
+	*/
+	FreeArray( meshExt->externalElements );
+	meshExt->nExternalElements = 0;
+	
+	/*
+	** Interpolate all new elements.
+	*/
+	
+	/* Compute coefficients for barycentric coordinates. */
+	for( eldI = 0; eldI < neldI-1; eldI++ ) 
+		for( eldJ = 0; eldJ < neldJ-1; eldJ++ ) 
+			for( eldK = 0; eldK < neldK-1; eldK++ ) {
+				Coord				hexCrds[8];
+				Tetrahedra_Index	tet_I;
+				Index				coef_i;
+				
+				/* Old domain grid is constructed: i.e., ghost elements are included in this grid. */
+				element_dI = eldI+eldJ*neldI+eldK*neldI*neldJ;
+
+				/* Eight-node hex defined. */
+				Vector_Set( hexCrds[0], meshExt->oldBarycenters[eldI+eldJ*neldI+eldK*neldI*neldJ] );
+				Vector_Set( hexCrds[1], meshExt->oldBarycenters[eldI+1+eldJ*neldI+eldK*neldI*neldJ] );
+				Vector_Set( hexCrds[2], meshExt->oldBarycenters[eldI+1+(eldJ+1)*neldI+eldK*neldI*neldJ] );
+				Vector_Set( hexCrds[3], meshExt->oldBarycenters[eldI+(eldJ+1)*neldI+eldK*neldI*neldJ] );
+				Vector_Set( hexCrds[4], meshExt->oldBarycenters[eldI+eldJ*neldI+(eldK+1)*neldI*neldJ] );
+				Vector_Set( hexCrds[5], meshExt->oldBarycenters[eldI+1+eldJ*neldI+(eldK+1)*neldI*neldJ] );
+				Vector_Set( hexCrds[6], meshExt->oldBarycenters[eldI+1+(eldJ+1)*neldI+(eldK+1)*neldI*neldJ] );
+				Vector_Set( hexCrds[7], meshExt->oldBarycenters[eldI+(eldJ+1)*neldI+(eldK+1)*neldI*neldJ] );
+				
+				for(tet_I=0;tet_I<5;tet_I++) {
+					/*
+					  [Ta Tb Tc] = [x0-x3 x1-x3 x2-x3]
+					  [Td Te Tf] = [y0-y3 y1-y3 y2-y3]
+					  [Tg Th Tk] = [z0-z3 z1-z3 z2-z3]
+					*/
+					double Ta = hexCrds[TetraToNode[tet_I][0]][0] - hexCrds[TetraToNode[tet_I][3]][0];
+					double Tb = hexCrds[TetraToNode[tet_I][1]][0] - hexCrds[TetraToNode[tet_I][3]][0];
+					double Tc = hexCrds[TetraToNode[tet_I][2]][0] - hexCrds[TetraToNode[tet_I][3]][0];
+					double Td = hexCrds[TetraToNode[tet_I][0]][1] - hexCrds[TetraToNode[tet_I][3]][1];
+					double Te = hexCrds[TetraToNode[tet_I][1]][1] - hexCrds[TetraToNode[tet_I][3]][1];
+					double Tf = hexCrds[TetraToNode[tet_I][2]][1] - hexCrds[TetraToNode[tet_I][3]][1];
+					double Tg = hexCrds[TetraToNode[tet_I][0]][2] - hexCrds[TetraToNode[tet_I][3]][2];
+					double Th = hexCrds[TetraToNode[tet_I][1]][2] - hexCrds[TetraToNode[tet_I][3]][2];
+					double Tk = hexCrds[TetraToNode[tet_I][2]][2] - hexCrds[TetraToNode[tet_I][3]][2];
+
+					double detT = Ta*(Te*Tk-Tf*Th) + Tb*(Tf*Tg-Tk*Td) + Tc*(Td*Th-Te*Tg);
+					/*
+					  Li(x,y,z) = a0*x+a1*y+a2*z+a3
+					*/
+					/* L1 coeffs */
+					meshExt->barcoef[element_dI].coef[tet_I][0][0] = (Te*Tk-Tf*Th)/detT;
+					meshExt->barcoef[element_dI].coef[tet_I][0][1] = (Tc*Th-Tb*Tk)/detT;
+					meshExt->barcoef[element_dI].coef[tet_I][0][2] = (Tb*Tf-Tc*Te)/detT;
+					meshExt->barcoef[element_dI].coef[tet_I][0][3] = 0.0;
+					/* L2 coeffs */
+					meshExt->barcoef[element_dI].coef[tet_I][1][0] = (Tf*Tg-Td*Tk)/detT;
+					meshExt->barcoef[element_dI].coef[tet_I][1][1] = (Ta*Tk-Tc*Tg)/detT;
+					meshExt->barcoef[element_dI].coef[tet_I][1][2] = (Tc*Td-Ta*Tf)/detT;
+					meshExt->barcoef[element_dI].coef[tet_I][1][3] = 0.0;
+					/* L3 coeffs */
+					meshExt->barcoef[element_dI].coef[tet_I][2][0] = (Td*Th-Te*Tg)/detT;
+					meshExt->barcoef[element_dI].coef[tet_I][2][1] = (Tg*Tb-Ta*Th)/detT;
+					meshExt->barcoef[element_dI].coef[tet_I][2][2] = (Ta*Te-Tb*Td)/detT;
+					meshExt->barcoef[element_dI].coef[tet_I][2][3] = 0.0;
+					/* L4 not needed because L4 = 1.0 - (L1 + L2 + L3) */
+
+					for(coef_i=0;coef_i<3;coef_i++) {
+						meshExt->barcoef[element_dI].coef[tet_I][0][3] -= meshExt->barcoef[element_dI].coef[tet_I][0][coef_i]*hexCrds[TetraToNode[tet_I][3]][coef_i];
+						meshExt->barcoef[element_dI].coef[tet_I][1][3] -= meshExt->barcoef[element_dI].coef[tet_I][1][coef_i]*hexCrds[TetraToNode[tet_I][3]][coef_i];
+						meshExt->barcoef[element_dI].coef[tet_I][2][3] -= meshExt->barcoef[element_dI].coef[tet_I][2][coef_i]*hexCrds[TetraToNode[tet_I][3]][coef_i];
+					}
+				}
+			}
+	
+	/* First find a containing tet in the grid of old hex's barycenters 
+	   and compute barycentric coordinates. */
+	for( ellK = 0; ellK < nellK; ellK++ ) 
+		for( ellJ = 0; ellJ < nellJ; ellJ++ ) 
+			for( ellI = 0; ellI < nellI; ellI++ ) {
+				unsigned			found_tet;
+				
+				Element_DomainIndex	eldI,eldJ,eldK; 
+				Element_DomainIndex	neldI =  decomp->elementDomain3DCounts[0];
+				Element_DomainIndex	neldJ =  decomp->elementDomain3DCounts[1];
+				Element_DomainIndex	neldK =  decomp->elementDomain3DCounts[2];
+				Element_DomainIndex	mindI,mindJ,mindK,maxdI,maxdJ,maxdK,searchI;
+
+				double				lambda_sqrd = 0.0;
+				double				lambda_sqrd_min = 1e+16;
+				Element_DomainIndex	closest_dI=0;
+				Tetrahedra_Index	closest_tI=0;
+
+				/* Grid of new barycenters is constructed without ghost elements included. */
+				element_lI = ellI+ellJ*nellI+ellK*nellI*nellJ;
+				
+				/* Start searching near the element in old barycenter grid 
+				   of which domain element number is equal to element_lI. */ 
+				searchI = 2;
+				mindI = (((ellI-searchI)<0)?0:(ellI-searchI));
+				mindJ = (((ellJ-searchI)<0)?0:(ellJ-searchI));
+				mindK = (((ellK-searchI)<0)?0:(ellK-searchI));
+				maxdI = (((ellI+searchI)>=neldI)?(neldI-1):(ellI+searchI));
+				maxdJ = (((ellJ+searchI)>=neldJ)?(neldJ-1):(ellJ+searchI));
+				maxdK = (((ellK+searchI)>=neldK)?(neldK-1):(ellK+searchI));
+				found_tet = 0;
+				for( eldK = mindK; eldK < maxdK; eldK++ ) {
+					for( eldJ = mindJ; eldJ < maxdJ; eldJ++ ) {
+						for( eldI = mindI; eldI < maxdI; eldI++ ) {
+							element_dI = eldI+eldJ*neldI+eldK*neldI*neldJ;
+							for(tet_I=0;tet_I<5;tet_I++) {
+								Index	coef_I;
+								double 	lambda[4];
+								double 	tol_error = 1e-4;
+								lambda[3] = 1.0;
+								for(coef_I=0;coef_I<3;coef_I++) {
+									lambda[coef_I] =
+										meshExt->newBarycenters[element_lI][0]*meshExt->barcoef[element_dI].coef[tet_I][coef_I][0] +
+										meshExt->newBarycenters[element_lI][1]*meshExt->barcoef[element_dI].coef[tet_I][coef_I][1] +
+										meshExt->newBarycenters[element_lI][2]*meshExt->barcoef[element_dI].coef[tet_I][coef_I][2] +
+										meshExt->barcoef[element_dI].coef[tet_I][coef_I][3];
+									lambda[3] -= lambda[coef_I];
+								}
+								/* Keep track of closest element in case the current new barycenter is outside of the old grid. */
+								for(coef_I=0;coef_I<3;coef_I++) 
+									lambda_sqrd += lambda[coef_I]*lambda[coef_I];
+								if( lambda_sqrd < lambda_sqrd_min ) {
+									lambda_sqrd_min = lambda_sqrd;
+									closest_dI = element_dI;
+									closest_tI = tet_I;
+								}
+
+								/* See if the barycenter is inside this tet. */
+								if( (lambda[0] >= -tol_error && lambda[0] <= (1.0+tol_error)) &&
+									(lambda[1] >= -tol_error && lambda[1] <= (1.0+tol_error)) &&
+									(lambda[2] >= -tol_error && lambda[2] <= (1.0+tol_error)) &&
+									(lambda[3] >= -tol_error && lambda[3] <= (1.0+tol_error)) ) {
+									found_tet = 1;
+									memcpy( meshExt->barcord[element_lI].L, lambda, sizeof(double)*4);
+									meshExt->barcord[element_lI].elnum = element_dI;
+									meshExt->barcord[element_lI].tetnum = tet_I;
+									break; /* break tet loop */
+								}
+							}
+							if( found_tet ) break; /* break eldI loop */
+						}
+						if( found_tet ) break; /* break eldJ loop */
+					}
+					if( found_tet ) break; /* break eldK loop */
+				} /* end of domain element search */
+
+				/* see if the point is outside of the old mesh.
+				   Assumed is that the current new barycenter is at least closest to "closest_dI" element. */
+				if( !found_tet ) { 
+					Index 					dim_I;
+					Coord					hexCrds[8];
+					struct dist_elem_pair 	dist_apexes[4];
+					double 					dist_sum;
+					Index 					apex_I;
+
+					/* Decompose closest_dI into ijk indexes. */
+					eldI = closest_dI % neldI;
+					eldJ = ((closest_dI-eldI)/neldI) % neldJ;
+					eldK = (closest_dI-eldI-eldJ*neldI)/(neldI*neldJ);
+
+					/* Eight-node hex defined. */
+					Vector_Set( hexCrds[0], meshExt->oldBarycenters[eldI+eldJ*neldI+eldK*neldI*neldJ] );
+					Vector_Set( hexCrds[1], meshExt->oldBarycenters[eldI+1+eldJ*neldI+eldK*neldI*neldJ] );
+					Vector_Set( hexCrds[2], meshExt->oldBarycenters[eldI+1+(eldJ+1)*neldI+eldK*neldI*neldJ] );
+					Vector_Set( hexCrds[3], meshExt->oldBarycenters[eldI+(eldJ+1)*neldI+eldK*neldI*neldJ] );
+					Vector_Set( hexCrds[4], meshExt->oldBarycenters[eldI+eldJ*neldI+(eldK+1)*neldI*neldJ] );
+					Vector_Set( hexCrds[5], meshExt->oldBarycenters[eldI+1+eldJ*neldI+(eldK+1)*neldI*neldJ] );
+					Vector_Set( hexCrds[6], meshExt->oldBarycenters[eldI+1+(eldJ+1)*neldI+(eldK+1)*neldI*neldJ] );
+					Vector_Set( hexCrds[7], meshExt->oldBarycenters[eldI+(eldJ+1)*neldI+(eldK+1)*neldI*neldJ] );
+					
+					/* compute distances to tet apexes to find the closest three (supposedly forming the closes face).*/
+					for( apex_I = 0; apex_I < 4; apex_I++ ) {
+						double tmp = 0.0;
+						for( dim_I = 0; dim_I < 3; dim_I++ ) 
+							tmp += pow((meshExt->newBarycenters[element_lI][dim_I]-hexCrds[TetraToNode[closest_tI][apex_I]][dim_I]),2.0);
+						dist_apexes[apex_I].dist = sqrt(tmp);
+						dist_apexes[apex_I].id = apex_I;
+					}
+					qsort( (void *)dist_apexes, 4, sizeof(struct dist_elem_pair), dist_compare ); /* dist arrary sorted in the ascending order. */
+					
+					dist_sum = 0.0;
+					for( apex_I = 0; apex_I < 3; apex_I++ ) 
+						dist_sum += (1.0/dist_apexes[apex_I].dist);
+						
+					found_tet = 1;
+					for( apex_I = 0; apex_I < 3; apex_I++ ) 
+						meshExt->barcord[element_lI].L[dist_apexes[apex_I].id] = (1.0/dist_apexes[apex_I].dist)/dist_sum;
+					meshExt->barcord[element_lI].L[dist_apexes[3].id] = 0.0;
+					meshExt->barcord[element_lI].elnum = closest_dI;
+					meshExt->barcord[element_lI].tetnum = closest_tI;
+				}
+			} /* end of loop oever new barycenters. */
+	
+	/* Finally, ready to interpolation for every element in the new "Local" mesh. */
+	for( element_lI = 0; element_lI < mesh->elementLocalCount; element_lI++ ) 
+		for(tet_I=0;tet_I<5;tet_I++) 
+			SnacRemesher_InterpolateElement( context, contextExt,
+											 element_lI, tet_I,
+											 meshExt->newElements,
+											 meshExt->barcord[element_lI].elnum, 
+											 meshExt->barcord[element_lI].tetnum );
+	
+}
+
+void createBarycenterGrids( void* _context ) {
+
+	Snac_Context*			context = (Snac_Context*)_context;
+	Mesh*					mesh = context->mesh;
+	SnacRemesher_Mesh*		meshExt = ExtensionManager_Get( context->meshExtensionMgr,
+												  mesh, 
+												  SnacRemesher_MeshHandle );
+	NodeLayout*				nLayout = mesh->layout->nodeLayout;
+	Element_LocalIndex		element_lI;
+	Element_DomainIndex		element_dI;
+
+	/* Loop over the new elements. */
+	for( element_lI = 0; element_lI < mesh->elementLocalCount; element_lI++ ) {
+		unsigned			nEltNodes;
+		Node_DomainIndex*	eltNodes;
+		
+		/* Extract the element's node indices.  Note that there should always be eight of these. */
+		{
+			Element_GlobalIndex	gEltInd;
+			
+			nEltNodes = 8;
+			eltNodes = Memory_Alloc_Array( Node_DomainIndex, nEltNodes, "SnacRemesher" );
+			//element_gI = Mesh_ElementMapLocalToGlobal( mesh, element_lI );
+			nLayout->buildElementNodes( nLayout, gEltInd, eltNodes );
+		}
+		
+		/* Convert global node indices to local. */
+		{
+			unsigned	eltNode_i;
+			
+			meshExt->newBarycenters[element_lI][0] = 0.0;
+			meshExt->newBarycenters[element_lI][1] = 0.0;
+			meshExt->newBarycenters[element_lI][2] = 0.0;
+			for( eltNode_i = 0; eltNode_i < nEltNodes; eltNode_i++ ) {
+				eltNodes[eltNode_i] = Mesh_NodeMapGlobalToLocal( mesh, eltNodes[eltNode_i] );
+				meshExt->newBarycenters[element_lI][0] += (meshExt->newNodeCoords[eltNodes[eltNode_i]][0]/nEltNodes);
+				meshExt->newBarycenters[element_lI][1] += (meshExt->newNodeCoords[eltNodes[eltNode_i]][1]/nEltNodes);
+				meshExt->newBarycenters[element_lI][2] += (meshExt->newNodeCoords[eltNodes[eltNode_i]][2]/nEltNodes);
+			}
+		}
+	}
+
+	/* Loop over the old elements. */
+	for( element_dI = 0; element_dI < mesh->elementDomainCount; element_dI++ ) {
+		unsigned			nEltNodes;
+		Node_DomainIndex*	eltNodes;
+		//Element_GlobalIndex		element_gI;
+		
+		/* Extract the element's node indices.  Note that there should always be eight of these. */
+		{
+			Element_GlobalIndex	gEltInd;
+			
+			nEltNodes = 8;
+			eltNodes = Memory_Alloc_Array( Node_DomainIndex, nEltNodes, "SnacRemesher" );
+			//element_gI = Mesh_ElementMapDomainToGlobal( mesh, element_dI );
+			nLayout->buildElementNodes( nLayout, gEltInd, eltNodes );
+		}
+		
+		/* Convert global node indices to local. */
+		{
+			unsigned	eltNode_i;
+			
+			meshExt->oldBarycenters[element_dI][0] = 0.0;
+			meshExt->oldBarycenters[element_dI][1] = 0.0;
+			meshExt->oldBarycenters[element_dI][2] = 0.0;
+			for( eltNode_i = 0; eltNode_i < nEltNodes; eltNode_i++ ) {
+				eltNodes[eltNode_i] = Mesh_NodeMapGlobalToLocal( mesh, eltNodes[eltNode_i] );
+				meshExt->oldBarycenters[element_dI][0] += (mesh->nodeCoord[eltNodes[eltNode_i]][0]/nEltNodes);
+				meshExt->oldBarycenters[element_dI][1] += (mesh->nodeCoord[eltNodes[eltNode_i]][1]/nEltNodes);
+				meshExt->oldBarycenters[element_dI][2] += (mesh->nodeCoord[eltNodes[eltNode_i]][2]/nEltNodes);
+			}
+		}
+	}
+		
+}
+
+void _SnacRemesher_UpdateElements( void* _context ) {
+
+	Snac_Context*			context = (Snac_Context*)_context;
+	Element_LocalIndex	element_lI;
+
+	/* Update all the elements, and in the process work out this processor's minLengthScale */
+	for( element_lI = 0; element_lI < context->mesh->elementLocalCount; element_lI++ ) {
+		double elementMinLengthScale;
+		
+		KeyCall( context, context->updateElementK, Snac_UpdateElementMomentum_CallCast* )
+			( KeyHandle(context,context->updateElementK),
+			  context,
+			  element_lI,
+			  &elementMinLengthScale );
+		if( elementMinLengthScale < context->minLengthScale ) {
+			context->minLengthScale = elementMinLengthScale;
+		}
+	}
+}
+
+
+/*
+  Interpolate an element's tetrahedra.
+  Note that srcEltInd and srcTetInd are those of the old barycenter grid.
+*/
+void _SnacRemesher_InterpolateElement( void*				_context, 
+									   Element_LocalIndex	dstEltInd, 
+									   Tetrahedra_Index		tetInd, 
+									   Snac_Element*		dstEltArray, 
+									   Element_DomainIndex	srcEltInd, 
+									   Tetrahedra_Index		srcTetInd )
+{
+
+	Snac_Context*		context = (Snac_Context*)_context;
+	Snac_Element*		dstElt = (Snac_Element*)ExtensionManager_At( context->mesh->elementExtensionMgr, 
+																	 dstEltArray, 
+																	 dstEltInd );
+	Element_DomainIndex eltdI[8],eldI,eldJ,eldK;
+	Tetrahedra_Index 	srcTet[8];
+	double 				dblMaterial_I;
+
+	/* Decompose srcEltInd into ijk indexes. */
+	eldI = srcEltInd % neldI;
+	eldJ = ((srcEltInd-eldI)/neldI) % neldJ;
+	eldK = (srcEltInd-eldI-eldJ*neldI)/(neldI*neldJ);
+	
+	/* Eight-node hex defined on the old barycenter grid. */
+	eltdI[0] = srcEltInd;
+	eltdI[1] = (eldI+1) + eldJ*neldI     + eldK*neldI*neldJ;
+	eltdI[2] = (eldI+1) + (eldJ+1)*neldI + eldK*neldI*neldJ;
+	eltdI[3] = eldI     + (eldJ+1)*neldI + eldK*neldI*neldJ;
+	eltdI[4] = eldI     + eldJ*neldI     + (eldK+1)*neldI*neldJ;
+	eltdI[5] = (eldI+1) + eldJ*neldI     + (eldK+1)*neldI*neldJ;
+	eltdI[6] = (eldI+1) + (eldJ+1)*neldI + (eldK+1)*neldI*neldJ;
+	eltdI[7] = eldI     + (eldJ+1)*neldI + (eldK+1)*neldI*neldJ;
+
+	memset( dstElt->tetra[tetInd].strain, 0, sizeof(double)*3*3 );
+	memset( dstElt->tetra[tetInd].stress, 0, sizeof(double)*3*3 );
+	dblMaterial_I = 0.0;
+	dstElt->tetra[dstTetInd].density = 0.0;
+	for(coef_I=0;coef_I<4;coef_I++) {
+		/* The actual src elements are the apexes of the tet in the old barycenter grid. */
+		Snac_Element* srcElt = Snac_Element_At( context, eltdI[TetraToNode[srcTetInd][coef_I]] );
+
+		dstElt->tetra[tetInd].strain[0][0] += meshExt->barcord[element_lI].L[coef_I]*srcElt->tetra[tetInd].strain[0][0];
+		dstElt->tetra[tetInd].strain[1][1] += meshExt->barcord[element_lI].L[coef_I]*srcElt->tetra[tetInd].strain[1][1];
+		dstElt->tetra[tetInd].strain[2][2] += meshExt->barcord[element_lI].L[coef_I]*srcElt->tetra[tetInd].strain[2][2];
+		dstElt->tetra[tetInd].strain[0][1] += meshExt->barcord[element_lI].L[coef_I]*srcElt->tetra[tetInd].strain[0][1];
+		dstElt->tetra[tetInd].strain[0][2] += meshExt->barcord[element_lI].L[coef_I]*srcElt->tetra[tetInd].strain[0][2];
+		dstElt->tetra[tetInd].strain[1][2] += meshExt->barcord[element_lI].L[coef_I]*srcElt->tetra[tetInd].strain[1][2];
+
+		dstElt->tetra[tetInd].stress[0][0] += meshExt->barcord[element_lI].L[coef_I]*srcElt->tetra[tetInd].stress[0][0];
+		dstElt->tetra[tetInd].stress[1][1] += meshExt->barcord[element_lI].L[coef_I]*srcElt->tetra[tetInd].stress[1][1];
+		dstElt->tetra[tetInd].stress[2][2] += meshExt->barcord[element_lI].L[coef_I]*srcElt->tetra[tetInd].stress[2][2];
+		dstElt->tetra[tetInd].stress[0][1] += meshExt->barcord[element_lI].L[coef_I]*srcElt->tetra[tetInd].stress[0][1];
+		dstElt->tetra[tetInd].stress[0][2] += meshExt->barcord[element_lI].L[coef_I]*srcElt->tetra[tetInd].stress[0][2];
+		dstElt->tetra[tetInd].stress[1][2] += meshExt->barcord[element_lI].L[coef_I]*srcElt->tetra[tetInd].stress[1][2];
+
+		dblMaterial_I += meshExt->barcord[element_lI].L[coef_I]*srcElt->tetra[tetInd].material_I;
+		dstElt->tetra[dstTetInd].density = meshExt->barcord[element_lI].L[coef_I]*srcElt->tetra[tetInd].density; 
+	}
+	dstElt->tetra[dstTetInd].material_I = (Material_Index)dblMaterial_I;
+
+}
+
+
+#if 0
+void _SnacRemesher_InterpolateElement( void*				_context, 
+									   Element_LocalIndex	dstEltInd, 
+									   Tetrahedra_Index		dstTetInd, 
+									   Snac_Element*		dstEltArray, 
+									   Element_DomainIndex	srcEltInd, 
+									   Tetrahedra_Index		srcTetInd )
+{
+
+	Snac_Context*	context = (Snac_Context*)_context;
+	Snac_Element*	dstElt = (Snac_Element*)ExtensionManager_At( context->mesh->elementExtensionMgr, 
+								     dstEltArray, 
+								     dstEltInd );
+	Snac_Element*	srcElt = Snac_Element_At( context, srcEltInd );
+
+	/* Copy the whole structure from the nearest tet in the old mesh. */
+	memcpy( &(dstElt->tetra[dstTetInd]), &(srcElt->tetra[srcTetInd]), sizeof(Snac_Element_Tetrahedra) );
+
+}
+#endif
+
+
+/*
+** Calculate the barycenter of a tetrahedron.
+*/
+
+void Tet_Barycenter( Coord tetCrds[4], Coord center ) {
+	unsigned	tet_i;
+	
+	center[0] = tetCrds[0][0];
+	center[1] = tetCrds[0][1];
+	center[2] = tetCrds[0][2];
+	
+	for( tet_i = 1; tet_i < 4; tet_i++ ) {
+		center[0] += tetCrds[tet_i][0];
+		center[1] += tetCrds[tet_i][1];
+		center[2] += tetCrds[tet_i][2];
+	}
+	
+	center[0] *= 0.25;
+	center[1] *= 0.25;
+	center[2] *= 0.25;
+}
+
+
+
+
+
+#if 0
+
+#define DIM 3
+
+#ifndef SQR
+	#define SQR(a) ((a)*(a))
+#endif
+#ifndef VECDIST3
+	#define VECDIST3(a,b)		( sqrt( SQR((a)[0]-(b)[0]) + SQR((a)[1]-(b)[1]) + SQR((a)[2]-(b)[2])  ) )
+#endif
+
+void _SnacRemesher_InterpolateElement(
+		void*			_context,
+		Element_LocalIndex	element_lI,
+		Tetrahedra_Index	tetra_I,
+		Element_LocalIndex	fromElement_lI,
+		Partition_Index		fromElement_rn_I,
+		Element_ShadowIndex	fromElement_sI,
+		Tetrahedra_Index	fromTetra_I,
+		Snac_Element*		newElement,
+		Snac_Element**		shadowElement )
+{
+	Snac_Context*				context = (Snac_Context*)_context;
+	Snac_Element*				element = (Snac_Element*)ExtensionManager_At(
+                                                                             context->mesh->elementExtensionMgr,
+                                                                             newElement,
+                                                                             element_lI );
+	Snac_Element*				fromElement;
+
+	/* Deference source element (local/shadow) */
+	if( fromElement_lI < context->mesh->elementLocalCount ) {
+		fromElement = Snac_Element_At( context, fromElement_lI );
+	}
+	else {
+		fromElement = (Snac_Element*)ExtensionManager_At(
+                                                         context->mesh->elementExtensionMgr,
+                                                         shadowElement[fromElement_rn_I],
+                                                         fromElement_sI );
+	}
+
+	element->tetra[tetra_I].strain[0][0] = fromElement->tetra[fromTetra_I].strain[0][0];
+	element->tetra[tetra_I].strain[1][1] = fromElement->tetra[fromTetra_I].strain[1][1];
+	element->tetra[tetra_I].strain[2][2] = fromElement->tetra[fromTetra_I].strain[2][2];
+	element->tetra[tetra_I].strain[0][1] = fromElement->tetra[fromTetra_I].strain[0][1];
+	element->tetra[tetra_I].strain[0][2] = fromElement->tetra[fromTetra_I].strain[0][2];
+	element->tetra[tetra_I].strain[1][2] = fromElement->tetra[fromTetra_I].strain[1][2];
+
+	element->tetraStress[tetra_I][0][0] = fromElement->tetraStress[fromTetra_I][0][0];
+	element->tetraStress[tetra_I][1][1] = fromElement->tetraStress[fromTetra_I][1][1];
+	element->tetraStress[tetra_I][2][2] = fromElement->tetraStress[fromTetra_I][2][2];
+	element->tetraStress[tetra_I][0][1] = fromElement->tetraStress[fromTetra_I][0][1];
+	element->tetraStress[tetra_I][0][2] = fromElement->tetraStress[fromTetra_I][0][2];
+	element->tetraStress[tetra_I][1][2] = fromElement->tetraStress[fromTetra_I][1][2];
+}
+
+
+void _SnacRemesher_InterpolateElements( void* _context ) {
+	Snac_Context*			context = (Snac_Context*)_context;
+	SnacRemesher_Context*	contextExt = ExtensionManager_Get(
+                                                       context->extensionMgr,
+                                                       context,
+                                                       SnacRemesher_ContextHandle );
+	Mesh*				mesh = (Mesh*)context->mesh;
+	SnacRemesher_Mesh*		meshExt = ExtensionManager_Get(
+                                                           context->meshExtensionMgr,
+                                                           mesh,
+                                                           SnacRemesher_MeshHandle );
+	MeshLayout*			layout = mesh->layout;
+	HexaMD*				decomp = (HexaMD*)layout->decomp;
+	Topology*			topology = layout->elementLayout->topology;
+	ElementLayout*			elementLayout = layout->elementLayout;
+	Element_LocalIndex		element_lI;
+
+	Partition_Index			rn_I;
+	Coord**				sbc;
+	double*				xbc;
+	int				n,i,d;
+
+	Journal_DPrintf( context->debug, "In: %s\n", __func__ );
+
+	/* Calculate the barycentric coords for each tetra of the old mesh */
+	xbc = calloc( DIM * Tetrahedra_Count * mesh->elementLocalCount, sizeof(double) );
+	for( element_lI = 0; element_lI < mesh->elementLocalCount; element_lI++ ) {
+		Tetrahedra_Index		tetra_I;
+
+		for( tetra_I = 0; tetra_I < Tetrahedra_Count; tetra_I++ ) {
+			double				*x0;
+			double				*x1;
+			double				*x2;
+			double				*x3;
+
+			x0=Snac_Element_NodeCoord( context, element_lI, TetraToNode[tetra_I][0] );
+			x1=Snac_Element_NodeCoord( context, element_lI, TetraToNode[tetra_I][1] );
+			x2=Snac_Element_NodeCoord( context, element_lI, TetraToNode[tetra_I][2] );
+			x3=Snac_Element_NodeCoord( context, element_lI, TetraToNode[tetra_I][3] );
+			for( d = 0; d < DIM; d++ ) {
+				xbc[(element_lI * Tetrahedra_Count + tetra_I) * DIM + d]= 0.25 * (x0[d] + x1[d] + x2[d] + x3[d]);
+			}
+		}
+	}
+
+	/* Calculate the barycentric coords for each tetra of the shadows */
+	sbc = (Coord**)malloc( sizeof(Coord*) * meshExt->neighbourRankCount );
+	for( rn_I = 0; rn_I < meshExt->neighbourRankCount; rn_I++ ) {
+		Element_ShadowIndex		element_sI;
+
+		sbc[rn_I] = (Coord*)malloc( sizeof(Coord) * meshExt->shadowElementRemoteCount[rn_I] * Tetrahedra_Count );
+
+		for( element_sI = 0; element_sI < meshExt->shadowElementRemoteCount[rn_I]; element_sI++ ) {
+			Element_GlobalIndex		element_gI = meshExt->shadowElementRemoteArray[rn_I][element_sI];
+			Node_GlobalIndex		elementNode[8];
+			Coord				coord[8];
+			Element_NodeIndex		en_I;
+			Tetrahedra_Index		tetra_I;
+
+			/* Build a temporary table of the coordinates of the points of this element. */
+			_HexaEL_BuildCornerIndices( elementLayout, element_gI, elementNode );
+			for( en_I = 0; en_I < 8; en_I++ ) {
+				Node_GlobalIndex	node_gI = elementNode[en_I];
+				Node_LocalIndex		node_lI = Mesh_NodeMapGlobalToLocal( mesh, node_gI );
+
+				/* Grab the coordinates of the element node. We do this by working out if the node is local and if
+				   so, directly copying the value from the mesh. If it isn't, it'll be in the shadow arrays...
+				   search for it and copy it. */
+				if( node_lI < meshExt->nodeLocalCount ) {
+					coord[en_I][0] = mesh->nodeCoord[node_lI][0];
+					coord[en_I][1] = mesh->nodeCoord[node_lI][1];
+					coord[en_I][2] = mesh->nodeCoord[node_lI][2];
+				}
+				else {
+					/*Partition_Index		rn_I2;
+
+					for( rn_I2 = 0; rn_I2 < meshExt->neighbourRankCount; rn_I2++ ) {*/
+						Node_ShadowIndex		node_sI;
+
+						for( node_sI = 0; node_sI < meshExt->shadowNodeRemoteCount[rn_I]; node_sI++ ) {
+							if( node_gI == meshExt->shadowNodeRemoteArray[rn_I][node_sI] ) {
+								coord[en_I][0] = meshExt->shadowNodeRemoteCoord[rn_I][node_sI][0];
+								coord[en_I][1] = meshExt->shadowNodeRemoteCoord[rn_I][node_sI][1];
+								coord[en_I][2] = meshExt->shadowNodeRemoteCoord[rn_I][node_sI][2];
+							}
+						}
+					/*}*/
+				}
+			}
+
+			for( tetra_I = 0; tetra_I < Tetrahedra_Count; tetra_I++ ) {
+				for( d = 0; d < DIM; d++ ) {
+					sbc[rn_I][element_sI * Tetrahedra_Count + tetra_I][d] = 0.25 * (
+						coord[TetraToNode[tetra_I][0]][d] +
+						coord[TetraToNode[tetra_I][1]][d] +
+						coord[TetraToNode[tetra_I][2]][d] +
+						coord[TetraToNode[tetra_I][3]][d] );
+				}
+			}
+		}
+	}
+
+	/* For each tetrahedra of the new mesh, calculate barycentric coords */
+	for( element_lI = 0; element_lI < context->mesh->elementLocalCount; element_lI++ ) {
+		Tetrahedra_Index		tetra_I;
+		Element_NeighbourIndex*		en = mesh->elementNeighbourTbl[element_lI];
+		Element_NeighbourIndex		enCount = mesh->elementNeighbourCountTbl[element_lI];
+
+		for( tetra_I = 0; tetra_I < Tetrahedra_Count; tetra_I++ ) {
+			Element_NeighbourIndex		en_I;
+			Element_LocalIndex		closest_element;
+			Tetrahedra_Index		closest_tetra;
+			Element_ShadowIndex		closest_sElement;
+			Partition_Index			closest_rn;
+			double				newxc[3];
+			double				oldxc[3];
+			double				selfdist;
+			Tetrahedra_Index		tetra_J;
+			double				dist2;
+			double				dist;
+
+			dist2 = selfdist = DBL_MAX;
+
+			/* Calculation of the barycenter for the tetra of new mesh */
+			memset( newxc, 0, sizeof(double) * 3 );
+			for( i = 0; i < 4; i++ ) {
+				n = TetraToNode[tetra_I][i];
+				for( d = 0; d < DIM; d++) {
+					newxc[d]+=0.25 * meshExt->newNodeCoord[mesh->elementNodeTbl[element_lI][n]][d];
+				}
+			}
+
+			/* Find the best tetra (in the sense of barycenter distance) of this element in the old mesh... this
+			   will be our starting-point/initial-compare. */
+			closest_element = closest_tetra = 0;
+			closest_rn = (unsigned)-1;
+			for( tetra_J = 0; tetra_J < Tetrahedra_Count; tetra_J++ ) {
+				for( d = 0; d < DIM; d++ ){
+					oldxc[d] = xbc[(element_lI * Tetrahedra_Count + tetra_J) * DIM + d];
+				}
+				dist = VECDIST3( newxc, oldxc );
+				if( tetra_I == tetra_J ){
+					selfdist = dist;
+				}
+				if( dist2 > dist ) {
+					closest_element = element_lI;
+					closest_tetra = tetra_J;
+					dist2 = dist;
+				}
+			}
+
+			/* Find the best tetra (in the sense of barycenter distance) of this element's neighbours in the old
+			   mesh, using the self-comparison above as a starting-point. */
+			for( en_I = 0; en_I < enCount; en_I++ ) {
+				Element_LocalIndex		enElement_lI = en[en_I];
+
+				/* The element neighbour is a local element */
+				if( enElement_lI < mesh->elementLocalCount ) {
+					Journal_DPrintf(
+						contextExt->debugElements,
+						"Element %03u's neighbour %02u (g%03u) is a local neighbour\n",
+						mesh->elementL2G[element_lI],
+						en_I,
+						mesh->elementL2G[enElement_lI] );
+
+					for( tetra_J = 0; tetra_J < Tetrahedra_Count; tetra_J++ ) {
+						for( d = 0; d  < DIM; d++ ) {
+							oldxc[d] = xbc[(enElement_lI * Tetrahedra_Count + tetra_J) * DIM + d];
+						}
+						dist = VECDIST3( newxc, oldxc );
+						if( dist2 > dist ) {
+							closest_element = enElement_lI;
+							closest_tetra = tetra_J;
+							dist2 = dist;
+						}
+					}
+				}
+				else { /* The element neighbour is a shadow element or non-existant */
+					Element_GlobalIndex		tmpEN[mesh->elementNeighbourCountTbl[element_lI]];
+					Element_GlobalIndex		element_gI = decomp->elementMapLocalToGlobal(
+                                                                                         decomp,
+                                                                                         element_lI );
+					Element_GlobalIndex		enElement_gI;
+
+					topology->buildNeighbours( topology, element_gI, tmpEN );
+					enElement_gI = tmpEN[en_I];
+
+					/* The element neighbour is a shadow */
+					if( enElement_gI < meshExt->elementGlobalCount ) {
+						Bool				found;
+
+						Journal_DPrintf(
+							contextExt->debugElements,
+							"Element %03u's neighbour %02u (g%03u) is a shadow neighbour\n",
+							mesh->elementL2G[element_lI],
+							en_I,
+							enElement_gI );
+
+						/* Search through the shadow lists for the element */
+						found = False;
+						for( rn_I = 0; rn_I < meshExt->neighbourRankCount && !found; rn_I++ ) {
+							Element_ShadowIndex		element_sI;
+
+							for(
+								element_sI = 0;
+								element_sI < meshExt->shadowElementRemoteCount[rn_I] && !found;
+								element_sI++ ) {
+								Journal_DPrintf(
+                                                contextExt->debugElements,
+                                                "enElement_gI == meshExt->ShadowElementArrayRemote[%u][%u] => %u == %u\n",
+                                                rn_I,
+                                                element_sI,
+                                                enElement_gI,
+                                                meshExt->shadowElementRemoteArray[rn_I][element_sI] );
+
+								if( enElement_gI == meshExt->shadowElementRemoteArray[rn_I][element_sI] ) {
+                                    /* Element found in shadow lists. Find if it has a closer
+									   tetra */
+									for( tetra_J = 0; tetra_J < Tetrahedra_Count; tetra_J++ ) {
+										for( d = 0; d  < DIM; d++ ) {
+											oldxc[d] = sbc[rn_I][element_sI * Tetrahedra_Count + tetra_J][d];
+										}
+										dist = VECDIST3( newxc, oldxc );
+										if( dist2 > dist ) {
+											closest_rn = rn_I;
+											closest_sElement = element_sI;
+											closest_element = (unsigned)-1;
+											closest_tetra = tetra_J;
+											dist2 = dist;
+										}
+									}
+									found = True;
+								}
+							}
+						}
+
+						/* Essentially the enElement_gI should be found in the shadow listings, else there
+						   is a big coding error! */
+						assert( found );
+					}
+					else {
+						Journal_DPrintf(
+							contextExt->debugElements,
+							"Element g%03u's neighbour %02u (g%03u) is out of bounds\n",
+							mesh->elementL2G[element_lI],
+							en_I,
+							enElement_gI );
+						continue;
+					}
+				}
+			}
+
+            if( dist2 > selfdist ) {
+                Journal_DPrintf(
+                                contextExt->debugElements,
+                                "Distance between barycentres of old and new tetrahadras cannot be bigger than" );
+                Journal_DPrintf(
+                                contextExt->debugElements,
+                                "barycentric distance of the same tetrahedra in old and new mesh\n\n" );
+            }
+
+
+			/* transfer */
+			SnacRemesher_InterpolateElement(
+                                            context,
+                                            contextExt,
+                                            element_lI,
+                                            tetra_I,
+                                            closest_element,
+                                            closest_rn,
+                                            closest_sElement,
+                                            closest_tetra,
+                                            meshExt->newElement,
+                                            meshExt->shadowElementRemote );
+		}
+	}
+
+#if 0
+    for( element_lI = 0; element_lI < mesh->elementLocalCount; element_lI++ ) {
+        Snac_Element*		element = (Snac_Element*)Extension_At(
+                                                                  context->mesh->elementExtensionMgr,
+                                                                  meshExt->newElement,
+                                                                  element_lI );
+        Tetrahedra_Index	tetra_I;
+
+        for( tetra_I = 0; tetra_I < Tetrahedra_Count; tetra_I++ ) {
+            Journal_DPrintf(
+                            contextExt->debugElements,
+                            "Element-tetra g%03u-%u: stress: %g %g %g %g %g %g\n",
+                            mesh->elementL2G[element_lI],
+                            tetra_I,
+                            element->tetraStress[tetra_I][0][0],
+                            element->tetraStress[tetra_I][1][1],
+                            element->tetraStress[tetra_I][2][2],
+                            element->tetraStress[tetra_I][0][1],
+                            element->tetraStress[tetra_I][0][2],
+                            element->tetraStress[tetra_I][1][2] );
+            Journal_DPrintf(
+                            contextExt->debugElements,
+                            "Element-tetra g%03u-%u: strain: %g %g %g %g %g %g\n",
+                            mesh->elementL2G[element_lI],
+                            tetra_I,
+                            element->tetra[tetra_I].strain[0][0],
+                            element->tetra[tetra_I].strain[1][1],
+                            element->tetra[tetra_I].strain[2][2],
+                            element->tetra[tetra_I].strain[0][1],
+                            element->tetra[tetra_I].strain[0][2],
+                            element->tetra[tetra_I].strain[1][2] );
+        }
+    }
+#endif
+
+	for( rn_I = 0; rn_I < meshExt->neighbourRankCount; rn_I++ ) {
+		free( sbc[rn_I] );
+	}
+	free( sbc );
+	free( xbc );
+}
+
+#endif

Added: long/3D/SNAC/trunk/Snac/plugins/remesher_BI/RemeshNodes.c
===================================================================
--- long/3D/SNAC/trunk/Snac/plugins/remesher_BI/RemeshNodes.c	                        (rev 0)
+++ long/3D/SNAC/trunk/Snac/plugins/remesher_BI/RemeshNodes.c	2011-10-07 16:18:20 UTC (rev 19040)
@@ -0,0 +1,1537 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+**
+** Copyright (C), 2003,
+**	Pururav Thoutireddy,
+**	Californian Institute of Technology, 1200 East California Boulevard, Pasadena, California, 91125, USA.
+**      110 Victoria Street, Melbourne, Victoria, 3053, Australia.
+**	University of Texas, 1 University Station, Austin, Texas, 78712, USA.
+**
+** Authors:
+**	Pururav Thoutireddy, Staff Scientist, Caltech
+**      Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
+**	Stevan M. Quenette, Visitor in Geophysics, Caltech.
+**	Luc Lavier, Research Scientist, The University of Texas. (luc at utig.ug.utexas.edu)
+**	Luc Lavier, Research Scientist, Caltech.
+**
+** This program is free software; you can redistribute it and/or modify it
+** under the terms of the GNU General Public License as published by the
+** Free Software Foundation; either version 2, or (at your option) any
+** later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+**
+** $Id: RemeshNodes.c 3259 2006-11-09 20:06:31Z EunseoChoi $
+**
+**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#include <mpi.h>
+#include <StGermain/StGermain.h>
+#include <StGermain/FD/FD.h>
+#include "Snac/Snac.h"
+#include "types.h"
+#include "EntryPoint.h"
+#include "Mesh.h"
+#include "Context.h"
+#include "Remesh.h"
+#include "Register.h"
+#include "Utils.h"
+
+#include <string.h>
+#include <assert.h>
+#include <float.h>
+#include <gsl/gsl_vector.h>
+#include <gsl/gsl_matrix.h>
+#include <gsl/gsl_linalg.h>
+
+
+void _SnacRemesher_InterpolateNodes( void* _context ) {
+	Snac_Context*		context = (Snac_Context*)_context;
+	Mesh*				mesh = context->mesh;
+	SnacRemesher_Mesh*	meshExt = ExtensionManager_Get( context->meshExtensionMgr,
+															mesh,
+															SnacRemesher_MeshHandle );
+	NodeLayout*			nLayout = mesh->layout->nodeLayout;
+	Node_LocalIndex		newNode_i;
+	IndexSet*			extNodes;
+
+	void interpolateNode( void* _context, Node_LocalIndex newNodeInd, Element_DomainIndex dEltInd );
+	void SPR( void* _context );
+
+	/*
+	** Free any owned arrays that may still exist from the last node interpolation.
+	*/
+
+	FreeArray( meshExt->externalNodes );
+	meshExt->nExternalNodes = 0;
+
+	
+	/*
+	** Populate arrays for recovered fields using the SPR method.
+	*/
+	SPR( context );
+
+	/*
+	** Scoot over all the new nodes and find the old element in which each one resides, then interpolate.
+	*/
+
+	/* Create an index set for storing any external nodes. */
+	extNodes = IndexSet_New( mesh->nodeLocalCount );
+
+	for( newNode_i = 0; newNode_i < mesh->nodeLocalCount; newNode_i++ ) {
+		Node_LocalIndex		dNodeInd;
+		unsigned				nElements;
+		Element_DomainIndex*	elements;
+		Coord				newPoint;
+		unsigned				elt_i;
+
+		/* Extract the new node's coordinate. */
+		Vector_Set( newPoint, meshExt->newNodeCoords[newNode_i] );
+
+		/* Find the closest old node. */
+		dNodeInd = findClosestNode( context, newPoint, newNode_i );
+
+		/* Grab incident elements. */
+		{
+			Node_GlobalIndex	gNodeInd;
+
+			gNodeInd = Mesh_NodeMapDomainToGlobal( mesh, dNodeInd );
+			nElements = nLayout->nodeElementCount( nLayout, gNodeInd );
+			if( nElements ) {
+				elements = Memory_Alloc_Array( Element_DomainIndex, nElements, "SnacRemesher" );
+				nLayout->buildNodeElements( nLayout, gNodeInd, elements );
+			}
+			else {
+				elements = NULL;
+			}
+		}
+
+		/* Convert global element indices to domain. */
+		for( elt_i = 0; elt_i < nElements; elt_i++ ) {
+			elements[elt_i] = Mesh_ElementMapGlobalToDomain( mesh, elements[elt_i] );
+		}
+
+		/* Which of the incident elements contains the node? */
+		for( elt_i = 0; elt_i < nElements; elt_i++ ) {
+			if( elements[elt_i] >= mesh->elementDomainCount ) {
+				continue;
+			}
+
+			if( pointInElement( context, newPoint, elements[elt_i] ) ) {
+				break;
+			}
+		}
+
+		/* Did we find the element? */
+		if( elt_i < nElements ) {
+			/* If so, call a function to locate the tetrahedra and interpolate. */
+			interpolateNode( context, newNode_i, elements[elt_i] );
+		}
+		else {
+			/* If not, then the new node finds itself outside the old mesh.  In this scenario, we cannot interpolate
+			   the nodal values with any accuracy (without knowing more about the physical problem).  So, we will leave
+			   the node with its old values and mark this node as not being interpolated so the user may deal with it. */
+
+			/* Stash the node index. */
+			IndexSet_Add( extNodes, newNode_i );
+
+			/* Copy across the old value. Note that this should be done using some other provided copy method. */
+			memcpy( (unsigned char*)meshExt->newNodes + newNode_i * mesh->nodeExtensionMgr->finalSize,
+				(unsigned char*)mesh->node + newNode_i * mesh->nodeExtensionMgr->finalSize,
+				mesh->nodeExtensionMgr->finalSize );
+			/* assert(0); */
+		}
+
+		/* Free element array. */
+		FreeArray( elements );
+	}
+
+	/* Dump the external nodes and delete the set. */
+	IndexSet_GetMembers( extNodes, &meshExt->nExternalNodes, &meshExt->externalNodes );
+	Stg_Class_Delete( extNodes );
+}
+
+
+#define det3_sub( x1, x2, x3 ) ( \
+	(x1)[0] * ( (x2)[1] * (x3)[2] - (x3)[1] * (x2)[2] ) - \
+	(x1)[1] * ( (x2)[0] * (x3)[2] - (x3)[0] * (x2)[2] ) + \
+	(x1)[2] * ( (x2)[0] * (x3)[1] - (x3)[0] * (x2)[1] ) )
+
+
+#define TetrahedronVolume( x1, x2,  x3, x4 ) ( \
+	( det3_sub( (x2), (x3), (x4) ) - \
+	  det3_sub( (x1), (x3), (x4) ) + \
+	  det3_sub( (x1), (x2), (x4) ) - \
+	  det3_sub( (x1), (x2), (x3) ) \
+	) / 6.0f )
+
+
+#define isLargerThanZero( val, tol ) \
+	(((val) >= -(tol) && (val) <= (tol)) ? 0.0 : (val))
+
+
+#define isLargerThanZero2( val, ref, tol ) \
+	(((val) >= -fabs( ref ) * (tol) && (val) <= fabs( ref ) * tol) ? 0.0 : (val))
+
+
+void interpolateNode( void* _context, Node_LocalIndex newNodeInd, Element_DomainIndex dEltInd ) {
+	Snac_Context*			context = (Snac_Context*)_context;
+	SnacRemesher_Context*	contextExt = ExtensionManager_Get( context->extensionMgr,
+								   context,
+								   SnacRemesher_ContextHandle );
+	Mesh*				mesh = context->mesh;
+	SnacRemesher_Mesh*		meshExt = ExtensionManager_Get( context->meshExtensionMgr,
+									mesh,
+									SnacRemesher_MeshHandle );
+	NodeLayout*			nLayout = mesh->layout->nodeLayout;
+	unsigned				nEltNodes;
+	Node_DomainIndex*		eltNodes;
+	Coord				newNodeCoord;
+	Coord			crds[8];
+	double			weights[4];
+	unsigned		tetNodeInds[4];
+	unsigned		eltNode_i;
+
+	/* Extract the element's node indices.  Note that there should always be eight of these. */
+	{
+		Element_GlobalIndex	gEltInd;
+
+		nEltNodes = 8;
+		eltNodes = Memory_Alloc_Array( Node_DomainIndex, nEltNodes, "SnacRemesher" );
+		gEltInd = Mesh_ElementMapDomainToGlobal( mesh, dEltInd );
+		nLayout->buildElementNodes( nLayout, gEltInd, eltNodes );
+	}
+
+	/* Convert global node indices to domain. */
+	{
+		unsigned	eltNode_i;
+
+		for( eltNode_i = 0; eltNode_i < nEltNodes; eltNode_i++ ) {
+			eltNodes[eltNode_i] = Mesh_NodeMapGlobalToDomain( mesh, eltNodes[eltNode_i] );
+		}
+	}
+
+	/* Extract the new node's coordinate. */
+	Vector_Set( newNodeCoord, meshExt->newNodeCoords[newNodeInd] );
+
+	/* Copy coordinates. */
+	for( eltNode_i = 0; eltNode_i < nEltNodes; eltNode_i++ )
+		memcpy( crds[eltNode_i], mesh->nodeCoord[eltNodes[eltNode_i]], sizeof(Coord) );
+
+	if( !_HexaEL_FindTetBarycenter( crds, newNodeCoord, weights, tetNodeInds, INCLUSIVE_UPPER_BOUNDARY, NULL, 0 ) )
+		abort();
+
+	SnacRemesher_InterpolateNode( context, contextExt,
+				      newNodeInd, dEltInd, 0,
+				      tetNodeInds, weights,
+				      meshExt->newNodes );
+
+#if 0
+	/* Loop over 10 sub tets in a brick element, work out the tetra it is in. */
+	for( tet_i = 0; tet_i < nTets; tet_i++ ) {
+		Coord	tCrds[4];
+		double	TOL = 0.0;
+
+		/* Extract the tetrahedron's coordinates. */
+		Vector_Set( tCrds[0], mesh->nodeCoord[eltNodes[nSub[tet_i * 4 + 0]]] );
+		Vector_Set( tCrds[1], mesh->nodeCoord[eltNodes[nSub[tet_i * 4 + 1]]] );
+		Vector_Set( tCrds[2], mesh->nodeCoord[eltNodes[nSub[tet_i * 4 + 2]]] );
+		Vector_Set( tCrds[3], mesh->nodeCoord[eltNodes[nSub[tet_i * 4 + 3]]] );
+
+		dett = TetrahedronVolume( tCrds[0], tCrds[1], tCrds[2], tCrds[3] );
+		det[0] = TetrahedronVolume( tCrds[1], tCrds[3], tCrds[2], newNodeCoord );
+		det[1] = TetrahedronVolume( tCrds[2], tCrds[3], tCrds[0], newNodeCoord );
+		det[2] = TetrahedronVolume( tCrds[0], tCrds[3], tCrds[1], newNodeCoord );
+		det[3] = TetrahedronVolume( tCrds[0], tCrds[1], tCrds[2], newNodeCoord );
+
+		dett = isLargerThanZero( dett, TOL );
+		det[0] = isLargerThanZero2( det[0], dett, TOL );
+		det[1] = isLargerThanZero2( det[1], dett, TOL );
+		det[2] = isLargerThanZero2( det[2], dett, TOL );
+		det[3] = isLargerThanZero2( det[3], dett, TOL );
+		dett = det[0] + det[1] + det[2] + det[3];
+
+		/* TODO: Convert to a journal command. */
+		/* Found if all det are greater than zero. */
+		Journal_Firewall( (dett != 0.0 ), "processor %d: element_lI=%d tetra=%d dett is zero!!\napexes: (%e %e %e) (%e %e %e) (%e %e %e) (%e %e %e)\nnewNodeCoord=(%e %e %e)\n",
+				  context->rank, dEltInd, tet_i,
+				  tCrds[0][0],tCrds[0][1],tCrds[0][2],tCrds[1][0],tCrds[1][1],tCrds[1][2],
+				  tCrds[2][0],tCrds[2][1],tCrds[2][2],tCrds[3][0],tCrds[3][1],tCrds[3][2],
+				  newNodeCoord[0],newNodeCoord[0],newNodeCoord[0]);
+		if ( det[0] >= 0.0 && det[1] >= 0.0 && det[2] >= 0.0 && det[3] >= 0.0 ) {
+			break;
+		}
+	}
+
+	/* Did we find the tetrahedron? */
+	if( tet_i < nTets ) {
+		Node_DomainIndex	tetNodeInds[4];
+		double			shape[4];
+		unsigned		tNode_i;
+
+		/* Calculate the shape funcs and remap the tetrahedron node indices. */
+		for( tNode_i = 0; tNode_i < 4; tNode_i++ ) {
+			shape[tNode_i] = det[tNode_i] / dett;
+			tetNodeInds[tNode_i] = eltNodes[nSub[tet_i * 4 + tNode_i]];
+		}
+
+		/* Interpolate the node. */
+
+		/*
+		** This is where we should be calling the entry points for node interpolation.
+		*/
+
+		SnacRemesher_InterpolateNode( context, contextExt,
+					      newNodeInd, dEltInd, tet_i,
+					      tetNodeInds, shape,
+					      meshExt->newNodes );
+	}
+	else {
+		/* If not, then something unpleasant is going on, and I don't know what it is. */
+		for( tet_i = 0; tet_i < nTets; tet_i++ ) {
+			Coord	tCrds[4];
+			double	TOL = 0.0;
+
+			/* Extract the tetrahedron's coordinates. */
+			Vector_Set( tCrds[0], mesh->nodeCoord[eltNodes[nSub[tet_i * 4 + 0]]] );
+			Vector_Set( tCrds[1], mesh->nodeCoord[eltNodes[nSub[tet_i * 4 + 1]]] );
+			Vector_Set( tCrds[2], mesh->nodeCoord[eltNodes[nSub[tet_i * 4 + 2]]] );
+			Vector_Set( tCrds[3], mesh->nodeCoord[eltNodes[nSub[tet_i * 4 + 3]]] );
+
+			dett = TetrahedronVolume( tCrds[0], tCrds[1], tCrds[2], tCrds[3] );
+			det[0] = TetrahedronVolume( tCrds[1], tCrds[3], tCrds[2], newNodeCoord );
+			det[1] = TetrahedronVolume( tCrds[2], tCrds[3], tCrds[0], newNodeCoord );
+			det[2] = TetrahedronVolume( tCrds[0], tCrds[3], tCrds[1], newNodeCoord );
+			det[3] = TetrahedronVolume( tCrds[0], tCrds[1], tCrds[2], newNodeCoord );
+
+			dett = isLargerThanZero( dett, TOL );
+			det[0] = isLargerThanZero2( det[0], dett, TOL );
+			det[1] = isLargerThanZero2( det[1], dett, TOL );
+			det[2] = isLargerThanZero2( det[2], dett, TOL );
+			det[3] = isLargerThanZero2( det[3], dett, TOL );
+			dett = det[0] + det[1] + det[2] + det[3];
+
+			Journal_Printf( context->debug, "processor %d: element_lI=%d/%d tetra=%d\napexes: (%e %e %e) (%e %e %e) (%e %e %e) (%e %e %e)\nnewNodeCoord=(%e %e %e) dets: %e %e %e %e (%e)\n\n",
+					context->rank, dEltInd, mesh->elementDomainCount,tet_i,
+					tCrds[0][0],tCrds[0][1],tCrds[0][2],tCrds[1][0],tCrds[1][1],tCrds[1][2],
+					tCrds[2][0],tCrds[2][1],tCrds[2][2],tCrds[3][0],tCrds[3][1],tCrds[3][2],
+					newNodeCoord[0],newNodeCoord[1],newNodeCoord[2],det[0],det[1],det[2],det[3],dett);
+
+		}
+		Journal_Firewall( 0, "processor %d: element_lI=%d tetra=%d failed to interpolate although a matching element was found!!\n",
+				  context->rank, dEltInd, tet_i );
+	}
+#endif
+
+	/* Free the element node array. */
+	FreeArray( eltNodes );
+}
+
+
+/*
+** Interpolate an individual node using a cartesian method or a spherical method.
+*/
+
+void _SnacRemesher_InterpolateNode( void* _context,
+				    unsigned nodeInd, unsigned elementInd, unsigned tetInd,
+				    unsigned* tetNodeInds, double* weights,
+				    Snac_Node* dstNodes )
+{
+	Snac_Context*	context = (Snac_Context*)_context;
+	Mesh*		mesh = context->mesh;
+	NodeLayout*			nLayout = mesh->layout->nodeLayout;
+	Snac_Node*	dstNode = (Snac_Node*)ExtensionManager_At( context->mesh->nodeExtensionMgr,
+								   dstNodes,
+								   nodeInd );
+	unsigned	tetNode_i;
+
+	/* Extract the element's node indices.  Note that there should always be eight of these. */
+	Node_DomainIndex*	eltNodes;
+	unsigned int nEltNodes = 8;
+	{
+		Element_GlobalIndex	gEltInd;
+
+		eltNodes = Memory_Alloc_Array( Node_DomainIndex, nEltNodes, "SnacRemesher" );
+		gEltInd = Mesh_ElementMapDomainToGlobal( mesh, elementInd );
+		nLayout->buildElementNodes( nLayout, gEltInd, eltNodes );
+	}
+
+	/* Convert global node indices to local. */
+	{
+		unsigned	eltNode_i;
+
+		for( eltNode_i = 0; eltNode_i < nEltNodes; eltNode_i++ ) {
+			eltNodes[eltNode_i] = Mesh_NodeMapGlobalToDomain( mesh, eltNodes[eltNode_i] );
+		}
+	}
+
+	/* Clear the velocity. */
+	dstNode->velocity[0] = 0.0;
+	dstNode->velocity[1] = 0.0;
+	dstNode->velocity[2] = 0.0;
+
+	dstNode->strainSPR[0] = 0.0;
+	dstNode->strainSPR[1] = 0.0;
+	dstNode->strainSPR[2] = 0.0;
+	dstNode->strainSPR[3] = 0.0;
+	dstNode->strainSPR[4] = 0.0;
+	dstNode->strainSPR[5] = 0.0;
+
+	dstNode->stressSPR[0] = 0.0;
+	dstNode->stressSPR[1] = 0.0;
+	dstNode->stressSPR[2] = 0.0;
+	dstNode->stressSPR[3] = 0.0;
+	dstNode->stressSPR[4] = 0.0;
+	dstNode->stressSPR[5] = 0.0;
+
+	/* Loop over each contributing node. */
+	for( tetNode_i = 0; tetNode_i < 4; tetNode_i++ ) {
+		Snac_Node*	srcNode;
+
+		/* Where is this contibution coming from? */
+
+		srcNode = Snac_Node_At( context, eltNodes[tetNodeInds[tetNode_i]] );
+
+		/* Add the contribution. */ // TODO: Do spherical part.
+		dstNode->velocity[0] += srcNode->velocity[0] * weights[tetNode_i];
+		dstNode->velocity[1] += srcNode->velocity[1] * weights[tetNode_i];
+		dstNode->velocity[2] += srcNode->velocity[2] * weights[tetNode_i];
+
+		dstNode->strainSPR[0] += srcNode->strainSPR[0] * weights[tetNode_i];
+		dstNode->strainSPR[1] += srcNode->strainSPR[1] * weights[tetNode_i];
+		dstNode->strainSPR[2] += srcNode->strainSPR[2] * weights[tetNode_i];
+		dstNode->strainSPR[3] += srcNode->strainSPR[3] * weights[tetNode_i];
+		dstNode->strainSPR[4] += srcNode->strainSPR[4] * weights[tetNode_i];
+		dstNode->strainSPR[5] += srcNode->strainSPR[5] * weights[tetNode_i];
+
+		dstNode->stressSPR[0] += srcNode->stressSPR[0] * weights[tetNode_i];
+		dstNode->stressSPR[1] += srcNode->stressSPR[1] * weights[tetNode_i];
+		dstNode->stressSPR[2] += srcNode->stressSPR[2] * weights[tetNode_i];
+		dstNode->stressSPR[3] += srcNode->stressSPR[3] * weights[tetNode_i];
+		dstNode->stressSPR[4] += srcNode->stressSPR[4] * weights[tetNode_i];
+		dstNode->stressSPR[5] += srcNode->stressSPR[5] * weights[tetNode_i];
+
+	}
+}
+
+
+void SPR( void* _context )
+{
+	Snac_Context*		context = (Snac_Context*)_context;
+	Mesh*				mesh = context->mesh;
+	NodeLayout*			nLayout = mesh->layout->nodeLayout;
+	Node_LocalIndex		node_lI;
+
+	/* Populate field variables by SPR */
+	for( node_lI = 0; node_lI < mesh->nodeLocalCount; node_lI++ ) {
+		Snac_Node*				node = Snac_Node_At( context, node_lI );
+		Coord*					coord = Snac_NodeCoord_P( context, node_lI );
+		Index 					nodeElementCount = context->mesh->nodeElementCountTbl[node_lI];
+		Index 					nodeElement_I;
+		Element_DomainIndex*	elements;
+		gsl_matrix*				matA;
+		gsl_vector* 			vecaStrain[6];
+		gsl_vector*				vecaStress[6];
+		gsl_vector*				vecaplStrain;
+		gsl_vector* 			vecbStrain[6];
+		gsl_vector* 			vecbStress[6];
+		gsl_vector* 			vecbplStrain;
+		Index 	 	 	 	 	i,j; 
+		
+		// initialize gsl vectors and matrix.
+		matA = gsl_matrix_alloc(4,4); gsl_matrix_set_zero( matA );
+		vecaplStrain = gsl_vector_alloc(4); gsl_vector_set_zero( vecaplStrain );
+		vecbplStrain = gsl_vector_alloc(4); gsl_vector_set_zero( vecbplStrain );
+		for(i=0;i<6;i++) {
+			vecaStrain[i] = gsl_vector_alloc(4); gsl_vector_set_zero( vecaStrain[i] );
+			vecaStress[i] = gsl_vector_alloc(4); gsl_vector_set_zero( vecaStress[i] );
+			vecbStrain[i] = gsl_vector_alloc(4); gsl_vector_set_zero( vecbStrain[i] );
+			vecbStress[i] = gsl_vector_alloc(4); gsl_vector_set_zero( vecbStress[i] );
+		}
+			
+		/* For each incident element, find inicident tets. */
+		for( nodeElement_I = 0; nodeElement_I < nodeElementCount; nodeElement_I++ ) {
+			Element_DomainIndex		element_dI = context->mesh->nodeElementTbl[node_lI][nodeElement_I];
+
+			if( element_dI < mesh->elementDomainCount ) {
+				Index elementTetra_I;
+				Snac_Element* element = Snac_Element_At( context, element_dI );
+
+				/* Extract the element's node indices.  Note that there should always be eight of these. */
+				{
+					Element_GlobalIndex	element_gI;
+					
+					elements = Memory_Alloc_Array( Node_DomainIndex, nodeElementCount, "SnacRemesher" );
+					element_gI = Mesh_ElementMapDomainToGlobal( mesh, element_dI );
+					nLayout->buildElementNodes( nLayout, element_gI, elements );
+				}
+				
+				/* Convert global node indices to domain. */
+				{
+					unsigned	eltNode_i;
+					
+					for( eltNode_i = 0; eltNode_i < nodeElementCount; eltNode_i++ ) {
+						elements[eltNode_i] = Mesh_NodeMapGlobalToDomain( mesh, elements[eltNode_i] );
+					}
+				}
+
+				/* For each incident tetrahedron in the incident element,
+				   add up contributions to P, A, and b as in Zienkiewicz and Zhu (1992), p. 1336 */
+				for( elementTetra_I = 0; elementTetra_I < Node_Element_Tetrahedra_Count;elementTetra_I++ ) {
+					Tetrahedra_Index	tetra_I = NodeToTetra[nodeElement_I][elementTetra_I];
+					Coord	tCrds[4];
+					double 	positionP[4] = {1.0,0.0,0.0,0.0};
+					Index 	ii,jj;
+
+					/* Extract the tetrahedron's coordinates. */
+					Vector_Set( tCrds[0], mesh->nodeCoord[elements[TetraToNode[tetra_I][0]]] );
+					Vector_Set( tCrds[1], mesh->nodeCoord[elements[TetraToNode[tetra_I][1]]] );
+					Vector_Set( tCrds[2], mesh->nodeCoord[elements[TetraToNode[tetra_I][2]]] );
+					Vector_Set( tCrds[3], mesh->nodeCoord[elements[TetraToNode[tetra_I][3]]] );
+					
+					for(ii=1;ii<4;ii++)
+						for(jj=0;jj<4;jj++)
+							positionP[ii] += (0.25f * tCrds[jj][ii-1]);
+					
+					for(ii=0;ii<4;ii++) {
+						double tmp;
+						tmp = gsl_vector_get(vecbStrain[0],ii) + positionP[ii]*element->tetra[tetra_I].strain[0][0];
+						gsl_vector_set(vecbStrain[0],ii,tmp);
+						tmp = gsl_vector_get(vecbStrain[1],ii) + positionP[ii]*element->tetra[tetra_I].strain[1][1];
+						gsl_vector_set(vecbStrain[1],ii,tmp);
+						tmp = gsl_vector_get(vecbStrain[2],ii) + positionP[ii]*element->tetra[tetra_I].strain[2][2];
+						gsl_vector_set(vecbStrain[2],ii,tmp);
+						tmp = gsl_vector_get(vecbStrain[3],ii) + positionP[ii]*element->tetra[tetra_I].strain[0][1];
+						gsl_vector_set(vecbStrain[3],ii,tmp);
+						tmp = gsl_vector_get(vecbStrain[4],ii) + positionP[ii]*element->tetra[tetra_I].strain[0][2];
+						gsl_vector_set(vecbStrain[4],ii,tmp);
+						tmp = gsl_vector_get(vecbStrain[5],ii) + positionP[ii]*element->tetra[tetra_I].strain[1][2];
+						gsl_vector_set(vecbStrain[5],ii,tmp);
+
+						tmp = gsl_vector_get(vecbStress[0],ii) + positionP[ii]*element->tetra[tetra_I].stress[0][0];
+						gsl_vector_set(vecbStress[0],ii,tmp);
+						tmp = gsl_vector_get(vecbStress[1],ii) + positionP[ii]*element->tetra[tetra_I].stress[1][1];
+						gsl_vector_set(vecbStress[1],ii,tmp);
+						tmp = gsl_vector_get(vecbStress[2],ii) + positionP[ii]*element->tetra[tetra_I].stress[2][2];
+						gsl_vector_set(vecbStress[2],ii,tmp);
+						tmp = gsl_vector_get(vecbStress[3],ii) + positionP[ii]*element->tetra[tetra_I].stress[0][1];
+						gsl_vector_set(vecbStress[3],ii,tmp);
+						tmp = gsl_vector_get(vecbStress[4],ii) + positionP[ii]*element->tetra[tetra_I].stress[0][2];
+						gsl_vector_set(vecbStress[4],ii,tmp);
+						tmp = gsl_vector_get(vecbStress[5],ii) + positionP[ii]*element->tetra[tetra_I].stress[1][2];
+						gsl_vector_set(vecbStress[5],ii,tmp);
+
+/* 						tmp = gsl_vector_get(vecbplStrain,i) + positionP[i]*plasticElement->tetra[tetra_I].stress[1][2]; */
+/* 						gsl_vector_set(vecStress[5],i,tmp); */
+						for(jj=0;jj<4;jj++) {
+							tmp = gsl_matrix_get(matA,ii,jj) + positionP[ii]*positionP[jj];
+							gsl_matrix_set(matA,ii,jj,tmp);
+						}
+					}
+				} // end of incident tets.
+			} // if within my domain
+		} // end of incident elements.
+		
+		// compute parameter vectors.
+		{
+			int s;
+			gsl_permutation * p = gsl_permutation_alloc (4);
+     
+			gsl_linalg_LU_decomp (matA, p, &s);
+			
+			for(i=0;i<6;i++) {
+				gsl_linalg_LU_solve (matA, p, vecbStrain[i], vecaStrain[i]);
+				gsl_linalg_LU_solve (matA, p, vecbStress[i], vecaStress[i]);
+			}
+/* 			printf ("x = \n"); */
+/* 			gsl_vector_fprintf (stdout, x, "%g"); */
+			gsl_permutation_free (p);
+		}	
+
+		// zero the arrays to store recovered field.
+		// probably not necessary.
+/* 		for(i=0;i<6;i++) { */
+/* 			node->strainSPR[i] = 0.0f; */
+/* 			node->stressSPR[i] = 0.0f; */
+/* 		} */
+
+		// Recover using the parameter vectors.
+		for(j=0;j<6;j++) {
+			node->strainSPR[j] = gsl_vector_get(vecaStrain[j],0);
+			node->stressSPR[j] = gsl_vector_get(vecaStress[j],0);
+			for(i=0;i<3;i++) {
+				node->strainSPR[j] += gsl_vector_get(vecaStrain[j],i+1)*(*coord)[i];
+				node->stressSPR[j] += gsl_vector_get(vecaStress[j],i+1)*(*coord)[i];
+			}
+		}
+
+		// free gsl vectors and matrix.
+		gsl_matrix_free( matA );
+		gsl_vector_free( vecaplStrain );
+		gsl_vector_free( vecbplStrain );
+		for(i=0;i<6;i++) {
+			gsl_vector_free( vecaStrain[i] );
+			gsl_vector_free( vecaStress[i] );
+			gsl_vector_free( vecbStrain[i] );
+			gsl_vector_free( vecbStress[i] );
+		}
+		/* Free the element node array. */
+		FreeArray( elements );
+	} // end of recovery.
+}
+
+
+
+#if 0
+
+#define DIM 3
+#define NODES_PER_ELEMENT 8
+
+#ifndef MAX
+#define MAX(a,b) ((a) > (b) ? (a) : (b))
+#endif
+#ifndef MIN
+#define MIN(a,b) ((a) < (b) ? (a) : (b))
+#endif
+
+
+#define det3_sub( x1, x2, x3 ) ( \
+	(x1)[0] * ( (x2)[1] * (x3)[2] - (x3)[1] * (x2)[2] ) - \
+	(x1)[1] * ( (x2)[0] * (x3)[2] - (x3)[0] * (x2)[2] ) + \
+	(x1)[2] * ( (x2)[0] * (x3)[1] - (x3)[0] * (x2)[1] ) )
+
+#define TetrahedronVolume( x1, x2,  x3, x4 ) ( \
+	( det3_sub( (x2), (x3), (x4) ) - \
+	  det3_sub( (x1), (x3), (x4) ) + \
+	  det3_sub( (x1), (x2), (x4) ) - \
+	  det3_sub( (x1), (x2), (x3) ) \
+	) / 6.0f )
+
+extern double isLargerThanZero( double, double );
+extern double isLargerThanZero2( double, double, double );
+extern void xyz2tprCoord( Coord, Coord* );
+extern void tpr2xyzCoord( Coord, Coord* );
+extern void xyz2tprVel( Coord, Coord, Coord* );
+extern void tpr2xyzVel( Coord, Coord, Coord* );
+
+/* For a given tetra_I (only interesting in first 5), what is the en_I of a given node of that tetra */
+const int nsub[] = {
+	0, 2, 3, 7,
+	0, 1, 2, 5,
+	4, 7, 5, 0,
+	5, 7, 6, 2,
+	5, 7, 2, 0,
+	3, 7, 4, 6,
+	4, 0, 3, 1,
+	6, 2, 1, 3,
+	1, 5, 6, 4,
+	1, 6, 3, 4
+};
+
+
+void _SnacRemesher_InterpolateNode(
+	void*			_context,
+	Index			contribution,
+	double			shapeFunction[4],
+	Node_LocalIndex		node_lI,
+	Node_LocalIndex		fromNode_lI,
+	Partition_Index		fromNode_rn_I,
+	Node_ShadowIndex	fromNode_sI,
+	Snac_Node*		newNode,
+	Snac_Node**		shadowNode )
+{
+	Snac_Context*			context = (Snac_Context*)_context;
+	SnacRemesher_Context*			contextExt = ExtensionManager_Get(
+		context->extensionMgr,
+		context,
+		SnacRemesher_ContextHandle );
+	SnacRemesher_Mesh*		meshExt = ExtensionManager_Get(
+		context->meshExtensionMgr,
+		context->mesh,
+		SnacRemesher_MeshHandle );
+	Snac_Node*			node = (Snac_Node*)ExtensionManager_At( context->mesh->nodeExtensionMgr, newNode, node_lI );
+	Snac_Node*			fromNode;
+	Index				d;
+	Coord                           temp,temp1,temp2,newNodeCoordS;
+
+	/* Zero out on first addition */
+	if( contribution == 0 ) {
+		memset( node->velocity, 0, sizeof(double) * DIM );
+	}
+	/* Deference source node (local/shadow) */
+	if( fromNode_lI < context->mesh->nodeLocalCount ) {
+		fromNode = Snac_Node_At( context, fromNode_lI );
+	}
+	else {
+		fromNode = (Snac_Node*)ExtensionManager_At( context->mesh->nodeExtensionMgr, shadowNode[fromNode_rn_I], fromNode_sI );
+	}
+	if(meshExt->meshType == SnacRemesher_Spherical) {
+		xyz2tprVel( meshExt->newNodeCoord[node_lI], fromNode->velocity, &temp1 );
+		for( d = 0; d < DIM; d++ ) {
+			temp2[d] = temp1[d] * shapeFunction[contribution];
+		}
+		xyz2tprCoord( meshExt->newNodeCoord[node_lI], &newNodeCoordS );
+		tpr2xyzVel( newNodeCoordS, temp2, &temp );
+		node->velocity[0] += temp[0];
+		node->velocity[1] += temp[1];
+		node->velocity[2] += temp[2];
+	}
+	else {
+		for( d = 0; d < DIM; d++ ) {
+			node->velocity[d] += fromNode->velocity[d] * shapeFunction[contribution];
+		}
+	}
+}
+
+void _SnacRemesher_InterpolateNodes( void* _context ) {
+	Snac_Context*			context = (Snac_Context*)_context;
+	SnacRemesher_Mesh*		meshExt = ExtensionManager_Get(
+		context->meshExtensionMgr,
+		context->mesh,
+		SnacRemesher_MeshHandle );
+
+	void _SnacRemesher_InterpolateNodes_Cartesian( void* _context );
+	void _SnacRemesher_InterpolateNodes_Spherical( void* _context );
+
+	if(meshExt->meshType == SnacRemesher_Spherical ) {
+		_SnacRemesher_InterpolateNodes_Spherical( context );
+		return;
+	}
+	else {
+		_SnacRemesher_InterpolateNodes_Cartesian( context );
+		return;
+	}
+}
+
+void _SnacRemesher_InterpolateNodes_Cartesian( void* _context ) {
+	Snac_Context*			context = (Snac_Context*)_context;
+	SnacRemesher_Context*		contextExt = ExtensionManager_Get(
+		context->extensionMgr,
+		context,
+		SnacRemesher_ContextHandle );
+	Mesh*					mesh = context->mesh;
+	HexaMD*				decomp = (HexaMD*)mesh->layout->decomp;
+	SnacRemesher_Mesh*		meshExt = ExtensionManager_Get(
+		context->meshExtensionMgr,
+		mesh,
+		SnacRemesher_MeshHandle );
+	int*				ind;
+	Index				d;
+	Element_LocalIndex      elX,elY,elZ;
+	Element_LocalIndex      nodeX,nodeY,nodeZ;
+	Element_NodeIndex		elementNodeCount;
+	double				xc[DIM*NODES_PER_ELEMENT];
+	PartitionIndex			rn_I;
+	Node_LocalIndex			node_lI,node_lN;
+	unsigned int                            All_passed;
+	double                          TOL;
+	int                    count;
+	const int                          shadowDepth = ( decomp->shadowDepth > 3) ? decomp->shadowDepth : 3;
+	const int                          numSearchElement = 2*shadowDepth-1;
+	const int                          numSearchDepth = shadowDepth-1;
+	const Element_LocalIndex		nElementX=decomp->elementLocal3DCounts[decomp->rank][0];
+	const Element_LocalIndex		nElementY=decomp->elementLocal3DCounts[decomp->rank][1];
+	const Element_LocalIndex		nElementZ=decomp->elementLocal3DCounts[decomp->rank][2];
+	const Node_LocalIndex		nNodeX=decomp->nodeLocal3DCounts[decomp->rank][0];
+	const Node_LocalIndex		nNodeY=decomp->nodeLocal3DCounts[decomp->rank][1];
+	const Node_LocalIndex		nNodeZ=decomp->nodeLocal3DCounts[decomp->rank][2];
+
+	Journal_DPrintf( context->debug, "In: %s\n", __func__ );
+
+	ind = (int*)malloc( sizeof( int ) * meshExt->nodeLocalCount );
+	memset( ind, 0, sizeof( int ) * meshExt->nodeLocalCount );
+
+	/* for all nodes, interpolate velocity; loop over local elements */
+	All_passed = 0;
+	TOL= 0.0f;
+	while(!All_passed) {
+		for(nodeZ=0; nodeZ < nNodeZ; nodeZ++)
+			for(nodeY=0; nodeY < nNodeY; nodeY++)
+				for(nodeX=0; nodeX < nNodeX; nodeX++) {
+					Element_NodeIndex       en_N;
+					double                  elembbox[2][DIM];
+					Node_LocalIndex**       elementNodeTbl = context->mesh->elementNodeTbl;
+					Element_LocalIndex      searchElement_lI,searchElement_lJ,searchElement_lK;
+					Element_LocalIndex      element_lN;
+
+					int				found;
+					Tetrahedra_Index		tetra_I;
+					Coord				newNodeCoord;
+
+					/* Ensure we haven't already done this node */
+					node_lI = nodeX + nodeY*nNodeX + nodeZ*nNodeX*nNodeY;
+					if( ind[node_lI] ) {
+						continue;
+					}
+					elX = (nodeX <= 1)? 0 : (nodeX-1);
+					elY = (nodeY <= 1)? 0 : (nodeY-1);
+					elZ = (nodeZ <= 1)? 0 : (nodeZ-1);
+
+					newNodeCoord[0] = meshExt->newNodeCoord[node_lI][0];
+					newNodeCoord[1] = meshExt->newNodeCoord[node_lI][1];
+					newNodeCoord[2] = meshExt->newNodeCoord[node_lI][2];
+
+					for(searchElement_lK=0;searchElement_lK<numSearchElement;searchElement_lK++) {
+						if( (elZ+searchElement_lK-numSearchDepth) < 0 || (elZ+searchElement_lK-numSearchDepth) >= nElementZ )
+							continue;
+						for(searchElement_lJ=0;searchElement_lJ<numSearchElement;searchElement_lJ++) {
+							if( (elY+searchElement_lJ-numSearchDepth) < 0 || (elY+searchElement_lJ-numSearchDepth) >= nElementY )
+								continue;
+							for(searchElement_lI=0;searchElement_lI<numSearchElement;searchElement_lI++) {
+								if( (elX+searchElement_lI-numSearchDepth) < 0 || (elX+searchElement_lI-numSearchDepth) >= nElementX )
+									continue;
+								element_lN = (elX+searchElement_lI-numSearchDepth) + (elY+searchElement_lJ-numSearchDepth)*nElementX
+									+ (elZ+searchElement_lK-numSearchDepth)*nElementY*nElementX;
+
+								if( ind[node_lI] ) {
+									break;
+								}
+
+								elementNodeCount = context->mesh->elementNodeCountTbl[element_lN];
+								if( elementNodeCount != (unsigned)NODES_PER_ELEMENT ) {
+									printf( "elementNodeCount != NODES_PER_ELEMENT  element_lN = %d", element_lN );
+									assert( 0 );
+								}
+
+								/* create a local copy of the veocity and coords for each of the element's nodes of the old mesh */
+								for( en_N = 0; en_N < NODES_PER_ELEMENT; en_N++) {
+									node_lN = elementNodeTbl[element_lN][en_N];
+									for( d = 0; d < DIM; d++ ) {
+										xc[en_N*DIM+d] = Mesh_CoordAt( context->mesh, node_lN )[d];
+									}
+									//xc[en_N*DIM+2] = meshExt->initialNodeCoord[elementNodeTbl[element_lN][en_N]][2];
+								}
+
+								/* Calculate element's bounding box */
+								for( d = 0; d < DIM; d++ ) {
+									elembbox[0][d] = DBL_MAX;
+									elembbox[1][d] = DBL_MIN;
+								}
+								for( en_N = 0; en_N < NODES_PER_ELEMENT; en_N++ ) {
+									for( d = 0; d < DIM; ++d ) {
+										elembbox[0][d] = MIN( elembbox[0][d], xc[en_N*DIM+d] );
+										elembbox[1][d] = MAX( elembbox[1][d], xc[en_N*DIM+d] );
+									}
+								}
+
+								/* If new mesh's current node is outside the bounding box, next loop */
+								if( newNodeCoord[0] < elembbox[0][0]-0.5f*(elembbox[1][0]-elembbox[0][0]) ||
+								    newNodeCoord[0] > elembbox[1][0]+0.5f*(elembbox[1][0]-elembbox[0][0]) ||
+								    newNodeCoord[1] < elembbox[0][1]-0.5f*(elembbox[1][1]-elembbox[0][1]) ||
+								    newNodeCoord[1] > elembbox[1][1]+0.5f*(elembbox[1][1]-elembbox[0][1]) ||
+								    newNodeCoord[2] < elembbox[0][2]-0.5f*(elembbox[1][2]-elembbox[0][2]) ||
+								    newNodeCoord[2] > elembbox[1][2]+0.5f*(elembbox[1][2]-elembbox[0][2]) ) {
+									continue;
+								}
+
+								/* loop over 10 sub tets in a brick element, work out the tetra it is in, and then interpolate */
+								found = 0;
+								for( tetra_I = 0; tetra_I < Tetrahedra_Count && !found; tetra_I++ ) {
+									double				x1[DIM];
+									double				x2[DIM];
+									double				x3[DIM];
+									double				x4[DIM];
+									double				dett;
+									double				det[4];
+
+									for( d = 0; d < DIM; d++ ) {
+										x1[d] = xc[nsub[tetra_I*4]*DIM+d];
+										x2[d] = xc[nsub[tetra_I*4+1]*DIM+d];
+										x3[d] = xc[nsub[tetra_I*4+2]*DIM+d];
+										x4[d] = xc[nsub[tetra_I*4+3]*DIM+d];
+									}
+
+									dett = TetrahedronVolume( x1, x2, x3, x4 );
+									det[0] = TetrahedronVolume( x2, x4, x3, newNodeCoord );
+									det[1] = TetrahedronVolume( x3, x4, x1, newNodeCoord );
+									det[2] = TetrahedronVolume( x1, x4, x2, newNodeCoord );
+									det[3] = TetrahedronVolume( x1, x2, x3, newNodeCoord );
+
+									dett = isLargerThanZero( dett, TOL );
+									det[0] = isLargerThanZero2( det[0], dett, TOL );
+									det[1] = isLargerThanZero2( det[1], dett, TOL );
+									det[2] = isLargerThanZero2( det[2], dett, TOL );
+									det[3] = isLargerThanZero2( det[3], dett, TOL );
+									dett = det[0] + det[1] + det[2] + det[3];
+
+									assert( dett != 0.0 );
+									if( dett < 0 )	{
+										printf( "Determinant evaluation is wrong node=%d\t xt[0]=%g \t xt[1]=%g \t xt[t]=%g\n",
+											en_N,
+											newNodeCoord[0],
+											newNodeCoord[1],
+											newNodeCoord[2]);
+										continue;
+									}
+
+									/* found if all det are greater than zero */
+									if ( det[0] >= 0.0f && det[1] >= 0.0f && det[2] >= 0.0f && det[3] >= 0.0f ) {
+										found = 1;
+									}
+									//fprintf(stderr,"%s: node_lI=%d element_lN=%d ind=%d foun=%d newCoord=%e %e %e\n\tdett=%e %e %e %e\n",__func__,node_lI,element_lN,ind[node_lI],found,newNodeCoord[0],newNodeCoord[1],newNodeCoord[2],det[0],det[1],det[2],dett);
+
+									if( found ) {
+										double				shape[4];
+										Index				tNode_I;
+
+										/* mark, such that we dont do it again */
+										ind[node_lI] = 1;
+
+										/* Calculate the shape funcs */
+										for( tNode_I = 0; tNode_I < 4; tNode_I++ ) {
+											shape[tNode_I] = det[tNode_I] / dett;
+										}
+
+										/* Assign proper values of velocities and temperatures from old mesh to new mesh */
+										for( tNode_I = 0; tNode_I < 4; tNode_I++ ) {
+
+											if( elementNodeTbl[element_lN][nsub[tetra_I*4+tNode_I]] >
+											    context->mesh->nodeLocalCount ) {
+												int i;
+
+												printf( "element_lN: %u, nsub[tetra_I*4+tNode_I]: %u\n",
+													element_lN,
+													nsub[tetra_I*4+tNode_I] );
+												printf( "elementNodeTbl: %p, { ",
+													elementNodeTbl );
+												for( i = 0; i < 8; i++ ) {
+													printf( "%u, ",
+														elementNodeTbl[element_lN][i] );
+												}
+												printf( "\n" );
+												assert(
+													elementNodeTbl[element_lN][nsub[tetra_I*4+tNode_I]] >
+													context->mesh->nodeLocalCount );
+											}
+
+											SnacRemesher_InterpolateNode(
+												context,
+												contextExt,
+												tNode_I,
+												shape,
+												node_lI,
+												elementNodeTbl[element_lN][nsub[tetra_I*4+tNode_I]],
+												0,
+												0,
+												meshExt->newNode,
+												0 );
+										}
+										break;
+									}
+								}
+							}
+						}
+					}
+					/*
+					** Loop over shadow elements
+					*/
+					for( rn_I = 0; rn_I < meshExt->neighbourRankCount; rn_I++ ) {
+						Element_ShadowIndex		element_sN;
+
+						/* Loop over all the shadow elements to find one including node_lI */
+						for( element_sN = 0; element_sN < meshExt->shadowElementRemoteCount[rn_I]; element_sN++ ) {
+							Element_GlobalIndex		gElement_N = meshExt->shadowElementRemoteArray[rn_I][element_sN];
+							Node_Index*			shadowElementNodesN = (Node_Index*)malloc( sizeof(Node_Index) * NODES_PER_ELEMENT );
+							Index				en_N;
+							double				elembbox[2][DIM];
+							Node_GlobalIndex	elementNodeN[8];
+
+							if(ind[node_lI] == 1)
+								break;
+
+							/* Figure out node index */
+							_HexaEL_BuildCornerIndices( context->mesh->layout->elementLayout, gElement_N, elementNodeN );
+							for( en_N = 0; en_N < NODES_PER_ELEMENT; en_N++ ) {
+								Node_GlobalIndex    node_gN = elementNodeN[en_N];
+								Index               node_lN = Mesh_NodeMapGlobalToLocal( context->mesh, node_gN );
+								unsigned int        found = 0;
+								if( node_lN < meshExt->nodeLocalCount ) {
+									shadowElementNodesN[en_N] = node_lN;
+									found = 1;
+									elementNodeN[en_N] = node_lN;
+								}
+								else {
+									Node_ShadowIndex		node_sI;
+									for( node_sI = 0; node_sI < meshExt->shadowNodeRemoteCount[rn_I]; node_sI++ ) {
+										if( node_gN == meshExt->shadowNodeRemoteArray[rn_I][node_sI] ) {
+											shadowElementNodesN[en_N] = context->mesh->nodeGlobalCount + node_sI;
+											found = 1;
+										}
+									}
+								}
+								assert( found ); /* we expected this to be a shadow node, but wasn't in list! */
+							}
+
+							for( en_N = 0; en_N < NODES_PER_ELEMENT; en_N++ ) {
+								node_lN = shadowElementNodesN[en_N];
+								if( node_lN < context->mesh->nodeDomainCount ) {
+									for( d = 0; d < DIM; d++ ) {
+										xc[en_N*DIM+d] = Mesh_CoordAt( context->mesh, node_lN )[d];
+									}
+								}
+								else {
+									node_lN -= context->mesh->nodeGlobalCount;
+									for( d = 0; d < DIM; d++ ) {
+										xc[en_N*DIM+d] = meshExt->shadowNodeRemoteCoord[rn_I][node_lN][d];
+									}
+								}
+							}
+							/* Calculate element's bounding box */
+							for( d = 0; d < DIM; ++d ) {
+								elembbox[0][d] = DBL_MAX;
+								elembbox[1][d] = DBL_MIN;
+							}
+							for( en_N = 0; en_N < NODES_PER_ELEMENT; en_N++ ) {
+								for( d = 0; d < DIM; ++d ) {
+									elembbox[0][d] = MIN( elembbox[0][d], xc[en_N*DIM+d] );
+									elembbox[1][d] = MAX( elembbox[1][d], xc[en_N*DIM+d] );
+								}
+							}
+							/* If new mesh's current node is outside the bounding box, next loop */
+							if( newNodeCoord[0] < elembbox[0][0]-0.5f*(elembbox[1][0]-elembbox[0][0]) ||
+							    newNodeCoord[0] > elembbox[1][0]+0.5f*(elembbox[1][0]-elembbox[0][0]) ||
+							    newNodeCoord[1] < elembbox[0][1]-0.5f*(elembbox[1][1]-elembbox[0][1]) ||
+							    newNodeCoord[1] > elembbox[1][1]+0.5f*(elembbox[1][1]-elembbox[0][1]) ||
+							    newNodeCoord[2] < elembbox[0][2]-0.5f*(elembbox[1][2]-elembbox[0][2]) ||
+							    newNodeCoord[2] > elembbox[1][2]+0.5f*(elembbox[1][2]-elembbox[0][2]) )
+							{
+								//assert(0);
+								continue;
+							}
+
+							/* loop over 10 sub tets in a brick element, work out the tetra it is in, and then interpolate */
+							found = 0;
+							for( tetra_I = 0; tetra_I < Tetrahedra_Count && !found; tetra_I++ ) {
+								double				x1[DIM];
+								double				x2[DIM];
+								double				x3[DIM];
+								double				x4[DIM];
+								double				dett;
+								double				det[4];
+
+								for( d = 0; d < DIM; d++ ) {
+									x1[d] = xc[nsub[tetra_I*4]*DIM+d];
+									x2[d] = xc[nsub[tetra_I*4+1]*DIM+d];
+									x3[d] = xc[nsub[tetra_I*4+2]*DIM+d];
+									x4[d] = xc[nsub[tetra_I*4+3]*DIM+d];
+								}
+								dett = TetrahedronVolume( x1, x2, x3, x4 );
+								det[0] = TetrahedronVolume( x2, x4, x3, newNodeCoord );
+								det[1] = TetrahedronVolume( x3, x4, x1, newNodeCoord );
+								det[2] = TetrahedronVolume( x1, x4, x2, newNodeCoord );
+								det[3] = TetrahedronVolume( x1, x2, x3, newNodeCoord );
+
+								dett = isLargerThanZero( dett, TOL );
+								det[0] = isLargerThanZero2( det[0], dett, TOL );
+								det[1] = isLargerThanZero2( det[1], dett, TOL );
+								det[2] = isLargerThanZero2( det[2], dett, TOL );
+								det[3] = isLargerThanZero2( det[3], dett, TOL );
+								dett = det[0] + det[1] + det[2] + det[3];
+
+								Journal_Firewall( dett != 0.0, context->snacError, "node_lI=%d element_sN=%d me=%d TOL=%e newCoord=%e %e %e\nx1(%d)=   %e %e %e\nx2(%d)=   %e %e %e \nx3(%d)=   %e %e %e\nx4(%d)=   %e %e %e\ndett=%e (%e %e %e %e)\n", node_lI,element_sN,context->rank,TOL, newNodeCoord[0],newNodeCoord[1],newNodeCoord[2],nsub[tetra_I*4],x1[0],x1[1],x1[2],nsub[tetra_I*4+1],x2[0],x2[1],x2[2],nsub[tetra_I*4+2],x3[0],x3[1],x3[2],nsub[tetra_I*4+3],x4[0],x4[1],x4[2],dett,det[0],det[1],det[2],det[3]);
+
+								if( dett < 0 ) {
+									continue;
+								}
+
+								/* found if all det are greater than zero */
+								if( det[0] >= 0.0f && det[1] >= 0.0f && det[2] >= 0.0f && det[3] >= 0.0f ) {
+									found = 1;
+								}
+								if( found ) {
+									double				shape[4];
+									Index				tNode_I;
+
+									/* mark, such that we dont do it again */
+									ind[node_lI] = 1;
+
+									/* Calculate the shape funcs */
+									for( tNode_I = 0; tNode_I < 4; tNode_I++ ) {
+										shape[tNode_I] = det[tNode_I] / dett;
+									}
+
+									/* Assign proper values of velocities and temperatures from old mesh to new mesh */
+									for( tNode_I = 0; tNode_I < 4; tNode_I++ ) {
+										SnacRemesher_InterpolateNode(
+											context,
+											contextExt,
+											tNode_I,
+											shape,
+											node_lI,
+											shadowElementNodesN[nsub[tetra_I*4+tNode_I]],
+											rn_I,
+											shadowElementNodesN[nsub[tetra_I*4+tNode_I]] -
+											context->mesh->nodeGlobalCount,
+											meshExt->newNode,
+											meshExt->shadowNodeRemote );
+									}
+									break;
+								}
+							}
+							if( shadowElementNodesN )
+								free( shadowElementNodesN );
+						}
+					}
+				}
+		All_passed = 1;
+		count = 0;
+		for( node_lI = 0; node_lI < meshExt->nodeLocalCount; node_lI++ ) {
+			//fprintf(stderr,"Interpolating Nodal values rank=%d Node #%d ind=%d\n",context->rank,node_lI,ind[node_lI]);
+			if( ind[node_lI] == 0 ) {
+				Journal_DPrintf( context->debug,
+						 " timeStep=%d rank=%d Node #%d cannot find tetra, New coord=%e %e %e  coord=%e %e %e diff=%e %e %e\n",
+						 context->timeStep,context->rank,node_lI,
+						 meshExt->newNodeCoord[node_lI][0],meshExt->newNodeCoord[node_lI][1],meshExt->newNodeCoord[node_lI][2],
+						 mesh->nodeCoord[node_lI][0],mesh->nodeCoord[node_lI][1],mesh->nodeCoord[node_lI][2],
+						 meshExt->newNodeCoord[node_lI][0]-mesh->nodeCoord[node_lI][0],
+						 meshExt->newNodeCoord[node_lI][1]-mesh->nodeCoord[node_lI][1],
+						 meshExt->newNodeCoord[node_lI][2]-mesh->nodeCoord[node_lI][2]
+					);
+
+				All_passed = 0;
+				count++;
+				//fprintf(stderr,"me=%d failed node=%d\n",context->rank,node_lI);
+			}
+		}
+		if(TOL==0.0)TOL = 1.0e-10;
+		else TOL *= 10.0;
+		Journal_DPrintf( context->debug," In: %s,rank=%d Increased tolerance: %e, the number of failed nodde: %d\n", __func__, context->rank, TOL,count);
+		Journal_Firewall( TOL <= 1.0e-03, context->snacError," In: %s,rank=%d Increased tolerance: %e, the number of failed nodde: %d\n", __func__, context->rank, TOL,count);
+	}
+	free( ind );
+}
+
+
+
+void _SnacRemesher_InterpolateNodes_Spherical( void* _context ) {
+	Snac_Context*			context = (Snac_Context*)_context;
+	SnacRemesher_Context*		contextExt = ExtensionManager_Get(
+		context->extensionMgr,
+		context,
+		SnacRemesher_ContextHandle );
+	Mesh*					mesh = context->mesh;
+	HexaMD*				decomp = (HexaMD*)mesh->layout->decomp;
+	SnacRemesher_Mesh*		meshExt = ExtensionManager_Get(
+		context->meshExtensionMgr,
+		mesh,
+		SnacRemesher_MeshHandle );
+	int*				ind;
+	Index				d;
+	Element_LocalIndex      elX,elY,elZ;
+	Element_LocalIndex      nodeX,nodeY,nodeZ;
+	Element_NodeIndex		elementNodeCount;
+	double				xc[DIM*NODES_PER_ELEMENT];
+	double				xcs[DIM*NODES_PER_ELEMENT];
+	PartitionIndex			rn_I;
+	Node_LocalIndex			node_lI,node_lN;
+	unsigned int                            All_passed;
+	double                          TOL;
+	int                             count;
+	const int                          shadowDepth = ( decomp->shadowDepth > 3) ? decomp->shadowDepth : 3;
+	const int                          numSearchElement = 2*shadowDepth-1;
+	const int                          numSearchDepth = shadowDepth-1;
+	const Element_LocalIndex		nElementX=decomp->elementLocal3DCounts[decomp->rank][0];
+	const Element_LocalIndex		nElementY=decomp->elementLocal3DCounts[decomp->rank][1];
+	const Element_LocalIndex		nElementZ=decomp->elementLocal3DCounts[decomp->rank][2];
+	const Node_LocalIndex		nNodeX=decomp->nodeLocal3DCounts[decomp->rank][0];
+	const Node_LocalIndex		nNodeY=decomp->nodeLocal3DCounts[decomp->rank][1];
+	const Node_LocalIndex		nNodeZ=decomp->nodeLocal3DCounts[decomp->rank][2];
+
+	Journal_DPrintf( context->debug, "In: %s\n", __func__ );
+
+	ind = (int*)malloc( sizeof( int ) * meshExt->nodeLocalCount );
+	memset( ind, 0, sizeof( int ) * meshExt->nodeLocalCount );
+
+	/* for all nodes, interpolate velocity; loop over local elements */
+	All_passed = 0;
+	TOL= 0.0f;
+	while(!All_passed) {
+		for(nodeZ=0; nodeZ < nNodeZ; nodeZ++)
+			for(nodeY=0; nodeY < nNodeY; nodeY++)
+				for(nodeX=0; nodeX < nNodeX; nodeX++) {
+					Element_NodeIndex       en_N;
+					double                  elembbox[2][DIM];
+					Node_LocalIndex**       elementNodeTbl = context->mesh->elementNodeTbl;
+					Coord                   temp1,temp2;
+					Element_LocalIndex      searchElement_lI,searchElement_lJ,searchElement_lK;
+					Element_LocalIndex      element_lN;
+
+					int				found;
+					Tetrahedra_Index		tetra_I;
+					Coord				newNodeCoord;
+					Coord				newNodeCoordS;
+
+					/* Ensure we haven't already done this node */
+					node_lI = nodeX + nodeY*nNodeX + nodeZ*nNodeX*nNodeY;
+					if( ind[node_lI] ) {
+						continue;
+					}
+					elX = (nodeX <= 1)? 0 : (nodeX-1);
+					elY = (nodeY <= 1)? 0 : (nodeY-1);
+					elZ = (nodeZ <= 1)? 0 : (nodeZ-1);
+
+					/* otherwise, try to interpolate old mesh's values for the new coordinates */
+					newNodeCoord[0] = meshExt->newNodeCoord[node_lI][0];
+					newNodeCoord[1] = meshExt->newNodeCoord[node_lI][1];
+					newNodeCoord[2] = meshExt->newNodeCoord[node_lI][2];
+					xyz2tprCoord( newNodeCoord, &newNodeCoordS );
+					newNodeCoordS[1] /= 6371000.0;
+
+					for(searchElement_lK=0;searchElement_lK<numSearchElement;searchElement_lK++) {
+						if( (elZ+searchElement_lK-numSearchDepth) < 0 || (elZ+searchElement_lK-numSearchDepth) >= nElementZ )
+							continue;
+						for(searchElement_lJ=0;searchElement_lJ<numSearchElement;searchElement_lJ++) {
+							if( (elY+searchElement_lJ-numSearchDepth) < 0 || (elY+searchElement_lJ-numSearchDepth) >= nElementY )
+								continue;
+							for(searchElement_lI=0;searchElement_lI<numSearchElement;searchElement_lI++) {
+								if( (elX+searchElement_lI-numSearchDepth) < 0 || (elX+searchElement_lI-numSearchDepth) >= nElementX )
+									continue;
+								element_lN = (elX+searchElement_lI-numSearchDepth) + (elY+searchElement_lJ-numSearchDepth)*nElementX
+									+ (elZ+searchElement_lK-numSearchDepth)*nElementY*nElementX;
+
+								if( ind[node_lI] ) {
+									break;
+								}
+
+								elementNodeCount = context->mesh->elementNodeCountTbl[element_lN];
+								if( elementNodeCount != (unsigned)NODES_PER_ELEMENT ) {
+									printf( "elementNodeCount != NODES_PER_ELEMENT  element_lN = %d", element_lN );
+									assert( 0 );
+								}
+
+								/* create a local copy of the veocity and coords for each of the element's nodes of the old mesh */
+								for( en_N = 0; en_N < NODES_PER_ELEMENT; en_N++) {
+
+									node_lN = elementNodeTbl[element_lN][en_N];
+									for( d = 0; d < DIM; d++ ) {
+										xc[en_N*DIM+d] = Mesh_CoordAt( context->mesh, node_lN )[d];
+									}
+									// (0,1,2) <=> (x,y,z) <=> (fi,r,theta)
+									temp1[0] = xc[en_N*DIM+0];
+									temp1[1] = xc[en_N*DIM+1];
+									temp1[2] = xc[en_N*DIM+2];
+									xyz2tprCoord( temp1, &temp2 );
+									xcs[en_N*DIM+0] = temp2[0];
+									xcs[en_N*DIM+1] = temp2[1]/6371000.0;
+									xcs[en_N*DIM+2] = temp2[2];
+								}
+
+								/* Calculate element's bounding box */
+								for( d = 0; d < DIM; d++ ) {
+									elembbox[0][d] = DBL_MAX;
+									elembbox[1][d] = DBL_MIN;
+								}
+								for( en_N = 0; en_N < NODES_PER_ELEMENT; en_N++ ) {
+									for( d = 0; d < DIM; ++d ) {
+										elembbox[0][d] = MIN( elembbox[0][d], xcs[en_N*DIM+d] );
+										elembbox[1][d] = MAX( elembbox[1][d], xcs[en_N*DIM+d] );
+									}
+								}
+								/* If new mesh's current node is outside the bounding box, next loop */
+								if(
+									newNodeCoordS[0] < elembbox[0][0]-0.5f*(elembbox[1][0]-elembbox[0][0]) ||
+									newNodeCoordS[0] > elembbox[1][0]+0.5f*(elembbox[1][0]-elembbox[0][0]) ||
+									newNodeCoordS[1] < elembbox[0][1]-0.5f*(elembbox[1][1]-elembbox[0][1]) ||
+									newNodeCoordS[1] > elembbox[1][1]+0.5f*(elembbox[1][1]-elembbox[0][1]) ||
+									newNodeCoordS[2] < elembbox[0][2]-0.5f*(elembbox[1][2]-elembbox[0][2]) ||
+									newNodeCoordS[2] > elembbox[1][2]+0.5f*(elembbox[1][2]-elembbox[0][2]) ) {
+									continue;
+								}
+								/* if the current coord is very close to the initial ones, just copy those initial values rather than bother to compute determinents and add error */
+								if( ( meshExt->newNodeCoord[node_lI][0] >= mesh->nodeCoord[node_lI][0] - TOL*(elembbox[1][0]-elembbox[0][0]) && meshExt->newNodeCoord[node_lI][0] <= mesh->nodeCoord[node_lI][0] + TOL*(elembbox[1][0]-elembbox[0][0]) ) &&
+								    ( meshExt->newNodeCoord[node_lI][1] >= mesh->nodeCoord[node_lI][1] - TOL*(elembbox[1][1]-elembbox[0][1]) && meshExt->newNodeCoord[node_lI][1] <= mesh->nodeCoord[node_lI][1] + TOL*(elembbox[1][1]-elembbox[0][1]) ) &&
+								    ( meshExt->newNodeCoord[node_lI][2] >= mesh->nodeCoord[node_lI][2] - TOL*(elembbox[1][2]-elembbox[0][2]) && meshExt->newNodeCoord[node_lI][2] <= mesh->nodeCoord[node_lI][2] + TOL*(elembbox[1][2]-elembbox[0][2]) ) ) {
+									ind[node_lI] = 1;
+									continue;
+								}
+
+								/* loop over 10 sub tets in a brick element, work out the tetra it is in, and then interpolate */
+								found = 0;
+								for( tetra_I = 0; tetra_I < Tetrahedra_Count && !found; tetra_I++ ) {
+									double				x1[DIM];
+									double				x2[DIM];
+									double				x3[DIM];
+									double				x4[DIM];
+									double				dett;
+									double				det[4];
+
+
+									for( d = 0; d < DIM; d++ ) {
+										x1[d] = xcs[nsub[tetra_I*4]*DIM+d];
+										x2[d] = xcs[nsub[tetra_I*4+1]*DIM+d];
+										x3[d] = xcs[nsub[tetra_I*4+2]*DIM+d];
+										x4[d] = xcs[nsub[tetra_I*4+3]*DIM+d];
+									}
+
+									dett = TetrahedronVolume( x1, x2, x3, x4 );
+									det[0] = TetrahedronVolume( x2, x4, x3, newNodeCoordS );
+									det[1] = TetrahedronVolume( x3, x4, x1, newNodeCoordS );
+									det[2] = TetrahedronVolume( x1, x4, x2, newNodeCoordS );
+									det[3] = TetrahedronVolume( x1, x2, x3, newNodeCoordS );
+
+									dett = isLargerThanZero2( dett, dett, TOL );
+									det[0] = isLargerThanZero2( det[0], dett, TOL );
+									det[1] = isLargerThanZero2( det[1], dett, TOL );
+									det[2] = isLargerThanZero2( det[2], dett, TOL );
+									det[3] = isLargerThanZero2( det[3], dett, TOL );
+									dett = det[0] + det[1] + det[2] + det[3];
+
+									assert( dett != 0.0 );
+									if( dett <= 0 )	{
+										continue;
+									}
+
+									/* found if all det are greater than zero */
+									if ( det[0] >= 0.0f && det[1] >= 0.0f && det[2] >= 0.0f && det[3] >= 0.0f ) {
+										found = 1;
+									}
+
+									if( found ) {
+										double				shape[4];
+										Index				tNode_I;
+
+										/* mark, such that we dont do it again */
+										ind[node_lI] = 1;
+
+										/* Calculate the shape funcs */
+										for( tNode_I = 0; tNode_I < 4; tNode_I++ ) {
+											shape[tNode_I] = det[tNode_I] / dett;
+										}
+
+										/* Assign proper values of velocities and temperatures from old mesh to new mesh */
+										for( tNode_I = 0; tNode_I < 4; tNode_I++ ) {
+
+											if( elementNodeTbl[element_lN][nsub[tetra_I*4+tNode_I]] >
+											    context->mesh->nodeLocalCount ) {
+												int i;
+
+												printf( "element_lI: %u, nsub[tetra_I*4+tNode_I]: %u\n",
+													element_lN,
+													nsub[tetra_I*4+tNode_I] );
+												printf( "elementNodeTbl: %p, { ",
+													elementNodeTbl );
+												for( i = 0; i < 8; i++ ) {
+													printf( "%u, ",
+														elementNodeTbl[element_lN][i] );
+												}
+												printf( "\n" );
+												assert(
+													elementNodeTbl[element_lN][nsub[tetra_I*4+tNode_I]] >
+													context->mesh->nodeLocalCount );
+											}
+
+											SnacRemesher_InterpolateNode(
+												context,
+												contextExt,
+												tNode_I,
+												shape,
+												node_lI,
+												elementNodeTbl[element_lN][nsub[tetra_I*4+tNode_I]],
+												0,
+												0,
+												meshExt->newNode,
+												0 );
+										}
+										break;
+									}
+#if 0
+									if(context->rank==0 && node_lI==32)
+										fprintf(stderr,"Found? %d TOL=%e timeStep=%d me=%d element_lI=%d node_lI=%d tetra_I=%d\nxc=(%e %e %e) (%e %e %e) (%e %e %e) (%e %e %e)\nnewX=%e %e %e bbox=(%e %e) (%e %e) (%e %e)\ndett=%e %e %e %e %e\n\n",
+											found,TOL,context->timeStep,context->rank,element_lN,node_lI,tetra_I,
+											x1[0],x1[1],x1[2],x2[0],x2[1],x2[2],x3[0],x3[1],x3[2],x4[0],x4[1],x4[2],
+											newNodeCoordS[0],newNodeCoordS[1],newNodeCoordS[2],
+											elembbox[0][0],elembbox[1][0],elembbox[0][1],elembbox[1][1],elembbox[0][2],elembbox[1][2],
+											det[0],det[1],det[2],det[3],dett);
+#endif
+								}
+							}
+						}
+					}
+					/*
+					** Loop over shadow elements
+					*/
+					for( rn_I = 0; rn_I < meshExt->neighbourRankCount; rn_I++ ) {
+						Element_ShadowIndex		element_sN;
+
+						/* Loop over all the shadow elements to find one including node_lI */
+						for( element_sN = 0; element_sN < meshExt->shadowElementRemoteCount[rn_I]; element_sN++ ) {
+							Element_GlobalIndex		gElement_N = meshExt->shadowElementRemoteArray[rn_I][element_sN];
+							Node_Index*			shadowElementNodesN = (Node_Index*)malloc( sizeof(Node_Index) * NODES_PER_ELEMENT );
+							Index				en_N;
+							double				elembbox[2][DIM];
+							Node_GlobalIndex	elementNodeN[8];
+
+							if(ind[node_lI] == 1)
+								break;
+
+							/* Figure out node index */
+							_HexaEL_BuildCornerIndices( context->mesh->layout->elementLayout, gElement_N, elementNodeN );
+							for( en_N = 0; en_N < NODES_PER_ELEMENT; en_N++ ) {
+								Node_GlobalIndex    node_gN = elementNodeN[en_N];
+								Index               node_lN = Mesh_NodeMapGlobalToLocal( context->mesh, node_gN );
+								unsigned int        found = 0;
+								if( node_lN < meshExt->nodeLocalCount ) {
+									shadowElementNodesN[en_N] = node_lN;
+									found = 1;
+									elementNodeN[en_N] = node_lN;
+								}
+								else {
+									Node_ShadowIndex		node_sI;
+									for( node_sI = 0; node_sI < meshExt->shadowNodeRemoteCount[rn_I]; node_sI++ ) {
+										if( node_gN == meshExt->shadowNodeRemoteArray[rn_I][node_sI] ) {
+											shadowElementNodesN[en_N] = context->mesh->nodeGlobalCount + node_sI;
+											found = 1;
+										}
+									}
+								}
+								assert( found ); /* we expected this to be a shadow node, but wasn't in list! */
+							}
+
+							/* create a local copy of the temp, vel, and coords for each of the element's nodes of the old mesh */
+							for( en_N = 0; en_N < NODES_PER_ELEMENT; en_N++ ) {
+								/* copying nodal field values and nodal coordinates of the old mesh for each hex element into local
+								   array */
+								node_lN = shadowElementNodesN[en_N];
+								if( node_lN < context->mesh->nodeLocalCount ) {
+									for( d = 0; d < DIM; d++ ) {
+										xc[en_N*DIM+d] = Mesh_CoordAt( context->mesh, node_lN )[d];
+									}
+								}
+								else {
+									node_lN -= context->mesh->nodeGlobalCount;
+									for( d = 0; d < DIM; d++ ) {
+										xc[en_N*DIM+d] = meshExt->shadowNodeRemoteCoord[rn_I][node_lN][d];
+									}
+								}
+								// (0,1,2) <=> (x,y,z) <=> (fi,r,theta)
+								temp1[0] = xc[en_N*DIM+0];
+								temp1[1] = xc[en_N*DIM+1];
+								temp1[2] = xc[en_N*DIM+2];
+								xyz2tprCoord( temp1, &temp2 );
+								xcs[en_N*DIM+0] = temp2[0];
+								xcs[en_N*DIM+1] = temp2[1]/6371000.0;
+								xcs[en_N*DIM+2] = temp2[2];
+							}
+
+							/* Calculate element's bounding box */
+							for( d = 0; d < DIM; ++d ) {
+								elembbox[0][d] = DBL_MAX;
+								elembbox[1][d] = DBL_MIN;
+							}
+							for( en_N = 0; en_N < NODES_PER_ELEMENT; en_N++ ) {
+								for( d = 0; d < DIM; ++d ) {
+									elembbox[0][d] = MIN( elembbox[0][d], xcs[en_N*DIM+d] );
+									elembbox[1][d] = MAX( elembbox[1][d], xcs[en_N*DIM+d] );
+								}
+							}
+							/* If new mesh's current node is outside the bounding box, next loop */
+							if( newNodeCoordS[0] < elembbox[0][0]-0.5f*(elembbox[1][0]-elembbox[0][0]) ||
+							    newNodeCoordS[0] > elembbox[1][0]+0.5f*(elembbox[1][0]-elembbox[0][0]) ||
+							    newNodeCoordS[1] < elembbox[0][1]-0.5f*(elembbox[1][1]-elembbox[0][1]) ||
+							    newNodeCoordS[1] > elembbox[1][1]+0.5f*(elembbox[1][1]-elembbox[0][1]) ||
+							    newNodeCoordS[2] < elembbox[0][2]-0.5f*(elembbox[1][2]-elembbox[0][2]) ||
+							    newNodeCoordS[2] > elembbox[1][2]+0.5f*(elembbox[1][2]-elembbox[0][2]) )
+							{
+								continue;
+							}
+
+							/* loop over 10 sub tets in a brick element, work out the tetra it is in, and then interpolate */
+							found = 0;
+							for( tetra_I = 0; tetra_I < Tetrahedra_Count && !found; tetra_I++ ) {
+								double				x1[DIM];
+								double				x2[DIM];
+								double				x3[DIM];
+								double				x4[DIM];
+								double				dett;
+								double				det[4];
+
+								for( d = 0; d < DIM; d++ ) {
+									x1[d] = xcs[nsub[tetra_I*4]*DIM+d];
+									x2[d] = xcs[nsub[tetra_I*4+1]*DIM+d];
+									x3[d] = xcs[nsub[tetra_I*4+2]*DIM+d];
+									x4[d] = xcs[nsub[tetra_I*4+3]*DIM+d];
+								}
+
+								dett = TetrahedronVolume( x1, x2, x3, x4 );
+								det[0] = TetrahedronVolume( x2, x4, x3, newNodeCoordS );
+								det[1] = TetrahedronVolume( x3, x4, x1, newNodeCoordS );
+								det[2] = TetrahedronVolume( x1, x4, x2, newNodeCoordS );
+								det[3] = TetrahedronVolume( x1, x2, x3, newNodeCoordS );
+
+								dett = isLargerThanZero2( dett, dett, TOL );
+								det[0] = isLargerThanZero2( det[0], dett, TOL );
+								det[1] = isLargerThanZero2( det[1], dett, TOL );
+								det[2] = isLargerThanZero2( det[2], dett, TOL );
+								det[3] = isLargerThanZero2( det[3], dett, TOL );
+								dett = det[0] + det[1] + det[2] + det[3];
+
+								Journal_Firewall( dett != 0.0, context->snacError, "node_lI=%d element_sN=%d me=%d TOL=%e newCoord=%e %e %e\nx1(%d)=   %e %e %e\nx2(%d)=   %e %e %e \nx3(%d)=   %e %e %e\nx4(%d)=   %e %e %e\ndett=%e (%e %e %e %e)\n", node_lI,element_sN,context->rank,TOL, newNodeCoordS[0],newNodeCoordS[1],newNodeCoordS[2],nsub[tetra_I*4],x1[0],x1[1],x1[2],nsub[tetra_I*4+1],x2[0],x2[1],x2[2],nsub[tetra_I*4+2],x3[0],x3[1],x3[2],nsub[tetra_I*4+3],x4[0],x4[1],x4[2],dett,det[0],det[1],det[2],det[3]);
+								if( dett < 0 ) {
+									continue;
+								}
+
+								/* found if all det are greater than zero */
+								if( det[0] >= 0.0f && det[1] >= 0.0f && det[2] >= 0.0f && det[3] >= 0.0f ) {
+									found = 1;
+								}
+								if( found ) {
+									double				shape[4];
+									Index				tNode_I;
+
+									/* mark, such that we dont do it again */
+									ind[node_lI] = 1;
+
+									/* Calculate the shape funcs */
+									for( tNode_I = 0; tNode_I < 4; tNode_I++ ) {
+										shape[tNode_I] = det[tNode_I] / dett;
+									}
+
+									/* Assign proper values of velocities and temperatures from old mesh to new mesh */
+									for( tNode_I = 0; tNode_I < 4; tNode_I++ ) {
+										SnacRemesher_InterpolateNode(
+											context,
+											contextExt,
+											tNode_I,
+											shape,
+											node_lI,
+											shadowElementNodesN[nsub[tetra_I*4+tNode_I]],
+											rn_I,
+											shadowElementNodesN[nsub[tetra_I*4+tNode_I]] -
+											context->mesh->nodeGlobalCount,
+											meshExt->newNode,
+											meshExt->shadowNodeRemote);
+									}
+									break;
+								}
+							}
+							if( shadowElementNodesN )
+								free( shadowElementNodesN );
+						}
+					}
+				}
+		All_passed = 1;
+		count = 0;
+		for( node_lI = 0; node_lI < meshExt->nodeLocalCount; node_lI++ )
+		{
+			if( ind[node_lI] == 0 ) {
+				All_passed = 0;
+				count++;
+			}
+		}
+		if(TOL==0.0)TOL = 1.0e-10;
+		else TOL *= 10.0;
+		Journal_DPrintf( context->debug," In: %s,rank=%d Increased tolerance: %e, the number of failed nodde: %d\n", __func__, context->rank, TOL,count);
+		//Journal_Firewall( TOL <= 1.0e-03, context->snacError," In: %s,rank=%d Increased tolerance: %e, the number of failed nodde: %d\n", __func__, context->rank, TOL,count);
+	}
+
+	free( ind );
+
+}
+
+#endif

Added: long/3D/SNAC/trunk/Snac/plugins/remesher_BI/Remesher.h
===================================================================
--- long/3D/SNAC/trunk/Snac/plugins/remesher_BI/Remesher.h	                        (rev 0)
+++ long/3D/SNAC/trunk/Snac/plugins/remesher_BI/Remesher.h	2011-10-07 16:18:20 UTC (rev 19040)
@@ -0,0 +1,54 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+**
+** Copyright (C), 2003, 
+**	Steve Quenette, 110 Victoria Street, Melbourne, Victoria, 3053, Australia.
+**	Californian Institute of Technology, 1200 East California Boulevard, Pasadena, California, 91125, USA.
+**	University of Texas, 1 University Station, Austin, Texas, 78712, USA.
+**
+** Authors:
+**	Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
+**	Stevan M. Quenette, Visitor in Geophysics, Caltech.
+**	Luc Lavier, Research Scientist, The University of Texas. (luc at utig.ug.utexas.edu)
+**	Luc Lavier, Research Scientist, Caltech.
+**
+** This program is free software; you can redistribute it and/or modify it
+** under the terms of the GNU General Public License as published by the
+** Free Software Foundation; either version 2, or (at your option) any
+** later version.
+** 
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+** GNU General Public License for more details.
+** 
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+**
+*/
+/** \file
+** Role:
+**
+** Assumptions:
+**
+** Comments:
+**
+** $Id: Remesher.h 3095 2005-07-13 09:50:46Z LukeHodkinson $
+**
+**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#ifndef __SnacRemesher_h__
+#define __SnacRemesher_h__
+	
+	#include "types.h"  
+	#include "Utils.h"
+	#include "Context.h"  
+	#include "Register.h"  
+	#include "ConstructExtensions.h"  
+	#include "Build.h"  
+	#include "InitialConditions.h"  
+	#include "TestCondFunc.h"
+	#include "Remesh.h"
+	#include "DeleteExtensions.h"  
+	
+#endif /* __SnacRemesher_h__ */

Added: long/3D/SNAC/trunk/Snac/plugins/remesher_BI/TestCondFunc.c
===================================================================
--- long/3D/SNAC/trunk/Snac/plugins/remesher_BI/TestCondFunc.c	                        (rev 0)
+++ long/3D/SNAC/trunk/Snac/plugins/remesher_BI/TestCondFunc.c	2011-10-07 16:18:20 UTC (rev 19040)
@@ -0,0 +1,112 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+**
+** Copyright (C), 2003,
+**	Steve Quenette, 110 Victoria Street, Melbourne, Victoria, 3053, Australia.
+**	Californian Institute of Technology, 1200 East California Boulevard, Pasadena, California, 91125, USA.
+**	University of Texas, 1 University Station, Austin, Texas, 78712, USA.
+**
+** Authors:
+**	Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
+**	Stevan M. Quenette, Visitor in Geophysics, Caltech.
+**	Luc Lavier, Research Scientist, The University of Texas. (luc at utig.ug.utexas.edu)
+**	Luc Lavier, Research Scientist, Caltech.
+**
+** This program is free software; you can redistribute it and/or modify it
+** under the terms of the GNU General Public License as published by the
+** Free Software Foundation; either version 2, or (at your option) any
+** later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+**
+** $Id: TestCondFunc.c 1792 2004-07-30 05:42:39Z SteveQuenette $
+**
+**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#include <mpi.h>
+#include <StGermain/StGermain.h>
+#include <StGermain/FD/FD.h>
+#include "Snac/Snac.h"
+#include "types.h"
+#include "Register.h"
+#include <stdio.h>
+#include <string.h>
+
+#include <math.h>
+#ifndef PI
+	#ifndef M_PIl
+		#ifndef M_PI
+			#define PI 3.1415927
+		#else
+			#define PI M_PI
+		#endif
+	#else
+		#define PI M_PIl
+	#endif
+#endif
+
+static double Bell( double x ) {
+	return exp( -((x) * (x)) * 10.0f );
+}
+
+
+void _SnacRemesher_TestCondFunc( Index node_dI, Variable_Index var_I, void* _context, void* result ) {
+	Snac_Context*			context = (Snac_Context*)_context;
+	MeshLayout*			meshLayout = (MeshLayout*)context->meshLayout;
+	HexaMD*				decomp = (HexaMD*)meshLayout->decomp;
+
+	double*				velComponent = (double*)result;
+	IJK				ijk;
+	double				x;
+	Node_GlobalIndex		node_gI = _MeshDecomp_Node_LocalToGlobal1D( decomp, node_dI );
+	
+	RegularMeshUtils_Node_1DTo3D( decomp, node_gI, &ijk[0], &ijk[1], &ijk[2] );
+	x = 1.0f / decomp->nodeGlobal3DCounts[0] * ijk[0] - 0.5;
+	(*velComponent) = Bell( x ) * 5e-7;
+}
+
+void _SnacRemesher_XFunc( Index node_dI, Variable_Index var_I, void* _context, void* result ) {
+	Snac_Context*			context = (Snac_Context*)_context;
+	MeshLayout*			meshLayout = (MeshLayout*)context->meshLayout;
+	HexaMD*				decomp = (HexaMD*)meshLayout->decomp;
+
+	double*				velComponent = (double*)result;
+	IJK				ijk;
+	const Node_GlobalIndex		midI = (decomp->nodeGlobal3DCounts[0] + 1) / 2;
+	Node_GlobalIndex		node_gI = _MeshDecomp_Node_LocalToGlobal1D( decomp, node_dI );
+	
+	RegularMeshUtils_Node_1DTo3D( decomp, node_gI, &ijk[0], &ijk[1], &ijk[2] );
+	if( ijk[0] < (midI-1) ) {
+		(*velComponent) += 1e-8;
+	}
+	else if( ijk[0] > (midI-1) ) {
+		(*velComponent) -= 1e-7;
+	}
+	/* else: leave centre to be free */
+}
+
+void _SnacRemesher_YFunc( Index node_dI, Variable_Index var_I, void* _context, void* result ) {
+	Snac_Context*			context = (Snac_Context*)_context;
+	MeshLayout*			meshLayout = (MeshLayout*)context->meshLayout;
+	HexaMD*				decomp = (HexaMD*)meshLayout->decomp;
+
+	double*				velComponent = (double*)result;
+	IJK				ijk;
+	const Node_GlobalIndex		midI = (decomp->nodeGlobal3DCounts[0] + 1) / 2;
+	Node_GlobalIndex		node_gI = _MeshDecomp_Node_LocalToGlobal1D( decomp, node_dI );
+	
+	RegularMeshUtils_Node_1DTo3D( decomp, node_gI, &ijk[0], &ijk[1], &ijk[2] );
+	if( ijk[0] < (midI-1) ) {
+		(*velComponent) += 5e-8;
+	}
+	else if( ijk[0] > (midI-1) ) {
+		(*velComponent) -= 1e-8;
+	}
+	/* else: leave centre to be free */
+}

Added: long/3D/SNAC/trunk/Snac/plugins/remesher_BI/TestCondFunc.h
===================================================================
--- long/3D/SNAC/trunk/Snac/plugins/remesher_BI/TestCondFunc.h	                        (rev 0)
+++ long/3D/SNAC/trunk/Snac/plugins/remesher_BI/TestCondFunc.h	2011-10-07 16:18:20 UTC (rev 19040)
@@ -0,0 +1,48 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+**
+** Copyright (C), 2003,
+**	Steve Quenette, 110 Victoria Street, Melbourne, Victoria, 3053, Australia.
+**	Californian Institute of Technology, 1200 East California Boulevard, Pasadena, California, 91125, USA.
+**	University of Texas, 1 University Station, Austin, Texas, 78712, USA.
+**
+** Authors:
+**	Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
+**	Stevan M. Quenette, Visitor in Geophysics, Caltech.
+**	Luc Lavier, Research Scientist, The University of Texas. (luc at utig.ug.utexas.edu)
+**	Luc Lavier, Research Scientist, Caltech.
+**
+** This program is free software; you can redistribute it and/or modify it
+** under the terms of the GNU General Public License as published by the
+** Free Software Foundation; either version 2, or (at your option) any
+** later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+**
+** Role:
+**	Handles the temperature initial and boundary conditions
+**
+** Assumptions:
+**	None as yet.
+**
+** Comments:
+**	None as yet.
+**
+** $Id: TestCondFunc.h 1506 2004-06-02 18:55:34Z SteveQuenette $
+**
+**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#ifndef __SnacRemesher_TestCondFunc_h__
+#define __SnacRemesher_TestCondFunc_h__
+
+	void _SnacRemesher_TestCondFunc( Index node_dI, Variable_Index var_I, void* _context, void* result );
+	void _SnacRemesher_XFunc( Index node_dI, Variable_Index var_I, void* _context, void* result );
+	void _SnacRemesher_YFunc( Index node_dI, Variable_Index var_I, void* _context, void* result );
+
+#endif /* __SnacRemesher_TestCondFunc_h__ */

Added: long/3D/SNAC/trunk/Snac/plugins/remesher_BI/Utils.c
===================================================================
--- long/3D/SNAC/trunk/Snac/plugins/remesher_BI/Utils.c	                        (rev 0)
+++ long/3D/SNAC/trunk/Snac/plugins/remesher_BI/Utils.c	2011-10-07 16:18:20 UTC (rev 19040)
@@ -0,0 +1,250 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+**
+** Copyright (C), 2003,
+**	Steve Quenette, 110 Victoria Street, Melbourne, Victoria, 3053, Australia.
+**	Californian Institute of Technology, 1200 East California Boulevard, Pasadena, California, 91125, USA.
+**	University of Texas, 1 University Station, Austin, Texas, 78712, USA.
+**
+** Authors:
+**	Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
+**	Stevan M. Quenette, Visitor in Geophysics, Caltech.
+**	Luc Lavier, Research Scientist, The University of Texas. (luc at utig.ug.utexas.edu)
+**	Luc Lavier, Research Scientist, Caltech.
+**
+** This program is free software; you can redistribute it and/or modify it
+** under the terms of the GNU General Public License as published by the
+** Free Software Foundation; either version 2, or (at your option) any
+** later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+**
+** $Id: Utils.c 2749 2005-03-06 06:43:47Z SteveQuenette $
+**
+**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#include <stdio.h>
+#include <mpi.h>
+#include <string.h>
+
+#include <StGermain/StGermain.h>
+#include <StGermain/FD/FD.h>
+
+#include "Snac/Snac.h"
+#include "types.h"
+#include "EntryPoint.h"
+#include "Mesh.h"
+#include "Context.h"
+#include "Remesh.h"
+#include "Register.h"
+
+
+Node_DomainIndex findClosestNode( void* _context, Coord point, Node_LocalIndex refNodeInd ) {
+	Snac_Context*			context = (Snac_Context*)_context;
+	Mesh*				mesh = context->mesh;
+	Topology*				nodeTopo = mesh->layout->nodeLayout->topology;
+	Node_DomainIndex		curNode = refNodeInd;
+	Bool					done = False;
+	
+	
+	/*
+	** Search through the mesh's old coordinates to find the closest node to the new node 'newNode'.
+	*/
+	
+	do {
+		unsigned			nNbrs;
+		Node_DomainIndex*	nbrs;
+		Coord			tmp;
+		double			minDist;
+		Node_DomainIndex	minNode;
+		unsigned			nbr_i;
+		
+		/* Collect the neighbours of the current node. */
+		{
+			Node_GlobalIndex	gNodeInd;
+			
+			gNodeInd = Mesh_NodeMapDomainToGlobal( mesh, curNode );
+			nNbrs = Topology_NeighbourCount( nodeTopo, gNodeInd );
+			if( nNbrs ) {
+				nbrs = Memory_Alloc_Array( Node_DomainIndex, nNbrs, "SnacRemesher" );
+#if 0
+				Topology_BuildNeighbours( nodeTopo, curNode, nbrs );
+#endif		
+			}
+			else {
+				nbrs = NULL;
+			}
+		}
+
+		/* Convert neighbours to domain indices. */
+		for( nbr_i = 0; nbr_i < nNbrs; nbr_i++ ) {
+#if 0
+ 			nbrs[nbr_i] = Mesh_NodeMapGlobalToDomain( mesh, nbrs[nbr_i] ); 
+#endif
+			nbrs[nbr_i] = mesh->nodeNeighbourTbl[curNode][nbr_i];
+		}
+		
+		/* Get the distance to the current node. */
+		Vector_Sub( tmp, point, mesh->nodeCoord[curNode] );
+		minDist = Vector_Mag( tmp );
+		minNode = curNode;
+		
+		/* Loop over neighbours to find the closest node. */
+		for( nbr_i = 0; nbr_i < nNbrs; nbr_i++ ) {
+			double	dist;
+			
+			if( nbrs[nbr_i] >= mesh->nodeDomainCount ) {
+				continue;
+			}
+			
+			Vector_Sub( tmp, point, mesh->nodeCoord[nbrs[nbr_i]] );
+			dist = Vector_Mag( tmp );
+			
+			if( dist < minDist ) {
+				minDist = dist;
+				minNode = nbrs[nbr_i];
+			}
+		}
+		
+		/* Have we found the closest node? */
+		if( minNode == curNode ) {
+			done = True;
+		}
+		else {
+			curNode = minNode;
+		}
+		
+		/* Free the neighbour array. */
+		FreeArray( nbrs );
+	}
+	while( !done );
+	
+	return curNode;
+}
+
+
+Node_DomainIndex findClosestNodeInElement( void* _context, Coord point,	unsigned nEltNodes, Node_DomainIndex *eltNodes ) {
+	Snac_Context*			context = (Snac_Context*)_context;
+	Mesh*				mesh = context->mesh;
+	/* Bool					done = False; */
+	unsigned	eltNode_i;
+	Coord			tmp;
+	double			minDist = 1.0e+32;
+	Node_DomainIndex	minNode = 0;
+
+	/*
+	** Search through the mesh's old coordinates to find the closest node to the new node 'newNode'.
+	*/
+
+	/* Get the distance from the current new node to the element nodes in the old mesh. */
+	for( eltNode_i = 0; eltNode_i < nEltNodes; eltNode_i++ ) {
+		double	dist=0.0;
+			
+		Vector_Sub( tmp, point, mesh->nodeCoord[eltNodes[eltNode_i]] );
+		dist = Vector_Mag( tmp );
+			
+		if( dist < minDist ) {
+			minDist = dist;
+			minNode = eltNodes[eltNode_i];
+		}
+	}
+	
+	return minNode;
+}
+
+/*
+** Determine if 'point' is inside the element corresponding to 'dElementInd'.
+*/
+
+Bool pointInElement( void* _context, Coord point, Element_DomainIndex dElementInd ) {
+	Snac_Context*		context = (Snac_Context*)_context;
+	Mesh*			mesh = context->mesh;
+	NodeLayout*		nLayout = mesh->layout->nodeLayout;
+	unsigned		nEltNodes;
+	Node_DomainIndex*	eltNodes;
+	Coord			crds[8];
+	double			bc[4];
+	unsigned		inds[4];
+	unsigned		eltNode_i;
+
+	/* Extract the element's nodes, of which there should be eight. */
+	{
+		Element_GlobalIndex	gEltInd;
+		
+		nEltNodes = 8;
+		eltNodes = Memory_Alloc_Array( Node_DomainIndex, nEltNodes, "SnacRemesher" );
+		gEltInd = Mesh_ElementMapDomainToGlobal( mesh, dElementInd );
+		nLayout->buildElementNodes( nLayout, gEltInd, eltNodes );
+	}
+	
+	/* Convert the node indices back to domain values. */
+	for( eltNode_i = 0; eltNode_i < nEltNodes; eltNode_i++ ) {
+		eltNodes[eltNode_i] = Mesh_NodeMapGlobalToDomain( mesh, eltNodes[eltNode_i] );
+	}
+
+	/* Copy coordinates. */
+	for( eltNode_i = 0; eltNode_i < nEltNodes; eltNode_i++ )
+		memcpy( crds[eltNode_i], mesh->nodeCoord[eltNodes[eltNode_i]], sizeof(Coord) );
+
+	if( _HexaEL_FindTetBarycenter( crds, point, bc, inds, INCLUSIVE_UPPER_BOUNDARY, NULL, 0 ) ) {
+		return True;
+	}
+
+	return False;
+
+#if 0
+
+	unsigned				plane_i;
+
+	
+	const unsigned			planeInds[6][3] = { { 0, 4, 1 }, { 3, 2, 7 }, { 0, 3, 4 }, 
+										{ 1, 5, 2 }, { 0, 1, 3 }, { 5, 4, 6 } };
+	
+	/* As we are dealing with hexahedral meshes with Snac, there will be six planes to check. */
+	for( plane_i = 0; plane_i < 6; plane_i++ ) {
+		Coord	norm;
+		double	dist;
+		
+		/* Build the plane normal. */
+		{
+			Node_DomainIndex	inds[3];
+			Coord			tmpA, tmpB;
+			
+			inds[0] = eltNodes[planeInds[plane_i][0]];
+			inds[1] = eltNodes[planeInds[plane_i][1]];
+			inds[2] = eltNodes[planeInds[plane_i][2]];
+			
+			Vector_Sub( tmpA, mesh->nodeCoord[inds[1]], mesh->nodeCoord[inds[0]] );
+			Vector_Sub( tmpB, mesh->nodeCoord[inds[2]], mesh->nodeCoord[inds[0]] );
+			Vector_Cross( norm, tmpA, tmpB );
+			Vector_Norm( norm, norm );
+		}
+		
+		/* Calc distance. */
+		dist = Vector_Dot( norm, mesh->nodeCoord[planeInds[plane_i][0]] );
+		
+		/* Check which side of the plane our new point is. */
+		if( Vector_Dot( norm, point ) <= dist ) {
+			/* It is inside, so we may continue. */
+			continue;
+		}
+		else {
+			/* It's outside, so this is the wrong element. */
+			break;
+		}
+	}
+	
+	/* Free the element nodes array. */
+	FreeArray( eltNodes );
+	
+	/* Return appropriately. */
+	
+	return (plane_i < 6) ? False : True;
+#endif
+}

Added: long/3D/SNAC/trunk/Snac/plugins/remesher_BI/Utils.h
===================================================================
--- long/3D/SNAC/trunk/Snac/plugins/remesher_BI/Utils.h	                        (rev 0)
+++ long/3D/SNAC/trunk/Snac/plugins/remesher_BI/Utils.h	2011-10-07 16:18:20 UTC (rev 19040)
@@ -0,0 +1,58 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+**
+** Copyright (C), 2003, 
+**	Steve Quenette, 110 Victoria Street, Melbourne, Victoria, 3053, Australia.
+**	Californian Institute of Technology, 1200 East California Boulevard, Pasadena, California, 91125, USA.
+**	University of Texas, 1 University Station, Austin, Texas, 78712, USA.
+**
+** Authors:
+**	Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
+**	Stevan M. Quenette, Visitor in Geophysics, Caltech.
+**	Luc Lavier, Research Scientist, The University of Texas. (luc at utig.ug.utexas.edu)
+**	Luc Lavier, Research Scientist, Caltech.
+**
+** This program is free software; you can redistribute it and/or modify it
+** under the terms of the GNU General Public License as published by the
+** Free Software Foundation; either version 2, or (at your option) any
+** later version.
+** 
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+** GNU General Public License for more details.
+** 
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+**
+*/
+/** \file
+** Role:
+**
+** Assumptions:
+**
+** Comments:
+**
+** $Id: Utils.h 1848 2004-08-11 07:10:08Z PatrickSunter $
+**
+**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#ifndef __SnacRemesher_Utils_h__
+#define __SnacRemesher_Utils_h__
+	
+	
+	#define SnacArcTan( o, a ) \
+		(((a) == 0.0) ? 0.5 * M_PI : \
+		((a) > 0.0) ? atan( (o) / (a) ) : \
+		((o) >= 0.0) ? M_PI + atan( (o) / (a) ) : \
+		atan( (o) / (a) ) - M_PI)
+	
+	
+	Node_DomainIndex findClosestNode( void* _context, Coord point, Node_LocalIndex refNodeInd );
+
+	Node_DomainIndex findClosestNodeInElement( void* _context, Coord point,	unsigned nEltNodes, Node_DomainIndex *eltNodes );
+	
+	Bool pointInElement( void* _context, Coord point, Element_DomainIndex dElementInd );
+	
+	
+#endif /* __SnacRemesher_Utils_h__ */

Added: long/3D/SNAC/trunk/Snac/plugins/remesher_BI/makefile
===================================================================
--- long/3D/SNAC/trunk/Snac/plugins/remesher_BI/makefile	                        (rev 0)
+++ long/3D/SNAC/trunk/Snac/plugins/remesher_BI/makefile	2011-10-07 16:18:20 UTC (rev 19040)
@@ -0,0 +1,53 @@
+##~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+##
+## Copyright (C), 2003, 
+##	Steve Quenette, 110 Victoria Street, Melbourne, Victoria, 3053, Australia.
+##	Californian Institute of Technology, 1200 East California Boulevard, Pasadena, California, 91125, USA.
+##	University of Texas, 1 University Station, Austin, Texas, 78712, USA.
+##
+## Authors:
+##	Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
+##	Stevan M. Quenette, Visitor in Geophysics, Caltech.
+##	Luc Lavier, Research Scientist, The University of Texas. (luc at utig.ug.utexas.edu)
+##	Luc Lavier, Research Scientist, Caltech.
+##
+## This program is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by the
+## Free Software Foundation; either version 2, or (at your option) any
+## later version.
+## 
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+## GNU General Public License for more details.
+## 
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+##
+## $Id: makefile 3049 2005-06-22 07:46:15Z AlanLo $
+##
+##~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+# obtain defaults for required variables according to system and project location, and then run the build.
+ifndef PROJ_ROOT
+	PROJ_ROOT=../..
+endif
+include ${PROJ_ROOT}/Makefile.system
+
+include Makefile.def
+
+mod = ${def_mod}
+includes = ${def_inc}
+
+SRCS = ${def_srcs}
+
+HDRS = ${def_hdrs}
+
+PROJ_LIBS = ${def_libs}
+EXTERNAL_LIBS = -L${STGERMAIN_LIBDIR}  -lSnac -lStGermain 
+EXTERNAL_INCLUDES = -I${STGERMAIN_INCDIR}/StGermain -I${STGERMAIN_INCDIR} 
+
+packages = MPI XML MATH GSL
+
+include ${PROJ_ROOT}/Makefile.vmake

Added: long/3D/SNAC/trunk/Snac/plugins/remesher_BI/types.h
===================================================================
--- long/3D/SNAC/trunk/Snac/plugins/remesher_BI/types.h	                        (rev 0)
+++ long/3D/SNAC/trunk/Snac/plugins/remesher_BI/types.h	2011-10-07 16:18:20 UTC (rev 19040)
@@ -0,0 +1,52 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+**
+** Copyright (C), 2003, 
+**	Steve Quenette, 110 Victoria Street, Melbourne, Victoria, 3053, Australia.
+**	Californian Institute of Technology, 1200 East California Boulevard, Pasadena, California, 91125, USA.
+**	University of Texas, 1 University Station, Austin, Texas, 78712, USA.
+**
+** Authors:
+**	Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
+**	Stevan M. Quenette, Visitor in Geophysics, Caltech.
+**	Luc Lavier, Research Scientist, The University of Texas. (luc at utig.ug.utexas.edu)
+**	Luc Lavier, Research Scientist, Caltech.
+**
+** This program is free software; you can redistribute it and/or modify it
+** under the terms of the GNU General Public License as published by the
+** Free Software Foundation; either version 2, or (at your option) any
+** later version.
+** 
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+** GNU General Public License for more details.
+** 
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+**
+*/
+/** \file
+** Role:
+**
+** Assumptions:
+**	None as yet.
+**
+** Comments:
+**	None as yet.
+**
+** $Id: types.h 1581 2004-07-02 14:39:36Z SteveQuenette $
+**
+**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#ifndef __SnacRemesher_types_h__
+#define __SnacRemesher_types_h__
+	
+	/* Plastic */
+	typedef struct _SnacRemesher_Context	SnacRemesher_Context;
+	typedef struct _SnacRemesher_Element	SnacRemesher_Element;
+	typedef struct _SnacRemesher_Node	SnacRemesher_Node;
+	typedef struct _SnacRemesher_Mesh	SnacRemesher_Mesh;
+	typedef struct _SnacRemesher_EntryPoint	SnacRemesher_EntryPoint;
+	
+#endif /* __SnacRemesher_types_h__ */



More information about the CIG-COMMITS mailing list