[cig-commits] r3936 - in long/3D/Gale/trunk/src/PICellerator: . Voronoi/src

walter at geodynamics.org walter at geodynamics.org
Thu Jul 6 02:04:14 PDT 2006


Author: walter
Date: 2006-07-06 02:04:14 -0700 (Thu, 06 Jul 2006)
New Revision: 3936

Modified:
   long/3D/Gale/trunk/src/PICellerator/
   long/3D/Gale/trunk/src/PICellerator/Voronoi/src/CellularAutomataVoronoi.c
   long/3D/Gale/trunk/src/PICellerator/Voronoi/src/CellularAutomataVoronoi.h
Log:
 r426 at earth:  boo | 2006-07-06 02:00:49 -0700
  r415 at earth (orig r354):  LukeHodkinson | 2006-07-05 21:40:00 -0700
  Modified some of the Voronoi cell calculations to 
  use the parent domain of regular elements when 
  assigning particles to voronoi cells. Still assumes
  topologically regular elements, but can now handle
  deformation.
  
  When the mesh deforms, I don't think the Vornoi cells
  get updated; that still needs to be tackled.
  
 



Property changes on: long/3D/Gale/trunk/src/PICellerator
___________________________________________________________________
Name: svk:merge
   - 00de75e2-39f1-0310-8538-9683d00a49cc:/trunk:353
aee11096-cf10-0410-a191-eea5772ba81f:/cig:425
   + 00de75e2-39f1-0310-8538-9683d00a49cc:/trunk:354
aee11096-cf10-0410-a191-eea5772ba81f:/cig:426

Modified: long/3D/Gale/trunk/src/PICellerator/Voronoi/src/CellularAutomataVoronoi.c
===================================================================
--- long/3D/Gale/trunk/src/PICellerator/Voronoi/src/CellularAutomataVoronoi.c	2006-07-06 09:04:11 UTC (rev 3935)
+++ long/3D/Gale/trunk/src/PICellerator/Voronoi/src/CellularAutomataVoronoi.c	2006-07-06 09:04:14 UTC (rev 3936)
@@ -68,44 +68,44 @@
 ** Constructors
 */
 CellularAutomataVoronoi* _CellularAutomataVoronoi_New(
-		SizeT                                              _sizeOfSelf, 
-		Type                                               type,
-		Stg_Class_DeleteFunction*                          _delete,
-		Stg_Class_PrintFunction*                           _print,
-		Stg_Class_CopyFunction*                            _copy, 
-		Stg_Component_DefaultConstructorFunction*          _defaultConstructor,
-		Stg_Component_ConstructFunction*                   _construct,
-		Stg_Component_BuildFunction*                       _build,
-		Stg_Component_InitialiseFunction*                  _initialise,
-		Stg_Component_ExecuteFunction*                     _execute,
-		Stg_Component_DestroyFunction*                     _destroy,		
-		DiscreteVoronoi_CalculateForCellFunction*          _calculate,
-		DiscreteVoronoi_GetParticleIndexFunction*          _getParticleIndex,
-		DiscreteVoronoi_GetVolumeFunction*                 _getVolume,
-		DiscreteVoronoi_GetCentroidFunction*               _getCentroid,
-		Name                                               name )
+	SizeT                                              _sizeOfSelf, 
+	Type                                               type,
+	Stg_Class_DeleteFunction*                          _delete,
+	Stg_Class_PrintFunction*                           _print,
+	Stg_Class_CopyFunction*                            _copy, 
+	Stg_Component_DefaultConstructorFunction*          _defaultConstructor,
+	Stg_Component_ConstructFunction*                   _construct,
+	Stg_Component_BuildFunction*                       _build,
+	Stg_Component_InitialiseFunction*                  _initialise,
+	Stg_Component_ExecuteFunction*                     _execute,
+	Stg_Component_DestroyFunction*                     _destroy,		
+	DiscreteVoronoi_CalculateForCellFunction*          _calculate,
+	DiscreteVoronoi_GetParticleIndexFunction*          _getParticleIndex,
+	DiscreteVoronoi_GetVolumeFunction*                 _getVolume,
+	DiscreteVoronoi_GetCentroidFunction*               _getCentroid,
+	Name                                               name )
 {
 	CellularAutomataVoronoi* self;
 	
 	/* Allocate memory */
 	assert( _sizeOfSelf >= sizeof(CellularAutomataVoronoi) );
 	self = (CellularAutomataVoronoi*)_DiscreteVoronoi_New( 
-			_sizeOfSelf,
-			type,
-			_delete,
-			_print,
-			_copy,
-			_defaultConstructor,
-			_construct,
-			_build,
-			_initialise,
-			_execute,
-			_destroy,		
-			_calculate,
-			_getParticleIndex,
-			_getVolume,
-			_getCentroid,
-			name );
+		_sizeOfSelf,
+		type,
+		_delete,
+		_print,
+		_copy,
+		_defaultConstructor,
+		_construct,
+		_build,
+		_initialise,
+		_execute,
+		_destroy,		
+		_calculate,
+		_getParticleIndex,
+		_getVolume,
+		_getCentroid,
+		name );
 
 	
 	/* General info */
@@ -127,6 +127,9 @@
 
 	/* Calculate Total number of cells */
 	self->claimedCellCount = resolution[ I_AXIS ] * resolution[ J_AXIS ] * resolution[ K_AXIS ];
+
+	/* Allocate for the volumes of each cell. */
+	self->cellVolumes = Memory_Alloc_Array( double, self->claimedCellCount, "CellularAutomataVoronoi::cellVolumes" );
 }
 
 
@@ -149,6 +152,7 @@
 	Memory_Free( self->cellList );
 	Memory_Free( self->cellsToGrow.array );
 	Memory_Free( self->cellsToCheck.array );
+	FreeArray( self->cellVolumes );
 	
 	/* Delete parent */
 	_DiscreteVoronoi_Delete( self );
@@ -173,22 +177,22 @@
 
 void* _CellularAutomataVoronoi_DefaultNew( Name name ) {
 	return (void*) _CellularAutomataVoronoi_New(
-			sizeof(CellularAutomataVoronoi),
-			CellularAutomataVoronoi_Type,
-			_CellularAutomataVoronoi_Delete,
-			_CellularAutomataVoronoi_Print,
-			_CellularAutomataVoronoi_Copy,
-			_CellularAutomataVoronoi_DefaultNew,
-			_CellularAutomataVoronoi_Construct,
-			_CellularAutomataVoronoi_Build,
-			_CellularAutomataVoronoi_Initialise,
-			_CellularAutomataVoronoi_Execute,
-			_CellularAutomataVoronoi_Destroy,
-			_CellularAutomataVoronoi_CalculateForCell,
-			_CellularAutomataVoronoi_GetParticleIndex,
-			_CellularAutomataVoronoi_GetVolume,
-			_CellularAutomataVoronoi_GetCentroid,
-			name );
+		sizeof(CellularAutomataVoronoi),
+		CellularAutomataVoronoi_Type,
+		_CellularAutomataVoronoi_Delete,
+		_CellularAutomataVoronoi_Print,
+		_CellularAutomataVoronoi_Copy,
+		_CellularAutomataVoronoi_DefaultNew,
+		_CellularAutomataVoronoi_Construct,
+		_CellularAutomataVoronoi_Build,
+		_CellularAutomataVoronoi_Initialise,
+		_CellularAutomataVoronoi_Execute,
+		_CellularAutomataVoronoi_Destroy,
+		_CellularAutomataVoronoi_CalculateForCell,
+		_CellularAutomataVoronoi_GetParticleIndex,
+		_CellularAutomataVoronoi_GetVolume,
+		_CellularAutomataVoronoi_GetCentroid,
+		name );
 }
 
 
@@ -205,9 +209,9 @@
 	resolution[ K_AXIS ] = Stg_ComponentFactory_GetUnsignedInt( cf, self->name, "resolutionZ", defaultResolution );
 	
 	_CellularAutomataVoronoi_Init( 
-			self, 
-			resolution, 
-			Stg_ComponentFactory_GetBool( cf, self->name, "diagonalNeighbours", True ) );
+		self, 
+		resolution, 
+		Stg_ComponentFactory_GetBool( cf, self->name, "diagonalNeighbours", True ) );
 }
 
 void _CellularAutomataVoronoi_Build( void* cellularAutomataVoronoi, void* data ) {
@@ -257,7 +261,7 @@
 									continue;
 
 								CellularAutomataVoronoi_AddNeighbourToCell( self, cell, 
-										vIJK[I_AXIS]+add[I_AXIS], vIJK[J_AXIS]+add[J_AXIS], vIJK[K_AXIS]+add[K_AXIS]);
+													    vIJK[I_AXIS]+add[I_AXIS], vIJK[J_AXIS]+add[J_AXIS], vIJK[K_AXIS]+add[K_AXIS]);
 							}
 						}
 					}
@@ -313,7 +317,7 @@
 double _CellularAutomataVoronoi_GetVolume(void* discreteVoronoi, Voronoi_CellIndex vCell_I ){
 	CellularAutomataVoronoi*             self            = (CellularAutomataVoronoi*)  discreteVoronoi;
 
-	return self->cellVolume;
+	return self->cellVolumes[vCell_I];
 }
 
 void _CellularAutomataVoronoi_GetCentroid(void* discreteVoronoi, Voronoi_CellIndex vCell_I, Coord centroid ){
@@ -407,10 +411,10 @@
 
 
 Particle_InCellIndex CellularAutomataVoronoi_Battle( 
-		void*                                              cellularAutomataVoronoi, 
-		CellularAutomataVoronoiCell*                       cell, 
-		Particle_InCellIndex                               champion_I, 
-		Particle_InCellIndex                               contender_I )
+	void*                                              cellularAutomataVoronoi, 
+	CellularAutomataVoronoiCell*                       cell, 
+	Particle_InCellIndex                               champion_I, 
+	Particle_InCellIndex                               contender_I )
 {
 	CellularAutomataVoronoi*  self            = (CellularAutomataVoronoi*)  cellularAutomataVoronoi;
 	double*                   cellCentroid;
@@ -432,7 +436,7 @@
 	for ( battle_I = 0 ; battle_I < battleCount ; battle_I++ ) {
 		battlePair = cell->battleHistory.battlePair[battle_I];
 		if (       ( champion_I == battlePair[LOSER ] && contender_I == battlePair[VICTOR] )
-		        || ( champion_I == battlePair[VICTOR] && contender_I == battlePair[LOSER ] ) )
+			   || ( champion_I == battlePair[VICTOR] && contender_I == battlePair[LOSER ] ) )
 			return battlePair[VICTOR];
 	}
 	
@@ -450,17 +454,17 @@
 	else {
 		/* LocalCoordSystem need to convert to global */
 		FiniteElement_Mesh_CalcGlobalCoordFromLocalCoord(
-						mesh,
-						swarm->dim,
-						lCell_I,
-						((LocalParticle*)champion)->xi,
-						championCoord );
+			mesh,
+			swarm->dim,
+			lCell_I,
+			((LocalParticle*)champion)->xi,
+			championCoord );
 		FiniteElement_Mesh_CalcGlobalCoordFromLocalCoord(
-						mesh,
-						swarm->dim,
-						lCell_I,
-						((LocalParticle*)contender)->xi,
-						contenderCoord );
+			mesh,
+			swarm->dim,
+			lCell_I,
+			((LocalParticle*)contender)->xi,
+			contenderCoord );
 	}
 						
 
@@ -511,16 +515,11 @@
 	Dimension_Index                      dim_I;
 	Dimension_Index                      dim = self->dim;
 	Index*                               resolution      = self->resolution;
-	double*                              startCoord      = (double*)swarm->cellPointTbl[lCell_I][0];
-	double*                              endCoord        = (double*)swarm->cellPointTbl[lCell_I][ dim == 2 ? 2 : 6 ];
 	IJK                                  ijk_I;
 
-	/* Find spacing of sub-cells */
-	self->cellVolume = 1.0;
-	for ( dim_I = 0 ; dim_I < dim ; dim_I++ ) {
-		self->dx[ dim_I ] = (endCoord[ dim_I ] - startCoord[ dim_I ])/((double) resolution[ dim_I ]);
-		self->cellVolume *= self->dx[ dim_I ];
-	}
+	/* Find spacing of sub-cells in the parent domain. */
+	for ( dim_I = 0 ; dim_I < dim ; dim_I++ )
+		self->dx[ dim_I ] = 2.0 / ((double) resolution[ dim_I ]);
 
 	/* Update 'Current' info */
 	self->swarm   = swarm;
@@ -538,12 +537,10 @@
 		cell->claimedParticle = CELLULAR_AUTOMATA_UNCLAIMED;
 		cell->particleToCheck = NO_CHECK;
 		cell->battleHistory.battleCount = 0;
+	}
 
-		/* Set up centroid */
-		for ( dim_I = 0 ; dim_I < dim ; dim_I++ ) {
-			cell->centroid[ dim_I ] = startCoord[ dim_I ] + ( ijk_I[ dim_I ] + 0.5 ) * self->dx[ dim_I ];
-		}
-	}
+	/* Calculate the volume and centroid of each sub-cell. */
+	CellularAutomataVoronoi_CalcSubCells( self, swarm, lCell_I );
 }
 
 void CellularAutomataVoronoi_AddNeighbourToCell( void* cellularAutomataVoronoi, CellularAutomataVoronoiCell* cell, Index iIndex, Index jIndex, Index kIndex ) {
@@ -579,10 +576,8 @@
 	Dimension_Index                      dim               = self->dim;
 	Dimension_Index                      dim_I;
 	Index*                               resolution        = self->resolution;
-	double*                              startCoord        = (double*)swarm->cellPointTbl[lCell_I][0];
-
 	FiniteElement_Mesh*                  mesh;
-	Coord                                globalCoord;
+	Coord                                localCoord;
 
 	mesh                = (FiniteElement_Mesh*)(((ElementCellLayout*)swarm->cellLayout)->mesh); /* Assume ElementCellLayout */
 
@@ -591,21 +586,20 @@
 		particle = Swarm_ParticleInCellAt( swarm, lCell_I, cParticle_I );
 
 		if ( swarm->particleLayout->coordSystem == GlobalCoordSystem ) {
-			memcpy( globalCoord, ((GlobalParticle*)particle)->coord, sizeof(Coord) );
+			/* Must convert global to local. */
+			FiniteElement_Mesh_CalcLocalCoordFromGlobalCoord( mesh, 
+									  lCell_I, 
+									  ((GlobalParticle*)particle)->coord, 
+									  localCoord );
 		}
 		else {
-			/* LocalCoordSystem need to convert to global */
-			FiniteElement_Mesh_CalcGlobalCoordFromLocalCoord(
-							mesh,
-							swarm->dim,
-							lCell_I,
-							((LocalParticle*)particle)->xi,
-							globalCoord );
+			/* Now we need to coordinate in locals. */
+			memcpy( localCoord, ((LocalParticle*)particle)->xi, sizeof(Coord) );
 		}
 
 		/* Find which discrete voronoi cell this particle is in */
 		for ( dim_I = 0 ; dim_I < dim ; dim_I++ ) {
-			vCell_IJK[ dim_I ] = (Index) ((globalCoord[ dim_I ] - startCoord[ dim_I ])/self->dx[ dim_I ]);
+			vCell_IJK[ dim_I ] = (Index)((localCoord[dim_I] + 1.0) / self->dx[dim_I]);
 			
 			/* Check if particle is right on edge of element */
 			if ( vCell_IJK[ dim_I ] == resolution[ dim_I ] )
@@ -707,4 +701,247 @@
 	cellList->cellCount++;
 }
 
+void CellularAutomataVoronoi_CalcSubCells( CellularAutomataVoronoi* self, Swarm* swarm, unsigned cellInd ) {
+	/* Sanity check. */
+	assert( self );
+	assert( swarm );
 
+	if( self->dim == 2 )
+		CellularAutomataVoronoi_CalcSubCells2D( self, swarm, cellInd );
+	else
+		CellularAutomataVoronoi_CalcSubCells3D( self, swarm, cellInd );
+}
+
+void CellularAutomataVoronoi_CalcSubCells2D( CellularAutomataVoronoi* self, Swarm* swarm, unsigned cellInd ) {
+	FiniteElement_Mesh*	mesh;
+	unsigned		nSubCells;
+	unsigned*		res;
+	double**		gCrds;
+	double**		lCrds;
+	unsigned		d_i, d_j;
+
+	/* Sanity check. */
+	assert( self );
+	assert( swarm );
+
+	/* Shortcuts. */
+	nSubCells = self->claimedCellCount;
+	res = self->resolution;
+	mesh = (FiniteElement_Mesh*)(((ElementCellLayout*)swarm->cellLayout)->mesh);
+
+	/* NOTE: It is assumed in an earlier function that the cell layout is based on the
+	   mesh's elements; I continue that assumption here. */
+
+	/* Need space for the coordinates that comprise this sub-cell. */
+	gCrds = Memory_Alloc_2DArray( double, 4, 2, "" );
+	lCrds = Memory_Alloc_2DArray( double, 4, 2, "" );
+
+	/* Calculate the volume of each cell. */
+	for( d_j = 0; d_j < res[1]; d_j++ ) {
+		lCrds[0][1] = (double)d_j * self->dx[1] - 1.0;
+		lCrds[1][1] = (double)d_j * self->dx[1] - 1.0;
+		lCrds[2][1] = (double)(d_j + 1) * self->dx[1] - 1.0;
+		lCrds[3][1] = (double)(d_j + 1) * self->dx[1] - 1.0;
+
+		for( d_i = 0; d_i < res[0]; d_i++ ) {
+			unsigned	subCellInd = d_j * res[0] + d_i;
+			unsigned	c_i;
+
+			lCrds[0][0] = (double)d_i * self->dx[0] - 1.0;
+			lCrds[1][0] = (double)(d_i + 1) * self->dx[0] - 1.0;
+			lCrds[2][0] = (double)d_i * self->dx[0] - 1.0;
+			lCrds[3][0] = (double)(d_i + 1) * self->dx[0] - 1.0;
+
+			/* Map the local coordinates back to globals. */
+			for( c_i = 0; c_i < 4; c_i++ ) {
+				FiniteElement_Mesh_CalcGlobalCoordFromLocalCoord( mesh, 
+										  self->dim, 
+										  cellInd, 
+										  lCrds[c_i], 
+										  gCrds[c_i] );
+			}
+
+			/* Calculate the volume. */
+			self->cellVolumes[subCellInd] = CellularAutomataVoronoi_QuadArea( self, gCrds );
+
+			/* Calculate centroid. */
+			CellularAutomataVoronoi_QuadCentroid( self, gCrds, self->cellList[subCellInd].centroid );
+		}
+	}
+
+	/* Free memory. */
+	FreeArray( gCrds );
+	FreeArray( lCrds );
+}
+
+void CellularAutomataVoronoi_CalcSubCells3D( CellularAutomataVoronoi* self, Swarm* swarm, unsigned cellInd ) {
+	const double		volWeight = 8.0;
+	const double		sign[3][8] = {{-1, 1, -1, 1, -1, 1, -1, 1}, 
+					      {-1, -1, 1, 1, -1, -1, 1, 1}, 
+					      {-1, -1, -1, -1, 1, 1, 1, 1}};
+	FiniteElement_Mesh*	mesh;
+	unsigned		nSubCells;
+	unsigned*		res;
+	double**		gCrds;
+	double**		lCrds;
+	Coord*			gCrdPtrs[8];
+	ElementType*		elType;
+	unsigned		d_i, d_j, d_k;
+
+	/* Sanity check. */
+	assert( self );
+	assert( swarm );
+
+	/* Shortcuts. */
+	nSubCells = self->claimedCellCount;
+	res = self->resolution;
+	mesh = (FiniteElement_Mesh*)(((ElementCellLayout*)swarm->cellLayout)->mesh);
+	elType = FiniteElement_Mesh_ElementTypeAt( mesh, cellInd );
+
+	/* NOTE: It is assumed in an earlier function that the cell layout is based on the
+	   mesh's elements; I continue that assumption here. */
+
+	/* Need space for the coordinates that comprise this sub-cell. */
+	gCrds = Memory_Alloc_2DArray( double, 8, 3, "" );
+	lCrds = Memory_Alloc_2DArray( double, 8, 3, "" );
+
+	/* Calculate the volume of each cell. */
+	for( d_k = 0; d_k < res[2]; d_k++ ) {
+		lCrds[0][2] = (double)d_k * self->dx[2] - 1.0;
+		lCrds[1][2] = (double)d_k * self->dx[2] - 1.0;
+		lCrds[2][2] = (double)d_k * self->dx[2] - 1.0;
+		lCrds[3][2] = (double)d_k * self->dx[2] - 1.0;
+		lCrds[4][2] = (double)(d_k + 1) * self->dx[2] - 1.0;
+		lCrds[5][2] = (double)(d_k + 1) * self->dx[2] - 1.0;
+		lCrds[6][2] = (double)(d_k + 1) * self->dx[2] - 1.0;
+		lCrds[7][2] = (double)(d_k + 1) * self->dx[2] - 1.0;
+
+		for( d_j = 0; d_j < res[1]; d_j++ ) {
+			lCrds[0][1] = (double)d_j * self->dx[1] - 1.0;
+			lCrds[1][1] = (double)d_j * self->dx[1] - 1.0;
+			lCrds[2][1] = (double)(d_j + 1) * self->dx[1] - 1.0;
+			lCrds[3][1] = (double)(d_j + 1) * self->dx[1] - 1.0;
+			lCrds[4][1] = (double)d_j * self->dx[1] - 1.0;
+			lCrds[5][1] = (double)d_j * self->dx[1] - 1.0;
+			lCrds[6][1] = (double)(d_j + 1) * self->dx[1] - 1.0;
+			lCrds[7][1] = (double)(d_j + 1) * self->dx[1] - 1.0;
+
+			for( d_i = 0; d_i < res[0]; d_i++ ) {
+				unsigned	subCellInd = d_k * res[0] * res[1] + d_j * res[0] + d_i;
+				double		jac[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
+				double		jacDet;
+				unsigned	c_i;
+
+				/* Calculate the local coordinates. */
+				lCrds[0][0] = (double)d_i * self->dx[0] - 1.0;
+				lCrds[1][0] = (double)(d_i + 1) * self->dx[0] - 1.0;
+				lCrds[2][0] = (double)d_i * self->dx[0] - 1.0;
+				lCrds[3][0] = (double)(d_i + 1) * self->dx[0] - 1.0;
+				lCrds[4][0] = (double)d_i * self->dx[0] - 1.0;
+				lCrds[5][0] = (double)(d_i + 1) * self->dx[0] - 1.0;
+				lCrds[6][0] = (double)d_i * self->dx[0] - 1.0;
+				lCrds[7][0] = (double)(d_i + 1) * self->dx[0] - 1.0;
+
+				/* Map the local coordinates back to globals. */
+				for( c_i = 0; c_i < 8; c_i++ ) {
+					/* Build a list of global coordinate pointers. */
+					gCrdPtrs[c_i] = (Coord*)(gCrds + c_i);
+
+					/* Convert to local coordinates. */
+					FiniteElement_Mesh_CalcGlobalCoordFromLocalCoord( mesh, 
+											  self->dim, 
+											  cellInd, 
+											  lCrds[c_i], 
+											  gCrds[c_i] );
+
+					/* Calculate the jacobian. */
+					jac[0][0] += 0.125 * sign[0][c_i] * gCrds[c_i][0];
+					jac[1][0] += 0.125 * sign[1][c_i] * gCrds[c_i][0];
+					jac[2][0] += 0.125 * sign[2][c_i] * gCrds[c_i][0];
+					jac[0][1] += 0.125 * sign[0][c_i] * gCrds[c_i][1];
+					jac[1][1] += 0.125 * sign[1][c_i] * gCrds[c_i][1];
+					jac[2][1] += 0.125 * sign[2][c_i] * gCrds[c_i][1];
+					jac[0][2] += 0.125 * sign[0][c_i] * gCrds[c_i][2];
+					jac[1][2] += 0.125 * sign[1][c_i] * gCrds[c_i][2];
+					jac[2][2] += 0.125 * sign[2][c_i] * gCrds[c_i][2];
+				}
+
+				/* Calculate centroid. */
+				CellularAutomataVoronoi_HexCentroid( self, gCrds, self->cellList[subCellInd].centroid );
+
+				/* Calculate the volume. Doing this for irregular hexahedron is a little tricky. */
+				jacDet = jac[0][0] * (jac[1][1] * jac[2][2] - jac[2][1] * jac[1][2]) - 
+					jac[1][0] * (jac[0][1] * jac[2][2] - jac[2][1] * jac[0][2]) + 
+					jac[2][0] * (jac[0][1] * jac[1][2] - jac[1][1] * jac[0][2]);
+				self->cellVolumes[subCellInd] = volWeight * jacDet;
+			}
+		}
+	}
+
+	/* Free memory. */
+	FreeArray( gCrds );
+	FreeArray( lCrds );
+}
+
+double CellularAutomataVoronoi_QuadArea( CellularAutomataVoronoi* self, double** gCrds ) {
+	double	area;
+	double	vecs[4][2];
+	double	diags[2][2];
+
+	/* Sanity check. */
+	assert( self );
+	assert( gCrds );
+
+	vecs[0][0] = gCrds[1][0] - gCrds[0][0];	vecs[0][1] = gCrds[1][1] - gCrds[0][1];
+	vecs[1][0] = gCrds[3][0] - gCrds[1][0];	vecs[1][1] = gCrds[3][1] - gCrds[1][1];
+	vecs[2][0] = gCrds[2][0] - gCrds[3][0];	vecs[2][1] = gCrds[2][1] - gCrds[3][1];
+	vecs[3][0] = gCrds[0][0] - gCrds[2][0];	vecs[3][1] = gCrds[0][1] - gCrds[2][1];
+
+	diags[0][0] = vecs[0][0] + vecs[1][0];	diags[0][1] = vecs[0][1] + vecs[1][1];
+	diags[1][0] = vecs[1][0] + vecs[2][0];	diags[1][1] = vecs[1][1] + vecs[2][1];
+
+	/* Calculate the area from the diagonals. */
+	area = diags[0][0] * diags[1][1] - diags[0][1] * diags[1][0];
+	area *= (area < 0.0) ? -0.5 : 0.5;
+
+	return area;
+}
+
+void CellularAutomataVoronoi_QuadCentroid( CellularAutomataVoronoi* self, double** gCrds, Coord centroid ) {
+	unsigned	c_i;
+
+	/* Sanity check. */
+	assert( self );
+	assert( gCrds );
+
+	/* The centroid of a convex quadrilateral is the average of it's corners. */
+	centroid[0] = gCrds[0][0];
+	centroid[1] = gCrds[0][1];
+	for( c_i = 1; c_i < 4; c_i++ ) {
+		centroid[0] += gCrds[c_i][0];
+		centroid[1] += gCrds[c_i][1];
+	}
+	centroid[0] *= 0.25;
+	centroid[1] *= 0.25;
+}
+
+void CellularAutomataVoronoi_HexCentroid( CellularAutomataVoronoi* self, double** gCrds, Coord centroid ) {
+	unsigned	c_i;
+
+	/* Sanity check. */
+	assert( self );
+	assert( gCrds );
+
+	/* The centroid of a convex hexahedron is the average of it's corners. */
+	centroid[0] = gCrds[0][0];
+	centroid[1] = gCrds[0][1];
+	centroid[2] = gCrds[0][2];
+	for( c_i = 1; c_i < 8; c_i++ ) {
+		centroid[0] += gCrds[c_i][0];
+		centroid[1] += gCrds[c_i][1];
+		centroid[2] += gCrds[c_i][2];
+	}
+	centroid[0] *= 0.125;
+	centroid[1] *= 0.125;
+	centroid[2] *= 0.125;
+}

Modified: long/3D/Gale/trunk/src/PICellerator/Voronoi/src/CellularAutomataVoronoi.h
===================================================================
--- long/3D/Gale/trunk/src/PICellerator/Voronoi/src/CellularAutomataVoronoi.h	2006-07-06 09:04:11 UTC (rev 3935)
+++ long/3D/Gale/trunk/src/PICellerator/Voronoi/src/CellularAutomataVoronoi.h	2006-07-06 09:04:14 UTC (rev 3936)
@@ -94,7 +94,7 @@
 		Bool                                               diagonalNeighbours;     \
 		CellularAutomataVoronoiCell*                       cellList;               \
 		XYZ                                                dx;                     \
-		double                                             cellVolume;             \
+		double*                                            cellVolumes;            \
 		CellularAutomataVoronoiCellList                    cellsToGrow;            \
 		CellularAutomataVoronoiCellList                    cellsToCheck;           \
 		/* Current Info */ \
@@ -163,5 +163,12 @@
 
 	void CellularAutomataVoronoiCellList_Build( CellularAutomataVoronoiCellList* cellList ) ;
 	void CellularAutomataVoronoiCellList_AddCell( CellularAutomataVoronoiCellList* cellList, CellularAutomataVoronoiCell* cell ) ;
+
+	void CellularAutomataVoronoi_CalcSubCells( CellularAutomataVoronoi* self, Swarm* swarm, unsigned cellInd );
+	void CellularAutomataVoronoi_CalcSubCells2D( CellularAutomataVoronoi* self, Swarm* swarm, unsigned cellInd );
+	void CellularAutomataVoronoi_CalcSubCells3D( CellularAutomataVoronoi* self, Swarm* swarm, unsigned cellInd );
+	double CellularAutomataVoronoi_QuadArea( CellularAutomataVoronoi* self, double** gCrds );
+	void CellularAutomataVoronoi_QuadCentroid( CellularAutomataVoronoi* self, double** gCrds, Coord centroid );
+	void CellularAutomataVoronoi_HexCentroid( CellularAutomataVoronoi* self, double** gCrds, Coord centroid );
 	
 #endif 



More information about the cig-commits mailing list