[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