[cig-commits] r4160 - in long/3D/Gale/trunk/src/StgFEM: . plugins/CompareFeVariableAgainstReferenceSolution

walter at geodynamics.org walter at geodynamics.org
Tue Aug 1 01:54:42 PDT 2006


Author: walter
Date: 2006-08-01 01:54:41 -0700 (Tue, 01 Aug 2006)
New Revision: 4160

Modified:
   long/3D/Gale/trunk/src/StgFEM/
   long/3D/Gale/trunk/src/StgFEM/plugins/CompareFeVariableAgainstReferenceSolution/CompareFeVariableAgainstReferenceSolution.c
Log:
 r724 at earth:  boo | 2006-08-01 01:52:55 -0700
  r714 at earth (orig r618):  PatrickSunter | 2006-07-24 19:53:12 -0700
  Improved the CompareFeVariableAgainstReferenceSolution plugin:
    * Cleaned up variable names to make them more readable/descriptive
    * Created a Rounded-off copy of the "live" FeVariable we are
    testing to compare against the "reference" or benchmark feVar
    we load from file - any precision of the live FeVariable beyond
    the number of sig. figs of the loaded one is wasted and creates
    a spurious error (this effect was more noticable when the 
    checkpoint sig figs used was only 6 instead of 15)
    (have hard-coded the roundoff to 15 for now since that's what's
    used by StgFEM-Native format - this is a hack and down the
    track it should be a property read from the FeVariable Importer
    used or something.)
    
  
 



Property changes on: long/3D/Gale/trunk/src/StgFEM
___________________________________________________________________
Name: svk:merge
   - 38867592-cf10-0410-9e16-a142ea72ac34:/cig:723
db209038-57f2-0310-97fa-b160e0ae9d04:/trunk:617
   + 38867592-cf10-0410-9e16-a142ea72ac34:/cig:724
db209038-57f2-0310-97fa-b160e0ae9d04:/trunk:618

Modified: long/3D/Gale/trunk/src/StgFEM/plugins/CompareFeVariableAgainstReferenceSolution/CompareFeVariableAgainstReferenceSolution.c
===================================================================
--- long/3D/Gale/trunk/src/StgFEM/plugins/CompareFeVariableAgainstReferenceSolution/CompareFeVariableAgainstReferenceSolution.c	2006-08-01 08:54:38 UTC (rev 4159)
+++ long/3D/Gale/trunk/src/StgFEM/plugins/CompareFeVariableAgainstReferenceSolution/CompareFeVariableAgainstReferenceSolution.c	2006-08-01 08:54:41 UTC (rev 4160)
@@ -50,7 +50,7 @@
 const Type CompareFeVariableAgainstReferenceSolution_Type = "StG_FEM_CompareFeVariableAgainstReferenceSolution";
 
 void CompareFeVariableAgainstReferenceSolution_TestAll( void* compareFeVariable, void* data );
-void CompareFeVariableAgainstReferenceSolution_TestVariable( void* compareFeVariable, FeVariable* var, double tolerance );
+void CompareFeVariableAgainstReferenceSolution_TestVariable( void* compareFeVariable, FeVariable* feVarToTest, double tolerance );
 void _CompareFeVariableAgainstReferenceSolution_Delete( void* compareFeVariable );
 
 typedef struct {
@@ -86,7 +86,7 @@
 	char*                    varName;
 	Dictionary_Entry_Value*  varList;
 
-	FeVariable*              var;
+	FeVariable*              feVarToTest;
 	Index                    var_I;
 	double                   tolerance;
 
@@ -134,15 +134,15 @@
 
 	for ( var_I = 0; var_I < Dictionary_Entry_Value_GetCount( varList ); ++var_I ) {
 		varName = Dictionary_Entry_Value_AsString( Dictionary_Entry_Value_GetElement( varList, var_I ) );
-		var = Stg_ComponentFactory_ConstructByName( cf, varName, FeVariable, True );
+		feVarToTest = Stg_ComponentFactory_ConstructByName( cf, varName, FeVariable, True );
 		Journal_Printf(
 			Journal_MyStream( Info_Type, self ),
 			"%s: Comparing FeVariable %s\n", self->name, varName );
 
-		tmpName = Stg_Object_AppendSuffix( var, "tolerance" );
+		tmpName = Stg_Object_AppendSuffix( feVarToTest, "tolerance" );
 		tolerance = Dictionary_GetDouble_WithDefault( dictionary, tmpName, 0.005 );
 		
-		Stg_ObjectList_Append( self->variables, var );
+		Stg_ObjectList_Append( self->variables, feVarToTest );
 		Stg_ObjectList_Append( self->tolerances, Stg_PrimitiveObject_New_Double( tolerance, varName ) );
 	}
 
@@ -199,7 +199,7 @@
 void CompareFeVariableAgainstReferenceSolution_TestAll( void* compareFeVariable, void* data ) {
 	CompareFeVariableAgainstReferenceSolution* self = (CompareFeVariableAgainstReferenceSolution*) compareFeVariable;
 
-	FeVariable*     var;
+	FeVariable*     feVarToTest;
 	double          tolerance;
 
 	Index           var_I;
@@ -215,31 +215,43 @@
 	}
 
 	for ( var_I = 0; var_I < self->variables->count; ++var_I ) {
-		var = (FeVariable*)Stg_ObjectList_At( self->variables, var_I );
+		feVarToTest = (FeVariable*)Stg_ObjectList_At( self->variables, var_I );
 		tolerance = ((Stg_PrimitiveObject*)Stg_ObjectList_At( self->tolerances, var_I ))->value.asDouble;
-		CompareFeVariableAgainstReferenceSolution_TestVariable( self, var, tolerance );
+		CompareFeVariableAgainstReferenceSolution_TestVariable( self, feVarToTest, tolerance );
 	}
 }
 
 
-void CompareFeVariableAgainstReferenceSolution_TestVariable( void* compareFeVariable, FeVariable* var, double tolerance ) {
+void CompareFeVariableAgainstReferenceSolution_TestVariable( void* compareFeVariable, FeVariable* feVarToTest, double tolerance ) {
 	CompareFeVariableAgainstReferenceSolution* self = (CompareFeVariableAgainstReferenceSolution*) compareFeVariable;
 	
 	Variable_Register*       variable_Register;
 
-	FeVariable*              ref;
-	Variable*                dataVariable;
-        Name                     variableName[9];
+	Variable*                referenceDataVariable;
+	Variable*                roundedDataVariable;
+        Name                     referenceVariableName[9];
+        Name                     roundedVariableName[9];
 	Variable_Index           variable_I;
-	DofLayout*               dofLayout;
-	Node_DomainIndex         node_I;
+	DofLayout*               referenceDofLayout;
+	DofLayout*               roundedDofLayout;
+	Node_DomainIndex         dNode_I;
+	Dof_Index                dofCountAtNode;
+	Dof_Index                dofCountAtPrevNode = 0;
+	Dof_Index                dof_I;
+	double*                  nodalValues = NULL;
 
+	FeVariable*              referenceFeVar;
+	FeVariable*              roundedFeVar;
 	OperatorFeVariable*      errorField;
 	OperatorFeVariable*      errorMagnitudeField;
 
 	char*                    tmpName;
+	char*                    tmpName2;
 	Bool                     scalar;
         Dof_Index                componentsCount;
+				// TODO: hardcode for now - should be read in constructor, or read from the reference
+				// feVar type, or file reader or something
+	unsigned int             numSigFigsInReferenceFeVar = 15;
 	
 	char*                    refName;
 
@@ -249,18 +261,32 @@
 	
 	variable_Register = self->context->variable_Register;
 
-	componentsCount = var->fieldComponentCount;
+	componentsCount = feVarToTest->fieldComponentCount;
 	scalar = componentsCount == 1;
 
+	/* Ok:- here, we know that the reference, or benchmark, FeVariable that we are
+	comparing against may have been rounded off already, and we don't want to give
+	a spurious error result just because the solution just calculated has accuracy
+	beyond what the rounded benchmark is giving. Thus, we truncate the result to the
+	level of the reference FeVariable */
+
 	/* Create a DataVariable for the Reference. This serves as the memory object is is linked to */
-	tmpName = Stg_Object_AppendSuffix( var, "Reference-DataVariable" );
+	/* Likewise, for the rounded-off version of the "live" FeVar we are testing */
+	tmpName = Stg_Object_AppendSuffix( feVarToTest, "Reference-DataVariable" );
+	tmpName2 = Stg_Object_AppendSuffix( feVarToTest, "Rounded-DataVariable" );
 	if ( scalar == 1 ) {
-		dataVariable = Variable_NewScalar(
+		referenceDataVariable = Variable_NewScalar(
 			tmpName,
 			Variable_DataType_Double,
-			&var->feMesh->nodeDomainCount,
+			&feVarToTest->feMesh->nodeDomainCount,
 			(void**)NULL,
 			variable_Register );
+		roundedDataVariable = Variable_NewScalar(
+			tmpName2,
+			Variable_DataType_Double,
+			&feVarToTest->feMesh->nodeDomainCount,
+			(void**)NULL,
+			variable_Register );
 	}
 	else {
 		Journal_Firewall( 
@@ -268,98 +294,163 @@
 			Journal_MyStream( Error_Type, self ),
 			"In func %s - Cannot create a variable with more than 9 components (%s)\n",
 			__func__,
-			var->name );
+			feVarToTest->name );
 		for ( variable_I = 0 ; variable_I < componentsCount; variable_I++ ) {
 			Stg_asprintf( 
-				&variableName[ variable_I ], 
+				&referenceVariableName[ variable_I ], 
 				"%s-Reference-ComponentVariable%d", 
-				var->name, 
+				feVarToTest->name, 
 				variable_I );
+			Stg_asprintf( 
+				&roundedVariableName[ variable_I ], 
+				"%s-Rounded-ComponentVariable%d", 
+				feVarToTest->name, 
+				variable_I );
 		}
-		dataVariable = Variable_NewVector(
+		referenceDataVariable = Variable_NewVector(
 				tmpName,
 				Variable_DataType_Double,
 				componentsCount,
-				&var->feMesh->nodeDomainCount,
+				&feVarToTest->feMesh->nodeDomainCount,
 				(void**)NULL,
 				variable_Register,
-				variableName[0],
-				variableName[1],
-				variableName[2],
-				variableName[3],
-				variableName[4],
-				variableName[5],
-				variableName[6],
-				variableName[7],
-				variableName[8] );
+				referenceVariableName[0],
+				referenceVariableName[1],
+				referenceVariableName[2],
+				referenceVariableName[3],
+				referenceVariableName[4],
+				referenceVariableName[5],
+				referenceVariableName[6],
+				referenceVariableName[7],
+				referenceVariableName[8] );
+		roundedDataVariable = Variable_NewVector(
+				tmpName2,
+				Variable_DataType_Double,
+				componentsCount,
+				&feVarToTest->feMesh->nodeDomainCount,
+				(void**)NULL,
+				variable_Register,
+				roundedVariableName[0],
+				roundedVariableName[1],
+				roundedVariableName[2],
+				roundedVariableName[3],
+				roundedVariableName[4],
+				roundedVariableName[5],
+				roundedVariableName[6],
+				roundedVariableName[7],
+				roundedVariableName[8] );
 	}
 	Memory_Free( tmpName );
+	Memory_Free( tmpName2 );
 	
-	dataVariable->allocateSelf = True;
+	referenceDataVariable->allocateSelf = True;
+	roundedDataVariable->allocateSelf = True;
 
+	Build( referenceDataVariable, NULL, False );
+	Initialise( referenceDataVariable, NULL, False );
+	Build( roundedDataVariable, NULL, False );
+	Initialise( roundedDataVariable, NULL, False );
+
 	/* Create Dof layout for this variable based on its own DataVariable */
-	tmpName = Stg_Object_AppendSuffix( var, "Reference-DofLayout" );
-	dofLayout = DofLayout_New( tmpName, variable_Register, var->feMesh->layout->decomp->nodeDomainCount );
+	tmpName = Stg_Object_AppendSuffix( feVarToTest, "Reference-DofLayout" );
+	tmpName2 = Stg_Object_AppendSuffix( feVarToTest, "Rounded-DofLayout" );
+	referenceDofLayout = DofLayout_New( tmpName, variable_Register, feVarToTest->feMesh->layout->decomp->nodeDomainCount );
+	roundedDofLayout = DofLayout_New( tmpName2, variable_Register, feVarToTest->feMesh->layout->decomp->nodeDomainCount );
 	if ( scalar ) {
-		DofLayout_AddAllFromVariableArray( dofLayout, 1, &dataVariable );
+		DofLayout_AddAllFromVariableArray( referenceDofLayout, 1, &referenceDataVariable );
+		DofLayout_AddAllFromVariableArray( roundedDofLayout, 1, &roundedDataVariable );
 	}
 	else {
 		for ( variable_I = 0 ; variable_I < componentsCount ; variable_I++ ) {
-
 			/* We have to set the array ptr ptr for these guys manually - this should be fixed */
-			Variable* variable = Variable_Register_GetByName( variable_Register, variableName[ variable_I ] );
-			variable->arrayPtrPtr = &dataVariable->arrayPtr;
+			Variable* refVariable = Variable_Register_GetByName( variable_Register, referenceVariableName[ variable_I ] );
+			Variable* roundedVariable = Variable_Register_GetByName( variable_Register, roundedVariableName[ variable_I ] );
 
+			refVariable->arrayPtrPtr = &referenceDataVariable->arrayPtr;
+			roundedVariable->arrayPtrPtr = &roundedDataVariable->arrayPtr;
+
 			/* Assign variable to each node */
-			for( node_I = 0; node_I < var->feMesh->layout->decomp->nodeDomainCount ; node_I++ ) {
-				DofLayout_AddDof_ByVarName( dofLayout, variableName[variable_I], node_I );
+			for( dNode_I = 0; dNode_I < feVarToTest->feMesh->layout->decomp->nodeDomainCount ; dNode_I++ ) {
+				DofLayout_AddDof_ByVarName( referenceDofLayout, referenceVariableName[variable_I], dNode_I );
+				DofLayout_AddDof_ByVarName( roundedDofLayout, roundedVariableName[variable_I], dNode_I );
 			}
 			/* Free Name */
-			Memory_Free( variableName[ variable_I ] );
+			Memory_Free( referenceVariableName[ variable_I ] );
+			Memory_Free( roundedVariableName[ variable_I ] );
 		}
 	}
 	Memory_Free( tmpName );
+	Memory_Free( tmpName2 );
 	
-	Build( dofLayout, NULL, False );
-	Build( dataVariable, NULL, False );
-	Initialise( dofLayout, NULL, False );
-	Initialise( dataVariable, NULL, False );
-	
-	dofLayout->dofCounts[0] = var->dofLayout->dofCounts[0];
+	Build( referenceDofLayout, NULL, False );
+	Initialise( referenceDofLayout, NULL, False );
+	Build( roundedDofLayout, NULL, False );
+	Initialise( roundedDofLayout, NULL, False );
 
 	/* Instantiate FeVariable, pre-reading reference */
 	if ( strlen( self->referenceFeVariableSuffix ) > 0 ) {
-		refName = Stg_Object_AppendSuffix( var, self->referenceFeVariableSuffix );
+		refName = Stg_Object_AppendSuffix( feVarToTest, self->referenceFeVariableSuffix );
 	}
 	else {
-		refName = var->name;
+		refName = feVarToTest->name;
 	}
-	ref = FeVariable_New( 
+
+	referenceFeVar = FeVariable_New_FromTemplate( 
 			refName, 
-			var->feMesh, 
-			var->geometryMesh, 
-			dofLayout, 
+			feVarToTest,
+			referenceDofLayout, 
 			NULL, 
+			feVarToTest->fieldVariable_Register );
+
+	tmpName = Stg_Object_AppendSuffix( feVarToTest, "Rounded" );
+	roundedFeVar = FeVariable_New_FromTemplate( 
+			tmpName, 
+			feVarToTest, 
+			roundedDofLayout, 
 			NULL, 
-			NULL, 
-			var->dim, 
-			self->importFormatType,
-			self->exportFormatType,
-			var->fieldVariable_Register );
+			feVarToTest->fieldVariable_Register );
+	Memory_Free( tmpName );
 
+	Build( referenceFeVar, NULL, False );
+	Initialise( referenceFeVar, NULL, False );
+	Build( roundedFeVar, NULL, False );
+	Initialise( roundedFeVar, NULL, False );
+
 	Stg_asprintf( &prefix, "%s/", self->referencePath );
-	FeVariable_ReadFromFile( ref, prefix, self->context->timeStep );
+	FeVariable_ReadFromFile( referenceFeVar, prefix, self->context->timeStep );
 	Memory_Free( prefix );
+	/* Ok, now we need to make sure the referenceFeVar has an appropriate suffix, so it doesn't clash with an
+	 * existing one */
+	if ( 0 == strcmp( feVarToTest->name, referenceFeVar->name ) ) {
+		Memory_Free( referenceFeVar->name );
+		referenceFeVar->name = Stg_Object_AppendSuffix( feVarToTest, "Reference" );
+	}
 
-	tmpName = Stg_Object_AppendSuffix( var, "ErrorField" );
-	errorField = OperatorFeVariable_NewBinary( tmpName, var, ref, "Subtraction" );
+	/* now we need to round off the feVar we are testing, and copy the result to the roundedFeVar */
+	for( dNode_I = 0; dNode_I < feVarToTest->feMesh->nodeDomainCount; dNode_I++ ) {
+		dofCountAtNode = feVarToTest->dofLayout->dofCounts[dNode_I];
+		
+		if ( dofCountAtNode != dofCountAtPrevNode ) {
+			nodalValues = Memory_Realloc_Array( nodalValues, double, dofCountAtNode ); 
+		}
+		FeVariable_GetValueAtNode( feVarToTest, dNode_I, nodalValues );
+
+		for ( dof_I=0; dof_I < dofCountAtNode; dof_I++ ) {
+			nodalValues[dof_I] = StG_RoundDoubleToNSigFigs( nodalValues[dof_I], numSigFigsInReferenceFeVar );
+		}
+		FeVariable_SetValueAtNode( roundedFeVar, dNode_I, nodalValues );
+		dofCountAtPrevNode = dofCountAtNode;
+	}
+	Memory_Free( nodalValues );
+
+	tmpName = Stg_Object_AppendSuffix( feVarToTest, "ErrorField" );
+	errorField = OperatorFeVariable_NewBinary( tmpName, roundedFeVar, referenceFeVar, "Subtraction" );
 	Memory_Free( tmpName );
 
-	tmpName = Stg_Object_AppendSuffix( var, "ErrorMagnitudeField" );
+	tmpName = Stg_Object_AppendSuffix( feVarToTest, "ErrorMagnitudeField" );
 	errorMagnitudeField = OperatorFeVariable_NewUnary( tmpName, errorField, "Magnitude" );
 	Memory_Free( tmpName );
 
-
         result = FeVariable_Integrate( errorMagnitudeField, self->integrationSwarm );
 
 	Journal_Printf( 
@@ -378,9 +469,12 @@
 	}	
 		
 	/*
-	Stg_Class_Delete( dataVariable );
-	Stg_Class_Delete( dofLayout );
-	Stg_Class_Delete( ref );
+	Stg_Class_Delete( referenceDataVariable );
+	Stg_Class_Delete( referenceDofLayout );
+	Stg_Class_Delete( referenceFeVar );
+	Stg_Class_Delete( roundedDataVariable );
+	Stg_Class_Delete( roundedDofLayout );
+	Stg_Class_Delete( roundedFeVar );
 	Stg_Class_Delete( errorField );
 	Stg_Class_Delete( errorMagnitudeField );
 	*/



More information about the cig-commits mailing list