[cig-commits] r6110 - in long/3D/Gale/trunk/src/StgFEM: . SLE/SystemSetup/src

walter at geodynamics.org walter at geodynamics.org
Fri Feb 23 12:21:01 PST 2007


Author: walter
Date: 2007-02-23 12:21:00 -0800 (Fri, 23 Feb 2007)
New Revision: 6110

Modified:
   long/3D/Gale/trunk/src/StgFEM/
   long/3D/Gale/trunk/src/StgFEM/SLE/SystemSetup/src/StiffnessMatrix.c
   long/3D/Gale/trunk/src/StgFEM/SLE/SystemSetup/src/StiffnessMatrix.h
Log:
 r993 at earth (orig r747):  LukeHodkinson | 2007-02-21 15:21:32 -0800
 In my efforts to reduce memory consumption, I found 
 that we were over-estimating the number of nonzeros
 to be allocated in our matrices.  I've modified the
 nonzero calculation algorithm to exactly calculate
 the diagonal and off-diagonal nonzeros, but it is
 a bit slower than the old one.  It is, however, still
 scalable.
 



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

Modified: long/3D/Gale/trunk/src/StgFEM/SLE/SystemSetup/src/StiffnessMatrix.c
===================================================================
--- long/3D/Gale/trunk/src/StgFEM/SLE/SystemSetup/src/StiffnessMatrix.c	2007-02-23 20:20:58 UTC (rev 6109)
+++ long/3D/Gale/trunk/src/StgFEM/SLE/SystemSetup/src/StiffnessMatrix.c	2007-02-23 20:21:00 UTC (rev 6110)
@@ -83,7 +83,7 @@
 		_StiffnessMatrix_Destroy,
 		name,
 		False,
-		_StiffnessMatrix_CalculateNonZeroEntries,
+		StiffnessMatrix_CalcNonZeros,
 		NULL, 
 		NULL, 
 		NULL, 
@@ -97,16 +97,16 @@
 
 
 StiffnessMatrix* StiffnessMatrix_New(
-		Name                                             name,
-		void*                                            rowVariable,
-		void*                                            columnVariable,
-		void*                                            rhs,
-		Stg_Component*                                   applicationDepInfo,
-		Dimension_Index                                  dim,
-		Bool                                             isNonLinear,
-		Bool                                             allowZeroElementContributions,
-		void*                                            entryPoint_Register,
-		MPI_Comm                                         comm )
+	Name                                             name,
+	void*                                            rowVariable,
+	void*                                            columnVariable,
+	void*                                            rhs,
+	Stg_Component*                                   applicationDepInfo,
+	Dimension_Index                                  dim,
+	Bool                                             isNonLinear,
+	Bool                                             allowZeroElementContributions,
+	void*                                            entryPoint_Register,
+	MPI_Comm                                         comm )
 {
 	return _StiffnessMatrix_New( 
 		sizeof(StiffnessMatrix), 
@@ -122,7 +122,7 @@
 		_StiffnessMatrix_Destroy,
 		name, 
 		True,
-		_StiffnessMatrix_CalculateNonZeroEntries,
+		StiffnessMatrix_CalcNonZeros,
 		rowVariable, 
 		columnVariable, 
 		rhs,
@@ -136,48 +136,48 @@
 
 
 StiffnessMatrix* _StiffnessMatrix_New(
-		SizeT                                            _sizeOfSelf,
-		Type                                             type,
-		Stg_Class_DeleteFunction*                        _delete,
-		Stg_Class_PrintFunction*                         _print,
-		Stg_Class_CopyFunction*                          _copy, 
-		Stg_Component_DefaultConstructorFunction*        _defaultConstructor,
-		Stg_Component_ConstructFunction*                 _construct,
-		Stg_Component_BuildFunction*                     _build,
-		Stg_Component_InitialiseFunction*                _initialise,
-		Stg_Component_ExecuteFunction*                   _execute,
-		Stg_Component_DestroyFunction*                   _destroy,
-		Name                                             name,
-		Bool                                             initFlag,
-		StiffnessMatrix_CalculateNonZeroEntriesFunction* _calculateNonZeroEntries,
-		void*                                            rowVariable,
-		void*                                            columnVariable,
-		void*                                            rhs,
-		Stg_Component*                                   applicationDepInfo,
-		Dimension_Index                                  dim,
-		Bool                                             isNonLinear,
-		Bool                                             allowZeroElementContributions,
-		void*                                            entryPoint_Register,
-		MPI_Comm                                         comm )
+	SizeT                                            _sizeOfSelf,
+	Type                                             type,
+	Stg_Class_DeleteFunction*                        _delete,
+	Stg_Class_PrintFunction*                         _print,
+	Stg_Class_CopyFunction*                          _copy, 
+	Stg_Component_DefaultConstructorFunction*        _defaultConstructor,
+	Stg_Component_ConstructFunction*                 _construct,
+	Stg_Component_BuildFunction*                     _build,
+	Stg_Component_InitialiseFunction*                _initialise,
+	Stg_Component_ExecuteFunction*                   _execute,
+	Stg_Component_DestroyFunction*                   _destroy,
+	Name                                             name,
+	Bool                                             initFlag,
+	StiffnessMatrix_CalculateNonZeroEntriesFunction* _calculateNonZeroEntries,
+	void*                                            rowVariable,
+	void*                                            columnVariable,
+	void*                                            rhs,
+	Stg_Component*                                   applicationDepInfo,
+	Dimension_Index                                  dim,
+	Bool                                             isNonLinear,
+	Bool                                             allowZeroElementContributions,
+	void*                                            entryPoint_Register,
+	MPI_Comm                                         comm )
 {
 	StiffnessMatrix*	self;
 	
 	/* Allocate memory */
 	assert( _sizeOfSelf >= sizeof(StiffnessMatrix) );
 	self = (StiffnessMatrix*)_Stg_Component_New(
-			_sizeOfSelf,
-			type,
-			_delete,
-			_print,
-			_copy,
-			_defaultConstructor,
-			_construct,
-			_build,
-			_initialise,
-			_execute,
-			_destroy, 
-			name, 
-			NON_GLOBAL );
+		_sizeOfSelf,
+		type,
+		_delete,
+		_print,
+		_copy,
+		_defaultConstructor,
+		_construct,
+		_build,
+		_initialise,
+		_execute,
+		_destroy, 
+		name, 
+		NON_GLOBAL );
 	
 	/* General info */
 	
@@ -186,39 +186,42 @@
 	
 	if( initFlag ){
 		_StiffnessMatrix_Init( self, rowVariable, columnVariable, rhs, applicationDepInfo, dim,
-		isNonLinear, allowZeroElementContributions, entryPoint_Register, comm );
+				       isNonLinear, allowZeroElementContributions, entryPoint_Register, comm );
 	}
 	
 	return self;
 }
 
 void _StiffnessMatrix_Init(
-		StiffnessMatrix*                                 self,
-		void*                                            rowVariable,
-		void*                                            columnVariable,
-		void*                                            rhs,
-		Stg_Component*                                   applicationDepInfo,
-		Dimension_Index                                  dim,
-		Bool                                             isNonLinear,
-		Bool                                             allowZeroElementContributions,
-		void*                                            entryPoint_Register,
-		MPI_Comm                                         comm )
+	StiffnessMatrix*                                 self,
+	void*                                            rowVariable,
+	void*                                            columnVariable,
+	void*                                            rhs,
+	Stg_Component*                                   applicationDepInfo,
+	Dimension_Index                                  dim,
+	Bool                                             isNonLinear,
+	Bool                                             allowZeroElementContributions,
+	void*                                            entryPoint_Register,
+	MPI_Comm                                         comm )
 {
 	Stream*		error = Journal_Register( ErrorStream_Type, self->type );
+	Stream*		stream;
 	
 	/* General and Virtual info should already be set */
+	stream = Journal_Register( Info_Type, self->type );
+	Stream_SetPrintingRank( stream, 0 );
 	
 	/* StiffnessMatrix info */
 	self->isConstructed = True;
 	self->debug = Stream_RegisterChild( StgFEM_SLE_SystemSetup_Debug, self->type );
 	Journal_Firewall( (rowVariable != NULL), error, "Error: NULL row FeVariable provided to \"%s\" %s.\n",
-		self->name, self->type );
+			  self->name, self->type );
 	self->rowVariable = (FeVariable*)rowVariable;
 	Journal_Firewall( (columnVariable != NULL), error, "Error: NULL column FeVariable provided to \"%s\" %s.\n",
-		self->name, self->type );
+			  self->name, self->type );
 	self->columnVariable = (FeVariable*)columnVariable;
 	Journal_Firewall( (rhs != NULL), error, "Error: NULL rhs ForceVector provided to \"%s\" %s.\n",
-		self->name, self->type );
+			  self->name, self->type );
 	self->rhs = (ForceVector*)rhs;
 	self->applicationDepInfo = applicationDepInfo;
 	self->comm = comm;
@@ -238,7 +241,7 @@
 
 	Stg_asprintf( &self->_assembleStiffnessMatrixEPName, "%s-%s", self->name, StiffnessMatrix_assembleStiffnessMatrixStr );
 	self->assembleStiffnessMatrix = FeEntryPoint_New( self->_assembleStiffnessMatrixEPName,
-		FeEntryPoint_AssembleStiffnessMatrix_CastType );
+							  FeEntryPoint_AssembleStiffnessMatrix_CastType );
 	EntryPoint_Register_Add( self->entryPoint_Register, self->assembleStiffnessMatrix );
 
 	self->stiffnessMatrixTermList = Stg_ObjectList_New();
@@ -293,7 +296,7 @@
 	Journal_Printf( stiffnessMatrixStream, "\tnonZeroCount: %u\n", self->nonZeroCount );
 	Journal_Printf( stiffnessMatrixStream, "\tisNonLinear: %s\n", StG_BoolToStringMap[self->isNonLinear] );
 	Journal_Printf( stiffnessMatrixStream, "\tallowZeroElementContributions: %s\n",
-		StG_BoolToStringMap[self->allowZeroElementContributions] );
+			StG_BoolToStringMap[self->allowZeroElementContributions] );
 }
 
 
@@ -334,7 +337,7 @@
 		if( self->_assembleStiffnessMatrixEPName ) {
 			if( nameExt ) {
 				Stg_asprintf( &newStiffnessMatrix->_assembleStiffnessMatrixEPName, "%s%s", 
-						self->_assembleStiffnessMatrixEPName, nameExt );
+					      self->_assembleStiffnessMatrixEPName, nameExt );
 			}
 			else {
 				newStiffnessMatrix->_assembleStiffnessMatrixEPName = StG_Strdup( self->_assembleStiffnessMatrixEPName );
@@ -348,7 +351,7 @@
 		if( (newStiffnessMatrix->diagonalNonZeroIndices = PtrMap_Find( map, self->diagonalNonZeroIndices )) == NULL ) {
 			if( self->diagonalNonZeroIndices ) {
 				newStiffnessMatrix->diagonalNonZeroIndices = Memory_Alloc_Array( Index, 
-					newStiffnessMatrix->rowLocalSize, "diagonalNonZeroIndices" );
+												 newStiffnessMatrix->rowLocalSize, "diagonalNonZeroIndices" );
 				memcpy( newStiffnessMatrix->diagonalNonZeroIndices, self->diagonalNonZeroIndices, 
 					newStiffnessMatrix->rowLocalSize * sizeof( Index ) );
 				PtrMap_Append( map, self->diagonalNonZeroIndices, newStiffnessMatrix->diagonalNonZeroIndices );
@@ -361,7 +364,7 @@
 		if( (newStiffnessMatrix->offDiagonalNonZeroIndices = PtrMap_Find( map, self->offDiagonalNonZeroIndices )) == NULL ) {
 			if( self->offDiagonalNonZeroIndices ) {
 				newStiffnessMatrix->offDiagonalNonZeroIndices = Memory_Alloc_Array( Index, 
-					newStiffnessMatrix->rowLocalSize, "diagonalNonZeroIndices" );
+												    newStiffnessMatrix->rowLocalSize, "diagonalNonZeroIndices" );
 				memcpy( newStiffnessMatrix->offDiagonalNonZeroIndices, self->offDiagonalNonZeroIndices, 
 					newStiffnessMatrix->rowLocalSize * sizeof( Index ) );
 				PtrMap_Append( map, self->offDiagonalNonZeroIndices, newStiffnessMatrix->offDiagonalNonZeroIndices );
@@ -415,16 +418,16 @@
 	allowZeroElementContributions = Stg_ComponentFactory_GetBool( cf, self->name, "allowZeroElementContributions", True );
 
 	_StiffnessMatrix_Init( 
-			self, 
-			rowVar, 
-			colVar, 
-			fVector, 
-			applicationDepInfo, 
-			dim,
-			isNonLinear,
-			allowZeroElementContributions,
-			entryPointRegister, 
-			0 );
+		self, 
+		rowVar, 
+		colVar, 
+		fVector, 
+		applicationDepInfo, 
+		dim,
+		isNonLinear,
+		allowZeroElementContributions,
+		entryPointRegister, 
+		0 );
 }
 
 void _StiffnessMatrix_Build( void* stiffnessMatrix, void* data ) {
@@ -448,14 +451,14 @@
 		Build( self->columnVariable, data, False );
 	
 	
-	#if DEBUG
+#if DEBUG
 	if ( Stream_IsPrintableLevel( self->debug, 3 ) ) {
 		Journal_DPrintf( self->debug, "Row variable(%s) I.D. array calc. as:\n", self->rowVariable->name );
 		FeEquationNumber_PrintDestinationArray( self->rowVariable->eqNum, self->debug );
 		Journal_DPrintf( self->debug, "Column variable(%s) I.D. array calc. as:\n", self->columnVariable->name );
 		FeEquationNumber_PrintDestinationArray( self->columnVariable->eqNum, self->debug );
 	}
-	#endif
+#endif
 	
 	/* update the row and column sizes for the variables */	
 	self->rowLocalSize = self->rowVariable->eqNum->localEqNumsOwnedCount;
@@ -467,7 +470,7 @@
 	StiffnessMatrix_CalculateNonZeroEntries( self );
 	
 	Journal_DPrintf( self->debug, "row(%s) localSize = %d : col(%s) localSize = %d \n", self->rowVariable->name,
-		self->rowLocalSize, self->columnVariable->name, self->colLocalSize );
+			 self->rowLocalSize, self->columnVariable->name, self->colLocalSize );
 	
 /* 	assert( self->nonZeroCount ); */
 
@@ -513,9 +516,9 @@
 	Node_LocalIndex		rowNode_lI = 0;
 	Dof_EquationNumber	lowestActiveEqNumAtCurrRowNode = 0;
 	Index			activeEqsAtCurrRowNodeCount = 0;
-	#ifdef DEBUG
-		unsigned int            totalNonZeroEntries = 0;
-	#endif
+#ifdef DEBUG
+	unsigned int            totalNonZeroEntries = 0;
+#endif
 
 	Journal_DPrintf( self->debug, "In %s - for matrix %s\n", __func__, self->name );
 	Stream_IndentBranch( StgFEM_Debug );
@@ -535,41 +538,41 @@
 
 	for( rowNode_lI = 0; rowNode_lI < FeMesh_GetNodeLocalSize( rFeMesh ); rowNode_lI++ ) {
 		activeEqsAtCurrRowNodeCount = FeEquationNumber_CalculateActiveEqCountAtNode( rowEqNum, rowNode_lI,
-			&lowestActiveEqNumAtCurrRowNode );
+											     &lowestActiveEqNumAtCurrRowNode );
 
 		if ( activeEqsAtCurrRowNodeCount > 0 ) {
 			currMatrixRow = lowestActiveEqNumAtCurrRowNode - rowEqNum->firstOwnedEqNum;
 			
 			if ( currMatrixRow >= rowEqNum->localEqNumsOwnedCount ) {
 				Journal_DPrintfL( self->debug, 1, "row node %d - eq nums not owned by this proc -> continue\n",
-					rowNode_lI );
+						  rowNode_lI );
 				continue;
 			}
 			
 			_StiffnessMatrix_CalcAndUpdateNonZeroEntriesAtRowNode( self, rowNode_lI, currMatrixRow,
-				activeEqsAtCurrRowNodeCount );
+									       activeEqsAtCurrRowNodeCount );
 		}
 	}
 
-	#ifdef DEBUG
-		for ( rowNode_lI = 0; rowNode_lI < self->rowLocalSize; rowNode_lI++ ) { 
-			totalNonZeroEntries += self->diagonalNonZeroIndices[rowNode_lI];
-			totalNonZeroEntries += self->offDiagonalNonZeroIndices[rowNode_lI];
-		}	
+#ifdef DEBUG
+	for ( rowNode_lI = 0; rowNode_lI < self->rowLocalSize; rowNode_lI++ ) { 
+		totalNonZeroEntries += self->diagonalNonZeroIndices[rowNode_lI];
+		totalNonZeroEntries += self->offDiagonalNonZeroIndices[rowNode_lI];
+	}	
 
-		Journal_DPrintfL( self->debug, 1, "Calculated %d non-zero entries in Matrix (results in %d bytes storage)\n",
-			totalNonZeroEntries, totalNonZeroEntries * sizeof(double) );
-	#endif	
+	Journal_DPrintfL( self->debug, 1, "Calculated %d non-zero entries in Matrix (results in %d bytes storage)\n",
+			  totalNonZeroEntries, totalNonZeroEntries * sizeof(double) );
+#endif	
 
 	Stream_UnIndentBranch( StgFEM_Debug );
 }
 
 
 void _StiffnessMatrix_CalcAndUpdateNonZeroEntriesAtRowNode(
-		StiffnessMatrix*	self,
-		Node_LocalIndex		rowNode_lI,
-		Dof_EquationNumber	currMatrixRow,
-		Index			activeEqsAtCurrRowNode )
+	StiffnessMatrix*	self,
+	Node_LocalIndex		rowNode_lI,
+	Dof_EquationNumber	currMatrixRow,
+	Index			activeEqsAtCurrRowNode )
 {
 	FeMesh*			rFeMesh = self->rowVariable->feMesh;
 	FeMesh*			cFeMesh = self->columnVariable->feMesh;
@@ -605,13 +608,13 @@
 	}
 	
 	Journal_DPrintfL( self->debug, 3, "Calculated the max possible number of unique related nodes as %d\n",
-		uniqueRelatedColNodes_AllocCount );
+			  uniqueRelatedColNodes_AllocCount );
 	uniqueRelatedColNodes = Memory_Alloc_Array( Node_DomainIndex, uniqueRelatedColNodes_AllocCount, "uniqueRelatedColNodes" );
 
 	_StiffnessMatrix_CalculatedListOfUniqueRelatedColNodes( self, rowNode_lI, uniqueRelatedColNodes, &uniqueRelatedColNodesCount);
 	
 	Journal_DPrintfL( self->debug, 3, "Searching the %d unique related col nodes for active dofs\n",
-		uniqueRelatedColNodesCount );
+			  uniqueRelatedColNodesCount );
 	Stream_Indent( self->debug );
 	for ( uniqueRelatedColNode_I = 0; uniqueRelatedColNode_I < uniqueRelatedColNodesCount; uniqueRelatedColNode_I++ ) {
 		colNode_dI = uniqueRelatedColNodes[uniqueRelatedColNode_I];
@@ -627,7 +630,7 @@
 			}
 			else {
 				if ( (currColEqNum >= colEqNum->firstOwnedEqNum ) && 
-					(currColEqNum <= colEqNum->lastOwnedEqNum ) )
+				     (currColEqNum <= colEqNum->lastOwnedEqNum ) )
 				{
 					Journal_DPrintfL( self->debug, 3, "is diagonal (eq %d)\n", currColEqNum );
 					countTableToAdjust = self->diagonalNonZeroIndices;
@@ -645,21 +648,21 @@
 						 * lowest held on this processor, so we need to check this */
 						if ( currDofMatrixRow >= self->rowLocalSize ) {	
 							Journal_DPrintfL( self->debug, 3, "Found currDofMatRow(=%d) >= self->rowLocalSize(=%d) : for "
-								"rowNode_lI=%d, currMatRow=%d, colNode_dI=%d, colNodeDof_I = %d, "
-								"currNodeDof_I = %d\n", currDofMatrixRow,
-								self->rowLocalSize, rowNode_lI, currMatrixRow,
-								colNode_dI, colNodeDof_I, currNodeDof_I ); 
+									  "rowNode_lI=%d, currMatRow=%d, colNode_dI=%d, colNodeDof_I = %d, "
+									  "currNodeDof_I = %d\n", currDofMatrixRow,
+									  self->rowLocalSize, rowNode_lI, currMatrixRow,
+									  colNode_dI, colNodeDof_I, currNodeDof_I ); 
 						}		
 						else if ( currDofMatrixRow < 0 ) {	
 							Journal_DPrintfL( self->debug, 3, "Found currDofMatRow(=%d) < 0 : for "
-								"rowNode_lI=%d, currMatRow=%d, colNode_dI=%d, colNodeDof_I = %d, "
-								"currNodeDof_I = %d\n", currDofMatrixRow,
-								 rowNode_lI, currMatrixRow,
-								colNode_dI, colNodeDof_I, currNodeDof_I ); 
+									  "rowNode_lI=%d, currMatRow=%d, colNode_dI=%d, colNodeDof_I = %d, "
+									  "currNodeDof_I = %d\n", currDofMatrixRow,
+									  rowNode_lI, currMatrixRow,
+									  colNode_dI, colNodeDof_I, currNodeDof_I ); 
 						}		
 						else {	
 							Journal_DPrintfL( self->debug, 3, "(incrementing app. count at row %d)\n",
-								currDofMatrixRow );
+									  currDofMatrixRow );
 
 							countTableToAdjust[ currDofMatrixRow ] += 1;
 						}
@@ -672,7 +675,7 @@
 	Stream_UnIndent( self->debug );
 
 	Journal_DPrintfL( self->debug, 3, "diagonal count\t%d off diagonal count\t%d\n", 
-			self->diagonalNonZeroIndices[currMatrixRow], self->offDiagonalNonZeroIndices[currMatrixRow]);
+			  self->diagonalNonZeroIndices[currMatrixRow], self->offDiagonalNonZeroIndices[currMatrixRow]);
 
 	Memory_Free( uniqueRelatedColNodes );
 
@@ -683,10 +686,10 @@
 
 
 void _StiffnessMatrix_CalculatedListOfUniqueRelatedColNodes(
-		StiffnessMatrix*	self,
-		Node_LocalIndex		rowNode_lI,
-		Node_DomainIndex*	uniqueRelatedColNodes,
-		Node_Index*		uniqueRelatedColNodesCountPtr )
+	StiffnessMatrix*	self,
+	Node_LocalIndex		rowNode_lI,
+	Node_DomainIndex*	uniqueRelatedColNodes,
+	Node_Index*		uniqueRelatedColNodesCountPtr )
 {
 	FeMesh*			rFeMesh = self->rowVariable->feMesh;
 	FeMesh*			cFeMesh = self->columnVariable->feMesh;
@@ -699,7 +702,7 @@
 
 	FeMesh_GetNodeElements( rFeMesh, rowNode_lI, &nNodeInc, &nodeInc );
 	Journal_DPrintfL( self->debug, 3, "Searching the %d elements this node belongs to for unique related col nodes:\n",
-		nNodeInc );
+			  nNodeInc );
 	
 	Stream_Indent( self->debug );
 	for ( rowNodeElement_I = 0; rowNodeElement_I < nNodeInc; rowNodeElement_I++ ) {
@@ -743,7 +746,7 @@
 	StiffnessMatrix_CreateMatrix( self );
 
 	Journal_DPrintf( self->debug, "In %s - for matrix \"%s\" - calling the \"%s\" E.P.\n", __func__, self->name,
-		self->assembleStiffnessMatrix->name );
+			 self->assembleStiffnessMatrix->name );
 	/* Call the Entry point directly from the base class */
 	/* Note that it may be empty: this is deliberate. */
 	((FeEntryPoint_AssembleStiffnessMatrix_CallFunction*)EntryPoint_GetRun( self->assembleStiffnessMatrix ))(
@@ -812,9 +815,9 @@
 	Stream_IndentBranch( StgFEM_Debug );
 
 	Journal_Firewall( Stg_ObjectList_Count( self->stiffnessMatrixTermList ) != 0,
-			Journal_Register(Error_Type, self->type),
-			"Error in func %s for %s '%s' - No StiffnessMatrixTerms registered.\n", 
-			__func__, self->type, self->name );
+			  Journal_Register(Error_Type, self->type),
+			  "Error in func %s for %s '%s' - No StiffnessMatrixTerms registered.\n", 
+			  __func__, self->type, self->name );
 
 	totalDofsThisElement[ROW_VAR] = Memory_Alloc( Dof_Index, "el nodal dofs" );
 	totalDofsPrevElement[ROW_VAR] = Memory_Alloc( Dof_Index, "el nodal dofs (prev element)" );
@@ -823,14 +826,14 @@
 	if ( self->rowVariable == self->columnVariable ) {
 		numFeVars = 1;
 		Journal_DPrintfL( self->debug, 2, "Detected both row and column FeVariable to assemble over are \"%s\", "
-			"so only processing once per element.\n", self->rowVariable->name );
+				  "so only processing once per element.\n", self->rowVariable->name );
 		/* since Row and Col FeVars are same, set LM_col and totalDofsThisElement to be same as row ones */
 		totalDofsThisElement[COL_VAR] = totalDofsThisElement[ROW_VAR];	
 		totalDofsPrevElement[COL_VAR] = totalDofsPrevElement[ROW_VAR];	
 	}
 	else {
 		Journal_DPrintfL( self->debug, 2, "Since row FeVariable \"%s\" and column FeVariable \"%s\" to assemble over "
-			"are different, processing both per element.\n", self->rowVariable->name, self->columnVariable->name );
+				  "are different, processing both per element.\n", self->rowVariable->name, self->columnVariable->name );
 		totalDofsThisElement[COL_VAR] = Memory_Alloc( Dof_Index, "el nodal dofs (col)" );
 		totalDofsPrevElement[COL_VAR] = Memory_Alloc( Dof_Index, "el nodal dofs (col) (prev element)" );
 		*totalDofsPrevElement[COL_VAR] = 0;
@@ -848,7 +851,7 @@
 		
 		/* This loop is how we handle the possiblity of different row-column variables: if both variables are
 		 * the same, then numFeVars is set to 1 and the loop only progresses through once.
-		-- PatrickSunter 13 September 2004 */
+		 -- PatrickSunter 13 September 2004 */
 		for ( feVar_I = 0; feVar_I < numFeVars; feVar_I++ ) {
 			FeEquationNumber* 		feEqNum = feVars[feVar_I]->eqNum;
 			DofLayout*			dofLayout = feVars[feVar_I]->dofLayout;
@@ -870,13 +873,13 @@
 				nDofsThisEl += dofLayout->dofCounts[nodeIdsThisEl[n_i]];
 			*totalDofsThisElement[feVar_I] = nDofsThisEl;
 /*
-			*totalDofsThisElement[feVar_I] = &elementLM[feVar_I][nodeCountThisEl-1][dofCountLastNode-1]
-				- &elementLM[feVar_I][0][0] + 1;
+ *totalDofsThisElement[feVar_I] = &elementLM[feVar_I][nodeCountThisEl-1][dofCountLastNode-1]
+ - &elementLM[feVar_I][0][0] + 1;
 */
 
 			if ( *totalDofsThisElement[feVar_I] > *totalDofsPrevElement[feVar_I] ) {
 				Journal_DPrintfL( self->debug, 2, "Reallocating bcLM_Id and bcValues for fe var \"%s\" "
-					"to size %d\n", feVars[feVar_I]->name, *totalDofsThisElement[feVar_I] );
+						  "to size %d\n", feVars[feVar_I]->name, *totalDofsThisElement[feVar_I] );
 
 				if ( bcLM_Id[feVar_I] ) Memory_Free( bcLM_Id[feVar_I] );
 				bcLM_Id[feVar_I] = Memory_Alloc_Array( Dof_Index, *totalDofsThisElement[feVar_I], "bcLM_Id" );
@@ -888,16 +891,16 @@
 
 		/* Reallocate el stiff mat and other arrays if necessary */
 		if ( (*totalDofsThisElement[ROW_VAR] != *totalDofsPrevElement[ROW_VAR]) ||
-			(*totalDofsThisElement[COL_VAR] != *totalDofsPrevElement[COL_VAR]) )
+		     (*totalDofsThisElement[COL_VAR] != *totalDofsPrevElement[COL_VAR]) )
 		{
 			if (h2Add) Memory_Free( h2Add );
 			Journal_DPrintfL( self->debug, 2, "Reallocating h2Add to size %d\n",
-				*totalDofsThisElement[COL_VAR] ); 
+					  *totalDofsThisElement[COL_VAR] ); 
 			h2Add = Memory_Alloc_Array( double, *totalDofsThisElement[COL_VAR], "h2Add" );
 			
 			if (elStiffMatToAdd) Memory_Free( elStiffMatToAdd );
 			Journal_DPrintfL( self->debug, 2, "Reallocating elStiffMatToAdd to size %d*%d\n",
-				*totalDofsThisElement[ROW_VAR], *totalDofsThisElement[COL_VAR] ); 
+					  *totalDofsThisElement[ROW_VAR], *totalDofsThisElement[COL_VAR] ); 
 			elStiffMatToAdd = Memory_Alloc_2DArray( double, *totalDofsThisElement[ROW_VAR], *totalDofsThisElement[COL_VAR], "elStiffMatToAdd" );
 		}
 
@@ -911,12 +914,12 @@
 		elStiffMatBuildTime += MPI_Wtime() - elStiffMatBuildStart;
 		if ( False == self->allowZeroElementContributions ) {
 			StiffnessMatrix_CheckElementAssembly( self, element_lI, elStiffMatToAdd, *totalDofsThisElement[ROW_VAR],
-				*totalDofsThisElement[COL_VAR] );
+							      *totalDofsThisElement[COL_VAR] );
 		}	
 
 		/* This loop is how we handle the possiblity of different row-column variables: if both variables are
 		 * the same, then numFeVars is set to 1 and the loop only progresses through once.
-		-- PatrickSunter 13 September 2004 */
+		 -- PatrickSunter 13 September 2004 */
 		for ( feVar_I = 0; feVar_I < numFeVars; feVar_I++ ) {
 			/* Reset from previous calculation */
 			nBC_NodalDof[feVar_I] = 0;
@@ -945,20 +948,20 @@
 		if ( numFeVars == 1 ) elementLM[COL_VAR] = elementLM[ROW_VAR];
 
 /*
-		#if DEBUG
-		if ( Stream_IsPrintableLevel( self->debug, 3 ) ) {
-			Journal_DPrintf( self->debug, "Handling Element %d:\n", element_lI );
-			for ( feVar_I = 0; feVar_I < numFeVars; feVar_I++ ) {
-				FeEquationNumber_PrintElementLocationMatrix( feVars[feVar_I]->eqNum,
-					elementLM[feVar_I], element_lI, self->debug );
+  #if DEBUG
+  if ( Stream_IsPrintableLevel( self->debug, 3 ) ) {
+  Journal_DPrintf( self->debug, "Handling Element %d:\n", element_lI );
+  for ( feVar_I = 0; feVar_I < numFeVars; feVar_I++ ) {
+  FeEquationNumber_PrintElementLocationMatrix( feVars[feVar_I]->eqNum,
+  elementLM[feVar_I], element_lI, self->debug );
 				
-			}
+  }
 			
-			Journal_DPrintf( self->debug, "El stiff Mat about to be added:\n" );
-			_StiffnessMatrix_PrintElementStiffnessMatrix( self, element_lI, elementLM[ROW_VAR],
-				elementLM[COL_VAR], elStiffMatToAdd );
-		}	
-		#endif
+  Journal_DPrintf( self->debug, "El stiff Mat about to be added:\n" );
+  _StiffnessMatrix_PrintElementStiffnessMatrix( self, element_lI, elementLM[ROW_VAR],
+  elementLM[COL_VAR], elStiffMatToAdd );
+  }	
+  #endif
 */
 
 
@@ -1039,16 +1042,16 @@
 		/* Add to the global matrix. */
 		matAddingStart = MPI_Wtime();
 		Matrix_AddEntries( self->matrix, *totalDofsThisElement[ROW_VAR], (Index *)(elementLM[ROW_VAR][0]), *totalDofsThisElement[COL_VAR],
-			(Index *)(elementLM[COL_VAR][0]), elStiffMatToAdd[0] );
+				   (Index *)(elementLM[COL_VAR][0]), elStiffMatToAdd[0] );
 		matAddingTime += MPI_Wtime() - matAddingStart;	
 		
 		
-		#if DEBUG
+#if DEBUG
 		if( element_lI % outputInterval == 0 ) {
 			Journal_DPrintfL( self->debug, 2, "done %d percent of global element stiffness assembly (general) \n",
-				(int)(100.0*((double)element_lI/(double)nLocalElements)) );
+					  (int)(100.0*((double)element_lI/(double)nLocalElements)) );
 		}
-		#endif
+#endif
 
 		for ( feVar_I = 0; feVar_I < numFeVars; feVar_I++ ) {
 			/* Save the number of dofs in this element */
@@ -1115,14 +1118,14 @@
 	}
 
 /*
-	#if DEBUG
-	if ( Stream_IsPrintableLevel( self->debug, 3 ) ) {
-		Journal_DPrintf( self->debug, "Completely built matrix %s is:\n", self->name );
-		Matrix_View( self->matrix, self->debug );
-		Journal_DPrintf( self->debug, "Updated RHS vector %s is now:\n", self->rhs->name );
-		Vector_View( self->rhs->vector, self->debug );
-	}
-	#endif
+  #if DEBUG
+  if ( Stream_IsPrintableLevel( self->debug, 3 ) ) {
+  Journal_DPrintf( self->debug, "Completely built matrix %s is:\n", self->name );
+  Matrix_View( self->matrix, self->debug );
+  Journal_DPrintf( self->debug, "Updated RHS vector %s is now:\n", self->rhs->name );
+  Vector_View( self->rhs->vector, self->debug );
+  }
+  #endif
 */
 
 	for ( feVar_I = 0; feVar_I < numFeVars; feVar_I++ ) {
@@ -1145,15 +1148,15 @@
 /* +++ PRIVATE FUNCTIONS +++ */
 	
 void _StiffnessMatrix_UpdateBC_CorrectionTables(
-		StiffnessMatrix*	self,
-		FeEquationNumber*	eqNum, 
-		DofLayout*		dofLayout,
-		Dof_EquationNumber**	elementLM,
-		Node_ElementLocalIndex	nodeCountThisEl,
-		Element_Nodes		nodeIdsThisEl,
-		Dof_Index*		bcLM_Id,
-		double*			bcValues,
-		int*			nBC_NodalDofPtr )
+	StiffnessMatrix*	self,
+	FeEquationNumber*	eqNum, 
+	DofLayout*		dofLayout,
+	Dof_EquationNumber**	elementLM,
+	Node_ElementLocalIndex	nodeCountThisEl,
+	Element_Nodes		nodeIdsThisEl,
+	Dof_Index*		bcLM_Id,
+	double*			bcValues,
+	int*			nBC_NodalDofPtr )
 {
 	Node_ElementLocalIndex		node_elLocalI = 0;
 	Node_LocalIndex			node_lI = 0;
@@ -1187,16 +1190,16 @@
 				/* offset into the elementStiffness matrix */
 				bcLM_Id[ *nBC_NodalDofPtr ] = pos;
 /*
-				bcLM_Id[ *nBC_NodalDofPtr ] = &elementLM[node_elLocalI][dof_nodeLocalI] - &elementLM[0][0];
+  bcLM_Id[ *nBC_NodalDofPtr ] = &elementLM[node_elLocalI][dof_nodeLocalI] - &elementLM[0][0];
 */
 
 /* 				 get bc values from the bc_layout  */
 				bcValues[ *nBC_NodalDofPtr ]  = DofLayout_GetValueDouble( dofLayout, node_lI, dof_nodeLocalI );
 
 				Journal_DPrintfL( self->debug, 3, "bcValues[%d]: at &LM[0][0] + %d=%d, is %f\n",
-					*nBC_NodalDofPtr, bcLM_Id[ *nBC_NodalDofPtr ],
-					elementLM[0][ bcLM_Id[ *nBC_NodalDofPtr ] ],
-					bcValues[ *nBC_NodalDofPtr ] );
+						  *nBC_NodalDofPtr, bcLM_Id[ *nBC_NodalDofPtr ],
+						  elementLM[0][ bcLM_Id[ *nBC_NodalDofPtr ] ],
+						  bcValues[ *nBC_NodalDofPtr ] );
 
 				(*nBC_NodalDofPtr)++;
 			}
@@ -1209,15 +1212,15 @@
 
 
 void _StiffnessMatrix_CorrectForceVectorWithOneElementsBoundaryConditions(
-		StiffnessMatrix*	self,
-		Dof_EquationNumber** 	elementLM[MAX_FE_VARS],
-		double*			h2Add,
-		double** 		elStiffMatToAdd,
-		Dof_Index*		totalDofsThisElement[MAX_FE_VARS],
-		Dof_Index*		bcLM_Id[MAX_FE_VARS],
-		double*			bcValues[MAX_FE_VARS],
-		int			nBC_NodalDof_Row, 
-		unsigned		elementInd /* NEW ONE */ )
+	StiffnessMatrix*	self,
+	Dof_EquationNumber** 	elementLM[MAX_FE_VARS],
+	double*			h2Add,
+	double** 		elStiffMatToAdd,
+	Dof_Index*		totalDofsThisElement[MAX_FE_VARS],
+	Dof_Index*		bcLM_Id[MAX_FE_VARS],
+	double*			bcValues[MAX_FE_VARS],
+	int			nBC_NodalDof_Row, 
+	unsigned		elementInd /* NEW ONE */ )
 {
 	int 		rowEqId;
 	double		bc_value;
@@ -1334,52 +1337,52 @@
 	Vector_AddEntries( self->rhs->vector, *totalDofsThisElement[COL_VAR], (Index *)(elementLM[COL_VAR][0]), h2Add );
 	
 	/* assume that K is symetric, so corrections are made with KTrans.
-	 this allows us to use this func with G, when we want velocity
-	 corrections from GTrans to appear in H.
+	   this allows us to use this func with G, when we want velocity
+	   corrections from GTrans to appear in H.
 	*/
 
 	/*
-	for( bcDof_I=0; bcDof_I < nBC_NodalDof_row; bcDof_I++ ) {
-		rowEqId = bcLM_Id[ROW_VAR][bcDof_I];
-		bc_value = bcValues[ROW_VAR][bcDof_I];
-		printf("bc_value = %f \n",bc_value ); 
+	  for( bcDof_I=0; bcDof_I < nBC_NodalDof_row; bcDof_I++ ) {
+	  rowEqId = bcLM_Id[ROW_VAR][bcDof_I];
+	  bc_value = bcValues[ROW_VAR][bcDof_I];
+	  printf("bc_value = %f \n",bc_value ); 
 		
-			printf("bc value = %f \n",bc_value );
-		correct = 0;
-		for( colDof_elLocalI=0; colDof_elLocalI< *totalDofsThisElement[COL_VAR]; colDof_elLocalI++ ) {
-			h2Add[correct] = h2Add[correct]
-				- elStiffMatToAdd[rowEqId* (*totalDofsThisElement[COL_VAR]) + colDof_elLocalI] * bc_value;
-			hIdx[correct] = elementLM[COL_VAR][0][ colDof_elLocalI ];
+	  printf("bc value = %f \n",bc_value );
+	  correct = 0;
+	  for( colDof_elLocalI=0; colDof_elLocalI< *totalDofsThisElement[COL_VAR]; colDof_elLocalI++ ) {
+	  h2Add[correct] = h2Add[correct]
+	  - elStiffMatToAdd[rowEqId* (*totalDofsThisElement[COL_VAR]) + colDof_elLocalI] * bc_value;
+	  hIdx[correct] = elementLM[COL_VAR][0][ colDof_elLocalI ];
 			
-			correct = correct + 1;
-		}
-	}
-	Vector_AddTo( self->rhs->vector, correct, hIdx, h2Add );
+	  correct = correct + 1;
+	  }
+	  }
+	  Vector_AddTo( self->rhs->vector, correct, hIdx, h2Add );
 	*/
 	
 /* 	 does not work */
 	/*
-	for( rowDof_elLocalI=0; rowDof_elLocalI < *totalDofsThisElement[ROW_VAR]; rowDof_elLocalI++ ) {
-		double sum = 0.0;
-		for( rowDof_elLocalI=0; rowDof_elLocalI<nBC_NodalDof[ROW_VAR]; rowDof_elLocalI++ ) {
-			colEqId = bcLM_Id[COL_VAR][rowDof_elLocalI];
-			bc_value = bcValues[COL_VAR][rowDof_elLocalI];
+	  for( rowDof_elLocalI=0; rowDof_elLocalI < *totalDofsThisElement[ROW_VAR]; rowDof_elLocalI++ ) {
+	  double sum = 0.0;
+	  for( rowDof_elLocalI=0; rowDof_elLocalI<nBC_NodalDof[ROW_VAR]; rowDof_elLocalI++ ) {
+	  colEqId = bcLM_Id[COL_VAR][rowDof_elLocalI];
+	  bc_value = bcValues[COL_VAR][rowDof_elLocalI];
 			
-			sum = sum + elStiffMatToAdd[ i* (*totalDofsThisElement[COL_VAR]) + colEqId] * bc_value;
-		}
-		h2Add[rowDof_elLocalI] = -sum;
-	}
-	Vector_AddTo( self->rhs->vector, *totalDofsThisElement[ROW_VAR], elementLM[ROW_VAR][0], h2Add );
+	  sum = sum + elStiffMatToAdd[ i* (*totalDofsThisElement[COL_VAR]) + colEqId] * bc_value;
+	  }
+	  h2Add[rowDof_elLocalI] = -sum;
+	  }
+	  Vector_AddTo( self->rhs->vector, *totalDofsThisElement[ROW_VAR], elementLM[ROW_VAR][0], h2Add );
 	*/
 }
 
 
 void _StiffnessMatrix_PrintElementStiffnessMatrix(
-		StiffnessMatrix* self,
-		Element_LocalIndex element_lI,
-		Dof_EquationNumber** rowElementLM,
-		Dof_EquationNumber** colElementLM,
-		double** elStiffMatToAdd )
+	StiffnessMatrix* self,
+	Element_LocalIndex element_lI,
+	Dof_EquationNumber** rowElementLM,
+	Dof_EquationNumber** colElementLM,
+	double** elStiffMatToAdd )
 {
 	FeMesh*			rFeMesh = self->rowVariable->feMesh;
 	FeMesh*			cFeMesh = self->columnVariable->feMesh;
@@ -1409,11 +1412,11 @@
 					colIndex = colNode_I*colDofsPerNode + colDof_I;
 
 					Journal_DPrintf( self->debug, "Row [%d][%d], Col [%d][%d] (LM (%4d,%4d)) = %.3f\n",
-						rowNode_I, rowDof_I,
-						colNode_I, colDof_I,
-						rowElementLM[rowNode_I][rowDof_I],
-						colElementLM[colNode_I][colDof_I],
-						elStiffMatToAdd[rowIndex][colIndex] ); 
+							 rowNode_I, rowDof_I,
+							 colNode_I, colDof_I,
+							 rowElementLM[rowNode_I][rowDof_I],
+							 colElementLM[colNode_I][colDof_I],
+							 elStiffMatToAdd[rowIndex][colIndex] ); 
 				}			
 			}
 		}
@@ -1436,11 +1439,11 @@
 
 
 void StiffnessMatrix_CheckElementAssembly( 
-		void* stiffnessMatrix,
-		Element_LocalIndex element_lI,
-		double** elStiffMatToAdd,
-		Index elStiffMatToAddRowSize,
-		Index elStiffMatToAddColSize )
+	void* stiffnessMatrix,
+	Element_LocalIndex element_lI,
+	double** elStiffMatToAdd,
+	Index elStiffMatToAddRowSize,
+	Index elStiffMatToAddColSize )
 {
 	StiffnessMatrix*  self = (StiffnessMatrix*)stiffnessMatrix;
 	Bool              atLeastOneNonZeroElementContributionEntry = False;
@@ -1461,10 +1464,10 @@
 	}
 
 	Journal_Firewall( atLeastOneNonZeroElementContributionEntry == True, errorStream,
-		"Error - in %s(): while assembling matrix \"%s\", for element %u - elStiffMatToAdd assembled at this "
-		"element is all zeros."
-		"Did you register a stiffnessMatrixTerm? Is there at least one integration point in this "
-		"element?\n", __func__, self->name, element_lI  );
+			  "Error - in %s(): while assembling matrix \"%s\", for element %u - elStiffMatToAdd assembled at this "
+			  "element is all zeros."
+			  "Did you register a stiffnessMatrixTerm? Is there at least one integration point in this "
+			  "element?\n", __func__, self->name, element_lI  );
 }
 
 
@@ -1497,3 +1500,154 @@
 					 self->diagonalNonZeroIndices, self->offDiagonalNonZeroIndices );
 #endif
 }
+
+
+void StiffnessMatrix_CalcNonZeros( void* stiffnessMatrix ) {
+	StiffnessMatrix*	self = (StiffnessMatrix*)stiffnessMatrix;
+	Stream*			stream;
+	FeVariable		*rowVar, *colVar;
+	FeMesh			*rowMesh, *colMesh;
+	FeEquationNumber	*rowEqNum, *colEqNum;
+	DofLayout		*rowDofs, *colDofs;
+	unsigned		nRowEqs, nColEqs;
+	unsigned		nRowNodes, *rowNodes;
+	unsigned		nColNodes, *colNodes;
+	unsigned		*nMaxNonZeros, maxNZ;
+	unsigned		*nNonZeros, **nonZeros;
+	unsigned		*nDiagNZs, *nOffDiagNZs;
+	unsigned		rowEq, colEq;
+	unsigned		netNonZeros;
+	unsigned		e_i, nz_i, eq_i;
+	unsigned		n_i, dof_i;
+	unsigned		n_j, dof_j;
+
+	assert( self && Stg_CheckType( self, StiffnessMatrix ) );
+	assert( self->rowVariable );
+
+	stream = Journal_Register( Info_Type, self->type );
+	Journal_Printf( stream, "Stiffness matrix: '%s'\n", self->name );
+	Stream_Indent( stream );
+	Journal_Printf( stream, "Calculating number of nonzero entries...\n" );
+	Stream_Indent( stream );
+
+	rowVar = self->rowVariable;
+	colVar = self->columnVariable ? self->columnVariable : rowVar;
+	rowMesh = rowVar->feMesh;
+	colMesh = colVar->feMesh;
+	rowEqNum = rowVar->eqNum;
+	colEqNum = colVar->eqNum;
+	nRowEqs = rowEqNum->localEqNumsOwnedCount;
+	nColEqs = colEqNum->localEqNumsOwnedCount;
+	rowDofs = rowVar->dofLayout;
+	colDofs = colVar->dofLayout;
+
+	nMaxNonZeros = AllocArray( unsigned, nRowEqs );
+	memset( nMaxNonZeros, 0, nRowEqs * sizeof(unsigned) );
+
+	for( e_i = 0; e_i < FeMesh_GetElementLocalSize( rowMesh ); e_i++ ) {
+		FeMesh_GetElementNodes( rowMesh, e_i, &nRowNodes, &rowNodes );
+		FeMesh_GetElementNodes( colMesh, e_i, &nColNodes, &colNodes );
+
+		for( n_i = 0; n_i < nRowNodes; n_i++ ) {
+			for( dof_i = 0; dof_i < rowDofs->dofCounts[rowNodes[n_i]]; dof_i++ ) {
+				rowEq = rowEqNum->locationMatrix[e_i][n_i][dof_i];
+				if( rowEq == (unsigned)-1 )
+					continue;
+
+				for( n_j = 0; n_j < nColNodes; n_j++ ) {
+					for( dof_j = 0; dof_j < colDofs->dofCounts[colNodes[n_j]]; dof_j++ ) {
+						colEq = colEqNum->locationMatrix[e_i][n_j][dof_j];
+						if( colEq == (unsigned)-1 )
+							continue;
+
+						nMaxNonZeros[rowEq]++;
+					}
+				}
+			}
+		}
+	}
+
+	maxNZ = 0;
+	for( eq_i = 0; eq_i < nRowEqs; eq_i++ ) {
+		if( nMaxNonZeros[eq_i] > maxNZ )
+			maxNZ = nMaxNonZeros[eq_i];
+	}
+
+	FreeArray( nMaxNonZeros );
+
+	nNonZeros = AllocArray( unsigned, nRowEqs );
+	memset( nNonZeros, 0, nRowEqs * sizeof(unsigned) );
+	nonZeros = AllocArray2D( unsigned, nRowEqs, maxNZ );
+
+	for( e_i = 0; e_i < FeMesh_GetElementLocalSize( rowMesh ); e_i++ ) {
+		FeMesh_GetElementNodes( rowMesh, e_i, &nRowNodes, &rowNodes );
+		FeMesh_GetElementNodes( colMesh, e_i, &nColNodes, &colNodes );
+
+		for( n_i = 0; n_i < nRowNodes; n_i++ ) {
+			for( dof_i = 0; dof_i < rowDofs->dofCounts[rowNodes[n_i]]; dof_i++ ) {
+				rowEq = rowEqNum->locationMatrix[e_i][n_i][dof_i];
+				if( rowEq == (unsigned)-1 )
+					continue;
+
+				for( n_j = 0; n_j < nColNodes; n_j++ ) {
+					for( dof_j = 0; dof_j < colDofs->dofCounts[colNodes[n_j]]; dof_j++ ) {
+						colEq = colEqNum->locationMatrix[e_i][n_j][dof_j];
+						if( colEq == (unsigned)-1 )
+							continue;
+
+						StiffnessMatrix_TrackUniqueEqs( self, rowEq, colEq, 
+										nNonZeros, nonZeros );
+					}
+				}
+			}
+		}
+	}
+
+	nDiagNZs = AllocArray( unsigned, nRowEqs );
+	memset( nDiagNZs, 0, nRowEqs * sizeof(unsigned) );
+	nOffDiagNZs = AllocArray( unsigned, nRowEqs );
+	memset( nOffDiagNZs, 0, nRowEqs * sizeof(unsigned) );
+
+	netNonZeros = 0;
+	for( eq_i = 0; eq_i < nRowEqs; eq_i++ ) {
+		netNonZeros += nNonZeros[eq_i];
+
+		for( nz_i = 0; nz_i < nNonZeros[eq_i]; nz_i++ ) {
+			if( nonZeros[eq_i][nz_i] < nRowEqs )
+				nDiagNZs[eq_i]++;
+			else
+				nOffDiagNZs[eq_i]++;
+		}
+	}
+
+	FreeArray( nNonZeros );
+	FreeArray( nonZeros );
+
+	self->diagonalNonZeroIndices = nDiagNZs;
+	self->offDiagonalNonZeroIndices = nOffDiagNZs;
+
+	Journal_Printf( stream, "Found %d nonzero entries.\n", netNonZeros );
+	Journal_Printf( stream, "Done.\n" );
+	Stream_UnIndent( stream );
+	Stream_UnIndent( stream );
+}
+
+
+void StiffnessMatrix_TrackUniqueEqs( StiffnessMatrix* self, unsigned rowEq, unsigned colEq, 
+					unsigned* nNonZeros, unsigned** nonZeros )
+{
+	unsigned	nz_i;
+
+	assert( self );
+	assert( nNonZeros && nonZeros );
+
+	for( nz_i = 0; nz_i < nNonZeros[rowEq]; nz_i++ ) {
+		if( nonZeros[rowEq][nz_i] == colEq )
+			break;
+	}
+	if( nz_i < nNonZeros[rowEq] )
+		return;
+
+	nNonZeros[rowEq]++;
+	nonZeros[rowEq][nNonZeros[rowEq] - 1] = colEq;
+}

Modified: long/3D/Gale/trunk/src/StgFEM/SLE/SystemSetup/src/StiffnessMatrix.h
===================================================================
--- long/3D/Gale/trunk/src/StgFEM/SLE/SystemSetup/src/StiffnessMatrix.h	2007-02-23 20:20:58 UTC (rev 6109)
+++ long/3D/Gale/trunk/src/StgFEM/SLE/SystemSetup/src/StiffnessMatrix.h	2007-02-23 20:21:00 UTC (rev 6110)
@@ -266,5 +266,10 @@
 	void StiffnessMatrix_AddStiffnessMatrixTerm( void* stiffnessMatrixVector, StiffnessMatrixTerm* stiffnessMatrixTerm ) ;
 
 	void StiffnessMatrix_CreateMatrix( StiffnessMatrix* self );
+
+	void StiffnessMatrix_CalcNonZeros( void* stiffnessMatrix );
+
+	void StiffnessMatrix_TrackUniqueEqs( StiffnessMatrix* self, unsigned rowEq, unsigned colEq, 
+					     unsigned* nNonZeros, unsigned** nonZeros );
 	
 #endif /* __StgFEM_SLE_SystemSetup_StiffnessMatrix_h__ */



More information about the cig-commits mailing list