void _GeneralSwarm_Init(
   void*                                 swarm,
   EscapedRoutine*                       escapedRoutine )
{
   GeneralSwarm*    self = (GeneralSwarm*)swarm;
   GlobalParticle          globalParticle;

   self->swarmAdvector      = NULL;		/* If we're using a SwarmAdvector, it will 'attach' itself later on. */
   self->escapedRoutine     = escapedRoutine;

   self->particleCoordVariable = Swarm_NewVectorVariable( self, (Name)"Position", GetOffsetOfMember( globalParticle, coord ),
                                 Variable_DataType_Double,
                                 self->dim,
                                 "PositionX",
                                 "PositionY",
                                 "PositionZ" );
   LiveComponentRegister_Add( LiveComponentRegister_GetLiveComponentRegister(), (Stg_Component*)self->particleCoordVariable->variable );
   LiveComponentRegister_Add( LiveComponentRegister_GetLiveComponentRegister(), (Stg_Component*)self->particleCoordVariable );

   /* init members */
   self->previousIntSwarmMap = NULL;
   /* lets init this guy with one spot for convenience */
   self->intSwarmMapList = List_New("intSwarmMapList");
   List_SetItemSize(self->intSwarmMapList, sizeof(SwarmMap*));

}
void _IntegrationPointsSwarm_Init( 
   void*                   swarm,
   FeMesh*                 mesh )
{
   IntegrationPointsSwarm* self = (IntegrationPointsSwarm*)swarm;
   LocalParticle           localParticle;
   IntegrationPoint        particle;

   self->mesh               = mesh;

   self->weightVariable = Swarm_NewScalarVariable( self, (Name)"Weight", GetOffsetOfMember( particle , weight ), 
      Variable_DataType_Double );

   LiveComponentRegister_Add( LiveComponentRegister_GetLiveComponentRegister(), (Stg_Component*)self->weightVariable );
   LiveComponentRegister_Add( LiveComponentRegister_GetLiveComponentRegister(), (Stg_Component*)self->weightVariable->variable );

   self->localCoordVariable = Swarm_NewVectorVariable( self, (Name)"LocalElCoord", GetOffsetOfMember( localParticle , xi ),
      Variable_DataType_Double, self->dim, "Xi", "Eta", "Zeta" );

   LiveComponentRegister_Add( LiveComponentRegister_GetLiveComponentRegister(), (Stg_Component*)self->localCoordVariable );
   LiveComponentRegister_Add( LiveComponentRegister_GetLiveComponentRegister(), (Stg_Component*)self->localCoordVariable->variable );
   
   /* _Construct calls _Swarm_Init */

   /* Lock down the extension manager.
    * It doesn't make sense for the IntegrationPointsSwarm to allow IntegrationPoints to be extended
    * This means attempts to extend integration points are firewalled to pickup errors.
    * -- Alan 20060506
    */
   ExtensionManager_SetLockDown( self->particleExtensionMgr, True );

   self->swarmsMappedTo = List_New("swarmsMappedTo");
   List_SetItemSize(self->swarmsMappedTo, sizeof(SwarmMap*));

}
void stgMainDestroy( Stg_ComponentFactory* cf ) {
   /* Destruct phase. */

   LiveComponentRegister_DestroyAll( LiveComponentRegister_GetLiveComponentRegister() );
   LiveComponentRegister_DeleteAll( LiveComponentRegister_GetLiveComponentRegister() );
   Stg_Class_Delete( cf );
   LiveComponentRegister_Delete();
}
Index LiveComponentRegister_IfRegThenAdd( Stg_Component *component ) {
   if( LiveComponentRegister_GetLiveComponentRegister() ) {
      LiveComponentRegister_Add( LiveComponentRegister_GetLiveComponentRegister(), component );
      return 1;
   }
   else
      return 0;
}
void _DruckerPrager_Init(
		DruckerPrager*                                     self,
		int                                                pressure_id,
		int                                                velocityGradients_id,
		double                                             minimumYieldStress,
		double                                             frictionCoefficient,
		double                                             frictionCoefficientAfterSoftening )
{
   MaterialPointsSwarm*      materialPointsSwarm;
	DruckerPrager_Particle*   particleExt;
	StandardParticle          materialPoint;
	Dimension_Index          dim = 0;
	
	/* Assign Pointers */
	self->frictionCoefficient = frictionCoefficient;
	self->minimumYieldStress  = minimumYieldStress;
	
	self->pressureTag         = pressure_id;
	self->velocityGradientsTag = velocityGradients_id;
   materialPointsSwarm = self->mgr->materialSwarm;
   dim = materialPointsSwarm->dim;	
    /* Strain softening of Friction - (linear weakening is assumed ) */
	/* needs a softening factor between +0 and 1 and a reference strain > 0 */
	self->frictionCoefficientAfterSoftening = frictionCoefficientAfterSoftening;

   /* get the particle extension */
   self->particleExtHandle = ExtensionManager_GetHandle( materialPointsSwarm->particleExtensionMgr, (Name)DruckerPrager_Type );

   if( self->particleExtHandle == (unsigned)-1 ) {
      /* if no particles extension add it and add Update hook */
      self->particleExtHandle = ExtensionManager_Add( materialPointsSwarm->particleExtensionMgr, (Name)DruckerPrager_Type, sizeof(DruckerPrager_Particle) );

      particleExt = (double*)ExtensionManager_Get( materialPointsSwarm->particleExtensionMgr, &materialPoint, self->particleExtHandle );
      
      /* The tensileFailure variable allows to check whether a materialPoint has failed in tensile mode or not */
      self->tensileFailure = Swarm_NewScalarVariable( materialPointsSwarm, (Name)"DruckerPragerTensileFailure", (ArithPointer) &particleExt->tensileFailure - (ArithPointer) &materialPoint, Variable_DataType_Char );
      LiveComponentRegister_Add( LiveComponentRegister_GetLiveComponentRegister(), (Stg_Component*)self->tensileFailure->variable );
      LiveComponentRegister_Add( LiveComponentRegister_GetLiveComponentRegister(), (Stg_Component*)self->tensileFailure );
	   
   } else {
      /* get references to all swarm variables */
      Name var_name = Stg_Object_AppendSuffix( materialPointsSwarm, (Name)"DruckerPragerTensileFailure"  );
      self->tensileFailure = SwarmVariable_Register_GetByName( materialPointsSwarm->swarmVariable_Register, var_name );
      Memory_Free( var_name );
	   
   }

   self->curFrictionCoef = 0.0;

}
PpcFeVariable* PpcFeVariable_New( Name name, 
      DomainContext *context, 
      FeMesh *mesh,
      IntegrationPointsSwarm *swarm,
      Bool accumulate,
      PpcManager *ppcMan,
      int tag ) {

   PpcFeVariable     *self = NULL;
   int               componentsCount=1;

   /* painfully define a new ParticleFeVariable, methods first */
   self = _PpcFeVariable_DefaultNew( name );

   /** define basics in data structures */
   self->isConstructed = True;
	_FieldVariable_Init( (FieldVariable*)self, context, componentsCount, context->dim, True, NULL, context->communicator, context->fieldVariable_Register, False );
   _FeVariable_Init( (FeVariable* )self, mesh, NULL, NULL, False, NULL, NULL, NULL, False, False );
	_ParticleFeVariable_Init( (ParticleFeVariable*)self, swarm, accumulate );
	_PpcFeVariable_Init( self, ppcMan, tag );

   LiveComponentRegister_Add( LiveComponentRegister_GetLiveComponentRegister(), (Stg_Component*) self );

   return self;

}
void _ModulesManager_Delete( void* modulesManager ) {
   ModulesManager*        self = (ModulesManager*)modulesManager;
   LiveComponentRegister* lcRegister = NULL;

   /* 
    * Note: We have to delete the codelets here rather than let the 
    * component factory do it as they refer to static data inside the
    * loaded module dlls, which are no longer available once we delete
    * all in self->modules. -- Main.PatrickSunter 18 May 2006 
    */
   if( ( lcRegister = LiveComponentRegister_GetLiveComponentRegister() ) ) {
      /* sweep through codelets list and delete each from the lcRegister */
      Index codelet_I;
      
      for( codelet_I = 0; codelet_I < self->codelets->count; ++codelet_I ) {
         LiveComponentRegister_RemoveOneComponentsEntry( lcRegister,
            ((Stg_Object*)self->codelets->data[codelet_I])->name );
      }
   }
   Stg_ObjectList_DeleteAllObjects( self->codelets );
   Stg_Class_Delete( self->codelets );
   ModulesManager_Unload( self ); 
   Stg_Class_Delete( self->modules );
   
   /* Delete parent */
   _Stg_Class_Delete( self );
}
void _MaterialPointsSwarm_Init( 
		void*                                 swarm,
		Material*                             material,
		Materials_Register*                   materials_Register )
{
	MaterialPointsSwarm*    self = (MaterialPointsSwarm*)swarm;
	MaterialPoint           particle;
	GlobalParticle          globalParticle;

	self->material           = material;
	self->materials_Register = materials_Register;
	
	self->materialIndexVariable = Swarm_NewScalarVariable( self, (Name)"MaterialIndex", GetOffsetOfMember( particle , materialIndex  ), Variable_DataType_Int ); /* Should be unsigned int */
   LiveComponentRegister_Add( LiveComponentRegister_GetLiveComponentRegister(), (Stg_Component*)self->materialIndexVariable->variable );
   LiveComponentRegister_Add( LiveComponentRegister_GetLiveComponentRegister(), (Stg_Component*)self->materialIndexVariable );

}
void _RateFieldTimeIntegrator_Build( void* rateFieldTimeIntegrator, void* data ) {
   RateFieldTimeIntegrator*  self = (RateFieldTimeIntegrator*) rateFieldTimeIntegrator;
   ExtensionInfo_Index   handle;

   Stg_Component_Build( self->swarm, data, False );
   Stg_Component_Build( self->rateField, data, False );

   handle = ExtensionManager_GetHandle( self->swarm->particleExtensionMgr, (Name)self->name );

   if ( handle == (ExtensionInfo_Index) -1 ) {
      ArithPointer offset;
      handle = ExtensionManager_Add( self->swarm->particleExtensionMgr, (Name)RateFieldTimeIntegrator_Type, self->rateField->fieldComponentCount*sizeof(double)  );

      /* Adding required increment variable */
      offset = (ArithPointer ) ExtensionManager_Get( self->swarm->particleExtensionMgr, NULL, handle );

      /* Add variables for vizualization / analysis purposes */
      self->particleTimeIntegral = Swarm_NewVectorVariable( self->swarm, self->name, offset, Variable_DataType_Double, self->rateField->fieldComponentCount, "STG_AUTONAME"  );
      LiveComponentRegister_Add( LiveComponentRegister_GetLiveComponentRegister(), (Stg_Component*)self->particleTimeIntegral->variable );
      LiveComponentRegister_Add( LiveComponentRegister_GetLiveComponentRegister(), (Stg_Component*)self->particleTimeIntegral );

      /* The RateFieldTimeIntegrator class inherits from the TimeIntegrand class - this class needs a 'Variable' to
       * integrate through time. */
      self->variable = self->particleTimeIntegral->variable;
   } else
      Journal_Firewall(False, Journal_Register( Error_Type, (Name)"RateFieldTimeIntegrator"  ),
                       "\n\nError in '%s' - Extension with name %s should not already exists.\n"
                       "An error has occurred.  Please contact developers.", __func__, self->name);


   /* Build parent.  Note that this needs to go last because it assumes that a variable has been set, which only just happens above */
   /* Another example where the build/init/etc phases don't work */

   _TimeIntegrand_Build( self, data );
   Stg_Component_Build( self->particleTimeIntegral, data, False );

}
void LiveComponentRegisterSuite_TestGet( LiveComponentRegisterSuiteData* data ) {
   typedef float Triple[3];

   float* array;
   Triple* structArray;

   StgVariable* var;
   StgVariable* vec;
   StgVariable* vecVar[3];
   StgVariable* tempVar = NULL;
   Index length = 10;

   Variable_Register* reg;

   array = Memory_Alloc_Array( float, length, "test" );
   structArray = Memory_Alloc_Array( Triple, length, "test" );

   reg = Variable_Register_New();

   var = StgVariable_NewScalar(
      "Scalar",
		NULL,
      StgVariable_DataType_Float,
      &length,
      NULL,
      (void**)&array,
      reg );

   vec = StgVariable_NewVector(
      "Three",
		NULL,
      StgVariable_DataType_Float,
      3,
      &length,
      NULL,
      (void**)&structArray,
      reg,
      "a",
      "b",
      "c" );

   vecVar[0] = Variable_Register_GetByName( reg, "a" );
   vecVar[1] = Variable_Register_GetByName( reg, "b" );
   vecVar[2] = Variable_Register_GetByName( reg, "c" );

   Variable_Register_BuildAll( reg );

   LiveComponentRegister_Add( data->lcRegister, (Stg_Component*) var );
   pcu_check_true( LiveComponentRegister_IfRegThenAdd( (Stg_Component*) vec ) );
   LiveComponentRegister_Add( data->lcRegister, (Stg_Component*) vecVar[0] );
   LiveComponentRegister_Add( data->lcRegister, (Stg_Component*) vecVar[1] );
   LiveComponentRegister_Add( data->lcRegister, (Stg_Component*) vecVar[2] );

   tempVar = (StgVariable*) LiveComponentRegister_Get( data->lcRegister, (Name)"Scalar" );
   pcu_check_true( tempVar == var );

   tempVar = (StgVariable* ) LiveComponentRegister_Get( LiveComponentRegister_GetLiveComponentRegister(), (Name)"Three" );
   pcu_check_true( tempVar == vec );

   tempVar = (StgVariable* ) LiveComponentRegister_Get( data->lcRegister, (Name)"a" );
   pcu_check_true( tempVar == vecVar[0] );

   tempVar = (StgVariable* ) LiveComponentRegister_Get( data->lcRegister, (Name)"b" );
   pcu_check_true( tempVar == vecVar[1] );

   tempVar = (StgVariable* ) LiveComponentRegister_Get( data->lcRegister, (Name)"c" );
   pcu_check_true( tempVar == vecVar[2] );
}
void _IntegrationPointsSwarm_Init( 
   void*                   swarm,
   FeMesh*                 mesh, 
   TimeIntegrator*         timeIntegrator,
   WeightsCalculator*      weights,
   IntegrationPointMapper* mapper,
   Materials_Register*     materials_Register,
   Bool                    recalculateWeights )
{
   IntegrationPointsSwarm* self = (IntegrationPointsSwarm*)swarm;
   LocalParticle           localParticle;
   IntegrationPoint        particle;

   self->mesh               = mesh;
   self->timeIntegrator     = timeIntegrator;
   self->weights            = weights;
   self->mapper             = mapper;
   self->materials_Register = materials_Register;

   self->recalculateWeights = recalculateWeights;

   /* Disable checkpointing and reloading of IP swarms - currently they can't be reloaded if the particles
   don't have a global coord. We assume there is no history info on them which means we're happy to re-create
   them from scratch given the position the material points were in when the checkpoint was made as input
   -- PatrickSunter 12 June 2006 */
   self->isSwarmTypeToCheckPointAndReload = False;

   self->weightVariable = Swarm_NewScalarVariable( self, (Name)"Weight", GetOffsetOfMember( particle , weight ), 
      Variable_DataType_Double );

   LiveComponentRegister_Add( LiveComponentRegister_GetLiveComponentRegister(), (Stg_Component*)self->weightVariable );
   LiveComponentRegister_Add( LiveComponentRegister_GetLiveComponentRegister(), (Stg_Component*)self->weightVariable->variable );

   self->localCoordVariable = Swarm_NewVectorVariable( self, (Name)"LocalElCoord", GetOffsetOfMember( localParticle , xi ),
      Variable_DataType_Double, self->dim, "Xi", "Eta", "Zeta" );

   LiveComponentRegister_Add( LiveComponentRegister_GetLiveComponentRegister(), (Stg_Component*)self->localCoordVariable );
   LiveComponentRegister_Add( LiveComponentRegister_GetLiveComponentRegister(), (Stg_Component*)self->localCoordVariable->variable );

   if ( timeIntegrator ) {
      /* Assuming this is called from _IntegrationPointsSwarm_AssignFromXML, it would have always called construct
       * on the mapper which in turn would have constructed any MaterialPointsSwarms with it.
       * The MaterialPointsSwarms would have already appended their update routines to the EP, and hence this
       * ensures that the _IntegrationPointsSwarm_UpdateHook will always be called last */
      TimeIntegrator_InsertAfterFinishEP(
         timeIntegrator,
         (Name) "MaterialPointsSwarm_Update", /* Needs to be after a the material update */
         (Name) "IntegrationPointsSwarm_Update",
         _IntegrationPointsSwarm_UpdateHook,
         self->name,
         self );
   }
   
   /* _Construct calls _Swarm_Init */

   /* Lock down the extension manager.
    * It doesn't make sense for the IntegrationPointsSwarm to allow IntegrationPoints to be extended
    * This means attempts to extend integration points are firewalled to pickup errors.
    * -- Alan 20060506
    */
   ExtensionManager_SetLockDown( self->particleExtensionMgr, True );
}