void _AnalyticFeVariable_Build( void* analyticFeVariable, void* data ) {
   AnalyticFeVariable* self = (AnalyticFeVariable*)analyticFeVariable;
   DomainContext*      context = self->context;
   DofLayout*          dofLayout = NULL;
   Name                name, varName[9];
   Variable*           variable = NULL;
   Variable*           baseVariable = NULL;
   FeMesh*             referenceMesh = NULL;
   unsigned            nDomainVerts;
   Index               var_I, node_I;
   double*             arrayPtr;
   Dof_Index           componentsCount;
   Variable_Register*  variable_Register = NULL;;

   _FeVariable_Build( self, data );

   context = self->context;
   variable_Register = context->variable_Register;
   referenceMesh = self->numericField->feMesh;
   componentsCount = self->numericField->fieldComponentCount;
   name = Stg_Object_AppendSuffix( self->numericField, (Name)"AnalyticVariable" );
   nDomainVerts = Mesh_GetDomainSize( referenceMesh, MT_VERTEX );
   
   if( componentsCount == 1 ) {
      arrayPtr = Memory_Alloc_Array_Unnamed( double, nDomainVerts );
      baseVariable = Variable_NewScalar( name,
         (AbstractContext*)context, Variable_DataType_Double, (Index*)&nDomainVerts,
         NULL, (void**)&arrayPtr, variable_Register );
   }
Variable* Mesh_GenerateElGlobalIdVar( void* mesh ) {
    /* Returns a Variable that stores the global element indices.
     * Assumes the number of mesh elements never changes.
     */

    Mesh* self = (Mesh*)mesh;
    char* name;
    unsigned dim;

    // if variable already exists return it
    if( self->eGlobalIdsVar ) return self->eGlobalIdsVar;

    dim = Mesh_GetDimSize(mesh);
    // Create the Variable data structure, int[local node count] 
    self->lEls = Mesh_GetLocalSize( self, dim );
    self->elgid = Memory_Alloc_Array( int, self->lEls, "Mesh::vertsgid" );
    Stg_asprintf( &name, "%s-%s", self->name, "verticesGlobalIds" );
    self->eGlobalIdsVar = Variable_NewScalar( name, NULL, Variable_DataType_Int, &self->lEls, NULL, (void**)&self->elgid, NULL );
    Stg_Component_Build(self->eGlobalIdsVar, NULL, False);
    Stg_Component_Initialise(self->eGlobalIdsVar, NULL, False);
    free(name);

    // Evaluate the global indices for the local nodes
    int ii, gid;
    for( ii=0; ii<self->lEls; ii++ ) {
        gid = Mesh_DomainToGlobal( self, dim, ii );
        Variable_SetValue( self->eGlobalIdsVar, ii, (void*)&gid );
    }

    // return new variable
    return self->eGlobalIdsVar;
}
void _MaterialFeVariable_Build( void* materialFeVariable, void* data ) {
   MaterialFeVariable*     self = (MaterialFeVariable*) materialFeVariable;
   IntegrationPointsSwarm* swarm;
   Name                    tmpName;
   Variable_Register*      variable_Register = NULL;

   Stg_Component_Build( self->feMesh, data, False );

   /* Create Dof Layout */
   swarm = self->picIntegrationPoints;
   if ( swarm->swarmVariable_Register )
      variable_Register = swarm->swarmVariable_Register->variable_Register;

   tmpName = Stg_Object_AppendSuffix( self, (Name)"DataVariable" );
   self->dataVariable = Variable_NewScalar( 
      tmpName,
      (AbstractContext*)self->context,
      Variable_DataType_Double, 
      &((IGraph*)self->feMesh->topo)->remotes[MT_VERTEX]->nDomains, 
      NULL,
      (void**)&self->data, 
      variable_Register );
   Memory_Free( tmpName );
   self->fieldComponentCount = 1;
   
   tmpName = Stg_Object_AppendSuffix( self, (Name)"DofLayout" );
   self->dofLayout = DofLayout_New( tmpName, self->context, variable_Register, ((IGraph*)self->feMesh->topo)->remotes[MT_VERTEX]->nDomains, NULL );
   DofLayout_AddAllFromVariableArray( self->dofLayout, 1, &self->dataVariable );
   Memory_Free( tmpName );
   self->eqNum->dofLayout = self->dofLayout;
   
   _ParticleFeVariable_Build( self, data );
}
void VariableSuite_Setup( VariableSuiteData* data ) {
    Particle                tmpParticle;
    Name                    pNames[] = { "mass", "force", "info" };
    SizeT                   pOffsets[] = { 0, 0, 0 };   /* Init later... */
    Variable_DataType       pDataTypes[] = {
        Variable_DataType_Int,
        Variable_DataType_Float,
        Variable_DataType_Pointer,
    };
    Index                   pDtCounts[] = { 1, 3, 1 };
    static SizeT            pSize = sizeof(Particle);

    data->aSize[0] = 16;
    data->aSize[1] = 16;
    data->aSize[2] = 16;

    pOffsets[0] = (ArithPointer)&tmpParticle.mass - (ArithPointer)&tmpParticle;
    pOffsets[1] = (ArithPointer)&tmpParticle.force - (ArithPointer)&tmpParticle;
    pOffsets[2] = (ArithPointer)&tmpParticle.info - (ArithPointer)&tmpParticle;

    /* Construction phase --------------------------------------------------------------------------------------------*/
    data->vr = Variable_Register_New();
    Variable_NewScalar( "temperature", NULL, Variable_DataType_Double, &data->aSize[0], NULL, (void**)&data->temperature, data->vr );
    Variable_NewVector( "velocity", NULL, Variable_DataType_Double, 3, &data->aSize[1], NULL, (void**)&data->velocity, data->vr, "vx", "vy", "vz" );
    Variable_New( "particle", NULL, 3, pOffsets, pDataTypes, pDtCounts, pNames, &pSize, &data->aSize[2], NULL, (void**)&data->particle, data->vr );

    /* Build phase ---------------------------------------------------------------------------------------------------*/
    data->temperature = Memory_Alloc_Array( double, data->aSize[0], "temperature" );
    data->velocity = Memory_Alloc_Array( VectorD, data->aSize[1], "velocity" );
    data->particle = Memory_Alloc_Array( Particle, data->aSize[2], "array" );

    Variable_Register_BuildAll( data->vr );
}
void _HeatingForce_Build( void* heatingForce, void* data ) {
	HeatingForce*	      	self	            = (HeatingForce*)heatingForce;
	unsigned		nDomainVerts;

	Stg_Component_Build( self->feMesh, data, False );
	nDomainVerts = Mesh_GetDomainSize( self->feMesh, MT_VERTEX );

	self->dataVariable = Variable_NewScalar( "dataVariable", self->context, Variable_DataType_Double, 
						 &nDomainVerts, NULL, (void**)&self->data, self->context->variable_Register );

	_ParticleFeVariable_Build( self, data );
	DofLayout_AddAllFromVariableArray( self->dofLayout, 1, &self->dataVariable );
}
void _PpcFeVariable_Build( void* _self, void* data ) {
   PpcFeVariable* self = (PpcFeVariable*) _self;
   Name                 tmpName;

   Stg_Component_Build( self->ppcMan, data, False );

   /* Create Dof Layout */
   tmpName = Stg_Object_AppendSuffix( self, (Name)"Variable" );
   self->dataVariable = Variable_NewScalar( tmpName, (AbstractContext*)self->context, Variable_DataType_Double, (Index*)&((IGraph*)self->feMesh->topo)->remotes[MT_VERTEX]->nDomains, NULL, (void**)&self->data, self->context->variable_Register );
   Memory_Free( tmpName  );
   self->fieldComponentCount = 1;

   tmpName = Stg_Object_AppendSuffix( self, (Name)"DOF" );
   self->dofLayout = DofLayout_New( tmpName, self->context, self->context->variable_Register, 0, self->feMesh );
   self->dofLayout->_numItemsInLayout = FeMesh_GetNodeDomainSize( self->feMesh );
   DofLayout_AddAllFromVariableArray( self->dofLayout, 1, &self->dataVariable );
   Memory_Free( tmpName );
   self->eqNum->dofLayout = self->dofLayout;

   _ParticleFeVariable_Build( self, data );
}
void WallVCSuite_TestWallVC( WallVCSuiteData* data ) {
   unsigned                    nDomains;
   unsigned                    nDims = 3;
   unsigned                    meshSize[3] = {3, 3, 3};
   int                         procToWatch;
   double                      minCrds[3] = {0.0, 0.0, 0.0};
   double                      maxCrds[3] = {1.0, 1.0, 1.0};
   char*                       vcKey[] = {"WallVC_Front", "WallVC_Back", "WallVC_Left", "WallVC_Right",
                                          "WallVC_Top", "WallVC_Bottom"};
   char*                       vcKeyName[] = {"WallVC_FrontName", "WallVC_BackName", "WallVC_LeftName", "WallVC_RightName",
                                          "WallVC_TopName", "WallVC_BottomName"};
   char*                       varName[] = {"x", "y", "z", "vx", "vy", "vz", "temp"};
   char                        input_file[PCU_PATH_MAX];
   char                        expected_file[PCU_PATH_MAX];
   Mesh*                       mesh;
   Variable_Register*          variable_Register;
   ConditionFunction*          quadCF;
   ConditionFunction*          expCF;
   ConditionFunction_Register* conFunc_Register;
   ExtensionManager_Register*  extensionMgr_Register;
   Dictionary*                 dictionary;
   Dictionary*                 sources;
   Stream*                     stream;
   XML_IO_Handler*             io_handler;
   Variable*                   var[7];
   double*                     array[7];
   VariableCondition*          vc; 
   Index                       i;

   procToWatch = data->nProcs >=2 ? 1 : 0;

   io_handler = XML_IO_Handler_New();

    stream = Journal_Register( Info_Type, (Name)"WallVCStream"  );
   Stream_RedirectFile( stream, "testWallVC.dat" );

   dictionary = Dictionary_New();
   sources = Dictionary_New();
   Dictionary_Add( dictionary, (Dictionary_Entry_Key)"outputPath", Dictionary_Entry_Value_FromString("./output") );

   /* Input file */
   pcu_filename_input( "wallVC.xml", input_file );
   IO_Handler_ReadAllFromFile( io_handler, input_file, dictionary, sources );
   fflush( stdout );

   extensionMgr_Register = ExtensionManager_Register_New(); 

   /* Create a mesh. */
   mesh = (Mesh*) WallVCSuite_buildMesh( nDims, meshSize, minCrds, maxCrds, extensionMgr_Register );
   nDomains = Mesh_GetDomainSize( mesh, MT_VERTEX );

   /* Create CF stuff */
   quadCF = ConditionFunction_New( WallVCSuite_quadratic, (Name)"quadratic", NULL );
   expCF = ConditionFunction_New( WallVCSuite_exponential, (Name)"exponential", NULL);
   conFunc_Register = ConditionFunction_Register_New( );
   ConditionFunction_Register_Add(conFunc_Register, quadCF);
   ConditionFunction_Register_Add(conFunc_Register, expCF);

   /* Create variable register */
   variable_Register = Variable_Register_New();

   /* Create variables */
   for (i = 0; i < 6; i++) {
      array[i] = Memory_Alloc_Array( double, nDomains, "array[i]" );
      var[i] = Variable_NewScalar( varName[i], NULL, Variable_DataType_Double, (Index*)&nDomains, NULL, (void**)&array[i], 0  );
      Variable_Register_Add(variable_Register, var[i]);
   }
   array[6] = Memory_Alloc_Array( double, nDomains * 5, "array[6]" );
   var[6] = Variable_NewVector( varName[6], NULL, Variable_DataType_Double, 5, &nDomains, NULL, (void**)&array[6], 0 );
   Variable_Register_Add(variable_Register, var[6]);
   Variable_Register_BuildAll(variable_Register);

   for (i = 0; i < 6; i++) {
      Index j, k;

      vc = (VariableCondition*) WallVC_New( vcKeyName[i], NULL, vcKey[i], variable_Register, conFunc_Register, dictionary, mesh );
      Stg_Component_Build( vc, 0, False );

      for (j = 0; j < 6; j++)
         memset(array[j], 0, sizeof(double)* nDomains );
      memset(array[6], 0, sizeof(double)* nDomains * 5);
      VariableCondition_Apply(vc, NULL);

      if (data->rank == procToWatch) {
         Journal_Printf( stream,"Testing for %s\n", vcKey[i]);
         for (j = 0; j < 6; j++) {
            Journal_Printf( stream,"\nvar[%u]: %.2lf", j, array[j][0]);
            for (k = 1; k < nDomains; k++)
               Journal_Printf( stream,", %.2lf", array[j][k]);
         }

         Journal_Printf( stream,"\nvar[6]: %.2lf", array[6][0]);
         for (j = 1; j < nDomains*5; j++)
            Journal_Printf( stream,", %.2lf", array[6][j]);
         Journal_Printf( stream,"\n\n");

         for (j = 0; j < 7; j++) {
            for (k = 0; k < nDomains; k++)
               Journal_Printf( stream,"%s ", VariableCondition_IsCondition(vc, k, j) ? "True " : "False");
            Journal_Printf( stream,"\n");
         } Journal_Printf( stream,"\n");

         for (j = 0; j < 7; j++) {
            for (k = 0; k < nDomains; k++) {
               VariableCondition_ValueIndex  valIndex;
               valIndex = VariableCondition_GetValueIndex(vc, k, j);
               if (valIndex != (unsigned)-1)
                  Journal_Printf( stream,"%03u ", valIndex);
               else
                  Journal_Printf( stream,"XXX ");
            } Journal_Printf( stream,"\n");
         } Journal_Printf( stream,"\n");
      }
      Stg_Class_Delete(vc);
   }

   if (data->rank == procToWatch) {
      pcu_filename_expected( "testWallVC.expected", expected_file );
      pcu_check_fileEq( "testWallVC.dat", expected_file );
      remove( "testWallVC.dat" );
   }

   Stg_Class_Delete(variable_Register);
   for (i = 0; i < 7; i++) {
      Stg_Class_Delete(var[i]);
      if (array[i]) Memory_Free(array[i]);
   }
   Stg_Class_Delete(extensionMgr_Register);
   Stg_Class_Delete(io_handler);
   Stg_Class_Delete(conFunc_Register);
   Stg_Class_Delete(quadCF);
   Stg_Class_Delete(expCF);
   Stg_Class_Delete(dictionary);
   Stg_Class_Delete(sources);
   FreeObject( mesh );
}
int main( int argc, char *argv[] ) {
	MPI_Comm		CommWorld;
	int		rank;
	int		procCount;
	int		procToWatch;
	
	/* Initialise MPI, get world info */
	MPI_Init( &argc, &argv );
	MPI_Comm_dup( MPI_COMM_WORLD, &CommWorld );
	MPI_Comm_size( MPI_COMM_WORLD, &procCount );
	MPI_Comm_rank( MPI_COMM_WORLD, &rank );
	
	Base_Init( &argc, &argv );
	
	DiscretisationGeometry_Init( &argc, &argv );
	DiscretisationShape_Init( &argc, &argv );
	DiscretisationMesh_Init( &argc, &argv );
	DiscretisationUtils_Init( &argc, &argv );
	MPI_Barrier( CommWorld ); /* Ensures copyright info always come first in output */
	
	if( argc >= 2 ) {
		procToWatch = atoi( argv[1] );
	}
	else {
		procToWatch = 0;
	}
	if( rank == procToWatch ) {
		DofLayout*		dof;
		Variable_Register*	variableRegister;
		Variable*		var[6];
		char*			varName[] = {"x", "y", "z", "vx", "vy", "vz"};
		Index			ii, var_I;
		Index			arraySize = 27;
		double*			varArrays[6];

		/* Create variable register */
		variableRegister = Variable_Register_New();

		/* Create variables */
		for (var_I = 0; var_I < 6; var_I++) {
			varArrays[var_I] = Memory_Alloc_Array_Unnamed( double, arraySize );
			var[var_I] = Variable_NewScalar( varName[var_I], Variable_DataType_Double, &arraySize, 
				(void**)&(varArrays[var_I]), variableRegister );
			Build( var[var_I], 0, False );	
			Initialise( var[var_I], 0, False );	
		}
			
		for (ii = 0; ii < arraySize; ii++) {
			for (var_I = 0; var_I < 6; var_I++) {
				Variable_SetValueDouble( var[var_I], ii, (ii*10 + var_I) );
			}
		}	

		/* Simple test */
		dof = DofLayout_New( "dofLayout", variableRegister, arraySize );
		for (ii = 0; ii < arraySize; ii++) {
			for (var_I = 0; var_I < 6; var_I++) {
				DofLayout_AddDof_ByVarName(dof, varName[var_I], ii);
			}
		}	
		Build(dof, 0, False);

		DofLayout_SaveAllVariablesToFiles( dof, "output/testDofSave", rank );

		DofLayout_SetAllToZero( dof );

		DofLayout_LoadAllVariablesFromFiles( dof, "output/testDofSave", rank );

		for (ii = 0; ii < arraySize; ii++) {
			printf("\tIndex %d - %2g,%2g,%2g,%2g,%2g,%2g\n", ii,
				DofLayout_GetValueDouble( dof, ii, 0 ),
				DofLayout_GetValueDouble( dof, ii, 1 ),
				DofLayout_GetValueDouble( dof, ii, 2 ),
				DofLayout_GetValueDouble( dof, ii, 3 ),
				DofLayout_GetValueDouble( dof, ii, 4 ),
				DofLayout_GetValueDouble( dof, ii, 5 ) );
		}	


		/* Cleanup */
		Stg_Class_Delete(dof);

		Stg_Class_Delete(variableRegister);
		for (var_I = 0; var_I < 6; var_I++) {
			if (var[var_I]) Stg_Class_Delete(var[var_I]);
			Memory_Free( varArrays[var_I] );
		}
	}
Exemple #9
0
int main(int argc, char *argv[])
{
	MPI_Comm		CommWorld;
	int		rank;
	int		procCount;
	int		procToWatch;
	Stream*		stream;
	
	Dictionary*		dictionary;
	XML_IO_Handler*		io_handler;
	
	Topology*       nTopology;
	ElementLayout*	eLayout;
	NodeLayout*	nLayout;
	MeshDecomp*	decomp;
	MeshLayout*	layout;
	Mesh*		mesh;
	
	Variable*			var[7];
	Variable_Register*		variable_Register;
	WallVC*				vc;
	ConditionFunction*		quadCF;
	ConditionFunction*		expCF;
	ConditionFunction_Register*	conFunc_Register;

	ExtensionManager_Register*		extensionMgr_Register;
	
	double*		array[7];
	char*		vcKey[] = {"WallVC_Front", "WallVC_Back", "WallVC_Left", "WallVC_Right",
				"WallVC_Top", "WallVC_Bottom"};
	char*		vcKeyName[] = {"WallVC_FrontName", "WallVC_BackName", "WallVC_LeftName", "WallVC_RightName",
				"WallVC_TopName", "WallVC_BottomName"};
	char*		varName[] = {"x", "y", "z", "vx", "vy", "vz", "temp"};
	
	Index	i;

	
	/* Initialise MPI, get world info */
	MPI_Init(&argc, &argv);
	MPI_Comm_dup( MPI_COMM_WORLD, &CommWorld );
	MPI_Comm_size(CommWorld, &procCount);
	MPI_Comm_rank(CommWorld, &rank);
	
	Base_Init( &argc, &argv );
	
	DiscretisationGeometry_Init( &argc, &argv );
	DiscretisationShape_Init( &argc, &argv );
	DiscretisationMesh_Init( &argc, &argv );
	DiscretisationUtils_Init( &argc, &argv );
	MPI_Barrier( CommWorld ); /* Ensures copyright info always come first in output */

	io_handler = XML_IO_Handler_New();

	stream = Journal_Register (Info_Type, "myStream");
	
	procToWatch = argc >= 2 ? atoi(argv[1]) : 0;
	
	dictionary = Dictionary_New();
	IO_Handler_ReadAllFromFile(io_handler, "data/wallVC.xml", dictionary);
	fflush(stdout);
	MPI_Barrier(MPI_COMM_WORLD);
	Dictionary_Add(dictionary, "rank", Dictionary_Entry_Value_FromUnsignedInt(rank));
	Dictionary_Add(dictionary, "numProcessors", Dictionary_Entry_Value_FromUnsignedInt(procCount));
	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, "allowUnbalancing", Dictionary_Entry_Value_FromBool(True));

	extensionMgr_Register = ExtensionManager_Register_New();	
	
	nTopology = (Topology*)IJK6Topology_New( "IJK6Topology", dictionary );
	eLayout = (ElementLayout*)ParallelPipedHexaEL_New( "PPHexaEL", 3, dictionary );
	nLayout = (NodeLayout*)CornerNL_New( "CornerNL", dictionary, eLayout, nTopology );
	decomp = (MeshDecomp*)HexaMD_New( "HexaMD", dictionary, MPI_COMM_WORLD, eLayout, nLayout );
	layout = MeshLayout_New( "MeshLayout", eLayout, nLayout, decomp );
	mesh = Mesh_New( "Mesh", layout, 0, 0, extensionMgr_Register, dictionary );
	
	/* Create CF stuff */
	quadCF = ConditionFunction_New(quadratic, "quadratic");
	expCF = ConditionFunction_New(exponential, "exponential");
	conFunc_Register = ConditionFunction_Register_New();
	ConditionFunction_Register_Add(conFunc_Register, quadCF);
	ConditionFunction_Register_Add(conFunc_Register, expCF);
	
	/* Create variable register */
	variable_Register = Variable_Register_New();
	
	/* Create variables */
	for (i = 0; i < 6; i++) {
		array[i] = Memory_Alloc_Array( double, decomp->nodeLocalCount, "array[i]" );
		var[i] = Variable_NewScalar( varName[i], Variable_DataType_Double, &decomp->nodeLocalCount, (void**)&array[i], 0 ); 
		Variable_Register_Add(variable_Register, var[i]);
	}
	array[6] = Memory_Alloc_Array( double, decomp->nodeLocalCount * 5, "array[6]" );
	var[6] = Variable_NewVector( varName[6], Variable_DataType_Double, 5, &decomp->nodeLocalCount, (void**)&array[6], 0 );
	Variable_Register_Add(variable_Register, var[6]);
	Variable_Register_BuildAll(variable_Register);
	
	/* Create WallVC */
	for (i = 0; i < 6; i++)
	{
		Index	j, k;
		
		vc = WallVC_New( vcKeyName[i], vcKey[i], variable_Register, conFunc_Register, dictionary, mesh );
		Build( vc, 0, False );
		
		for (j = 0; j < 6; j++)
			memset(array[j], 0, sizeof(double)* decomp->nodeLocalCount );
		memset(array[6], 0, sizeof(double)* decomp->nodeLocalCount * 5);
		VariableCondition_Apply(vc, NULL);
	
		if (rank == procToWatch)
		{
			printf("Testing for %s\n", vcKey[i]);
			Print(vc, stream);
			printf("\n");
			for (j = 0; j < 6; j++)
			{
				printf("\nvar[%u]: %.2lf", j, array[j][0]);
				for (k = 1; k < decomp->nodeLocalCount; k++)
					printf(", %.2lf", array[j][k]);
			}
			printf("\nvar[6]: %.2lf", array[6][0]);
			for (j = 1; j < decomp->nodeLocalCount*5; j++)
				printf(", %.2lf", array[6][j]);
			printf("\n\n");
			
			for (j = 0; j < 7; j++)
			{
				for (k = 0; k < decomp->nodeLocalCount; k++)
					printf("%s ", VariableCondition_IsCondition(vc, k, j) ? "True " : "False");
				printf("\n");
			}
			printf("\n");
			
			for (j = 0; j < 7; j++)
			{
				for (k = 0; k < decomp->nodeLocalCount; k++)
				{
					VariableCondition_ValueIndex	valIndex;
					
					valIndex = VariableCondition_GetValueIndex(vc, k, j);
					if (valIndex != (unsigned)-1)
						printf("%03u ", valIndex);
					else
						printf("XXX ");
				}
				printf("\n");
			}
			printf("\n");
		}
		
		Stg_Class_Delete(vc);
	}
		
	Stg_Class_Delete(variable_Register);
	for (i = 0; i < 7; i++)
	{
		Stg_Class_Delete(var[i]);
		if (array[i]) Memory_Free(array[i]);
	}
	Stg_Class_Delete(conFunc_Register);
	Stg_Class_Delete(quadCF);
	Stg_Class_Delete(expCF);
	Stg_Class_Delete(layout);
	Stg_Class_Delete(decomp);
	Stg_Class_Delete(nLayout);
	Stg_Class_Delete(eLayout);
	Stg_Class_Delete( nTopology );
	Stg_Class_Delete(dictionary);
	
	DiscretisationUtils_Finalise();
	DiscretisationMesh_Finalise();
	DiscretisationShape_Finalise();
	DiscretisationGeometry_Finalise();
	
	Base_Finalise();
	
	/* Close off MPI */
	MPI_Finalize();
	
	return 0; /* success */
}
void LiveComponentRegisterSuite_TestGet( LiveComponentRegisterSuiteData* data ) {
   typedef float Triple[3];

   float* array;
   Triple* structArray;

   Variable* var;
   Variable* vec;
   Variable* vecVar[3];
   Variable* tempVar = NULL;
   Index length = 10;

   Variable_Register* reg;

   array = Memory_Alloc_Array( float, length, "test" );
   structArray = Memory_Alloc_Array( Triple, length, "test" );

   reg = Variable_Register_New();

   var = Variable_NewScalar(
      "Scalar",
		NULL,
      Variable_DataType_Float,
      &length,
      NULL,
      (void**)&array,
      reg );

   vec = Variable_NewVector(
      "Three",
		NULL,
      Variable_DataType_Float,
      3,
      &length,
      NULL,
      (void**)&structArray,
      reg,
      "a",
      "b",
      "c" );

   vecVar[0] = Variable_Register_GetByName( reg, "a" );
   vecVar[1] = Variable_Register_GetByName( reg, "b" );
   vecVar[2] = Variable_Register_GetByName( reg, "c" );

   Variable_Register_BuildAll( reg );

   LiveComponentRegister_Add( data->lcRegister, (Stg_Component*) var );
   pcu_check_true( LiveComponentRegister_IfRegThenAdd( (Stg_Component*) vec ) );
   LiveComponentRegister_Add( data->lcRegister, (Stg_Component*) vecVar[0] );
   LiveComponentRegister_Add( data->lcRegister, (Stg_Component*) vecVar[1] );
   LiveComponentRegister_Add( data->lcRegister, (Stg_Component*) vecVar[2] );

   tempVar = (Variable*) LiveComponentRegister_Get( data->lcRegister, (Name)"Scalar" );
   pcu_check_true( tempVar == var );

   tempVar = (Variable* ) LiveComponentRegister_Get( LiveComponentRegister_GetLiveComponentRegister(), (Name)"Three" );
   pcu_check_true( tempVar == vec );

   tempVar = (Variable* ) LiveComponentRegister_Get( data->lcRegister, (Name)"a" );
   pcu_check_true( tempVar == vecVar[0] );

   tempVar = (Variable* ) LiveComponentRegister_Get( data->lcRegister, (Name)"b" );
   pcu_check_true( tempVar == vecVar[1] );

   tempVar = (Variable* ) LiveComponentRegister_Get( data->lcRegister, (Name)"c" );
   pcu_check_true( tempVar == vecVar[2] );
}
Variable* Mesh_GenerateENMapVar( void* mesh ) {
    /* Returns a Variable that stores the mapping of 
     * [local element] [global node indices]
     * Assumes the mapping never changes.
     */

    Mesh* self = (Mesh*)mesh;
    char* name;
    int n_i, e_i, nNbr, localElements, localtotal;
    unsigned buffy_tvs;     // buffer for global node indices
    unsigned dim, *nbr, temp;
    int *numberNodesPerEl = NULL;
    IArray* inc = NULL;
    Stream* error = Journal_Register( Error_Type, (Name)self->type );

    // if variable already exists return it
    if( self->enMapVar ) return self->enMapVar;

    /* go over local elementNode map to get size of data */
    inc = IArray_New( );
    self->localtotalNodes=0;
    dim = Mesh_GetDimSize( self );
    localElements = Mesh_GetLocalSize( self, dim );
    numberNodesPerEl = Memory_Alloc_Array( int, localElements, "Mesh::numberNodesPerEl" );

    for( e_i=0 ; e_i < localElements; e_i++ ) {
        Mesh_GetIncidence( self, dim, (unsigned)e_i, MT_VERTEX, inc );
        nNbr = IArray_GetSize( inc );
        nbr = IArray_GetPtr( inc );

        numberNodesPerEl[e_i] = nNbr;
        self->localtotalNodes += nNbr;
    }
    
    /* Create the Variable data structure, int[nbrNodesPerEl*local element count]
     * Note: this is stored in a 1D array - so whatever read or writes to this variable 
     * needs to know how to parse it. */ 
    self->e_n = Memory_Alloc_Array( int, self->localtotalNodes, "Mesh::nodeConn" );
    Stg_asprintf( &name, "%s-%s", self->name, "nodeConn" );
    self->enMapVar = Variable_NewScalar( name, NULL, Variable_DataType_Int, &self->localtotalNodes, NULL, (void**)&self->e_n, NULL );
    Stg_Component_Build(self->enMapVar, NULL, False);
    Stg_Component_Initialise(self->enMapVar, NULL, False);
    free(numberNodesPerEl);
    free(name);

    // Evaluate the global indices for the local nodes
    localtotal=0;
    for( e_i=0; e_i<localElements; e_i++ ) {
        Mesh_GetIncidence( self, dim, (unsigned)e_i, MT_VERTEX, inc );
        nNbr = IArray_GetSize( inc );
        nbr = IArray_GetPtr( inc );
        for( n_i=0; n_i< nNbr; n_i++ ) {
            buffy_tvs = Mesh_DomainToGlobal( self, MT_VERTEX, nbr[n_i] );
            Variable_SetValue( self->enMapVar, localtotal, (void*)&buffy_tvs );
            localtotal++;
        }
    }

    Stg_Class_Delete( inc );

    // return new variable
    return self->enMapVar;
}
void VariableSuite_TestVariable_Short( VariableSuiteData* data ) {
    typedef short Triple[3];

    short* array;
    Triple* structArray;
    Index length = 10;

    /* List of values to test the variable with.
     * Values to test are hex 5's and a's because they are a series of 0101 and 1010 respectively so they test
     * each bit in memory to read/set.
     */
    long int testValues[] = { 0x5555, 0xaaaa };
    Index testValueCount = 2;
    Index test_I;
    long int testValue;

    Variable* var;
    Variable* vec;
    Variable* vecVar[3];

    int i, j;

    array = Memory_Alloc_Array( short, length, "test" );
    structArray = Memory_Alloc_Array( Triple, length, "test" );

    var = Variable_NewScalar( "Short-Scalar", NULL, Variable_DataType_Short, &length, NULL, (void**)&array, data->vr );
    vec = Variable_NewVector( "Short-Three", NULL, Variable_DataType_Short, 3, &length, NULL, (void**)&structArray, data->vr, "a", "b", "c" );

    vecVar[0] = Variable_Register_GetByName( data->vr, "a" );
    vecVar[1] = Variable_Register_GetByName( data->vr, "b" );
    vecVar[2] = Variable_Register_GetByName( data->vr, "c" );

    Variable_Register_BuildAll( data->vr );


    for ( test_I = 0; test_I < testValueCount; ++test_I ) {

        testValue = testValues[test_I];


        for ( i = 0; i < length; ++i ) {
            Variable_SetValueShort( var, i, testValue );

            Variable_SetValueAtShort( vec, i, 0, testValue );
            Variable_SetValueAtShort( vec, i, 1, testValue );
            Variable_SetValueAtShort( vec, i, 2, testValue );
        }

        for ( i = 0; i < length; ++i ) {
            pcu_check_true( Variable_GetValueShort( var, i ) == (short)(short)testValue );
            pcu_check_true( Variable_GetValueShortAsChar( var, i ) == (char)(short)testValue );
            pcu_check_true( Variable_GetValueShortAsInt( var, i ) == (int)(short)testValue );
            pcu_check_true( Variable_GetValueShortAsFloat( var, i ) == (float)(short)testValue );
            pcu_check_true( Variable_GetValueShortAsDouble( var, i ) == (double)(short)testValue );
        }

        for ( i = 0; i < length; ++i ) {
            pcu_check_true( Variable_GetValueAtShort( vec, i, 0 ) == (short)(short)testValue );
            pcu_check_true( Variable_GetValueAtShortAsChar( vec, i, 0 ) == (char)(short)testValue );
            pcu_check_true( Variable_GetValueAtShortAsInt( vec, i, 0 ) == (int)(short)testValue );
            pcu_check_true( Variable_GetValueAtShortAsFloat( vec, i, 0 ) == (float)(short)testValue );
            pcu_check_true( Variable_GetValueAtShortAsDouble( vec, i, 0 ) == (double)(short)testValue );
            pcu_check_true( Variable_GetPtrAtShort( vec, i, 0 ) == &structArray[i][0] );

            pcu_check_true( Variable_GetValueAtShort( vec, i, 1 ) == (short)(short)testValue );
            pcu_check_true( Variable_GetValueAtShortAsChar( vec, i, 1 ) == (char)(short)testValue );
            pcu_check_true( Variable_GetValueAtShortAsInt( vec, i, 1 ) == (int)(short)testValue );
            pcu_check_true( Variable_GetValueAtShortAsFloat( vec, i, 1 ) == (float)(short)testValue );
            pcu_check_true( Variable_GetValueAtShortAsDouble( vec, i, 1 ) == (double)(short)testValue );
            pcu_check_true( Variable_GetPtrAtShort( vec, i, 1 ) == &structArray[i][1] );

            pcu_check_true( Variable_GetValueAtShort( vec, i, 2 ) == (short)(short)testValue );
            pcu_check_true( Variable_GetValueAtShortAsChar( vec, i, 2 ) == (char)(short)testValue );
            pcu_check_true( Variable_GetValueAtShortAsInt( vec, i, 2 ) == (int)(short)testValue );
            pcu_check_true( Variable_GetValueAtShortAsFloat( vec, i, 2 ) == (float)(short)testValue );
            pcu_check_true( Variable_GetValueAtShortAsDouble( vec, i, 2 ) == (double)(short)testValue );
            pcu_check_true( Variable_GetPtrAtShort( vec, i, 2 ) == &structArray[i][2] );
        }

        for ( i = 0; i < length; ++i ) {
            for ( j = 0; j < 3; ++j ) {
                pcu_check_true( Variable_GetStructPtr( vecVar[j], i ) == &structArray[i][j] );
            }
        }
    }
}
void VariableSuite_TestVariable_Float( VariableSuiteData* data ) {
    typedef float Triple[3];

    float* array;
    Triple* structArray;
    Index length = 10;

    float testValues[] = { 123456789.0, 0.987654321 };
    Index testValueCount = 2;
    Index test_I;
    float testValue;

    Variable* var;
    Variable* vec;
    Variable* vecVar[3];

    int i, j;

    array = Memory_Alloc_Array( float, length, "test" );
    structArray = Memory_Alloc_Array( Triple, length, "test" );

    var = Variable_NewScalar( "Float-Scalar", NULL, Variable_DataType_Float, &length, NULL, (void**)&array, data->vr );
    vec = Variable_NewVector( "Float-Three", NULL, Variable_DataType_Float, 3, &length, NULL, (void**)&structArray, data->vr, "a", "b", "c" );

    vecVar[0] = Variable_Register_GetByName( data->vr, "a" );
    vecVar[1] = Variable_Register_GetByName( data->vr, "b" );
    vecVar[2] = Variable_Register_GetByName( data->vr, "c" );

    Variable_Register_BuildAll( data->vr );

    for ( test_I = 0; test_I < testValueCount; ++test_I ) {
        testValue = testValues[test_I];

        for ( i = 0; i < length; ++i ) {
            Variable_SetValueFloat( var, i, testValue );

            Variable_SetValueAtFloat( vec, i, 0, testValue );
            Variable_SetValueAtFloat( vec, i, 1, testValue );
            Variable_SetValueAtFloat( vec, i, 2, testValue );
        }

        /* "~~~Scalar~~~\n" */
        for ( i = 0; i < length; ++i ) {
            pcu_check_true( Variable_GetValueFloat( var, i ) == (float)(float)testValue );
            pcu_check_true( Variable_GetValueFloatAsChar( var, i ) == (float)(char)testValue );
            pcu_check_true( Variable_GetValueFloatAsShort( var, i ) == (float)(short)testValue );
            pcu_check_true( Variable_GetValueFloatAsInt( var, i ) == (float)(int)testValue );
            pcu_check_true( Variable_GetValueFloatAsDouble( var, i ) == (double)(float)testValue );
        }

        /*~~~Vector~~~*/
        for ( i = 0; i < length; ++i ) {
            pcu_check_true( Variable_GetValueAtFloat( vec, i, 0 ) == (float)(float)testValue );
            pcu_check_true( Variable_GetValueAtFloatAsChar( vec, i, 0 ) == (char)(float)testValue );
            pcu_check_true( Variable_GetValueAtFloatAsShort( vec, i, 0 ) == (short)(float)testValue );
            pcu_check_true( Variable_GetValueAtFloatAsInt( vec, i, 0 ) == (int)(float)testValue );
            pcu_check_true( Variable_GetValueAtFloatAsDouble( vec, i, 0 ) == (double)(float)testValue );
            pcu_check_true( Variable_GetPtrAtFloat( vec, i, 0 ) == &structArray[i][0] );

            pcu_check_true( Variable_GetValueAtFloat( vec, i, 1 ) == (float)(float)testValue );
            pcu_check_true( Variable_GetValueAtFloatAsChar( vec, i, 1 ) == (char)(float)testValue );
            pcu_check_true( Variable_GetValueAtFloatAsShort( vec, i, 1 ) == (short)(float)testValue );
            pcu_check_true( Variable_GetValueAtFloatAsInt( vec, i, 1 ) == (int)(float)testValue );
            pcu_check_true( Variable_GetValueAtFloatAsDouble( vec, i, 1 ) == (double)(float)testValue );
            pcu_check_true( Variable_GetPtrAtFloat( vec, i, 1 ) == &structArray[i][1] );

            pcu_check_true( Variable_GetValueAtFloat( vec, i, 2 ) == (float)(float)testValue );
            pcu_check_true( Variable_GetValueAtFloatAsChar( vec, i, 2 ) == (char)(float)testValue );
            pcu_check_true( Variable_GetValueAtFloatAsShort( vec, i, 2 ) == (short)(float)testValue );
            pcu_check_true( Variable_GetValueAtFloatAsInt( vec, i, 2 ) == (int)(float)testValue );
            pcu_check_true( Variable_GetValueAtFloatAsDouble( vec, i, 2 ) == (double)(float)testValue );
            pcu_check_true( Variable_GetPtrAtFloat( vec, i, 2 ) == &structArray[i][2] );
        }

        /*~~~Vector: Sub-Variable~~~*/
        for ( i = 0; i < length; ++i ) {
            for ( j = 0; j < 3; ++j ) {
                pcu_check_true( Variable_GetStructPtr( vecVar[j], i ) == &structArray[i][j] );
            }
        }
    }
}