void DictionaryCheckSuite_TestCheckKeys( DictionaryCheckSuiteData* data ) {
   Dictionary*       dictionary = Dictionary_New();
   Dictionary*       dictionary2 = Dictionary_New();
   const char*       testFilename1 = "testDictionaryCheck-1.txt";
   const char*       testFilename2 = "testDictionaryCheck-2.txt";
   char              expectedFilename[PCU_PATH_MAX];
   const char*       errMessage = "Component dictionary must have unique names\n";
   
   Stream_RedirectFile( Journal_Register( Error_Type, (Name)"DictionaryCheck" ), testFilename1 );
   Stream_SetPrintingRank( Journal_Register( Error_Type, (Name)"DictionaryCheck" ), 0 );
   Stream_ClearCustomFormatters( Journal_Register( Error_Type, (Name)"DictionaryCheck") );

   /* Create a set of Dictionary entries */
   /* For dictionary */
   Dictionary_Add( dictionary, (Dictionary_Entry_Key)"test_dict_string", Dictionary_Entry_Value_FromString( "hello" ) );
   Dictionary_Add( dictionary, (Dictionary_Entry_Key)"test_dict_double", Dictionary_Entry_Value_FromDouble( 45.567 ) );
   Dictionary_Add( dictionary, (Dictionary_Entry_Key)"test_dict_string", Dictionary_Entry_Value_FromString( "goodbye" ) );   
   Dictionary_Add( dictionary, (Dictionary_Entry_Key)"test_dict_string", Dictionary_Entry_Value_FromString( "hello" ) );
   Dictionary_Add( dictionary, (Dictionary_Entry_Key)"test_dict_string2", Dictionary_Entry_Value_FromString( "hello" ) );
   
   CheckDictionaryKeys( dictionary,  errMessage );

   if ( data->rank==0 ) {
      pcu_filename_expected( testFilename1, expectedFilename );
      pcu_check_fileEq( testFilename1, expectedFilename );
      remove( testFilename1 );
   }

   /* For dictionary2 */
   Dictionary_Add( dictionary2, (Dictionary_Entry_Key)"test_dict_string", Dictionary_Entry_Value_FromString( "hello" ) );
   Dictionary_Add( dictionary2, (Dictionary_Entry_Key)"test_dict_double", Dictionary_Entry_Value_FromDouble( 45.567 ) );
   Dictionary_Add( dictionary2, (Dictionary_Entry_Key)"test_dict_stuff", Dictionary_Entry_Value_FromString( "hello") );

   /* Call DictionaryCheck function */
   Stream_RedirectFile(Journal_Register( Error_Type, (Name)"DictionaryCheck" ), testFilename2 );
   CheckDictionaryKeys(dictionary2, errMessage);

   /* This file expected to be empty */
   if ( data->rank==0 ) {
      pcu_filename_expected( testFilename2, expectedFilename );
      pcu_check_fileEq( testFilename2, expectedFilename );
      remove( testFilename2 );
   }
   
   Stg_Class_Delete( dictionary );
   Stg_Class_Delete( dictionary2 );

   if ( data->rank==0 ) {
      remove( testFilename1 );
      remove( testFilename2 );
   }
}
void DictionarySuite_TestCreateValues( DictionarySuiteData* data ) {
   Dictionary_Entry_Value*   dev;

   /* Don't use the pre-created test values. Want to do a very fundamental test here */
   dev = Dictionary_Entry_Value_FromString( "hello" );
   pcu_check_true( Dictionary_Entry_Value_Type_String == dev->type );
   pcu_check_streq( "hello", dev->as.typeString );
   Dictionary_Entry_Value_Delete( dev );
   dev = Dictionary_Entry_Value_FromDouble( 45.567 );
   pcu_check_true( Dictionary_Entry_Value_Type_Double == dev->type );
   pcu_check_true( 45.567 == dev->as.typeDouble );
   Dictionary_Entry_Value_Delete( dev );
   dev = Dictionary_Entry_Value_FromUnsignedInt( 5 );
   pcu_check_true( Dictionary_Entry_Value_Type_UnsignedInt == dev->type );
   pcu_check_true( 5 == dev->as.typeUnsignedInt );
   Dictionary_Entry_Value_Delete( dev );
   dev = Dictionary_Entry_Value_FromInt( -5 );
   pcu_check_true( Dictionary_Entry_Value_Type_Int == dev->type );
   pcu_check_true( -5 == dev->as.typeInt );
   Dictionary_Entry_Value_Delete( dev );
   dev = Dictionary_Entry_Value_FromUnsignedLong( 52342423 );
   pcu_check_true( Dictionary_Entry_Value_Type_UnsignedLong == dev->type );
   pcu_check_true( 52342423 == dev->as.typeUnsignedLong );
   Dictionary_Entry_Value_Delete( dev );
   dev = Dictionary_Entry_Value_FromBool( True );
   pcu_check_true( Dictionary_Entry_Value_Type_Bool == dev->type );
   pcu_check_true( True == dev->as.typeBool );
   Dictionary_Entry_Value_Delete( dev );

   /* Since we know the DEV Struct is basically a Dictionary, won't test that one
    *  until after we've tested Dictionary_Add works */   
}
void _SnacDikeInjection_ConstructExtensions( void* _context, void* data ) {
	Snac_Context*				context = (Snac_Context*)_context;
	SnacDikeInjection_Context*			contextExt = ExtensionManager_Get(
																		  context->extensionMgr,
																		  context,
																		  SnacDikeInjection_ContextHandle );
#ifdef DEBUG
	printf( "In %s()\n", __func__ );
#endif
	
	/* DikeInjection variables */
	contextExt->startX = Dictionary_Entry_Value_AsDouble(
			Dictionary_GetDefault( context->dictionary, "startX", 
								   Dictionary_Entry_Value_FromDouble( 29800.0f ) ) );
	//printf("startX is not the value %d", startX )
       contextExt->startZ = Dictionary_Entry_Value_AsDouble(
			Dictionary_GetDefault( context->dictionary, "startZ", 
								   Dictionary_Entry_Value_FromDouble( 0.0f ) ) );
	contextExt->endX = Dictionary_Entry_Value_AsDouble(
			Dictionary_GetDefault( context->dictionary, "endX", 
								   Dictionary_Entry_Value_FromDouble( 30200.0f ) ) );
	contextExt->endZ = Dictionary_Entry_Value_AsDouble(
			Dictionary_GetDefault( context->dictionary, "endZ", 
								   Dictionary_Entry_Value_FromDouble( 1000.0f ) ) );
	contextExt->dikeDepth = Dictionary_Entry_Value_AsDouble(
			Dictionary_GetDefault( context->dictionary, "dikeDepth", 
								   Dictionary_Entry_Value_FromDouble( 6000.0 ) ) );
	contextExt->dikeWidth = Dictionary_Entry_Value_AsDouble(
			Dictionary_GetDefault( context->dictionary, "dikeWidth", 
								   Dictionary_Entry_Value_FromDouble( 720 ) ) ); /* 1.8 * dx looks appropriate. */
	contextExt->injectionRate = Dictionary_Entry_Value_AsDouble(
			Dictionary_GetDefault( context->dictionary, "injectionRate", 
								   Dictionary_Entry_Value_FromDouble( 7.9e-10 ) ) ); /* a fraction of applied plate vel. */

}
float Dictionary_GetFloat_WithDefault(
   Dictionary*          dictionary,
   Dictionary_Entry_Key key,
   const float          defaultVal )
{
   return(float) Dictionary_Entry_Value_AsDouble( 
      Dictionary_GetDefault(
         dictionary, key, Dictionary_Entry_Value_FromDouble( (double)defaultVal ) ) );
}
double Dictionary_GetDouble_WithDefault(
   Dictionary*          dictionary,
   Dictionary_Entry_Key key,
   const double         defaultVal )
{
   return Dictionary_Entry_Value_AsDouble( 
      Dictionary_GetDefault(
         dictionary, key, Dictionary_Entry_Value_FromDouble( defaultVal ) ) );
}
void DictionarySuite_TestMerge( DictionarySuiteData* data ) {
   Dictionary_Entry_Value*    testStruct2=NULL;
   Dictionary_Entry_Value*    testGeomStruct2=NULL;
   Dictionary_Entry_Value*    mergedStruct=NULL;
   Dictionary_Entry_Value*    expectedMergedStruct=NULL;

   testStruct2 = Dictionary_Entry_Value_NewStruct( );
   Dictionary_Entry_Value_AddMember( testStruct2, (Dictionary_Entry_Key)"height", Dictionary_Entry_Value_FromDouble( data->testDD->testStruct->height )  );
   Dictionary_Entry_Value_AddMember( testStruct2, (Dictionary_Entry_Key)"anisotropic", Dictionary_Entry_Value_FromBool( False )  );
   Dictionary_Entry_Value_AddMember( testStruct2, (Dictionary_Entry_Key)"new_person", Dictionary_Entry_Value_FromString( "Luke" ) );
   testGeomStruct2 = Dictionary_Entry_Value_NewStruct( );
   Dictionary_Entry_Value_AddMember( testStruct2, (Dictionary_Entry_Key)"geom", testGeomStruct2  );
   Dictionary_Entry_Value_AddMember( testGeomStruct2, (Dictionary_Entry_Key)"startx", Dictionary_Entry_Value_FromUnsignedInt( data->testDD->testStruct->geom.startx )  );
   Dictionary_Entry_Value_AddMember( testGeomStruct2, (Dictionary_Entry_Key)"startz", Dictionary_Entry_Value_FromUnsignedInt( 222 )  );

   /* Testing Merge_Append */
   DictionarySuite_PopulateDictWithTestValues( data->dict, data->testDD );
   /* Do a copy of the DEV during merge, since we don't want it being deleted */
   Dictionary_AddMerge( data->dict, "test_struct", Dictionary_Entry_Value_Copy( testStruct2, True ), Dictionary_MergeType_Append );
   /* OK: since this was an append, we expect _two_ entries called "test_struct",
    * one preceding the other, one with the orig data, one with new data */    
   pcu_check_true( (data->testDD->testEntriesCount+1) == data->dict->count );
   pcu_check_true( Dictionary_Entry_Value_Compare( data->testDD->testValues[8], Dictionary_Get( data->dict, (Dictionary_Entry_Key)"test_struct" ) )  );
   pcu_check_true( Dictionary_Entry_Value_Compare( testStruct2, data->dict->entryPtr[9]->value ) );
   Dictionary_Empty( data->dict );

   /* Testing Merge_Merge */
   DictionarySuite_PopulateDictWithTestValues( data->dict, data->testDD );

   /* The nicest way for this test I think is to manually build a merged struct
    *  to compare against */
   expectedMergedStruct = Dictionary_Entry_Value_Copy( data->testDD->testValues[8], True );
   Dictionary_Set( expectedMergedStruct->as.typeStruct, (Dictionary_Entry_Key)"anisotropic", Dictionary_Entry_Value_FromBool( False )  );
   Dictionary_Add( expectedMergedStruct->as.typeStruct, (Dictionary_Entry_Key)"new_person", Dictionary_Entry_Value_FromString( "Luke" )  );
   Dictionary_Set( (Dictionary_Get( expectedMergedStruct->as.typeStruct, (Dictionary_Entry_Key)"geom" ) )->as.typeStruct, "startz", Dictionary_Entry_Value_FromUnsignedInt( 222 ) );

   Dictionary_AddMerge( data->dict, "test_struct", Dictionary_Entry_Value_Copy( testStruct2, True ), Dictionary_MergeType_Merge );
   /* This time, the new struct should be merged into the existing one */
   pcu_check_true( data->testDD->testEntriesCount == data->dict->count );
   mergedStruct = Dictionary_Get( data->dict, (Dictionary_Entry_Key)"test_struct"  );
   pcu_check_true( Dictionary_Entry_Value_Compare( mergedStruct, expectedMergedStruct ) );
   Dictionary_Empty( data->dict );
   Dictionary_Entry_Value_Delete( expectedMergedStruct );

   /* Testing Merge_Replace */
   DictionarySuite_PopulateDictWithTestValues( data->dict, data->testDD );
   Dictionary_AddMerge( data->dict, "test_struct", Dictionary_Entry_Value_Copy( testStruct2, True ), Dictionary_MergeType_Replace );
   pcu_check_true( data->testDD->testEntriesCount == data->dict->count );
   pcu_check_true( Dictionary_Entry_Value_Compare( testStruct2, Dictionary_Get( data->dict, (Dictionary_Entry_Key)"test_struct" ) ) );
   Dictionary_Empty( data->dict );

   Dictionary_Entry_Value_Delete( testStruct2 );
}
Beispiel #7
0
void _ShellGeometry_Init(
		ShellGeometry*					self )
{
	/* General and Virtual info should already be set */
	
	/* ShellGeometry info */
	self->isConstructed = True;
	self->size[0] = Dictionary_Entry_Value_AsUnsignedInt( Dictionary_GetDefault( self->dictionary, "meshSizeI",
		Dictionary_Entry_Value_FromUnsignedInt( 2 ) ) );
	self->size[1] = Dictionary_Entry_Value_AsUnsignedInt( Dictionary_GetDefault( self->dictionary, "meshSizeJ",
		Dictionary_Entry_Value_FromUnsignedInt( 2 ) ) );
	self->size[2] = Dictionary_Entry_Value_AsUnsignedInt( Dictionary_GetDefault( self->dictionary, "meshSizeK",
		Dictionary_Entry_Value_FromUnsignedInt( 2 ) ) );
	self->pointCount = self->size[0] * self->size[1] * self->size[2];
	assert( self->pointCount );
	
	self->min[0] = Dictionary_Entry_Value_AsDouble( Dictionary_GetDefault( self->dictionary, "minTheta",
		Dictionary_Entry_Value_FromDouble( 2.0 * M_PI / 3.0 ) ) );
	self->min[1] = Dictionary_Entry_Value_AsDouble( Dictionary_GetDefault( self->dictionary, "minPhi",
		Dictionary_Entry_Value_FromDouble( 2.0 * M_PI / 3.0 ) ) );
	self->min[2] = Dictionary_Entry_Value_AsDouble( Dictionary_GetDefault( self->dictionary, "minR",
		Dictionary_Entry_Value_FromDouble( 0.5f ) ) );
	self->max[0] = Dictionary_Entry_Value_AsDouble( Dictionary_GetDefault( self->dictionary, "maxTheta",
		Dictionary_Entry_Value_FromDouble( M_PI / 3.0 ) ) );
	self->max[1] = Dictionary_Entry_Value_AsDouble( Dictionary_GetDefault( self->dictionary, "maxPhi",
		Dictionary_Entry_Value_FromDouble( M_PI / 3.0 ) ) );
	self->max[2] = Dictionary_Entry_Value_AsDouble( Dictionary_GetDefault( self->dictionary, "maxR",
		Dictionary_Entry_Value_FromDouble( 1.0f ) ) );
}
void Dictionary_Entry_Value_AddElementWithSource( Dictionary_Entry_Value* self, Dictionary_Entry_Value* element,
							Dictionary_Entry_Source source )
{
	/* check type - convert to a list if not so... */
	if (Dictionary_Entry_Value_Type_List != self->type) {
		Dictionary_Entry_Value* copy;
		
		switch (self->type) {
			case Dictionary_Entry_Value_Type_String:
				copy = Dictionary_Entry_Value_FromString( self->as.typeString );
				break;
			case Dictionary_Entry_Value_Type_Double:
				copy = Dictionary_Entry_Value_FromDouble( self->as.typeDouble );
				break;
			case Dictionary_Entry_Value_Type_UnsignedInt:
				copy = Dictionary_Entry_Value_FromUnsignedInt( self->as.typeUnsignedInt );
				break;
			case Dictionary_Entry_Value_Type_Int:
				copy = Dictionary_Entry_Value_FromInt( self->as.typeInt );
				break;
			case Dictionary_Entry_Value_Type_UnsignedLong:
				copy = Dictionary_Entry_Value_FromUnsignedLong( self->as.typeUnsignedLong );
				break;
			case Dictionary_Entry_Value_Type_Bool:
				copy = Dictionary_Entry_Value_FromBool( self->as.typeBool );
				break;
			case Dictionary_Entry_Value_Type_Struct:
				copy = Dictionary_Entry_Value_NewStruct();
				copy->as.typeStruct = self->as.typeStruct;
				break;
			default: {
				Stream* errorStream = Journal_Register( Error_Type, "Dictionary_Entry_Value" );
				Journal_Firewall( False, errorStream, "In func %s: self->type '%d' is invalid.\n", __func__, self->type );
			}
		}
		
		Dictionary_Entry_Value_SetNewList( self );	
		Dictionary_Entry_Value_AddElementWithSource( self, copy, source );
	}
	
	if (!self->as.typeList->first) {
		self->as.typeList->first = element;
	} else {
		self->as.typeList->last->next = element;
	}
	self->as.typeList->last = element;
	self->as.typeList->count++;
}
void DictionarySuite_TestAddElement( DictionarySuiteData* data ) {
   Dictionary_Entry_Value* yValue;
   Dictionary_Entry_Value* testStruct;
   Dictionary_Entry_Value* currValue;
   double                  newVal = -45.0;

   DictionarySuite_PopulateDictWithTestValues( data->dict, data->testDD );

   /* turning the starty value into a list using add element */
   testStruct = Dictionary_Get( data->dict, (Dictionary_Entry_Key)"test_struct"  );
   yValue = Dictionary_Entry_Value_GetMember( Dictionary_Entry_Value_GetMember(testStruct, (Dictionary_Entry_Key)"geom" ), "starty");
   Dictionary_Entry_Value_AddElement( yValue, Dictionary_Entry_Value_FromDouble(newVal) );

   pcu_check_true( Dictionary_Entry_Value_Type_List == yValue->type );
   pcu_check_true( 2 == Dictionary_Entry_Value_GetCount( yValue ) );

   currValue = Dictionary_Entry_Value_GetFirstElement( yValue );
   pcu_check_le( fabs( data->testDD->testStruct->geom.starty - Dictionary_Entry_Value_AsDouble( currValue )), 0.01 );
   currValue = currValue->next;
   pcu_check_le( fabs( newVal - Dictionary_Entry_Value_AsDouble( currValue )), 0.01 );
}
int main( int argc, char* argv[] ) {
	MPI_Comm		CommWorld;
	int			rank;
	int			numProcessors;
	int			procToWatch;
	Dictionary*		dictionary;
	Snac_Context*		snacContext;
	Tetrahedra_Index	tetraIndex;
	Element_Index		elementIndex;
	double			minLengthScale;
	
	/* Initialise MPI, get world info */
	MPI_Init( &argc, &argv );
	Snac_Init( &argc, &argv );
	MPI_Comm_dup( MPI_COMM_WORLD, &CommWorld );
	MPI_Comm_size( CommWorld, &numProcessors );
	MPI_Comm_rank( CommWorld, &rank );
	if( argc >= 2 ) {
		procToWatch = atoi( argv[1] );
	}
	else {
		procToWatch = 0;
	}
	if( rank == procToWatch ) printf( "Watching rank: %i\n", rank );
	
	/* Read input */
	dictionary = Dictionary_New();
	dictionary->add( dictionary, "rank", Dictionary_Entry_Value_FromUnsignedInt( rank ) );
	dictionary->add( dictionary, "numProcessors", Dictionary_Entry_Value_FromUnsignedInt( numProcessors ) );
	dictionary->add( dictionary, "meshSizeI", Dictionary_Entry_Value_FromUnsignedInt( 4 ) );
	dictionary->add( dictionary, "meshSizeJ", Dictionary_Entry_Value_FromUnsignedInt( 4 ) );
	dictionary->add( dictionary, "meshSizeK", Dictionary_Entry_Value_FromUnsignedInt( 4 ) );
	dictionary->add( dictionary, "minX", Dictionary_Entry_Value_FromDouble( 0.0f ) );
	dictionary->add( dictionary, "minY", Dictionary_Entry_Value_FromDouble( -300.0f ) );
	dictionary->add( dictionary, "minZ", Dictionary_Entry_Value_FromDouble( 0.0f ) );
	dictionary->add( dictionary, "maxX", Dictionary_Entry_Value_FromDouble( 300.0f ) );
	dictionary->add( dictionary, "maxY", Dictionary_Entry_Value_FromDouble( 0.0f ) );
	dictionary->add( dictionary, "maxZ", Dictionary_Entry_Value_FromDouble( 300.0f ) );

	/* Build the context */
	snacContext = Snac_Context_New( 0.0f, 10.0f, sizeof(Snac_Node), sizeof(Snac_Element), CommWorld, dictionary );
	
	/* Construction phase -----------------------------------------------------------------------------------------------*/
	Stg_Component_Construct( snacContext, 0 /* dummy */, &snacContext, True );
	
	/* Building phase ---------------------------------------------------------------------------------------------------*/
	Stg_Component_Build( snacContext, 0 /* dummy */, False );
	
	/* Initialisaton phase ----------------------------------------------------------------------------------------------*/
	Stg_Component_Initialise( snacContext, 0 /* dummy */, False );

	/* Work out the first element's tetrahedra values, and print them. */
	printf( "Element: 0, Coords: (%g %g %g), (%g %g %g), (%g %g %g), (%g %g %g), (%g %g %g) (%g %g %g) (%g %g %g) (%g %g %g)\n",
		Snac_Element_NodeCoord( snacContext, 0, 0 )[0],
		Snac_Element_NodeCoord( snacContext, 0, 0 )[1],
		Snac_Element_NodeCoord( snacContext, 0, 0 )[2],
		Snac_Element_NodeCoord( snacContext, 0, 1 )[0],
		Snac_Element_NodeCoord( snacContext, 0, 1 )[1],
		Snac_Element_NodeCoord( snacContext, 0, 1 )[2],
		Snac_Element_NodeCoord( snacContext, 0, 3 )[0],
		Snac_Element_NodeCoord( snacContext, 0, 3 )[1],
		Snac_Element_NodeCoord( snacContext, 0, 3 )[2],
		Snac_Element_NodeCoord( snacContext, 0, 2 )[0],
		Snac_Element_NodeCoord( snacContext, 0, 2 )[1],
		Snac_Element_NodeCoord( snacContext, 0, 2 )[2],
		Snac_Element_NodeCoord( snacContext, 0, 4 )[0],
		Snac_Element_NodeCoord( snacContext, 0, 4 )[1],
		Snac_Element_NodeCoord( snacContext, 0, 4 )[2],
		Snac_Element_NodeCoord( snacContext, 0, 5 )[0],
		Snac_Element_NodeCoord( snacContext, 0, 5 )[1],
		Snac_Element_NodeCoord( snacContext, 0, 5 )[2],
		Snac_Element_NodeCoord( snacContext, 0, 7 )[0],
		Snac_Element_NodeCoord( snacContext, 0, 7 )[1],
		Snac_Element_NodeCoord( snacContext, 0, 7 )[2],
		Snac_Element_NodeCoord( snacContext, 0, 6 )[0],
		Snac_Element_NodeCoord( snacContext, 0, 6 )[1],
		Snac_Element_NodeCoord( snacContext, 0, 6 )[2] );

	/* For each element, compare to the first element's */
	for( elementIndex = 0; elementIndex < snacContext->mesh->elementLocalCount; elementIndex++ ) {
		Bool error;
		
		Snac_UpdateElementMomentum( (Context*)snacContext, elementIndex, &minLengthScale );
		
		if( elementIndex == 0 ) {
			for( tetraIndex = 0; tetraIndex < Tetrahedra_Count; tetraIndex++ ) {
				Tetrahedra_Surface_Index faceIndex;

				for( faceIndex = 0; faceIndex < Tetrahedra_Surface_Count; faceIndex++ ) {
					printf( "Element: 0, Tetrahedra: %u, Face: %u, Normal: %g %g %g\n", 
						tetraIndex, 
						faceIndex, 
						Snac_Element_At( snacContext, elementIndex )->tetra[tetraIndex].surface[faceIndex].normal[0],
						Snac_Element_At( snacContext, elementIndex )->tetra[tetraIndex].surface[faceIndex].normal[1],
						Snac_Element_At( snacContext, elementIndex )->tetra[tetraIndex].surface[faceIndex].normal[2] );
				}
			}
		}
		else {
			for( tetraIndex = 0, error = False; tetraIndex < Tetrahedra_Count; tetraIndex++ ) {
				Tetrahedra_Surface_Index faceIndex;

				for( faceIndex = 0; faceIndex < Tetrahedra_Surface_Count; faceIndex++ ) {
					if( Snac_Element_At( snacContext, elementIndex )->tetra[tetraIndex].surface[faceIndex].normal[0] !=
						Snac_Element_At( snacContext, 0 )->tetra[tetraIndex].surface[faceIndex].normal[0] || 
						Snac_Element_At( snacContext, elementIndex )->tetra[tetraIndex].surface[faceIndex].normal[1] !=
						Snac_Element_At( snacContext, 0 )->tetra[tetraIndex].surface[faceIndex].normal[1] ||
						Snac_Element_At( snacContext, elementIndex )->tetra[tetraIndex].surface[faceIndex].normal[2] !=
						Snac_Element_At( snacContext, 0 )->tetra[tetraIndex].surface[faceIndex].normal[2] )
					{
						printf( "Element: %u, Tetrahedra: %u, Face %u, Area: %g %g %g\n", 
							elementIndex, 
							faceIndex, 
							tetraIndex, 
							Snac_Element_At( snacContext, elementIndex )->tetra[tetraIndex].surface[faceIndex].normal[0],
							Snac_Element_At( snacContext, elementIndex )->tetra[tetraIndex].surface[faceIndex].normal[1],
							Snac_Element_At( snacContext, elementIndex )->tetra[tetraIndex].surface[faceIndex].normal[2] );
						error = True;
					}
				}
			}
			if( error ) {
				printf( "Element: 0, Coords: (%g %g %g), (%g %g %g), (%g %g %g), (%g %g %g), (%g %g %g) (%g %g %g) (%g %g %g) (%g %g %g)\n",
					Snac_Element_NodeCoord( snacContext, elementIndex, 0 )[0],
					Snac_Element_NodeCoord( snacContext, elementIndex, 0 )[1],
					Snac_Element_NodeCoord( snacContext, elementIndex, 0 )[2],
					Snac_Element_NodeCoord( snacContext, elementIndex, 1 )[0],
					Snac_Element_NodeCoord( snacContext, elementIndex, 1 )[1],
					Snac_Element_NodeCoord( snacContext, elementIndex, 1 )[2],
					Snac_Element_NodeCoord( snacContext, elementIndex, 2 )[0],
					Snac_Element_NodeCoord( snacContext, elementIndex, 2 )[1],
					Snac_Element_NodeCoord( snacContext, elementIndex, 2 )[2],
					Snac_Element_NodeCoord( snacContext, elementIndex, 3 )[0],
					Snac_Element_NodeCoord( snacContext, elementIndex, 3 )[1],
					Snac_Element_NodeCoord( snacContext, elementIndex, 3 )[2],
					Snac_Element_NodeCoord( snacContext, elementIndex, 4 )[0],
					Snac_Element_NodeCoord( snacContext, elementIndex, 4 )[1],
					Snac_Element_NodeCoord( snacContext, elementIndex, 4 )[2],
					Snac_Element_NodeCoord( snacContext, elementIndex, 5 )[0],
					Snac_Element_NodeCoord( snacContext, elementIndex, 5 )[1],
					Snac_Element_NodeCoord( snacContext, elementIndex, 5 )[2],
					Snac_Element_NodeCoord( snacContext, elementIndex, 6 )[0],
					Snac_Element_NodeCoord( snacContext, elementIndex, 6 )[1],
					Snac_Element_NodeCoord( snacContext, elementIndex, 6 )[2],
					Snac_Element_NodeCoord( snacContext, elementIndex, 7 )[0],
					Snac_Element_NodeCoord( snacContext, elementIndex, 7 )[1],
					Snac_Element_NodeCoord( snacContext, elementIndex, 7 )[2] );
			}
			else {
				printf( "Element %u: has same values as element 0.\n", elementIndex );
			}		
		}
	}
	
	/* Stg_Class_Delete stuff */
	Stg_Class_Delete( snacContext );
	Stg_Class_Delete( dictionary );

	/* Close off MPI */
	MPI_Finalize();

	return 0; /* success */
}
Beispiel #11
0
void _SnacCylinderQuad_InitialConditions( void* _context, void* data ) {
	Snac_Context*			context = (Snac_Context*)_context;
	Mesh*				mesh = context->mesh;
	MeshLayout*			layout = (MeshLayout*)mesh->layout;
	HexaMD*				decomp = (HexaMD*)layout->decomp;
	BlockGeometry*			geometry = (BlockGeometry*)layout->elementLayout->geometry;
	Node_GlobalIndex		node_gI;
	double				ri,ro,ztop,zbot;
	double				alpha,d;
#ifdef DEBUG
	printf( "In: %s\n", __func__ );
#endif

	ri = Dictionary_Entry_Value_AsDouble(Dictionary_GetDefault( context->dictionary, "cylinder_ri", Dictionary_Entry_Value_FromDouble( 3.0f ) ) );
	ro = Dictionary_Entry_Value_AsDouble(Dictionary_GetDefault( context->dictionary, "cylinder_ro", Dictionary_Entry_Value_FromDouble( 10.0f ) ) );
	zbot = Dictionary_Entry_Value_AsDouble(Dictionary_GetDefault( context->dictionary, "cylinder_zbot", Dictionary_Entry_Value_FromDouble( 0.0f ) ) );
	ztop = Dictionary_Entry_Value_AsDouble(Dictionary_GetDefault( context->dictionary, "cylinder_ztop", Dictionary_Entry_Value_FromDouble( 1.0f ) ) );
	alpha = Dictionary_Entry_Value_AsDouble(Dictionary_GetDefault( context->dictionary, "cylinder_alpha", Dictionary_Entry_Value_FromDouble( 1.1f ) ) );

	d = (ro - ri)*(alpha-1.0)/(pow(alpha,decomp->nodeGlobal3DCounts[2]-1)-1.0);
	/* apply the cylindrical initial mesh */
	for( node_gI = 0; node_gI < context->mesh->nodeGlobalCount; node_gI++ ) {
		Node_LocalIndex			node_lI = _MeshDecomp_Node_GlobalToLocal1D( decomp, node_gI );
		Index				i_gI;
		Index				j_gI;
		Index				k_gI;
		Coord*				coord = 0;
		Coord				initialRTZ,tmpCoord;
		double				rsum = 0.0f;

		/* If a local node, directly change the node coordinates and initial tpr, else use a temporary location */
		if( node_lI < context->mesh->nodeLocalCount ) { /* a local node */
			coord = Snac_NodeCoord_P( context, node_lI );
		}
		else { /* Not a local node */
			coord = &tmpCoord;
		}

		RegularMeshUtils_Node_1DTo3D( decomp, node_gI, &i_gI, &j_gI, &k_gI );

		/*               -----                   */
		/*         right |    \ front            */
		/*     z ^       --\   \                 */
		/*       |     back  |_ |                */
		/*       -->x       left                 */
		initialRTZ[0] = ri; // radius
		if(k_gI>0) rsum = (pow(alpha,k_gI)-1.0)/(alpha-1.0)*d;
		initialRTZ[0] += rsum;
		initialRTZ[1] = (90.0f/(decomp->nodeGlobal3DCounts[0]-1)*i_gI)*PI/180.0f; // theta
		initialRTZ[2] = ztop - (ztop-zbot)/(decomp->nodeGlobal3DCounts[1]-1)*j_gI; // Z

		(*coord)[0] = initialRTZ[0]*cos(initialRTZ[1]);
		(*coord)[1] = initialRTZ[2];
		(*coord)[2] = initialRTZ[0]*sin(initialRTZ[1]);

		if( node_gI == 0 ) {
			geometry->min[0] = geometry->max[0] = (*coord)[0];
			geometry->min[1] = geometry->max[1] = (*coord)[1];
			geometry->min[2] = geometry->max[2] = (*coord)[2];
		}
		else {
			if( geometry->min[0] > (*coord)[0] ) geometry->min[0] = (*coord)[0];
			if( geometry->min[1] > (*coord)[1] ) geometry->min[1] = (*coord)[1];
			if( geometry->min[2] > (*coord)[2] ) geometry->min[2] = (*coord)[2];
			if( geometry->max[0] < (*coord)[0] ) geometry->max[0] = (*coord)[0];
			if( geometry->max[1] < (*coord)[1] ) geometry->max[1] = (*coord)[1];
			if( geometry->max[2] < (*coord)[2] ) geometry->max[2] = (*coord)[2];
		}

		#ifdef DEBUG
			printf( "\tnode_lI: %2u, node_gI: %2u, i: %2u, j: %2u, k: %2u, r: %8g, theta: %8g, z: %8g,",
				node_lI,
				node_gI,
				i_gI,
				j_gI,
				k_gI,
				initialRTZ[0],
				initialRTZ[1],
				initialRTZ[2] );
			printf( "x: %12g, y: %12g, z: %12g\n", (*coord)[0], (*coord)[1], (*coord)[2] );
		#endif
	}
}
void DictionarySuite_TestReadAllParamFromCommandLine( DictionarySuiteData* data  ) {
   int                        argc;
   char**                     argv;
   char**                     expectedKeys;
   Dictionary_Entry_Value**   expectedVals;
   Index                      ii;
   Dictionary_Entry_Value*    tmpStruct=NULL;
   Dictionary_Entry_Value*    tmpStruct2=NULL;
   Dictionary_Entry_Value*    tmpList=NULL;
   Index                      numExp = 7;

   argc = 16;
   argv = Memory_Alloc_Array_Unnamed( char*, argc );
   expectedVals = Memory_Alloc_Array_Unnamed( Dictionary_Entry_Value*, numExp );
   expectedKeys = Memory_Alloc_Array_Unnamed( char*, numExp );

   /* Now fill in our mock command line, and create the expected values to test
    *  against along the way */   
   Stg_asprintf( &argv[0], "./testStGermain");
   Stg_asprintf( &argv[1], "-param=hey");
   Stg_asprintf( &argv[2], "--option");
   Stg_asprintf( &argv[3], "--output-dir=");
   Stg_asprintf( &expectedKeys[0], "output-dir" );

   expectedVals[0] = Dictionary_Entry_Value_FromString( "" );
   Stg_asprintf( &argv[4], "--Ra=1.0e4");
   Stg_asprintf( &expectedKeys[1], "Ra" );

   expectedVals[1] = Dictionary_Entry_Value_FromDouble( 1.0e4 );
   Stg_asprintf( &argv[5], "--foo.bar=5");
   Stg_asprintf( &expectedKeys[2], "foo" );

   expectedVals[2] = Dictionary_Entry_Value_NewStruct();
   Dictionary_Entry_Value_AddMember( expectedVals[2], (Dictionary_Entry_Key)"bar", Dictionary_Entry_Value_FromDouble( 5 )  );
   Stg_asprintf( &expectedKeys[3], "vpac" );

   expectedVals[3] = Dictionary_Entry_Value_NewStruct();
   Dictionary_Entry_Value_AddMember( expectedVals[3], (Dictionary_Entry_Key)"csd", tmpStruct = Dictionary_Entry_Value_NewStruct()  );
     Stg_asprintf( &argv[7], "--foo.bot=7");
   Dictionary_Entry_Value_AddMember( expectedVals[2], (Dictionary_Entry_Key)"bot", Dictionary_Entry_Value_FromDouble( 7 )  );
   Stg_asprintf( &argv[8], "--sports[]=hockey");
   Stg_asprintf( &expectedKeys[4], "sports" );

   expectedVals[4] = Dictionary_Entry_Value_NewList();
   Dictionary_Entry_Value_AddElement( expectedVals[4], Dictionary_Entry_Value_FromString( "hockey" ) );
   Stg_asprintf( &argv[9], "--sports[]=chess");
   /* This should be overwritten by next entry, so ignore */
   Stg_asprintf( &argv[10], "--sports[1]=tennis");
   Dictionary_Entry_Value_AddElement( expectedVals[4], Dictionary_Entry_Value_FromString( "tennis" ) );
   Stg_asprintf( &argv[11], "--sles[].name=pressure");
   Stg_asprintf( &expectedKeys[5], "sles" );

   expectedVals[5] = Dictionary_Entry_Value_NewList();
   Dictionary_Entry_Value_AddElement( expectedVals[5], tmpStruct = Dictionary_Entry_Value_NewStruct() );
   Dictionary_Entry_Value_AddMember( tmpStruct, (Dictionary_Entry_Key)"name", Dictionary_Entry_Value_FromString( "pressure" )  );
   Stg_asprintf( &argv[12], "--sles[].name=temperature");
   Dictionary_Entry_Value_AddElement( expectedVals[5], tmpStruct2 = Dictionary_Entry_Value_NewStruct() );
   Dictionary_Entry_Value_AddMember( tmpStruct2, (Dictionary_Entry_Key)"name", Dictionary_Entry_Value_FromString( "temperature" )  );
   Stg_asprintf( &argv[13], "--sles[0].solver=mg");
   Dictionary_Entry_Value_AddMember( tmpStruct, (Dictionary_Entry_Key)"solver", Dictionary_Entry_Value_FromString( "mg" )  );
   Stg_asprintf( &argv[14], "--sles[1].solver=direct");
   Dictionary_Entry_Value_AddMember( tmpStruct2, (Dictionary_Entry_Key)"solver", Dictionary_Entry_Value_FromString( "direct" )  );
   Stg_asprintf( &argv[15], "--some.crazy[].shit=here");
   Stg_asprintf( &expectedKeys[6], "some" );

   expectedVals[6] = Dictionary_Entry_Value_NewStruct();
   Dictionary_Entry_Value_AddMember( expectedVals[6], (Dictionary_Entry_Key)"crazy", tmpList = Dictionary_Entry_Value_NewList()  );
   Dictionary_Entry_Value_AddElement( tmpList, tmpStruct = Dictionary_Entry_Value_NewStruct() );
   Dictionary_Entry_Value_AddMember( tmpStruct, (Dictionary_Entry_Key)"shit", Dictionary_Entry_Value_FromString( "here" )  );

   Dictionary_ReadAllParamFromCommandLine( data->dict, argc, argv );

   for (ii=0; ii < numExp; ii++) {
      pcu_check_true( Dictionary_Entry_Compare( data->dict->entryPtr[ii], expectedKeys[ii]));
      pcu_check_true( Dictionary_Entry_Value_Compare( expectedVals[ii], data->dict->entryPtr[ii]->value ));
   }

   for (ii=0; ii < argc; ii++) {
      Memory_Free( argv[ii] );
   }
   Memory_Free( argv );

   for (ii=0; ii < numExp; ii++) {
      Memory_Free( expectedKeys[ii] );
      Memory_Free( expectedVals[ii] );
   }
   Memory_Free( expectedKeys );
   Memory_Free( expectedVals );
}
void _SnacHillSlope_ConstructExtensions( void* _context, void* data ) {
	Snac_Context*				context = (Snac_Context*)_context;
	SnacHillSlope_Context*			contextExt = ExtensionManager_Get(
								context->extensionMgr,
								context,
								SnacHillSlope_ContextHandle );
/* 	Dictionary*				hillSlopeBCsDict; */
/* 	char					tmpBuf[PATH_MAX]; */

	/* Because hillSlope is not an array by itself, we must the "complex" constructor for Variable... the info needs to be
	 * wrapped this generic way... */
/* 	Index					hillSlopeOffsetCount = 1; */
/*  	SizeT					hillSlopeOffsets[] = { (SizeT)((char*)&tmpNodeExt->hillSlope - (char*)&tmpNode) };  */
/* 	Variable_DataType			hillSlopeDataTypes[] = { Variable_DataType_Double }; */
/* 	Index					hillSlopeDataTypeCounts[] = { 1 }; */
	#ifdef DEBUG
		printf( "In %s()\n", __func__ );
	#endif


	/* Create the StGermain variable hillSlope, which is stored on a node extension */
/* 	Variable_New(  */
/* 		"hillSlope",  */
/* 		hillSlopeOffsetCount,  */
/* 		hillSlopeOffsets,  */
/* 		hillSlopeDataTypes,  */
/* 		hillSlopeDataTypeCounts,  */
/* 		0,  */
/* 		&ExtensionManager_GetFinalSize( context->mesh->nodeExtensionMgr ), */
/* 		&context->mesh->layout->decomp->nodeDomainCount, */
/* 		(void**)&context->mesh->node, */
/* 		context->variable_Register ); */



	/* HillSlope variables */
	contextExt->slopeAngle = Dictionary_Entry_Value_AsDouble(
		Dictionary_GetDefault( context->dictionary, "slopeAngle", Dictionary_Entry_Value_FromDouble( 30.0f ) ) );

/* 	contextExt->rngSeed = Dictionary_Entry_Value_AsUnsignedInt( */
/* 		Dictionary_GetDefault( context->dictionary, "rngSeed", Dictionary_Entry_Value_FromUnsignedInt( 1 ) ) ); */

/* 	contextExt->fractionPlasticSeeds = Dictionary_Entry_Value_AsDouble( */
/* 		Dictionary_GetDefault( context->dictionary, "fractionPlasticSeeds", Dictionary_Entry_Value_FromDouble( 0.02f ) ) ); */




	/* Build the hillSlope IC and BC managers */
/* 	hillSlopeBCsDict = Dictionary_Entry_Value_AsDictionary( Dictionary_Get( context->dictionary, "hillSlopeBCs" ) ); */
/* 	contextExt->hillSlopeBCs = CompositeVC_New("tempBC", */
/* 		context->variable_Register, */
/* 		context->condFunc_Register, */
/* 		hillSlopeBCsDict, */
/* 		context->mesh ); */


/* 	#ifdef DEBUG */
/* 		fprintf( stderr, "In %s()\n", __func__ ); */
/* 	#endif */

/* 	Journal_Printf( context->debug, "slopeAngle:  %g\n", contextExt->slopeAngle ); */

}
void DictionarySuite_SetupTestDictData( DictionarySuite_TestDictData* testDD ) {
   Index                   ii=0;
   Index                   iter=0;
   Dictionary_Entry_Value* testStruct; 
   Dictionary_Entry_Value* testStruct2; 
   Dictionary_Entry_Value* testList; 

   testDD->testEntriesCount = 9;
   testDD->testKeys = Memory_Alloc_Array_Unnamed( char*, testDD->testEntriesCount );
   testDD->testValues = Memory_Alloc_Array_Unnamed( Dictionary_Entry_Value*,
      testDD->testEntriesCount );

   for ( ii=0; ii< testDD->testEntriesCount; ii++ ) {
      testDD->testKeys[ii] = NULL;
      testDD->testValues[ii] = NULL;
   }

   Stg_asprintf( &testDD->testString, "hello" );
   Stg_asprintf( &testDD->testPlaceHolder, "test_double" );
   testDD->testDouble=45.567;
   testDD->testUint = 5;
   testDD->testInt = -5;
   testDD->testUnsignedlong = 52342423;
   testDD->testBool = True;
   iter = 0;
   Stg_asprintf( &testDD->testKeys[iter], "test_cstring" );
   testDD->testValues[iter] = Dictionary_Entry_Value_FromString( testDD->testString );
   Stg_asprintf( &testDD->testKeys[++iter], "test_double" );
   testDD->testValues[iter] = Dictionary_Entry_Value_FromDouble( testDD->testDouble );
   Stg_asprintf( &testDD->testKeys[++iter], "test_uint" );
   testDD->testValues[iter] = Dictionary_Entry_Value_FromUnsignedInt( testDD->testUint );
   Stg_asprintf( &testDD->testKeys[++iter], "test_int" );
   testDD->testValues[iter] = Dictionary_Entry_Value_FromInt( testDD->testInt );
   Stg_asprintf( &testDD->testKeys[++iter], "test_unsignedlong" );
   testDD->testValues[iter] = Dictionary_Entry_Value_FromUnsignedLong( testDD->testUnsignedlong );
   Stg_asprintf( &testDD->testKeys[++iter], "test_bool" );
   testDD->testValues[iter] = Dictionary_Entry_Value_FromUnsignedInt( testDD->testBool );
   Stg_asprintf( &testDD->testKeys[++iter], "test_placeholder" );
   testDD->testValues[iter] = Dictionary_Entry_Value_FromString( testDD->testPlaceHolder );

   /* adding a list */
   testDD->testListCount = 5;
   testDD->testList = Memory_Alloc_Array_Unnamed( double, testDD->testListCount );
   for (ii=0; ii<testDD->testListCount; ii++ ) {
      testDD->testList[ii] = 10.0 * ii;
   }

   testList = Dictionary_Entry_Value_NewList();
   Stg_asprintf( &testDD->testKeys[++iter], "test_list" );
   testDD->testValues[iter] = testList;
   for (ii=0; ii < testDD->testListCount; ii++ ) {
      Dictionary_Entry_Value_AddElement( testList, Dictionary_Entry_Value_FromDouble(testDD->testList[ii]) );
   }

   /* Adding members to a struct */
   testDD->testStruct = Memory_Alloc_Unnamed( TestStruct );
   testDD->testStruct->height = 37;
   testDD->testStruct->anisotropic = True;
   Stg_asprintf( &testDD->testStruct->person, "Patrick" );
   testDD->testStruct->geom.startx = 45;
   testDD->testStruct->geom.starty = 60;
   testDD->testStruct->geom.startz = 70;

   testStruct = Dictionary_Entry_Value_NewStruct();
   Stg_asprintf( &testDD->testKeys[++iter], "test_struct" );
   testDD->testValues[iter] = testStruct;
   Dictionary_Entry_Value_AddMember( testStruct, (Dictionary_Entry_Key)"height", Dictionary_Entry_Value_FromDouble( testDD->testStruct->height )  );
   Dictionary_Entry_Value_AddMember( testStruct, (Dictionary_Entry_Key)"anisotropic", Dictionary_Entry_Value_FromBool( testDD->testStruct->anisotropic )  );
   Dictionary_Entry_Value_AddMember( testStruct, (Dictionary_Entry_Key)"person", Dictionary_Entry_Value_FromString( testDD->testStruct->person ) );

   /* Adding a 2nd struct within the first struct */
   testStruct2 = Dictionary_Entry_Value_NewStruct( );
   Dictionary_Entry_Value_AddMember( testStruct, (Dictionary_Entry_Key)"geom", testStruct2  );
   Dictionary_Entry_Value_AddMember( testStruct2, (Dictionary_Entry_Key)"startx", Dictionary_Entry_Value_FromUnsignedInt( testDD->testStruct->geom.startx )  );
   Dictionary_Entry_Value_AddMember( testStruct2, (Dictionary_Entry_Key)"starty", Dictionary_Entry_Value_FromUnsignedInt( testDD->testStruct->geom.starty )  );
   Dictionary_Entry_Value_AddMember( testStruct2, (Dictionary_Entry_Key)"startz", Dictionary_Entry_Value_FromUnsignedInt( testDD->testStruct->geom.startz ) );
}
double Stg_ComponentFactory_PluginGetDouble( void* cf, void *codelet, Dictionary_Entry_Key key, double defaultVal ) {
   return Dictionary_Entry_Value_AsDouble( 
                _Stg_ComponentFactory_PluginGetNumericalValue( cf, codelet, key, 
                                                               Dictionary_Entry_Value_FromDouble( defaultVal )));
}
void _SnacTemperature_ConstructExtensions( void* _context, void* data ) {
	Snac_Context*				context = (Snac_Context*)_context;
	SnacTemperature_Context*		contextExt = ExtensionManager_Get(
							context->extensionMgr,
							context,
							SnacTemperature_ContextHandle );
	Snac_Node				tmpNode;
	SnacTemperature_Node*			tmpNodeExt = ExtensionManager_Get(
							context->mesh->nodeExtensionMgr,
							&tmpNode,
							SnacTemperature_NodeHandle );
	Dictionary*				temperatureBCsDict;
	char					tmpBuf[PATH_MAX];
	
	/* Because temperature is not an array by itself, we must the "complex" constructor for Variable... the info needs to be
	 * wrapped this generic way... */
	Index					temperatureOffsetCount = 1;
	SizeT					temperatureOffsets[] = { /*GetOffsetOfMember( *tmpNodeExt, temperature ) };*/
		(SizeT)((char*)&tmpNodeExt->temperature - (char*)&tmpNode) };
	Variable_DataType			temperatureDataTypes[] = { Variable_DataType_Double };
	Index					temperatureDataTypeCounts[] = { 1 };
	
		
	#if DEBUG
		printf( "In %s()\n", __func__ );
	#endif

	/* Create the StGermain variable temperature, which is stored on a node extension */
	Variable_New( 
		"temperature", 
		temperatureOffsetCount, 
		temperatureOffsets, 
		temperatureDataTypes, 
		temperatureDataTypeCounts, 
		0, 
		&ExtensionManager_GetFinalSize( context->mesh->nodeExtensionMgr ),
		&context->mesh->layout->decomp->nodeDomainCount,
		(void**)&context->mesh->node,
		context->variable_Register );

	/* Register these functions for use in VCs */
	ConditionFunction_Register_Add(
		context->condFunc_Register,
		ConditionFunction_New( _SnacTemperature_Top2BottomSweep, "SnacTemperature_Top2BottomSweep" ) );
	ConditionFunction_Register_Add(
		context->condFunc_Register,
		ConditionFunction_New( _SnacTemperature_Top2BottomSweep_Spherical, "SnacTemperature_Top2BottomSweep_Spherical" ) );
	ConditionFunction_Register_Add(
		context->condFunc_Register,
		ConditionFunction_New( _SnacTemperature_Citcom_Compatible, "SnacTemperature_Citcom_Compatible" ) );

	/* Temperature variables */
	contextExt->topTemp = Dictionary_Entry_Value_AsDouble(
		Dictionary_GetDefault( context->dictionary, "topTemp", Dictionary_Entry_Value_FromDouble( 0.0f ) ) );

	contextExt->bottomTemp = Dictionary_Entry_Value_AsDouble(
		Dictionary_GetDefault( context->dictionary, "bottomTemp", Dictionary_Entry_Value_FromDouble( 1300.0f ) ) );

	/* Build the temperature IC and BC managers */
	temperatureBCsDict = Dictionary_Entry_Value_AsDictionary( Dictionary_Get( context->dictionary, "temperatureBCs" ) );
	contextExt->temperatureBCs = CompositeVC_New("tempBC",
		context->variable_Register,
		context->condFunc_Register,
		temperatureBCsDict,
		context->mesh );

	/* Prepare the dump and checkpoint file */
	sprintf( tmpBuf, "%s/temperature.%u", context->outputPath, context->rank );
	if( (contextExt->temperatureOut = fopen( tmpBuf, "w+" )) == NULL ) {
		assert( contextExt->temperatureOut /* failed to open file for writing */ );
		abort();
	}
	sprintf( tmpBuf, "%s/temperatureCP.%u", context->outputPath, context->rank );
	if( (contextExt->temperatureCheckpoint = fopen( tmpBuf, "w+" )) == NULL ) {
		assert( contextExt->temperatureCheckpoint /* failed to open file for writing */ );
		abort();
	}
}
double _Stg_ComponentFactory_GetDouble( void* cf, Name componentName, Dictionary_Entry_Key key, double defaultVal ) {
   return Dictionary_Entry_Value_AsDouble( 
         _Stg_ComponentFactory_GetNumericalValue( cf, componentName, key, 
            Dictionary_Entry_Value_FromDouble( defaultVal )));
}
int main( int argc, char* argv[] ) {
	
	Stream*				stream = NULL;
	Dictionary*			dictionary;
	Dictionary_Entry_Value*		tmpVal0;
	Dictionary_Entry_Value*		tmpVal1; 
	
	MPI_Init( &argc, &argv );
	BaseFoundation_Init( &argc, &argv );
	BaseIO_Init( &argc, &argv );
	stream = Journal_Register (Info_Type, "myStream");

	dictionary = Dictionary_New();

	tmpVal0 = Dictionary_Entry_Value_NewStruct();
	tmpVal1 = Dictionary_Entry_Value_NewStruct();
	Dictionary_Entry_Value_AddMember( tmpVal1, "name", Dictionary_Entry_Value_FromString( "bill" ) );
	Dictionary_Entry_Value_AddMember( tmpVal1, "value", Dictionary_Entry_Value_FromDouble( 1.0f ) );
	Dictionary_Entry_Value_AddMember( tmpVal0, "inside", tmpVal1 );
	tmpVal1 = Dictionary_Entry_Value_NewList();
	Dictionary_Entry_Value_AddElement( tmpVal1, Dictionary_Entry_Value_FromString( "bottom" ) );
	Dictionary_Entry_Value_AddElement( tmpVal1, Dictionary_Entry_Value_FromString( "top" ) );
	Dictionary_Entry_Value_AddMember( tmpVal0, "list_one", tmpVal1 );
	Dictionary_Add( dictionary, "one", tmpVal0 );
	
	tmpVal0 = Dictionary_Entry_Value_NewStruct();
	tmpVal1 = Dictionary_Entry_Value_NewStruct();
	Dictionary_Entry_Value_AddMember( tmpVal1, "new_name", Dictionary_Entry_Value_FromString( "frank" ) );
	Dictionary_Entry_Value_AddMember( tmpVal1, "value", Dictionary_Entry_Value_FromDouble( 2.0f ) );
	Dictionary_Entry_Value_AddMember( tmpVal0, "inside", tmpVal1 );
	tmpVal1 = Dictionary_Entry_Value_NewList();
	Dictionary_Entry_Value_AddElement( tmpVal1, Dictionary_Entry_Value_FromString( "left" ) );
	Dictionary_Entry_Value_AddElement( tmpVal1, Dictionary_Entry_Value_FromString( "right" ) );
	Dictionary_Entry_Value_AddMember( tmpVal0, "list_one", tmpVal1 );
	Dictionary_AddMerge( dictionary, "one", tmpVal0, Dictionary_MergeType_Append );
	
	Print( dictionary, stream );
	Stg_Class_Delete( dictionary );
	
	dictionary = Dictionary_New();
	
	tmpVal0 = Dictionary_Entry_Value_NewStruct();
	tmpVal1 = Dictionary_Entry_Value_NewStruct();
	Dictionary_Entry_Value_AddMember( tmpVal1, "name", Dictionary_Entry_Value_FromString( "bill" ) );
	Dictionary_Entry_Value_AddMember( tmpVal1, "value", Dictionary_Entry_Value_FromDouble( 1.0f ) );
	Dictionary_Entry_Value_AddMember( tmpVal0, "inside", tmpVal1 );
	tmpVal1 = Dictionary_Entry_Value_NewList();
	Dictionary_Entry_Value_AddElement( tmpVal1, Dictionary_Entry_Value_FromString( "bottom" ) );
	Dictionary_Entry_Value_AddElement( tmpVal1, Dictionary_Entry_Value_FromString( "top" ) );
	Dictionary_Entry_Value_AddMember( tmpVal0, "list_one", tmpVal1 );
	Dictionary_Add( dictionary, "one", tmpVal0 );
	
	tmpVal0 = Dictionary_Entry_Value_NewStruct();
	tmpVal1 = Dictionary_Entry_Value_NewStruct();
	Dictionary_Entry_Value_AddMember( tmpVal1, "new_name", Dictionary_Entry_Value_FromString( "frank" ) );
	Dictionary_Entry_Value_AddMember( tmpVal1, "value", Dictionary_Entry_Value_FromDouble( 2.0f ) );
	Dictionary_Entry_Value_AddMember( tmpVal0, "inside", tmpVal1 );
	tmpVal1 = Dictionary_Entry_Value_NewList();
	Dictionary_Entry_Value_AddElement( tmpVal1, Dictionary_Entry_Value_FromString( "left" ) );
	Dictionary_Entry_Value_AddElement( tmpVal1, Dictionary_Entry_Value_FromString( "right" ) );
	Dictionary_Entry_Value_AddMember( tmpVal0, "list_one", tmpVal1 );
	Dictionary_AddMerge( dictionary, "one", tmpVal0, Dictionary_MergeType_Merge );
	
	Print( dictionary, stream );
	Stg_Class_Delete( dictionary );
	
	dictionary = Dictionary_New();
	
	tmpVal0 = Dictionary_Entry_Value_NewStruct();
	tmpVal1 = Dictionary_Entry_Value_NewStruct();
	Dictionary_Entry_Value_AddMember( tmpVal1, "name", Dictionary_Entry_Value_FromString( "bill" ) );
	Dictionary_Entry_Value_AddMember( tmpVal1, "value", Dictionary_Entry_Value_FromDouble( 1.0f ) );
	Dictionary_Entry_Value_AddMember( tmpVal0, "inside", tmpVal1 );
	tmpVal1 = Dictionary_Entry_Value_NewList();
	Dictionary_Entry_Value_AddElement( tmpVal1, Dictionary_Entry_Value_FromString( "bottom" ) );
	Dictionary_Entry_Value_AddElement( tmpVal1, Dictionary_Entry_Value_FromString( "top" ) );
	Dictionary_Entry_Value_AddMember( tmpVal0, "list_one", tmpVal1 );
	Dictionary_Add( dictionary, "one", tmpVal0 );
	
	tmpVal0 = Dictionary_Entry_Value_NewStruct();
	tmpVal1 = Dictionary_Entry_Value_NewStruct();
	Dictionary_Entry_Value_AddMember( tmpVal1, "new_name", Dictionary_Entry_Value_FromString( "frank" ) );
	Dictionary_Entry_Value_AddMember( tmpVal1, "value", Dictionary_Entry_Value_FromDouble( 2.0f ) );
	Dictionary_Entry_Value_AddMember( tmpVal0, "inside", tmpVal1 );
	tmpVal1 = Dictionary_Entry_Value_NewList();
	Dictionary_Entry_Value_AddElement( tmpVal1, Dictionary_Entry_Value_FromString( "left" ) );
	Dictionary_Entry_Value_AddElement( tmpVal1, Dictionary_Entry_Value_FromString( "right" ) );
	Dictionary_Entry_Value_AddMember( tmpVal0, "list_one", tmpVal1 );
	Dictionary_AddMerge( dictionary, "one", tmpVal0, Dictionary_MergeType_Replace );
	
	Print( dictionary, stream );
	Stg_Class_Delete( dictionary );
	
	BaseIO_Finalise();
	BaseFoundation_Finalise();
	MPI_Finalize();
	
	return EXIT_SUCCESS;
}
Dictionary_Entry_Value* Dictionary_Entry_Value_Copy(
		Dictionary_Entry_Value*  self,
		Bool deep )
{
	Dictionary_Entry_Value* copy = NULL;
	
	switch (self->type) {
		case Dictionary_Entry_Value_Type_String:
			copy = Dictionary_Entry_Value_FromString( self->as.typeString );
			break;
		case Dictionary_Entry_Value_Type_Double:
			copy = Dictionary_Entry_Value_FromDouble( self->as.typeDouble );
			break;
		case Dictionary_Entry_Value_Type_UnsignedInt:
			copy = Dictionary_Entry_Value_FromUnsignedInt( self->as.typeUnsignedInt );
			break;
		case Dictionary_Entry_Value_Type_Int:
			copy = Dictionary_Entry_Value_FromInt( self->as.typeInt );
			break;
		case Dictionary_Entry_Value_Type_UnsignedLong:
			copy = Dictionary_Entry_Value_FromUnsignedLong( self->as.typeUnsignedLong );
			break;
		case Dictionary_Entry_Value_Type_Bool:
			copy = Dictionary_Entry_Value_FromBool( self->as.typeBool );
			break;
		case Dictionary_Entry_Value_Type_List:
			if ( False == deep ) {
				Stream* errorStream = Journal_Register( Error_Type, "Dictionary_Entry_Value" );
				Journal_Firewall( False, errorStream, "In func %s: Shallow copy operation of list DEV not supported.\n", __func__ );
			}
			else {
				Dictionary_Entry_Value* cur = self->as.typeList->first;
				Dictionary_Entry_Value* copiedEntry = NULL;

				copy = Dictionary_Entry_Value_NewList();
				while ( cur ) {
					copiedEntry = Dictionary_Entry_Value_Copy( cur, True );
					Dictionary_Entry_Value_AddElement( copy, copiedEntry );
					cur = cur->next;
				}	
			}
			break;
		case Dictionary_Entry_Value_Type_Struct:
			if ( False == deep ) {
				copy = Dictionary_Entry_Value_FromStruct( self->as.typeStruct );
			}
			else {
				Dictionary* copiedDict;
				copiedDict = (Dictionary*)Stg_Class_Copy( self->as.typeStruct,
					NULL, True, NULL, NULL );
				copy = Dictionary_Entry_Value_FromStruct( copiedDict );
			}
			break;
		default: {
			Stream* errorStream = Journal_Register( Error_Type, "Dictionary_Entry_Value" );
			Journal_Firewall( False, errorStream, "In func %s: self->type '%d' is invalid.\n", __func__, self->type );
		}
	}

	return copy;
}
int main( int argc, char* argv[] ) {
	MPI_Comm			CommWorld;
	int				rank;
	int				numProcessors;
	int				procToWatch;
	Dictionary*			dictionary;
	Snac_Context*			snacContext;
	Element_LocalIndex		elementIndex;
	Node_LocalIndex		nodeIndex;
	double				minLengthScale;
	double				speedOfSound;
	Mass				mass;
	Mass				inertialMass;
	Force				force;
	Snac_Node*          node;
	Force				balance;
	Stream*				stream;
	Index elementNode_lI;
	Coord *coord;
	Index timeStep;

	Dictionary_Entry_Value* pluginsList;
	Dictionary_Entry_Value* velocityBCs;
	Dictionary_Entry_Value* vcList;
	Dictionary_Entry_Value* varStruct;
	Dictionary_Entry_Value* eachVarList;
	Dictionary_Entry_Value* vxStruct;

	/* Initialise MPI, get world info */
	MPI_Init( &argc, &argv );
	Snac_Init( &argc, &argv );
	MPI_Comm_dup( MPI_COMM_WORLD, &CommWorld );
	MPI_Comm_size( CommWorld, &numProcessors );
	MPI_Comm_rank( CommWorld, &rank );

	stream = Journal_Register (InfoStream_Type, "myStream");

	if( argc >= 2 ) {
		procToWatch = atoi( argv[1] );
	}
	else {
		procToWatch = 0;
	}
	if( rank == procToWatch ) printf( "Watching rank: %i\n", rank );

	/* Read input */
	dictionary = Dictionary_New();
	dictionary->add( dictionary, "rank", Dictionary_Entry_Value_FromUnsignedInt( rank ) );
	dictionary->add( dictionary, "numProcessors", Dictionary_Entry_Value_FromUnsignedInt( numProcessors ) );
	dictionary->add( dictionary, "meshSizeI", Dictionary_Entry_Value_FromUnsignedInt( 3 ) );
	dictionary->add( dictionary, "meshSizeJ", Dictionary_Entry_Value_FromUnsignedInt( 3 ) );
	dictionary->add( dictionary, "meshSizeK", Dictionary_Entry_Value_FromUnsignedInt( 3 ) );
	dictionary->add( dictionary, "minX", Dictionary_Entry_Value_FromDouble( 0.0f ) );
	dictionary->add( dictionary, "minY", Dictionary_Entry_Value_FromDouble( -1.0f ) );
	dictionary->add( dictionary, "minZ", Dictionary_Entry_Value_FromDouble( 0.0f ) );
	dictionary->add( dictionary, "maxX", Dictionary_Entry_Value_FromDouble( 1.0f ) );
	dictionary->add( dictionary, "maxY", Dictionary_Entry_Value_FromDouble( 0.0f ) );
	dictionary->add( dictionary, "maxZ", Dictionary_Entry_Value_FromDouble( 1.0f ) );
	dictionary->add( dictionary, "gravity", Dictionary_Entry_Value_FromDouble( 0 ) );
	dictionary->add( dictionary, "dtType", Dictionary_Entry_Value_FromString( "constant" ) );
	dictionary->add( dictionary, "timeStep", Dictionary_Entry_Value_FromDouble( 1.0 ) );
	dictionary->add( dictionary, "topo_kappa", Dictionary_Entry_Value_FromDouble( 0 ) );
	dictionary->add( dictionary, "alpha", Dictionary_Entry_Value_FromDouble( 0 ) );
	dictionary->add( dictionary, "forceCalcType", Dictionary_Entry_Value_FromString( "complete" ) );

	pluginsList = Dictionary_Entry_Value_NewList();
	Dictionary_Add( dictionary, "plugins", pluginsList );
	
	velocityBCs = Dictionary_Entry_Value_NewStruct();
	vcList = Dictionary_Entry_Value_NewList();
	/* left wall */
	varStruct = Dictionary_Entry_Value_NewStruct();
	eachVarList = Dictionary_Entry_Value_NewList();
	vxStruct = Dictionary_Entry_Value_NewStruct();
	Dictionary_Entry_Value_AddMember( vxStruct, "name", Dictionary_Entry_Value_FromString( "vx" ) );
	Dictionary_Entry_Value_AddMember( vxStruct, "type", Dictionary_Entry_Value_FromString( "double" ) );
	Dictionary_Entry_Value_AddMember( vxStruct, "value", Dictionary_Entry_Value_FromDouble( 0.0 ) );
	Dictionary_Entry_Value_AddElement( eachVarList, vxStruct );
	Dictionary_Entry_Value_AddMember( varStruct, "type", Dictionary_Entry_Value_FromString( "WallVC" ) );
	Dictionary_Entry_Value_AddMember( varStruct, "wall", Dictionary_Entry_Value_FromString( "left" ) );
	Dictionary_Entry_Value_AddMember( varStruct, "variables", eachVarList );
	Dictionary_Entry_Value_AddElement( vcList, varStruct );
	/* right wall */
	varStruct = Dictionary_Entry_Value_NewStruct();
	eachVarList = Dictionary_Entry_Value_NewList();
	vxStruct = Dictionary_Entry_Value_NewStruct();
	Dictionary_Entry_Value_AddMember( vxStruct, "name", Dictionary_Entry_Value_FromString( "vx" ) );
	Dictionary_Entry_Value_AddMember( vxStruct, "type", Dictionary_Entry_Value_FromString( "double" ) );
	Dictionary_Entry_Value_AddMember( vxStruct, "value", Dictionary_Entry_Value_FromDouble( 0.01 ) );
	Dictionary_Entry_Value_AddElement( eachVarList, vxStruct );
	Dictionary_Entry_Value_AddMember( varStruct, "type", Dictionary_Entry_Value_FromString( "WallVC" ) );
	Dictionary_Entry_Value_AddMember( varStruct, "wall", Dictionary_Entry_Value_FromString( "right" ) );
	Dictionary_Entry_Value_AddMember( varStruct, "variables", eachVarList );
	Dictionary_Entry_Value_AddElement( vcList, varStruct );
	/* back wall */
	varStruct = Dictionary_Entry_Value_NewStruct();
	eachVarList = Dictionary_Entry_Value_NewList();
	vxStruct = Dictionary_Entry_Value_NewStruct();
	Dictionary_Entry_Value_AddMember( vxStruct, "name", Dictionary_Entry_Value_FromString( "vz" ) );
	Dictionary_Entry_Value_AddMember( vxStruct, "type", Dictionary_Entry_Value_FromString( "double" ) );
	Dictionary_Entry_Value_AddMember( vxStruct, "value", Dictionary_Entry_Value_FromDouble( 0.0 ) );
	Dictionary_Entry_Value_AddElement( eachVarList, vxStruct );
	Dictionary_Entry_Value_AddMember( varStruct, "type", Dictionary_Entry_Value_FromString( "WallVC" ) );
	Dictionary_Entry_Value_AddMember( varStruct, "wall", Dictionary_Entry_Value_FromString( "back" ) );
	Dictionary_Entry_Value_AddMember( varStruct, "variables", eachVarList );
	Dictionary_Entry_Value_AddElement( vcList, varStruct );
	/* front wall */
	varStruct = Dictionary_Entry_Value_NewStruct();
	eachVarList = Dictionary_Entry_Value_NewList();
	vxStruct = Dictionary_Entry_Value_NewStruct();
	Dictionary_Entry_Value_AddMember( vxStruct, "name", Dictionary_Entry_Value_FromString( "vz" ) );
	Dictionary_Entry_Value_AddMember( vxStruct, "type", Dictionary_Entry_Value_FromString( "double" ) );
	Dictionary_Entry_Value_AddMember( vxStruct, "value", Dictionary_Entry_Value_FromDouble( 0.0 ) );
	Dictionary_Entry_Value_AddElement( eachVarList, vxStruct );
	Dictionary_Entry_Value_AddMember( varStruct, "type", Dictionary_Entry_Value_FromString( "WallVC" ) );
	Dictionary_Entry_Value_AddMember( varStruct, "wall", Dictionary_Entry_Value_FromString( "front" ) );
	Dictionary_Entry_Value_AddMember( varStruct, "variables", eachVarList );
	Dictionary_Entry_Value_AddElement( vcList, varStruct );
	/* bottom wall */
	varStruct = Dictionary_Entry_Value_NewStruct();
	eachVarList = Dictionary_Entry_Value_NewList();
	vxStruct = Dictionary_Entry_Value_NewStruct();
	Dictionary_Entry_Value_AddMember( vxStruct, "name", Dictionary_Entry_Value_FromString( "vy" ) );
	Dictionary_Entry_Value_AddMember( vxStruct, "type", Dictionary_Entry_Value_FromString( "double" ) );
	Dictionary_Entry_Value_AddMember( vxStruct, "value", Dictionary_Entry_Value_FromDouble( 0.0 ) );
	Dictionary_Entry_Value_AddElement( eachVarList, vxStruct );
	Dictionary_Entry_Value_AddMember( varStruct, "type", Dictionary_Entry_Value_FromString( "WallVC" ) );
	Dictionary_Entry_Value_AddMember( varStruct, "wall", Dictionary_Entry_Value_FromString( "bottom" ) );
	Dictionary_Entry_Value_AddMember( varStruct, "variables", eachVarList );
	Dictionary_Entry_Value_AddElement( vcList, varStruct );
	/* top wall */
	varStruct = Dictionary_Entry_Value_NewStruct();
	eachVarList = Dictionary_Entry_Value_NewList();
	vxStruct = Dictionary_Entry_Value_NewStruct();
	Dictionary_Entry_Value_AddMember( vxStruct, "name", Dictionary_Entry_Value_FromString( "vy" ) );
	Dictionary_Entry_Value_AddMember( vxStruct, "type", Dictionary_Entry_Value_FromString( "double" ) );
	Dictionary_Entry_Value_AddMember( vxStruct, "value", Dictionary_Entry_Value_FromDouble( 0.0 ) );
	Dictionary_Entry_Value_AddElement( eachVarList, vxStruct );
	Dictionary_Entry_Value_AddMember( varStruct, "type", Dictionary_Entry_Value_FromString( "WallVC" ) );
	Dictionary_Entry_Value_AddMember( varStruct, "wall", Dictionary_Entry_Value_FromString( "top" ) );
	Dictionary_Entry_Value_AddMember( varStruct, "variables", eachVarList );
	Dictionary_Entry_Value_AddElement( vcList, varStruct );
	/* add to dictionary */
	Dictionary_Entry_Value_AddMember( velocityBCs, "vcList", vcList );
	Dictionary_Add( dictionary, "velocityBCs", velocityBCs );

	/* Build the context */
	snacContext = Snac_Context_New( 0.0f, 10.0f, sizeof(Snac_Node), sizeof(Snac_Element), CommWorld, dictionary );

	/* Construction phase -----------------------------------------------------------------------------------------------*/
	Stg_Component_Construct( snacContext, 0 /* dummy */, &snacContext, True );
	
	/* Building phase ---------------------------------------------------------------------------------------------------*/
	Stg_Component_Build( snacContext, 0 /* dummy */, False );
	
	/* Initialisaton phase ----------------------------------------------------------------------------------------------*/
	Stg_Component_Initialise( snacContext, 0 /* dummy */, False );

	/* Check the coordinates of the nodes. */
	for( elementIndex = 0; elementIndex < snacContext->mesh->elementLocalCount; elementIndex ++ ) {
		printf( "Element: %u, Coords: ", elementIndex );
		for( elementNode_lI = 0; elementNode_lI < 8; elementNode_lI++ ) {
			printf( "(%g %g %g) ",
					Snac_Element_NodeCoord( snacContext, elementIndex, elementNode_lI )[0],
					Snac_Element_NodeCoord( snacContext, elementIndex, elementNode_lI )[1],
					Snac_Element_NodeCoord( snacContext, elementIndex, elementNode_lI )[2] );
		}
		printf( "\n" );
	}

	/* Check the velocity field. */
	for( elementIndex = 0; elementIndex < snacContext->mesh->elementLocalCount; elementIndex ++ ) {
		printf( "Element: %u, Vel: ",elementIndex );
		for( elementNode_lI = 0; elementNode_lI < 8; elementNode_lI++ ) {
			printf( "(%g %g %g) ",
					Snac_Element_Node_P( snacContext, elementIndex, elementNode_lI )->velocity[0],
					Snac_Element_Node_P( snacContext, elementIndex, elementNode_lI )->velocity[1],
					Snac_Element_Node_P( snacContext, elementIndex, elementNode_lI )->velocity[2] );
		}
		printf( "\n" );
	}

	/* Check the coordinates of the nodes. */
	for( elementIndex = 0; elementIndex < snacContext->mesh->elementLocalCount; elementIndex ++ ) {
		printf( "Element: %u, Coords: ", elementIndex );
		for( elementNode_lI = 0; elementNode_lI < 8; elementNode_lI++ ) {
			printf( "(%g %g %g) ",
					Snac_Element_NodeCoord( snacContext, elementIndex, elementNode_lI )[0],
					Snac_Element_NodeCoord( snacContext, elementIndex, elementNode_lI )[1],
					Snac_Element_NodeCoord( snacContext, elementIndex, elementNode_lI )[2] );
		}
		printf( "\n" );
	}

	/* Loop until the static solution is reached. */
	timeStep = 0;
	while( timeStep < 10 ) {
		for( elementIndex = 0; elementIndex < snacContext->mesh->elementLocalCount; elementIndex++ ) {
			double elementMinLengthScale;

			Snac_UpdateElementMomentum( snacContext, elementIndex, &elementMinLengthScale );

			if( elementMinLengthScale < minLengthScale ) {
				minLengthScale = elementMinLengthScale;
			}
		}

		/* Find the global minLengthScale, and then calculate the new dt and speed of sound, assuming frac=0.5,
		 * strain_inert=1.0e-5f & vbc_max=3.0e-10f */
		{
			double localMinLengthScale = minLengthScale;

			MPI_Allreduce( &localMinLengthScale, &minLengthScale, 1, MPI_DOUBLE, MPI_MIN, CommWorld );

			//snacContext->dt = minLengthScale * 0.5f * 1.0e-5f / 3.0e-10f;
			speedOfSound = minLengthScale * 0.5f / snacContext->dt;
		}

		/* For each element, calculate strain-rate and then stress */
		for( elementIndex = 0; elementIndex < snacContext->mesh->elementLocalCount; elementIndex++ ) {
			Snac_StrainRate( (Context*)snacContext, elementIndex );
			SnacTest_Stress( (Context*)snacContext, elementIndex );
		}

		for( nodeIndex = 0; nodeIndex < snacContext->mesh->nodeLocalCount; nodeIndex++ ) {
			node = Snac_Node_At( snacContext, nodeIndex );
			Snac_Force( snacContext, nodeIndex, speedOfSound, &mass, &inertialMass, &force, &balance );
			Snac_UpdateNodeMomentum_PreProcess( snacContext, nodeIndex, inertialMass, force );
			Snac_UpdateNodeMomentum( snacContext, nodeIndex, inertialMass, force );
		}
		timeStep++;
	}
	/* Check coordinates. */
	for( nodeIndex = 0; nodeIndex < snacContext->mesh->nodeLocalCount; nodeIndex++ ) {
		coord = Snac_NodeCoord_P( snacContext, nodeIndex );

		printf( "Node %u : coord = %g %g %g\n", nodeIndex, (*coord)[0],(*coord)[1],(*coord)[2]);
	}

	/* Stg_Class_Delete stuff */
	Stg_Class_Delete( snacContext );
	Stg_Class_Delete( dictionary );

	/* Close off MPI */
	MPI_Finalize();

	return 0; /* success */
}
int main( int argc, char* argv[] ) {
    MPI_Comm			CommWorld;
    int				rank;
    int				numProcessors;
    int				procToWatch;
    Dictionary*			dictionary;
    Snac_Context*			snacContext;
    Element_LocalIndex		elementIndex;
    Node_LocalIndex		nodeIndex;
    double				minLengthScale;
    double				speedOfSound;
    Mass				mass;
    Mass				inertialMass;
    Force				force;
    Force				balance;
    Stream*				stream;

    Dictionary_Entry_Value* nodeICs;
    Dictionary_Entry_Value* vcList;
    Dictionary_Entry_Value* varStruct;
    Dictionary_Entry_Value* eachVarList;
    Dictionary_Entry_Value* vxStruct;
    Dictionary_Entry_Value* vyStruct;
    Dictionary_Entry_Value* vzStruct;

    /* Initialise MPI, get world info */
    MPI_Init( &argc, &argv );
    Snac_Init( &argc, &argv );
    MPI_Comm_dup( MPI_COMM_WORLD, &CommWorld );
    MPI_Comm_size( CommWorld, &numProcessors );
    MPI_Comm_rank( CommWorld, &rank );

    stream = Journal_Register (Info_Type, "myStream");

    if( argc >= 2 ) {
        procToWatch = atoi( argv[1] );
    }
    else {
        procToWatch = 0;
    }
    if( rank == procToWatch ) printf( "Watching rank: %i\n", rank );

    /* Read input */
    dictionary = Dictionary_New();
    dictionary->add( dictionary, "rank", Dictionary_Entry_Value_FromUnsignedInt( rank ) );
    dictionary->add( dictionary, "numProcessors", Dictionary_Entry_Value_FromUnsignedInt( numProcessors ) );
    dictionary->add( dictionary, "meshSizeI", Dictionary_Entry_Value_FromUnsignedInt( 4 ) );
    dictionary->add( dictionary, "meshSizeJ", Dictionary_Entry_Value_FromUnsignedInt( 4 ) );
    dictionary->add( dictionary, "meshSizeK", Dictionary_Entry_Value_FromUnsignedInt( 4 ) );
    dictionary->add( dictionary, "minX", Dictionary_Entry_Value_FromDouble( 0.0f ) );
    dictionary->add( dictionary, "minY", Dictionary_Entry_Value_FromDouble( -300.0f ) );
    dictionary->add( dictionary, "minZ", Dictionary_Entry_Value_FromDouble( 0.0f ) );
    dictionary->add( dictionary, "maxX", Dictionary_Entry_Value_FromDouble( 300.0f ) );
    dictionary->add( dictionary, "maxY", Dictionary_Entry_Value_FromDouble( 0.0f ) );
    dictionary->add( dictionary, "maxZ", Dictionary_Entry_Value_FromDouble( 300.0f ) );

    nodeICs = Dictionary_Entry_Value_NewStruct();
    vcList = Dictionary_Entry_Value_NewList();
    varStruct = Dictionary_Entry_Value_NewStruct();
    eachVarList = Dictionary_Entry_Value_NewList();
    vxStruct = Dictionary_Entry_Value_NewStruct();
    vyStruct = Dictionary_Entry_Value_NewStruct();
    vzStruct = Dictionary_Entry_Value_NewStruct();
    Dictionary_Entry_Value_AddMember( vxStruct, "name", Dictionary_Entry_Value_FromString( "vx" ) );
    Dictionary_Entry_Value_AddMember( vxStruct, "type", Dictionary_Entry_Value_FromString( "double" ) );
    Dictionary_Entry_Value_AddMember( vxStruct, "value", Dictionary_Entry_Value_FromDouble( 3.0e-10f ) );
    Dictionary_Entry_Value_AddMember( vyStruct, "name", Dictionary_Entry_Value_FromString( "vy" ) );
    Dictionary_Entry_Value_AddMember( vyStruct, "type", Dictionary_Entry_Value_FromString( "double" ) );
    Dictionary_Entry_Value_AddMember( vyStruct, "value", Dictionary_Entry_Value_FromDouble( 3.0e-10f ) );
    Dictionary_Entry_Value_AddMember( vzStruct, "name", Dictionary_Entry_Value_FromString( "vz" ) );
    Dictionary_Entry_Value_AddMember( vzStruct, "type", Dictionary_Entry_Value_FromString( "double" ) );
    Dictionary_Entry_Value_AddMember( vzStruct, "value", Dictionary_Entry_Value_FromDouble( 6.0e-10f ) );
    Dictionary_Entry_Value_AddElement( eachVarList, vxStruct );
    Dictionary_Entry_Value_AddElement( eachVarList, vyStruct );
    Dictionary_Entry_Value_AddElement( eachVarList, vzStruct );
    Dictionary_Entry_Value_AddMember( varStruct, "type", Dictionary_Entry_Value_FromString( "AllNodesVC" ) );
    Dictionary_Entry_Value_AddMember( varStruct, "variables", eachVarList );
    Dictionary_Entry_Value_AddElement( vcList, varStruct );
    Dictionary_Entry_Value_AddMember( nodeICs, "vcList", vcList );
    Dictionary_Add( dictionary, "nodeICs", nodeICs );

    /* Build the context */
    snacContext = Snac_Context_New( 0.0f, 10.0f, sizeof(Snac_Node), sizeof(Snac_Element), CommWorld, dictionary );

    /* Construction phase -----------------------------------------------------------------------------------------------*/
    Stg_Component_Construct( snacContext, 0 /* dummy */, &snacContext, True );

    /* Building phase ---------------------------------------------------------------------------------------------------*/
    Stg_Component_Build( snacContext, 0 /* dummy */, False );

    /* Initialisaton phase ----------------------------------------------------------------------------------------------*/
    Stg_Component_Initialise( snacContext, 0 /* dummy */, False );

    /* Work out the first element's tetrahedra values, and print them. */
    printf( "Element: 0, Coords: (%g %g %g), (%g %g %g), (%g %g %g), (%g %g %g), (%g %g %g) (%g %g %g) (%g %g %g) (%g %g %g)\n",
            Snac_Element_NodeCoord( snacContext, 0, 0 )[0],
            Snac_Element_NodeCoord( snacContext, 0, 0 )[1],
            Snac_Element_NodeCoord( snacContext, 0, 0 )[2],
            Snac_Element_NodeCoord( snacContext, 0, 1 )[0],
            Snac_Element_NodeCoord( snacContext, 0, 1 )[1],
            Snac_Element_NodeCoord( snacContext, 0, 1 )[2],
            Snac_Element_NodeCoord( snacContext, 0, 3 )[0],
            Snac_Element_NodeCoord( snacContext, 0, 3 )[1],
            Snac_Element_NodeCoord( snacContext, 0, 3 )[2],
            Snac_Element_NodeCoord( snacContext, 0, 2 )[0],
            Snac_Element_NodeCoord( snacContext, 0, 2 )[1],
            Snac_Element_NodeCoord( snacContext, 0, 2 )[2],
            Snac_Element_NodeCoord( snacContext, 0, 4 )[0],
            Snac_Element_NodeCoord( snacContext, 0, 4 )[1],
            Snac_Element_NodeCoord( snacContext, 0, 4 )[2],
            Snac_Element_NodeCoord( snacContext, 0, 5 )[0],
            Snac_Element_NodeCoord( snacContext, 0, 5 )[1],
            Snac_Element_NodeCoord( snacContext, 0, 5 )[2],
            Snac_Element_NodeCoord( snacContext, 0, 7 )[0],
            Snac_Element_NodeCoord( snacContext, 0, 7 )[1],
            Snac_Element_NodeCoord( snacContext, 0, 7 )[2],
            Snac_Element_NodeCoord( snacContext, 0, 6 )[0],
            Snac_Element_NodeCoord( snacContext, 0, 6 )[1],
            Snac_Element_NodeCoord( snacContext, 0, 6 )[2] );
    printf( "Element: 0, Vel: (%g %g %g), (%g %g %g), (%g %g %g), (%g %g %g), (%g %g %g) (%g %g %g) (%g %g %g) (%g %g %g)\n",
            Snac_Element_Node_P( snacContext, 0, 0 )->velocity[0],
            Snac_Element_Node_P( snacContext, 0, 0 )->velocity[1],
            Snac_Element_Node_P( snacContext, 0, 0 )->velocity[2],
            Snac_Element_Node_P( snacContext, 0, 1 )->velocity[0],
            Snac_Element_Node_P( snacContext, 0, 1 )->velocity[1],
            Snac_Element_Node_P( snacContext, 0, 1 )->velocity[2],
            Snac_Element_Node_P( snacContext, 0, 3 )->velocity[0],
            Snac_Element_Node_P( snacContext, 0, 3 )->velocity[1],
            Snac_Element_Node_P( snacContext, 0, 3 )->velocity[2],
            Snac_Element_Node_P( snacContext, 0, 2 )->velocity[0],
            Snac_Element_Node_P( snacContext, 0, 2 )->velocity[1],
            Snac_Element_Node_P( snacContext, 0, 2 )->velocity[2],
            Snac_Element_Node_P( snacContext, 0, 4 )->velocity[0],
            Snac_Element_Node_P( snacContext, 0, 4 )->velocity[1],
            Snac_Element_Node_P( snacContext, 0, 4 )->velocity[2],
            Snac_Element_Node_P( snacContext, 0, 5 )->velocity[0],
            Snac_Element_Node_P( snacContext, 0, 5 )->velocity[1],
            Snac_Element_Node_P( snacContext, 0, 5 )->velocity[2],
            Snac_Element_Node_P( snacContext, 0, 7 )->velocity[0],
            Snac_Element_Node_P( snacContext, 0, 7 )->velocity[1],
            Snac_Element_Node_P( snacContext, 0, 7 )->velocity[2],
            Snac_Element_Node_P( snacContext, 0, 6 )->velocity[0],
            Snac_Element_Node_P( snacContext, 0, 6 )->velocity[1],
            Snac_Element_Node_P( snacContext, 0, 6 )->velocity[2] );
    /*	Snac_Material_Print( &snacContext->materialProperty[Snac_Element_At( snacContext, 0 )->material_I], stream ); */


    /* Update all the elements, and in the process work out this processor's minLengthScale */
    elementIndex = 0;
    Snac_UpdateElementMomentum( (Context*)snacContext, elementIndex, &minLengthScale );
    for( elementIndex = 1; elementIndex < snacContext->mesh->elementLocalCount; elementIndex++ ) {
        double elementMinLengthScale;

        Snac_UpdateElementMomentum( (Context*)snacContext, elementIndex, &elementMinLengthScale );

        if( elementMinLengthScale < minLengthScale ) {
            minLengthScale = elementMinLengthScale;
        }
    }

    /* Find the global minLengthScale, and then calculate the new dt and speed of sound, assuming frac=0.5,
     * strain_inert=1.0e-5f & vbc_max=3.0e-10f */
    {
        double localMinLengthScale = minLengthScale;

        MPI_Allreduce( &localMinLengthScale, &minLengthScale, 1, MPI_DOUBLE, MPI_MIN, CommWorld );

        snacContext->dt = minLengthScale * 0.5f * 1.0e-5f / 3.0e-10f;
        speedOfSound = minLengthScale * 0.5f / snacContext->dt;
    }
    printf( "Global minLengthScale: %g\n", minLengthScale );
    printf( "Dt: %g\n", snacContext->dt );
    printf( "Speed of sound: %g\n", speedOfSound );


    /* For each element, calculate strain-rate and then stress */
    for( elementIndex = 0; elementIndex < snacContext->mesh->elementLocalCount; elementIndex++ ) {
        Snac_StrainRate( (Context*)snacContext, elementIndex );
        SnacTest_Stress( (Context*)snacContext, elementIndex );
    }


    /* For each node, calculate the mass, force, veloity and coordinates */
    for( nodeIndex = 0; nodeIndex < snacContext->mesh->nodeLocalCount; nodeIndex++ ) {
        Snac_Force( (Context*)snacContext, nodeIndex, speedOfSound, &mass, &inertialMass, &force, &balance );
        Snac_UpdateNodeMomentum( (Context*)snacContext, nodeIndex, inertialMass, force );
    }


    /* For each element... just print out the info... too complicated to work out which ones have the same value */
    for( elementIndex = 0; elementIndex < snacContext->mesh->elementLocalCount; elementIndex++ ) {
        double 			elementMinLengthScale;
        Tetrahedra_Index	tetra_I;

        Snac_UpdateElementMomentum( (Context*)snacContext, elementIndex, &elementMinLengthScale );
        for( tetra_I = 0; tetra_I < Tetrahedra_Count; tetra_I++ ) {
            printf( "Element: %u, tetrahedra: %u, strain: (%g %g %g) (%g %g %g)\n", elementIndex, tetra_I,
                    Snac_Element_At( snacContext, elementIndex )->tetra[tetra_I].strain[0][0],
                    Snac_Element_At( snacContext, elementIndex )->tetra[tetra_I].strain[1][1],
                    Snac_Element_At( snacContext, elementIndex )->tetra[tetra_I].strain[2][2],
                    Snac_Element_At( snacContext, elementIndex )->tetra[tetra_I].strain[0][1],
                    Snac_Element_At( snacContext, elementIndex )->tetra[tetra_I].strain[0][2],
                    Snac_Element_At( snacContext, elementIndex )->tetra[tetra_I].strain[1][2] );
        }
    }


    /* Stg_Class_Delete stuff */
    Stg_Class_Delete( snacContext );
    Stg_Class_Delete( dictionary );

    /* Close off MPI */
    MPI_Finalize();

    return 0; /* success */
}