void DictionaryCheckSuite_TestCheckKeys( DictionaryCheckSuiteData* data ) {
   Dictionary*       dictionary = Dictionary_New();
   Dictionary*       dictionary2 = Dictionary_New();
   const char*       testFilename1 = "testDictionaryCheck-1.txt";
   const char*       testFilename2 = "testDictionaryCheck-2.txt";
   char              expectedFilename[PCU_PATH_MAX];
   const char*       errMessage = "Component dictionary must have unique names\n";
   
   Stream_RedirectFile( Journal_Register( Error_Type, (Name)"DictionaryCheck" ), testFilename1 );
   Stream_SetPrintingRank( Journal_Register( Error_Type, (Name)"DictionaryCheck" ), 0 );
   Stream_ClearCustomFormatters( Journal_Register( Error_Type, (Name)"DictionaryCheck") );

   /* Create a set of Dictionary entries */
   /* For dictionary */
   Dictionary_Add( dictionary, (Dictionary_Entry_Key)"test_dict_string", Dictionary_Entry_Value_FromString( "hello" ) );
   Dictionary_Add( dictionary, (Dictionary_Entry_Key)"test_dict_double", Dictionary_Entry_Value_FromDouble( 45.567 ) );
   Dictionary_Add( dictionary, (Dictionary_Entry_Key)"test_dict_string", Dictionary_Entry_Value_FromString( "goodbye" ) );   
   Dictionary_Add( dictionary, (Dictionary_Entry_Key)"test_dict_string", Dictionary_Entry_Value_FromString( "hello" ) );
   Dictionary_Add( dictionary, (Dictionary_Entry_Key)"test_dict_string2", Dictionary_Entry_Value_FromString( "hello" ) );
   
   CheckDictionaryKeys( dictionary,  errMessage );

   if ( data->rank==0 ) {
      pcu_filename_expected( testFilename1, expectedFilename );
      pcu_check_fileEq( testFilename1, expectedFilename );
      remove( testFilename1 );
   }

   /* For dictionary2 */
   Dictionary_Add( dictionary2, (Dictionary_Entry_Key)"test_dict_string", Dictionary_Entry_Value_FromString( "hello" ) );
   Dictionary_Add( dictionary2, (Dictionary_Entry_Key)"test_dict_double", Dictionary_Entry_Value_FromDouble( 45.567 ) );
   Dictionary_Add( dictionary2, (Dictionary_Entry_Key)"test_dict_stuff", Dictionary_Entry_Value_FromString( "hello") );

   /* Call DictionaryCheck function */
   Stream_RedirectFile(Journal_Register( Error_Type, (Name)"DictionaryCheck" ), testFilename2 );
   CheckDictionaryKeys(dictionary2, errMessage);

   /* This file expected to be empty */
   if ( data->rank==0 ) {
      pcu_filename_expected( testFilename2, expectedFilename );
      pcu_check_fileEq( testFilename2, expectedFilename );
      remove( testFilename2 );
   }
   
   Stg_Class_Delete( dictionary );
   Stg_Class_Delete( dictionary2 );

   if ( data->rank==0 ) {
      remove( testFilename1 );
      remove( testFilename2 );
   }
}
SizeT BinaryStream_WriteAllProcessors( Name filename, void *data, SizeT elem_size, SizeT num_elems, MPI_Comm comm ) {
    Stream*    stream = Journal_Register( BinaryStream_Type, BinaryStream_Type );
    MPI_Status status;
    int        rank;
    int        nproc;
    int        confirmation = 0;
    const int         FINISHED_WRITING_TAG = 100;
    MPI_Comm_rank( comm, &rank );
    MPI_Comm_size( comm, &nproc );

    /* wait for go-ahead from process ranked lower than me, to avoid competition writing to file */
    if ( rank != 0 ) {
        MPI_Recv( &confirmation, 1, MPI_INT, rank - 1, FINISHED_WRITING_TAG, comm, &status );
    }
    /* open the file */
    if ( rank == 0 ) {
        Stream_RedirectFile( stream, filename );
    }
    else {
        Stream_AppendFile( stream, filename );
    }

    /* write the data */
    Stream_Write( stream, data, elem_size, num_elems );

    /* close the file */
    Stream_CloseFile( stream);
    /* send go-ahead from process ranked lower than me, to avoid competition writing to file */
    if ( rank != nproc - 1 ) {
        MPI_Ssend( &confirmation, 1, MPI_INT, rank + 1, FINISHED_WRITING_TAG, comm );
    }

    return (SizeT) NULL;
}
예제 #3
0
Bool Stream_RedirectFile_WithPrependedPath( Stream* stream, char* prependedPath, char* filename ) {
   Bool result;

   /* Check to make sure output path is emtpy */ 
   if( Stg_StringIsEmpty( prependedPath ) )
      result = Stream_RedirectFile( stream, filename );
   else {
      char* prependedFilename;

      Stg_asprintf( &prependedFilename, "%s/%s", prependedPath, filename );
      result = Stream_RedirectFile( stream, prependedFilename );
      Memory_Free( prependedFilename );
   }

   return result;
}
예제 #4
0
void _SwarmDump_Execute( void* swarmDump, void* data ) {
	SwarmDump*	      self                = (SwarmDump*)     swarmDump;
	AbstractContext*  context             = Stg_CheckType( data, AbstractContext );
	Stream*           stream              = Journal_Register( MPIStream_Type, Swarm_Type );
	Particle_Index    particleLocalCount;
	SizeT             particleSize;
	Name              filename;
	Index             swarm_I;
	Swarm*            swarm;
	Stream*           info = Journal_Register( Info_Type, self->type );
	Processor_Index   rank_I;

	Journal_DPrintf( info, "Proc %d: beginning Swarm binary checkpoint in %s():\n", self->swarmList[0]->myRank, __func__ );
	Stream_Indent( info );
	
	for ( swarm_I = 0 ; swarm_I < self->swarmCount ; swarm_I++ ) {
		swarm = self->swarmList[ swarm_I ];
		particleLocalCount = swarm->particleLocalCount;
		particleSize = (SizeT) swarm->particleExtensionMgr->finalSize;

		if ( self->newFileEachTime ) {
			if ( strlen(context->checkPointPrefixString) > 0 ) {
				Stg_asprintf( &filename, "%s/%s.%s.%05d.dat", context->outputPath,
					context->checkPointPrefixString, swarm->name, context->timeStep );
			}
			else {
				Stg_asprintf( &filename, "%s/%s.%05d.dat", context->outputPath,
					swarm->name, context->timeStep );
			}
		}	
		else { 
			if ( strlen(context->checkPointPrefixString) > 0 ) {
				Stg_asprintf( &filename, "%s/%s.%s.dat", context->outputPath,
					context->checkPointPrefixString, swarm->name );
			}
			else {
				Stg_asprintf( &filename, "%s/%s.dat", context->outputPath, swarm->name );
			}
		}	

		for ( rank_I = 0; rank_I < swarm->nProc; rank_I++ ) {
			if ( swarm->myRank == rank_I ) {
				Journal_DPrintf( info, "Proc %d: for swarm \"%s\", dumping its %u particles of size %u bytes "
					"each (= %g bytes total) to file %s\n", swarm->myRank, swarm->name, particleLocalCount,
					particleSize, (float)(particleLocalCount * particleSize), filename );
			}	
			MPI_Barrier( swarm->comm );
		}

		Stream_RedirectFile( stream, filename );

		MPIStream_WriteAllProcessors( stream, swarm->particles, particleSize, (SizeT) particleLocalCount, swarm->comm );

		Stream_CloseFile( stream );
		Memory_Free( filename );
	}
	Stream_UnIndent( info );
	Journal_DPrintf( info, "Proc %d: finished Swarm binary checkpoint.\n", self->swarmList[0]->myRank );
}
void DimensionMacrosSuite_TestDimensionMacros( DimensionMacrosSuiteData* data ) {
   char    expected_file[PCU_PATH_MAX];
   Stream* stream = Journal_Register( Info_Type, (Name)"DimensionMacrosStream" );
   IJK     coord;
   IJK     meshSize;
   Index   i, j, k;

   Stream_RedirectFile( stream, "testDimensionMacros.dat" );

   Journal_Printf( stream,  "+++ 1D Tests +++\n\n" );
   coord[I_AXIS] = 3; coord[J_AXIS] = 0; coord[K_AXIS] = 0;
   meshSize[I_AXIS] = 8; meshSize[J_AXIS] = 0; meshSize[K_AXIS] = 0;
   DimensionMacrosSuite_testDimensionMacros_DoOneTest( coord, meshSize, stream );
   
   coord[I_AXIS] = 0; coord[J_AXIS] = 3; coord[K_AXIS] = 0;
   meshSize[I_AXIS] = 0; meshSize[J_AXIS] = 8; meshSize[K_AXIS] = 0;
   DimensionMacrosSuite_testDimensionMacros_DoOneTest( coord, meshSize, stream );
   
   coord[I_AXIS] = 0; coord[J_AXIS] = 0; coord[K_AXIS] = 3;
   meshSize[I_AXIS] = 0; meshSize[J_AXIS] = 0; meshSize[K_AXIS] = 8;
   DimensionMacrosSuite_testDimensionMacros_DoOneTest( coord, meshSize, stream );

   Journal_Printf( stream,  "\n+++ 2D Tests +++\n\n" );
   coord[I_AXIS] = 3; coord[J_AXIS] = 4; coord[K_AXIS] = 0;
   meshSize[I_AXIS] = 8; meshSize[J_AXIS] = 8; meshSize[K_AXIS] = 0;
   DimensionMacrosSuite_testDimensionMacros_DoOneTest( coord, meshSize, stream );
   
   coord[I_AXIS] = 3; coord[J_AXIS] = 0; coord[K_AXIS] = 4;
   meshSize[I_AXIS] = 8; meshSize[J_AXIS] = 0; meshSize[K_AXIS] = 8;
   DimensionMacrosSuite_testDimensionMacros_DoOneTest( coord, meshSize, stream );
   
   coord[I_AXIS] = 0; coord[J_AXIS] = 3; coord[K_AXIS] = 4;
   meshSize[I_AXIS] = 0; meshSize[J_AXIS] = 8; meshSize[K_AXIS] = 8;
   DimensionMacrosSuite_testDimensionMacros_DoOneTest( coord, meshSize, stream );
   
   Journal_Printf( stream,  "\n+++ 3D Tests +++\n\n" );
   meshSize[I_AXIS] = 3; meshSize[J_AXIS] = 4; meshSize[K_AXIS] = 5;
   for ( k=0; k < meshSize[K_AXIS]; k++ ) {
      for ( j=0; j < meshSize[J_AXIS]; j++ ) {
         for ( i=0; i < meshSize[I_AXIS]; i++ ) {
            coord[I_AXIS] = i; coord[J_AXIS] = j; coord[K_AXIS] = k;
            DimensionMacrosSuite_testDimensionMacros_DoOneTest( coord, meshSize, stream );
         }
      }
   }   

   pcu_filename_expected( "testDimensionMacros.expected", expected_file );
   pcu_check_fileEq( "testDimensionMacros.dat", expected_file );
   remove( "testDimensionMacros.dat" );

   Stream_CloseAndFreeFile( stream );
}
void SpaceFillerParticleLayoutSuite_TestSpaceFillerParticle( SpaceFillerParticleLayoutSuiteData* data ) {
   ExtensionManager_Register* extensionMgr_Register;
   SpaceFillerParticleLayout* particleLayout;
   ElementCellLayout*         elementCellLayout;
   Mesh*                      mesh;
   Swarm*                     swarm;
   Stream*                    stream;
   unsigned                   nDims;
   unsigned                   meshSize[3];
   double                     minCrds[3];
   double                     maxCrds[3];
   int                        procToWatch = data->nProcs > 1 ? 1 : 0;
   char                       expected_file[PCU_PATH_MAX];

   if( data->rank == procToWatch ) {
      nDims = 3;
      meshSize[0] = 4;    meshSize[1] = 2;    meshSize[2] = 1;
      minCrds[0] = 0.0;   minCrds[1] = 0.0;   minCrds[2] = 0.0;
      maxCrds[0] = 400.0; maxCrds[1] = 200.0; maxCrds[2] = 100.0;

      extensionMgr_Register = ExtensionManager_Register_New();
      mesh = SpaceFillerParticleLayoutSuite_BuildMesh( nDims, meshSize, minCrds, maxCrds, extensionMgr_Register );
      
      elementCellLayout = ElementCellLayout_New( "spaceFillerParticlElementCellLayout", NULL, mesh );
      particleLayout = SpaceFillerParticleLayout_New( "spaceFillerParticleLayout", NULL, GlobalCoordSystem, False, SpaceFillerParticleLayout_Invalid, 20, nDims );
   
      swarm = Swarm_New( "testSpaceFIllerParticle", NULL, elementCellLayout, particleLayout, nDims, sizeof(Particle),
         extensionMgr_Register, NULL, data->comm, NULL );
 
      Stg_Component_Build( swarm, 0, False );
      Stg_Component_Initialise( swarm, 0, False );

      Journal_Enable_AllTypedStream( True );
      stream = Journal_Register( Info_Type, (Name)"TestSpaceFillerParticle"  );
      Stream_RedirectFile( stream, "spaceFillerParticle.dat" );
      Swarm_PrintParticleCoords_ByCell( swarm, stream );
      Journal_Enable_AllTypedStream( False );

      pcu_filename_expected( "testSpaceFillerParticleLayoutOutput.expected", expected_file );
      pcu_check_fileEq( "spaceFillerParticle.dat", expected_file );
      remove( "spaceFillerParticle.dat" );

      Stg_Class_Delete( extensionMgr_Register );
      /*Stg_Component_Destroy( mesh, NULL, True );*/
      Stg_Component_Destroy( elementCellLayout, NULL, True );
      Stg_Component_Destroy( particleLayout, NULL, True );
      Stg_Component_Destroy( swarm, NULL, True );
   }
}
void ParticleCoordsSuite_TestLineParticle( ParticleCoordsSuiteData* data ) {
	ExtensionManager_Register*	extensionMgr_Register;
	Variable_Register*			variable_Register;
	Swarm*							swarm;
	Stream*							stream;
	Dictionary*						dictionary;
	DomainContext*					context;
	int								procToWatch = data->nProcs > 1 ? 1 : 0;
	char								input_file[PCU_PATH_MAX];
	char								expected_file[PCU_PATH_MAX];
	Stg_ComponentFactory*		cf;

	if( data->rank == procToWatch ) {
		Journal_Enable_AllTypedStream( False );
		/* Registers */
		extensionMgr_Register = ExtensionManager_Register_New();   
		variable_Register = Variable_Register_New();

		/* read in the xml input file */
		pcu_filename_input( "testLineParticleLayout.xml", input_file );
		cf = stgMainInitFromXML( input_file, data->comm, NULL );
		stgMainBuildAndInitialise( cf );
		context = (DomainContext*)LiveComponentRegister_Get( cf->LCRegister, (Name)"context" );
		dictionary = context->dictionary;

		swarm = (Swarm* ) LiveComponentRegister_Get( context->CF->LCRegister, (Name)"swarm" );
		pcu_check_true( swarm );

		Journal_Enable_AllTypedStream( True  );
		stream = Journal_Register( Info_Type, (Name)"LinearParticleStream"  );
		Stream_RedirectFile( stream, "linearParticle.dat" );
		Swarm_PrintParticleCoords( swarm, stream );
		Journal_Enable_AllTypedStream( False );

		pcu_filename_expected( "testLineParticleLayoutOutput.expected", expected_file );
		pcu_check_fileEq( "linearParticle.dat", expected_file );

		/* Destroy stuff */
		Stg_Class_Delete( extensionMgr_Register );
		Stg_Class_Delete( variable_Register );

		remove( "linearParticle.dat" );
	}

	stgMainDestroy( cf );
}
int main( int argc, char* argv[] ) {
	Dictionary* dictionary;
	Stream* stream;
	
	MPI_Init( &argc, &argv );
	BaseFoundation_Init( &argc, &argv );
	BaseIO_Init( &argc, &argv );
	stream = Journal_Register (Info_Type, "myStream");
	Stream_RedirectFile( stream, "dictionaryOutput.dat" );

	dictionary = Dictionary_New();

	Dictionary_ReadAllParamFromCommandLine( dictionary, argc, argv );
	Print( dictionary, stream );
	
	Stg_Class_Delete( dictionary );
	
	BaseIO_Finalise();
	BaseFoundation_Finalise();
	MPI_Finalize();
	
	return EXIT_SUCCESS;
}
예제 #9
0
void DofLayoutSuite_TestBasic( DofLayoutSuiteData* data ) {
   char    expected_file[PCU_PATH_MAX];
   int     procToWatch;
   Stream* stream = Journal_Register( Info_Type, (Name)"DofLayoutBasic" );   

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

   if( data->rank == procToWatch  ) {
      DofLayout*         dof;
      DofLayout*         destDof;
      Variable_Register* variableRegister;
      StgVariable*          var[6];
      char*              varName[] = {"x", "y", "z", "vx", "vy", "vz"};
      Index              ii, dof_I, var_I;
      Index              arraySize = 27;
      double*            varArrays[6];
      int                counts[27];

      Stream_RedirectFile( stream, "testBasic.dat" );

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

      /* Create variables */
      for (var_I = 0; var_I < 6; var_I++) {
         varArrays[var_I] = Memory_Alloc_Array_Unnamed( double, arraySize );
         var[var_I] = StgVariable_NewScalar( varName[var_I], NULL, StgVariable_DataType_Double, (Index*)&arraySize, NULL, (void**)&(varArrays[var_I]), variableRegister  );
         Stg_Component_Build( var[var_I], 0, False );
         Stg_Component_Initialise( var[var_I], 0, False );
      }

      for (ii = 0; ii < arraySize; ii++) {
         for (var_I = 0; var_I < 6; var_I++) {
            StgVariable_SetValueDouble( var[var_I], ii, 0.0 );
         }
      }

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

      Stg_Component_Build(dof, 0, False);

      Journal_Printf( stream, "Simple test:\n" );
        for (ii = 0; ii < arraySize; ii++) {
         Journal_Printf( stream, "\t%u\n", dof->dofCounts[ii] );
         pcu_check_true( dof->dofCounts[ii] == 6 );
      }
         
      Stg_Class_Delete(dof);

      /* Advanced test */
      for (ii = 0; ii < 27; ii++) counts[ii] = 0;
      dof = DofLayout_New( "dofLayout1", variableRegister, arraySize, NULL );
      
      for (ii = 0; ii < 12; ii++) {
         for (var_I = 0; var_I < 2; var_I++) {
            DofLayout_AddDof_ByVarName(dof, varName[var_I], ii);
            counts[ii]++;
         }
      }
 
      for (ii = 9; ii < 20; ii++) {
         for (var_I = 2; var_I < 6; var_I++) {
            DofLayout_AddDof_ByVarName(dof, varName[var_I], ii);
            counts[ii]++;
         }
      }
 
      Stg_Component_Build(dof, 0, False);
 
      Journal_Printf( stream, "\nAdvanced test:\n" );
      for (ii = 0; ii < arraySize; ii++) {
         Journal_Printf( stream, "\t%u\n", dof->dofCounts[ii] );
         pcu_check_true( counts[ii] == dof->dofCounts[ii] );
      }
      Stg_Class_Delete(dof);

      /* Copy test */
       dof = DofLayout_New( "dofLayout2", variableRegister, arraySize, NULL );
      destDof = DofLayout_New( "dofLayout3", variableRegister, arraySize, NULL );
      for (ii = 0; ii < arraySize; ii++) {
         for (var_I = 0; var_I < 3; var_I++) {
            DofLayout_AddDof_ByVarName(dof, varName[var_I], ii);
         }
         for (var_I = 3; var_I < 6; var_I++) {
            DofLayout_AddDof_ByVarName(destDof, varName[var_I], ii);
         }
      }

      Stg_Component_Build(dof, NULL, False);
      Stg_Component_Build(destDof, NULL, False);

      for (ii = 0; ii < arraySize; ii++) {
         for (dof_I = 0; dof_I < 3; dof_I++) {
            DofLayout_SetValueDouble( dof, ii, dof_I, ii*10 );
            DofLayout_SetValueDouble( destDof, ii, dof_I, 0 );
         }
      }

      Journal_Printf( stream, "Copy Test: pre copy:\n" );
      for (ii = 0; ii < arraySize; ii++) {
         Journal_Printf( stream, "\tIndex %d - src %2g,%2g,%2g - dest %2g, %2g, %2g\n", ii,
            DofLayout_GetValueDouble( dof, ii, 0 ),
            DofLayout_GetValueDouble( dof, ii, 1 ),
            DofLayout_GetValueDouble( dof, ii, 2 ),
            DofLayout_GetValueDouble( destDof, ii, 0 ),
            DofLayout_GetValueDouble( destDof, ii, 1 ),
            DofLayout_GetValueDouble( destDof, ii, 2 ) );
         pcu_check_true( DofLayout_GetValueDouble( dof, ii, 0 ) == ii * 10 );
         pcu_check_true( DofLayout_GetValueDouble( dof, ii, 1 ) == ii * 10 );
         pcu_check_true( DofLayout_GetValueDouble( dof, ii, 2 ) == ii * 10 );
         pcu_check_true( DofLayout_GetValueDouble( destDof, ii, 0 ) == 0 );
         pcu_check_true( DofLayout_GetValueDouble( destDof, ii, 1 ) == 0 );
         pcu_check_true( DofLayout_GetValueDouble( destDof, ii, 2 ) == 0 );
      }

      DofLayout_CopyValues( dof, destDof );

      Journal_Printf( stream, "Copy Test: post copy:\n" );
      for (ii = 0; ii < arraySize; ii++) {
         Journal_Printf( stream, "\tIndex %d - src %2g,%2g,%2g - dest %2g, %2g, %2g\n", ii,
            DofLayout_GetValueDouble( dof, ii, 0 ),
            DofLayout_GetValueDouble( dof, ii, 1 ),
            DofLayout_GetValueDouble( dof, ii, 2 ),
            DofLayout_GetValueDouble( destDof, ii, 0 ),
            DofLayout_GetValueDouble( destDof, ii, 1 ),
            DofLayout_GetValueDouble( destDof, ii, 2 ) );
         pcu_check_true( DofLayout_GetValueDouble( dof, ii, 0 ) == DofLayout_GetValueDouble( destDof, ii, 0 ) );
         pcu_check_true( DofLayout_GetValueDouble( dof, ii, 1 ) == DofLayout_GetValueDouble( destDof, ii, 1 ) );
         pcu_check_true( DofLayout_GetValueDouble( dof, ii, 2 ) == DofLayout_GetValueDouble( destDof, ii, 2 ) );
      }

      Stg_Class_Delete(destDof);

      Journal_Printf( stream, "Zero Test: all values in src dof should be zero again\n" );
      DofLayout_SetAllToZero( dof );
      for (ii = 0; ii < arraySize; ii++) {
         Journal_Printf( stream,  "\tIndex %d - src %2g,%2g,%2g\n", ii,
            DofLayout_GetValueDouble( dof, ii, 0 ),
            DofLayout_GetValueDouble( dof, ii, 1 ),
            DofLayout_GetValueDouble( dof, ii, 2 ) );
         pcu_check_true( DofLayout_GetValueDouble( dof, ii, 0 ) == 0 );
         pcu_check_true( DofLayout_GetValueDouble( dof, ii, 1 ) == 0 );
         pcu_check_true( DofLayout_GetValueDouble( dof, ii, 2 ) == 0 );
      }

      Stg_Class_Delete(dof);

      /* Cleanup */

      Stg_Class_Delete(variableRegister);

      for (var_I = 0; var_I < 6; var_I++) {
         if (var[var_I]) Stg_Class_Delete(var[var_I]);
            Memory_Free( varArrays[var_I] );
      }
      pcu_filename_expected( "testDofLayoutBasicOutput.expected", expected_file );
      pcu_check_fileEq( "testBasic.dat", expected_file );
      remove( "testBasic.dat" );
   }
void WallVCSuite_TestWallVC( WallVCSuiteData* data ) {
   unsigned                    nDomains;
   unsigned                    nDims = 3;
   unsigned                    meshSize[3] = {3, 3, 3};
   int                         procToWatch;
   double                      minCrds[3] = {0.0, 0.0, 0.0};
   double                      maxCrds[3] = {1.0, 1.0, 1.0};
   char*                       vcKey[] = {"WallVC_Front", "WallVC_Back", "WallVC_Left", "WallVC_Right",
                                          "WallVC_Top", "WallVC_Bottom"};
   char*                       vcKeyName[] = {"WallVC_FrontName", "WallVC_BackName", "WallVC_LeftName", "WallVC_RightName",
                                          "WallVC_TopName", "WallVC_BottomName"};
   char*                       varName[] = {"x", "y", "z", "vx", "vy", "vz", "temp"};
   char                        input_file[PCU_PATH_MAX];
   char                        expected_file[PCU_PATH_MAX];
   Mesh*                       mesh;
   Variable_Register*          variable_Register;
   ConditionFunction*          quadCF;
   ConditionFunction*          expCF;
   ConditionFunction_Register* conFunc_Register;
   ExtensionManager_Register*  extensionMgr_Register;
   Dictionary*                 dictionary;
   Dictionary*                 sources;
   Stream*                     stream;
   XML_IO_Handler*             io_handler;
   Variable*                   var[7];
   double*                     array[7];
   VariableCondition*          vc; 
   Index                       i;

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

   io_handler = XML_IO_Handler_New();

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

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

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

   extensionMgr_Register = ExtensionManager_Register_New(); 

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

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

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

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

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

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

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

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

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

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

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

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

   Stg_Class_Delete(variable_Register);
   for (i = 0; i < 7; i++) {
      Stg_Class_Delete(var[i]);
      if (array[i]) Memory_Free(array[i]);
   }
   Stg_Class_Delete(extensionMgr_Register);
   Stg_Class_Delete(io_handler);
   Stg_Class_Delete(conFunc_Register);
   Stg_Class_Delete(quadCF);
   Stg_Class_Delete(expCF);
   Stg_Class_Delete(dictionary);
   Stg_Class_Delete(sources);
   FreeObject( mesh );
}
void SobolGeneratorSuite_TestSobolGenerator( SobolGeneratorSuiteData* data ) {
   int             procToWatch;
   Stream*         stream;
   SobolGenerator* sobolGenerator;
   Index           index;
   Index           sobol_I;
   int             bit_I;
   double          result;
   char            output_file[PCU_PATH_MAX];
   char            rightmostBit_file[PCU_PATH_MAX];
   char            expected_name[PCU_PATH_MAX];
   char            expected_file[PCU_PATH_MAX];

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

   if( data->rank == procToWatch ) {
      stream = Journal_Register( Info_Type, (Name)"SobolGeneratorStream" );
      Stream_RedirectFile( stream, "testSobolGeneratorRightmostBit.dat" );
   
      Journal_Printf( stream, " *********************** Testing _SobolGenerator_FindRightmostZeroBit *******************\n" );
      for ( index = 0 ; index < 30 ; index++ ) {
         for ( bit_I = sizeof( Index ) * 4 - 1 ; bit_I >= 0 ; bit_I-- )
            Journal_Printf( stream, "%u", index & 1 << bit_I ? 1 : 0 );
         Journal_Printf( stream, " number %u: %u\n", index, _SobolGenerator_FindRightmostZeroBit( index ) );
      }

      /* constructor  */
      for ( sobol_I = 0 ; sobol_I < 100 ; sobol_I++ ) {
         sprintf( output_file, "testSobolGenerator.%03u.dat", sobol_I );
         Stream_RedirectFile( stream, output_file );
         sobolGenerator = SobolGenerator_NewFromTable( output_file );

         Journal_Printf( stream," ****************** Testing SobolGenerator_GetDirectionalNumber ***************\n" );
         for ( index = 0 ; index < 30 ; index++ )
            SobolGenerator_GetDirectionalNumber( sobolGenerator, index );
   
         /* Checking up to 200000 numbers - this number is arbitary - 
         * it's only limited because we don't want file size to be huge
         * This number is intentionally over 25535 = 2^16 - 1 because there was a time when numbers repeated after this */
         for ( index = 0 ; index < 200000 ; index++ ) {
            result = SobolGenerator_GetNextNumber(sobolGenerator);
   
            assert( fabs( result - SobolGenerator_GetNumberByIndex(sobolGenerator, index)) < 1e-8 );

            /* Only dump subset of data - this output criterion is completely arbitary */
            if ( index % 773 == 3 )
               Journal_Printf( stream, "%.4g\n", result );
         }
         sprintf( expected_name, "testSobolGeneratorOutput.%03u-%03u.expected", sobolGenerator->polynomialDegree, sobolGenerator->polynomialCoefficient );

         pcu_filename_expected( "testSobolGeneratorRightmostBitOutput.expected", rightmostBit_file );
         pcu_check_fileEq( "testSobolGeneratorRightmostBit.dat", rightmostBit_file );

         pcu_filename_expected( expected_name, expected_file );
         pcu_check_fileEq( output_file, expected_file ); 

         remove( output_file );

         Stg_Class_Delete( sobolGenerator );
      }
      remove( "testSobolGeneratorRightmostBit.dat" );
   }
}
void TimeIntegrationSuite_TestDriver( TimeIntegrationSuiteData* data, char *_name, char *_DerivName0, char *_DerivName1, int _order ) {
   Stg_ComponentFactory* cf;
   Stream*               stream;
   Dictionary*           dictionary;
   TimeIntegrator*       timeIntegrator;
   TimeIntegrand*        timeIntegrand;
   TimeIntegrand*        timeIntegrandList[2];
   DomainContext*        context;
   Variable*             variable;
   Variable*             variableList[2];
   double*               array;
   double*               array2;
   Index                 size0 = 11;
   Index                 size1 = 7;
   Index                 array_I;
   Index                 timestep = 0;
   Index                 maxTimesteps = 10;
   Bool                  simultaneous;
   unsigned              order;
   double                error = 0.0;
   Name                  derivName;
   double                tolerance = 0.001;
   Index                 integrand_I;
   Index                 integrandCount = 2;
   char                  expected_file[PCU_PATH_MAX];

   dictionary = Dictionary_New();
   Dictionary_Add( dictionary, (Dictionary_Entry_Key)"outputPath", Dictionary_Entry_Value_FromString("./output") );
   Dictionary_Add( dictionary, (Dictionary_Entry_Key)"DerivName0", Dictionary_Entry_Value_FromString(_DerivName0) );
   Dictionary_Add( dictionary, (Dictionary_Entry_Key)"DerivName1", Dictionary_Entry_Value_FromString(_DerivName1) );

   context = DomainContext_New( "context", 0, 0, MPI_COMM_WORLD, NULL );
   cf = stgMainConstruct( dictionary, NULL, data->comm, context );
   stgMainBuildAndInitialise( cf );
      
   ContextEP_Append( context, AbstractContext_EP_Dt, TimeIntegrationSuite_GetDt );

   /* Create Stuff */
   order = _order;
   simultaneous = False;
   variableList[0] = Variable_NewVector( "testVariable", (AbstractContext*)context, Variable_DataType_Double, 2, &size0, NULL, (void**)&array, NULL );
   variableList[1] = Variable_NewVector( "testVariable2", (AbstractContext*)context, Variable_DataType_Double, 2, &size1, NULL, (void**)&array2, NULL );
   timeIntegrator = TimeIntegrator_New( "testTimeIntegrator", order, simultaneous, NULL, NULL );
   timeIntegrator->context = context;
   timeIntegrandList[0] = TimeIntegrand_New( "testTimeIntegrand0", context, timeIntegrator, variableList[0], 0, NULL, True );
   timeIntegrandList[1] = TimeIntegrand_New( "testTimeIntegrand1", context, timeIntegrator, variableList[1], 0, NULL, True );

   Journal_Enable_AllTypedStream( True );
   stream = Journal_Register( Info_Type, (Name)"EulerStream"  );
   Stream_RedirectFile( stream, _name );

   Stream_Enable( timeIntegrator->info, False );
   derivName = Dictionary_GetString( dictionary, (Dictionary_Entry_Key)"DerivName0" );
   timeIntegrandList[0]->_calculateTimeDeriv = TimeIntegrationSuite_GetFunctionPtr( derivName  );
   Journal_Printf( stream, "DerivName0 - %s\n", derivName );
   derivName = Dictionary_GetString( dictionary, (Dictionary_Entry_Key)"DerivName1" );
   timeIntegrandList[1]->_calculateTimeDeriv = TimeIntegrationSuite_GetFunctionPtr( derivName  );
   Journal_Printf( stream, "DerivName1 - %s\n", derivName );

   /* Print Stuff to file */
   Journal_PrintValue( stream, order );
   Journal_PrintBool( stream, simultaneous );

   /* Add stuff to EPs */
   TimeIntegrator_AppendSetupEP( timeIntegrator, "start1", TimeIntegrationSuite_TestContextType, CURR_MODULE_NAME, context );
   TimeIntegrator_AppendFinishEP( timeIntegrator, "finish1", TimeIntegrationSuite_TestVariableType, CURR_MODULE_NAME, variableList[0] );
   TimeIntegrator_PrependSetupEP( timeIntegrator, "start0", TimeIntegrationSuite_TestVariableType, CURR_MODULE_NAME, variableList[0] );
   TimeIntegrator_PrependFinishEP( timeIntegrator, "finish0", TimeIntegrationSuite_TestContextType, CURR_MODULE_NAME, context );

   /* Build */
   Stg_Component_Build( variableList[0], context, False );
   Stg_Component_Build( variableList[1], context, False );
   Stg_Component_Build( timeIntegrator, context, False );
   Stg_Component_Build( timeIntegrandList[0], context, False );
   Stg_Component_Build( timeIntegrandList[1], context, False );
   array = Memory_Alloc_Array( double, 2 * size0, "name" );
   array2 = Memory_Alloc_Array( double, 2 * size1, "name" );

   /* Initialise */
   memset( array, 0, sizeof(double) * 2 * size0 );
   memset( array2, 0, sizeof(double) * 2 * size1 );
   Stg_Component_Initialise( timeIntegrator, context, False );
   Stg_Component_Initialise( variableList[0], context, False );
   Stg_Component_Initialise( variableList[1], context, False );
   Stg_Component_Initialise( timeIntegrandList[0], context, False );
   Stg_Component_Initialise( timeIntegrandList[1], context, False );

   for ( timestep = 0.0 ; timestep < maxTimesteps ; timestep ++ ) {
      Journal_Printf( stream, "Step %u - Time = %.3g\n", timestep, context->currentTime );

      Stg_Component_Execute( timeIntegrator, context, True );
      context->currentTime += AbstractContext_Dt( context );

      for ( integrand_I = 0 ; integrand_I < integrandCount ; integrand_I++ ) {
         timeIntegrand   = timeIntegrandList[ integrand_I ];
         variable         = variableList[ integrand_I ];
         for ( array_I = 0 ; array_I < variable->arraySize ; array_I++ ) {
            if ( timeIntegrand->_calculateTimeDeriv == TimeIntegrationSuite_ConstantTimeDeriv ) {
               error += fabs( Variable_GetValueAtDouble( variable, array_I, 0 ) - 2.0 * array_I * context->currentTime );
               error += fabs( Variable_GetValueAtDouble( variable, array_I, 1 ) + array_I * context->currentTime );
            }
            else if ( timeIntegrand->_calculateTimeDeriv == TimeIntegrationSuite_ConstantTimeDeriv2 ) {
               error += fabs( Variable_GetValueAtDouble( variable, array_I, 0 ) + 0.5 * array_I * context->currentTime );
               error += fabs( Variable_GetValueAtDouble( variable, array_I, 1 ) - 3 * array_I * context->currentTime );
            }
            else if ( timeIntegrand->_calculateTimeDeriv == TimeIntegrationSuite_LinearTimeDeriv ) {
               error += fabs( Variable_GetValueAtDouble( variable, array_I, 0 ) - array_I * context->currentTime * context->currentTime );
               error += fabs( Variable_GetValueAtDouble( variable, array_I, 1 ) + 0.5 * array_I * context->currentTime * context->currentTime );
            }
            else if ( timeIntegrand->_calculateTimeDeriv == TimeIntegrationSuite_LinearTimeDeriv2 ) {
               error += fabs( Variable_GetValueAtDouble( variable, array_I, 0 ) + 0.25 * array_I * context->currentTime * context->currentTime );
               error += fabs( Variable_GetValueAtDouble( variable, array_I, 1 ) - 1.5 * array_I * context->currentTime * context->currentTime );
            }
            else if ( timeIntegrand->_calculateTimeDeriv == TimeIntegrationSuite_CubicTimeDeriv ) {
               error += fabs( Variable_GetValueAtDouble( variable, array_I, 0 ) - 2.0 * array_I * ( 0.25 * pow( context->currentTime, 4.0 ) - pow( context->currentTime, 3.0)/3.0));
               error += fabs( Variable_GetValueAtDouble( variable, array_I, 1 ) + array_I * ( 0.25 * pow( context->currentTime, 4.0 ) - pow( context->currentTime, 3.0 )/3.0));
            }
            else if ( timeIntegrand->_calculateTimeDeriv == TimeIntegrationSuite_CubicTimeDeriv2 ) {
               error += fabs( Variable_GetValueAtDouble( variable, array_I, 0 ) + 0.5 * array_I * ( 0.25 * pow( context->currentTime, 4.0 ) - pow( context->currentTime, 3.0)/3.0));
               error += fabs( Variable_GetValueAtDouble( variable, array_I, 1 ) - 3.0 * array_I * ( 0.25 * pow( context->currentTime, 4.0 ) - pow( context->currentTime, 3.0 )/3.0));
            }
            else
               Journal_Firewall( 0 , Journal_Register( Error_Type, (Name)CURR_MODULE_NAME  ), "Don't understand _calculateTimeDeriv = %p\n", timeIntegrand->_calculateTimeDeriv );
         }
      }
   }
   pcu_check_lt( error, tolerance );

   if ( error < tolerance )
      Journal_Printf( stream, "Passed\n" );
   else
      Journal_Printf( stream, "Failed - Error = %lf\n", error );
   
   Journal_Enable_AllTypedStream( False );

   if ( timeIntegrand->_calculateTimeDeriv == TimeIntegrationSuite_ConstantTimeDeriv
      || timeIntegrand->_calculateTimeDeriv == TimeIntegrationSuite_ConstantTimeDeriv2 ) {
      pcu_filename_expected( "testTimeIntegrationEulerOutput.expected", expected_file );
   }
   else if ( timeIntegrand->_calculateTimeDeriv == TimeIntegrationSuite_LinearTimeDeriv
      || timeIntegrand->_calculateTimeDeriv == TimeIntegrationSuite_LinearTimeDeriv2 ) {
      pcu_filename_expected( "testTimeIntegrationRK2Output.expected", expected_file );
   }
   else if ( timeIntegrand->_calculateTimeDeriv == TimeIntegrationSuite_CubicTimeDeriv
      || timeIntegrand->_calculateTimeDeriv == TimeIntegrationSuite_CubicTimeDeriv2 ) {
      pcu_filename_expected( "testTimeIntegrationRK4Output.expected", expected_file );
   }

   pcu_check_fileEq( _name, expected_file );

   /* Destroy stuff */
   Stream_CloseAndFreeFile( stream );
   Memory_Free( array );
   Memory_Free( array2 );
   Stg_Class_Delete( variable );
   _Stg_Component_Delete( timeIntegrator );
   _Stg_Component_Delete( timeIntegrandList[0] );
   _Stg_Component_Delete( timeIntegrandList[1] );
   remove( _name );
}
void ComplexVectorMathSuite_TestComplexVectorMathBasic( ComplexVectorMathSuiteData* data ) {
   unsigned procToWatch;
   Stream*  stream = Journal_Register( Info_Type, (Name)"VectorMathBasicStream" );
   char     expected_file[PCU_PATH_MAX];

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

   if (data->rank == procToWatch ) {
      CoordC a, b, c;
      CoordC d = { {1.0, 1.0}, {1.0, 0.0}, {0.0, 1.0} };
      CoordC e = { {1.0, 0.0}, {2.0, 2.0}, {-3.0, -1.0} };
      Cmplx  value = {1.0, 1.0}; 
      Cmplx  c1 = {1.0, 0.0};
      Cmplx  c2 = {2.0, 1.0};
      Cmplx  c3 = {1.5, 1.0};

      Stream_RedirectFile( stream, "testComplexVectorMathBasic.dat" );

      Journal_Printf( stream, "Basic tests:\n" );
      Journal_Printf( stream, "d = \n");
      Journal_PrintCmplx( stream, d[0]);
      Journal_PrintCmplx( stream, d[1]);
      Journal_PrintCmplx( stream, d[2]);
       
      Journal_Printf( stream, "Set Complex Scalar\n");
      ComplexVector_SetScalar( c1, c2, c3, d );
      Journal_Printf( stream, "d = \n");
      Journal_PrintCmplx( stream, d[0]);
      Journal_PrintCmplx( stream, d[1]);
      Journal_PrintCmplx( stream, d[2]);

      Journal_Printf( stream, "Set c = d\n");
      ComplexVector_Set( d, c );
      Journal_Printf( stream, "c = \n");
      Journal_PrintCmplx( stream, c[0]);
      Journal_PrintCmplx( stream, c[1]);
      Journal_PrintCmplx( stream, c[2]);

      ComplexVector_Add(c, d, b );
      Journal_Printf( stream, "b = c + d \n");
      Journal_Printf( stream, "b = \n");
      Journal_PrintCmplx( stream, b[0]);
      Journal_PrintCmplx( stream, b[1]);
      Journal_PrintCmplx( stream, b[2]);

      ComplexVector_Sub( b, d, a );
      Journal_Printf( stream, "a = b - d \n");
      Journal_Printf( stream, "a = \n");
      Journal_PrintCmplx( stream, a[0]);
      Journal_PrintCmplx( stream, a[1]);
      Journal_PrintCmplx( stream, a[2]);

      ComplexVector_Cross( a, e, d );      
      Journal_Printf( stream, "d = a x e \n");
      Journal_Printf( stream, "e = \n");
      Journal_PrintCmplx( stream, e[0]);
      Journal_PrintCmplx( stream, e[1]);
      Journal_PrintCmplx( stream, e[2]);      
      Journal_Printf( stream, "d = \n");
      Journal_PrintCmplx( stream, d[0]);
      Journal_PrintCmplx( stream, d[1]);
      Journal_PrintCmplx( stream, d[2]);
      
      ComplexVector_Dot( a, e, value );
      Journal_Printf( stream, "value = a . e \n");
      Journal_PrintCmplx( stream, value);
      
      value[REAL_PART] = 2.0;
      value[IMAG_PART] = 1.0;
      Journal_Printf( stream, "b = \n");
      Journal_PrintCmplx( stream, b[0]);
      Journal_PrintCmplx( stream, b[1]);
      Journal_PrintCmplx( stream, b[2]);      
      ComplexVector_Mult( b, value, b);
      Journal_Printf( stream, "b = (2 + i) * b \n");
      Journal_Printf( stream, "b = \n");
      Journal_PrintCmplx( stream, b[0]);
      Journal_PrintCmplx( stream, b[1]);
      Journal_PrintCmplx( stream, b[2]);
      
      ComplexVector_MultReal(b, 3.0, b);
      Journal_Printf( stream, "b = 3 * b \n");
      Journal_Printf( stream, "b = \n");
      Journal_PrintCmplx( stream, b[0]);
      Journal_PrintCmplx( stream, b[1]);
      Journal_PrintCmplx( stream, b[2]);   

      b[0][REAL_PART] = 0.0; b[0][IMAG_PART] = 1.0; 
      b[1][REAL_PART] = 1.0; b[1][IMAG_PART] = 1.0;
      b[2][REAL_PART] = 0.0; b[2][IMAG_PART] = 1.0;
      
      Journal_Printf( stream, "b = \n");
      Journal_PrintCmplx( stream, b[0]);
      Journal_PrintCmplx( stream, b[1]);
      Journal_PrintCmplx( stream, b[2]);

      Journal_Printf( stream, "|b| = %g\n", ComplexVector_Mag(b));
            
      ComplexVector_Proj(a, b, d);
      Journal_Printf( stream, "d = proj a onto b \n");
      Journal_Printf( stream, "d = \n");
      Journal_PrintCmplx( stream, d[0]);
      Journal_PrintCmplx( stream, d[1]);
      Journal_PrintCmplx( stream, d[2]);         
      
      ComplexVector_Div(a, value, e);
      Journal_Printf( stream, "e = a / value \n");
      Journal_PrintCmplx( stream, value);
      Journal_Printf( stream, "e = \n");
      Journal_PrintCmplx( stream, e[0]);
      Journal_PrintCmplx( stream, e[1]);
      Journal_PrintCmplx( stream, e[2]);

      Journal_Printf( stream, "b = \n");
      Journal_PrintCmplx( stream, b[0]);
      Journal_PrintCmplx( stream, b[1]);
      Journal_PrintCmplx( stream, b[2]);
      ComplexVector_Norm( b, b );
      Journal_Printf( stream, "Norm(b) = \n");
      Journal_PrintCmplx( stream, b[0]);
      Journal_PrintCmplx( stream, b[1]);
      Journal_PrintCmplx( stream, b[2]);
   
      Journal_Printf( stream, "|b| = %g\n", ComplexVector_Mag(b));
      
      Journal_Printf( stream, "a  = \n");
      Journal_PrintCmplx( stream, a[0]);
      Journal_PrintCmplx( stream, a[1]);
      Journal_PrintCmplx( stream, a[2]);
      
      ComplexVector_Swizzle(a, K_AXIS, I_AXIS, J_AXIS, a);
      Journal_Printf( stream, "swizzle(a)(k, i, j) = \n");
      Journal_PrintCmplx( stream, a[0]);
      Journal_PrintCmplx( stream, a[1]);
      Journal_PrintCmplx( stream, a[2]);

      pcu_filename_expected( "testComplexVectorMathBasic.expected", expected_file );
      pcu_check_fileEq( "testComplexVectorMathBasic.dat", expected_file );
      remove( "testComplexVectorMathBasic.dat" );

      Stream_CloseAndFreeFile( stream );
   }
}
void ComplexVectorMathSuite_TestComplexVectorMathOperations( ComplexVectorMathSuiteData* data ) {
   unsigned procToWatch;
   Stream*  stream = Journal_Register( Info_Type, (Name)"VectorMathOperationsStream" );
   char     expected_file[PCU_PATH_MAX];

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

   if (data->rank == procToWatch ) {
      #define STG_COMPLEXVECTOR_TOL 1e-16;
      
      Cmplx  i[] = {{1.00000000, 0.000000000},{0.00000000, 0.000000000},{0.000000000, 0.00000000}};
      Cmplx  j[] = {{0.00000000, 0.00000000},{1.0000000, 0.00000000},{0.00000000, 0.0000000}};
      Cmplx  k[] = {{0.00000000, 0.000000000},{0.00000000, 0.000000000},{1.000000000, 0.000000000}};
      Cmplx  A[] = {{7.4, 1.0}, {  2, 0.0}, {  5, 1.0}, { 1, 0.0}, {  3, 2.0}, {  -42, 0.0}};
      Cmplx  B[] = {{  4, 2.0}, {2.3, 0.0}, {5.8, 0.0}, { 6, 0.0}, {-12, 0.0}, {39289, 0.0}};
      Cmplx  C[] = {{23, 0.0}, {  5, 0.0}, {-14, 0.0}, {32, 0.0}, {-21, 1.0}, {   78, 0.0}};
      Cmplx  D[] = {{23, 0.0}, {  5, 0.0}, {-14, 0.0}, {32, 0.0}, {-21, 0.0}, {   78, 0.0}};
      double angle;
      Cmplx  **matrix;
      Cmplx  vector[6], differenceVector[6];
      Cmplx  *coordList[4];
      int    d;
      double realVector[3], tolerance;
      Cmplx  dotProductResult;
      Cmplx  value;
      
      Stream_RedirectFile( stream, "testComplexVectorMathOperations.dat" );

      tolerance = STG_COMPLEXVECTOR_TOL;
      
      coordList[0] = A;
      coordList[1] = B;
      coordList[2] = C;
      coordList[3] = D;
      Journal_Printf( stream, "****************************\n");
      Journal_Printf(stream, "Vectors - A, B, C, and D\n");
      
      StGermain_PrintNamedComplexVector( stream, A, 6 );
      StGermain_PrintNamedComplexVector( stream, B, 6 );
      StGermain_PrintNamedComplexVector( stream, C, 6 );
      StGermain_PrintNamedComplexVector( stream, D, 6 );

      /* Check Rotation functions */
      Journal_Printf( stream, "\n****************************\n");

      StGermain_PrintNamedComplexVector( stream, i, 3 );
      StGermain_PrintNamedComplexVector( stream, j, 3 );
      StGermain_PrintNamedComplexVector( stream, k, 3 );
      
      angle = M_PI / 2.0;
      
      Journal_Printf(stream, "Axis Rotation\n");            
      StGermain_RotateCoordinateAxisComplex( k, I_AXIS, angle, vector ) ;
      Journal_Printf( stream, "K Rotated %g radians around I axis - \n", angle);
      Cmplx_Subtract(vector[0], j[0], differenceVector[0]);
      Cmplx_Subtract(vector[1], j[1], differenceVector[1]);
      Cmplx_Subtract(vector[2], j[2], differenceVector[2]);
      
      if ( (Cmplx_Modulus(differenceVector[0]) < tolerance) && (Cmplx_Modulus(differenceVector[1]) < tolerance) &&
          (Cmplx_Modulus(differenceVector[2]) < tolerance) ) {
         Journal_Printf( stream, "Answer within tolerance %g of expected result: ", tolerance);
         StGermain_PrintNamedComplexVector( stream, j, 3);
      }
      else {
         Journal_Printf( stream, "Answer not within tolerance %g of expected result: ", tolerance);
         StGermain_PrintNamedComplexVector( stream, j, 3);
      }
      
      Journal_Printf(stream, "Angle Rotation\n");      
      StGermain_RotateComplexVector(k, angle,0.0, 0.0, vector);
      Journal_Printf( stream, "K Rotated %g radians around I axis - \n", angle); 
      Cmplx_Subtract(vector[0], j[0], differenceVector[0]);
      Cmplx_Subtract(vector[1], j[1], differenceVector[1]);
      Cmplx_Subtract(vector[2], j[2], differenceVector[2]);
      
      if ( (Cmplx_Modulus(differenceVector[0]) < tolerance) && (Cmplx_Modulus(differenceVector[1]) < tolerance) &&
          (Cmplx_Modulus(differenceVector[2]) < tolerance) ) {
         Journal_Printf( stream, "Answer within tolerance %g of expected result: ", tolerance);
         StGermain_PrintNamedComplexVector( stream, j, 3);
      }
      else {
         Journal_Printf( stream, "Answer not within tolerance %g of expected result: ", tolerance);
         StGermain_PrintNamedComplexVector( stream, j, 3);
      }
      
      Journal_Printf(stream, "Axis Rotation\n");      
      StGermain_RotateCoordinateAxisComplex( i, J_AXIS, angle, vector );
      Journal_Printf( stream, "I Rotated %g radians around J axis - \n", angle); 
      Cmplx_Subtract(vector[0], k[0], differenceVector[0]);
      Cmplx_Subtract(vector[1], k[1], differenceVector[1]);
      Cmplx_Subtract(vector[2], k[2], differenceVector[2]);
      
      if ( (Cmplx_Modulus(differenceVector[0]) < tolerance) && (Cmplx_Modulus(differenceVector[1]) < tolerance) &&
          (Cmplx_Modulus(differenceVector[2]) < tolerance) ) {
         Journal_Printf( stream, "Answer within tolerance %g of expected result: ", tolerance);
         StGermain_PrintNamedComplexVector( stream, k, 3);
      }
      else {
         Journal_Printf( stream, "Answer not within tolerance %g of expected result: ", tolerance);
         StGermain_PrintNamedComplexVector( stream, k, 3);
      }
      
      Journal_Printf(stream, "Angle Rotation\n");
      StGermain_RotateComplexVector(i, 0.0, angle, 0.0, vector );
      Journal_Printf( stream, "I Rotated %g radians around J axis - \n", angle); 
      Cmplx_Subtract(vector[0], k[0], differenceVector[0]);
      Cmplx_Subtract(vector[1], k[1], differenceVector[1]);
      Cmplx_Subtract(vector[2], k[2], differenceVector[2]);
      
      if ( (Cmplx_Modulus(differenceVector[0]) < tolerance) && (Cmplx_Modulus(differenceVector[1]) < tolerance) &&
          (Cmplx_Modulus(differenceVector[2]) < tolerance) ) {
         Journal_Printf( stream, "Answer within tolerance %g of expected result: ", tolerance);
         StGermain_PrintNamedComplexVector( stream, k, 3);
      }
      else {
         Journal_Printf( stream, "Answer not within tolerance %g of expected result: ", tolerance);
         StGermain_PrintNamedComplexVector( stream, k, 3);
      }
      
      Journal_Printf(stream, "Axis Rotation\n");      
      StGermain_RotateCoordinateAxisComplex( j, K_AXIS, angle, vector );
      Journal_Printf( stream, "J Rotated %g radians around K axis - \n", angle); 
      Cmplx_Subtract(vector[0], i[0], differenceVector[0]);
      Cmplx_Subtract(vector[1], i[1], differenceVector[1]);
      Cmplx_Subtract(vector[2], i[2], differenceVector[2]);
      
      if ( (Cmplx_Modulus(differenceVector[0]) < tolerance) && (Cmplx_Modulus(differenceVector[1]) < tolerance) &&
          (Cmplx_Modulus(differenceVector[2]) < tolerance) ) {
         Journal_Printf( stream, "Answer within tolerance %g of expected result: ", tolerance);
         StGermain_PrintNamedComplexVector( stream, i, 3);
      }
      else {
         Journal_Printf( stream, "Answer not within tolerance %g of expected result: ", tolerance);
         StGermain_PrintNamedComplexVector( stream, i, 3);
      }

      Journal_Printf(stream, "Angle Rotation\n");
      StGermain_RotateComplexVector( j, 0.0, 0.0, angle, vector );
      Journal_Printf( stream, "J Rotated %g radians around K axis - \n", angle); 
      Cmplx_Subtract(vector[0], i[0], differenceVector[0]);
      Cmplx_Subtract(vector[1], i[1], differenceVector[1]);
      Cmplx_Subtract(vector[2], i[2], differenceVector[2]);
      
      if ( (Cmplx_Modulus(differenceVector[0]) < tolerance) && (Cmplx_Modulus(differenceVector[1]) < tolerance) &&
          (Cmplx_Modulus(differenceVector[2]) < tolerance) ) {
         Journal_Printf( stream, "Answer within tolerance %g of expected result: ", tolerance);
         StGermain_PrintNamedComplexVector( stream, i, 3);
      }
      else {
         Journal_Printf( stream, "Answer not within tolerance %g of expected result: ", tolerance);
         StGermain_PrintNamedComplexVector( stream, i, 3);
      }

      angle = M_PI / 4.0;

      StGermain_RotateComplexVector(i, 0.0, angle, angle, vector );
      Journal_Printf( stream, "I Rotated %g radians around J axis "
      "and %2g radians around K axis: \n", angle, angle);
      StGermain_PrintNamedComplexVector( stream, vector, 3 );

      StGermain_RotateComplexVector(j, angle, 0.0, angle, vector );
      Journal_Printf( stream, "J Rotated %g radians around I axis "
      "and %g radians around K axis: \n", angle, angle); 
      StGermain_PrintNamedComplexVector( stream, vector, 3 );

      StGermain_RotateComplexVector(k, angle, angle, 0.0, vector );
      Journal_Printf( stream, "K Rotated %g radians around I axis "
      "and %g radians around J axis: \n", angle, angle); 
      StGermain_PrintNamedComplexVector( stream, vector, 3 );

      /* Check addition function */
      Journal_Printf( stream, "\n****************************\n");
      Journal_Printf( stream, "vector = A + B\n");
      for ( d = 0 ; d <= 6 ; d++ ) {
         StGermain_ComplexVectorAddition( vector, A, B, d );
         StGermain_PrintNamedComplexVector( stream, vector, d );
      }

      /* Check subtraction function */
      Journal_Printf( stream, "\n****************************\n");
      Journal_Printf( stream, "vector = A - B\n");
      for ( d = 0 ; d <= 6 ; d++ ) {
         StGermain_ComplexVectorSubtraction( vector, A, B, d );
         StGermain_PrintNamedComplexVector( stream, vector, d );
      }
   
      /* Check Magnitude Function */
      Journal_Printf( stream, "\n****************************\n");
      Journal_Printf( stream, "Check Magnitude Function\n");
      for ( d = 0 ; d <= 6 ; d++ ) {
         Journal_Printf( stream, "dim = %d magnitude A = %2.3f\n", d, StGermain_ComplexVectorMagnitude( A, d ) );
         Journal_Printf( stream, "dim = %d magnitude B = %2.3f\n", d, StGermain_ComplexVectorMagnitude( B, d ) );
      }

      /* Check Dot Product */
      Journal_Printf( stream, "\n****************************\n");
      Journal_Printf( stream, "Check Dot Product Function\n");
      Journal_Printf( stream, "value = A . B \n");
      
      for (d = 0; d <=6; d++) {
      StGermain_ComplexVectorDotProduct(A, B, d, dotProductResult);         
      Journal_Printf( stream, "dim = %d dot product = %2.3f + %2.3f i\n",
         d, dotProductResult[0], dotProductResult[1] );
      }

      /* Check Cross Product */
      /* Tested against http://www.engplanet.com/redirect.html?3859 */
      Journal_Printf( stream, "\n****************************\n");
      Journal_Printf( stream, "Check Cross Product Function\n");
      Journal_Printf( stream, " A x B in 3-D\n");
      StGermain_ComplexVectorCrossProduct( vector, A, B );
      StGermain_PrintNamedComplexVector( stream, vector, 3 );

      /* Checking centroid function */
      Journal_Printf( stream, "\n****************************\n");
      Journal_Printf( stream, "Checking centroid function\n");
      for ( d = 0 ; d <= 6 ; d++ ) {
         StGermain_ComplexTriangleCentroid( vector, A, B, C, d );
         StGermain_PrintNamedComplexVector( stream, vector, d );
      }

      /* Check Normalisation Function */
      Journal_Printf( stream, "\n****************************\n");
      Journal_Printf( stream, "Check Normalisation Function\n");
      
      Journal_Printf( stream, "2-D\n\n");
      d = 2;
      StGermain_PrintNamedComplexVector( stream, A, d );
      StGermain_ComplexVectorNormalise( A, d );
      StGermain_PrintNamedComplexVector( stream, A, d);
      Journal_Printf( stream, "mag = %2.3f\n", StGermain_ComplexVectorMagnitude( A, d ) );

      Journal_Printf( stream, "3-D\n\n");
      d = 3;
      StGermain_PrintNamedComplexVector( stream, B, d );
      StGermain_ComplexVectorNormalise( B, d );
      StGermain_PrintNamedComplexVector( stream, B, d);
      Journal_Printf( stream, "mag = %2.3f\n", StGermain_ComplexVectorMagnitude( B, d ) );

      Journal_Printf( stream, "5-D\n\n");
      d = 5;
      StGermain_PrintNamedComplexVector( stream, C, d );
      StGermain_ComplexVectorNormalise( C, d );
      StGermain_PrintNamedComplexVector( stream, C, d);
      Journal_Printf( stream, "mag = %2.3f\n", StGermain_ComplexVectorMagnitude( C, d ) );

      Journal_Printf( stream, "\n****************************\n");
      Journal_Printf( stream, "Check StGermain_ComplexVectorCrossProductMagnitude\n");
      A[0][REAL_PART] = 1.0; A[0][IMAG_PART] = 1.0; 
      A[1][REAL_PART] = 2.0; A[1][IMAG_PART] = 0.0;
      A[2][REAL_PART] = 3.0; A[2][IMAG_PART] = 0.0;
      B[0][REAL_PART] = 4.0; B[0][IMAG_PART] = 0.0;
      B[1][REAL_PART] = 5.0; B[1][IMAG_PART] = 0.0;
      B[2][REAL_PART] = 6.0; B[2][IMAG_PART] = 3.0;
      StGermain_PrintNamedComplexVector( stream, A, 3);
      StGermain_PrintNamedComplexVector( stream, B, 3);
      
      StGermain_ComplexVectorCrossProductMagnitude(A, B, 2, value ) ;
      Journal_Printf( stream, "mag = %2.3g + %2.3g i (2D)\n", value[REAL_PART], value[IMAG_PART] );
      
      StGermain_ComplexVectorCrossProductMagnitude(A, B, 3, value ) ;
      Journal_Printf( stream, "mag = %2.3g + %2.3g i (3D)\n", value[REAL_PART], value[IMAG_PART] );

      Journal_Printf( stream, "\n****************************\n");
      Journal_Printf( stream, "Check StGermain_ComplexScalarTripleProduct \n");
      
      matrix = Memory_Alloc_2DArray( Cmplx, 3, 3, (Name)"matrix"  );
      
      matrix[0][0][REAL_PART] = 1.0;  matrix[0][0][IMAG_PART] = 1.0;
      matrix[0][1][REAL_PART] = 2.0;  matrix[0][1][IMAG_PART] = 0.0; 
      matrix[0][2][REAL_PART] = 3.0;  matrix[0][2][IMAG_PART] = 2.0;
      matrix[1][0][REAL_PART] = 4.0;  matrix[1][0][IMAG_PART] = 0.0;
      matrix[1][1][REAL_PART] = 5.0;  matrix[1][1][IMAG_PART] = 3.0; 
      matrix[1][2][REAL_PART] = 6.0;  matrix[1][2][IMAG_PART] = 0.0;
      matrix[2][0][REAL_PART] = 7.0;  matrix[2][0][IMAG_PART] = 1.0;
      matrix[2][1][REAL_PART] = 8.0;  matrix[2][1][IMAG_PART] = 0.0;
      matrix[2][2][REAL_PART] = 11.0; matrix[2][2][IMAG_PART] = 1.0;
      StGermain_PrintNamedComplexVector( stream, matrix[0], 3);
      StGermain_PrintNamedComplexVector( stream, matrix[1], 3);
      StGermain_PrintNamedComplexVector( stream, matrix[2], 3);

      StGermain_ComplexScalarTripleProduct( matrix[0], matrix[1], matrix[2], value );
      Journal_Printf( stream, "scalar triple product: ");
      Journal_PrintCmplx( stream, value );
      
      StGermain_ComplexScalarTripleProduct( matrix[2], matrix[0], matrix[1], value );
      Journal_Printf( stream, "scalar triple product: ");
      Journal_PrintCmplx( stream, value );
      StGermain_ComplexScalarTripleProduct( matrix[1], matrix[2], matrix[0], value );
      Journal_Printf( stream, "scalar triple product: ");
      Journal_PrintCmplx( stream, value );
      
      Journal_Printf( stream, "\n****************************\n");
      Journal_Printf( stream, "Check Vector_ToComplexVector function \n");
      
      realVector[0] = 1.0; realVector[1] = 2.0; realVector[2] = 3.0;
      
      StGermain_PrintNamedVector(stream, realVector, 3);
      Vector_ToComplexVector(realVector, 3, matrix[0]) ;
      StGermain_PrintNamedComplexVector( stream, matrix[0], 3);

      Journal_Printf( stream, "\n****************************\n");
      Journal_Printf( stream, "Check ComplexVector_ToVector function \n");   
      
      matrix[0][0][REAL_PART] = 5.0; matrix[0][0][IMAG_PART] = 0.0;
      matrix[0][1][REAL_PART] = 6.0; matrix[0][1][IMAG_PART] = 0.0; 
      matrix[0][2][REAL_PART] = 7.0; matrix[0][2][IMAG_PART] = 0.0;
      
      StGermain_PrintNamedComplexVector( stream, matrix[0], 3);
      ComplexVector_ToVector(matrix[0], 3, realVector) ;
      StGermain_PrintNamedVector(stream, realVector, 3);

      pcu_filename_expected( "testComplexVectorMathOperations.expected", expected_file );
      pcu_check_fileEq( "testComplexVectorMathOperations.dat", expected_file );
      remove( "testComplexVectorMathOperations.dat" );

      Memory_Free( matrix );
      Stream_CloseAndFreeFile( stream );
   }
}