Exemplo n.º 1
0
Stg_Class* Stg_Class_CheckType( void* classPtr, Type possibleParentType ) {
	Stg_Class* self = (Stg_Class*) classPtr;
	/* Check if the pointer is null */
	Journal_Firewall(
		self != NULL,
		Journal_Register( Error_Type, HierarchyTable_Type ),
		"Error doing type checking against possibleParentType %s - pointer is NULL.\n",
		possibleParentType );
	
	if ( ! Stg_Class_IsInstance( self, possibleParentType ) ) {
		Stream* stream = Journal_Register( Error_Type, HierarchyTable_Type );
		
		Journal_Printf( stream, "Error doing type checking:\nTrying to cast " );

		/* Give the user the name of the object if you can */
		if ( Stg_Class_IsInstance( classPtr, Stg_Object_Type ) ) 
			Journal_Printf( stream, "'%s' ", ((Stg_Object*)classPtr)->name );
		else 		
			Journal_Printf( stream, "pointer '%p' ", classPtr );

		Journal_Printf( stream, 
				"as '%s' when it is actually of type '%s'.\n",
				possibleParentType, self->type );
		
		PrintParents( possibleParentType, stream );
		
		Journal_Firewall( 
			0,
			stream, 
			"Either the HierarchyTable for this class is incorrect or this object has been cast incorrectly.\n" );
	}
	return self;
}
Exemplo n.º 2
0
void* Fn::IntegrationSwarmInput::_CheckIsIntegrationSwarm(void* intSwarm){
    // check is type IntegrationPointsSwarm
    if(!Stg_Class_IsInstance( intSwarm, IntegrationPointsSwarm_Type ))
        throw std::invalid_argument("Provided 'integrationSwarm' does not appear to be of 'IntegrationPointsSwarm' type.");
    // lets also check that it has the correct celllayout type
    if(!Stg_Class_IsInstance( ((IntegrationPointsSwarm*)intSwarm)->cellLayout, ElementCellLayout_Type ))
        throw std::invalid_argument("Provided 'integrationSwarm' does not appear to have a cell layout of 'ElementCellLayout' type.");
    return intSwarm;
}
Exemplo n.º 3
0
Fn::MeshIndexSet::MeshIndexSet( IndexSet* indexSet, void* mesh )
    : IOIterator(), _indexSet(indexSet), _mesh(mesh), _indexArray(NULL)
{
    if(!Stg_Class_IsInstance( mesh, Mesh_Type ))
        throw std::invalid_argument("Provided 'mesh' does not appear to be of 'Mesh' type.");
    if(!Stg_Class_IsInstance( indexSet, IndexSet_Type ))
        throw std::invalid_argument("Provided 'indexSet' does not appear to be of 'IndexSet' type.");
    
    // get array from index set
    IndexSet_GetMembers( _indexSet, &_size, &_indexArray );
}
Exemplo n.º 4
0
void _SwarmAdvector_Build( void* swarmAdvector, void* data ) {
   SwarmAdvector*	self = (SwarmAdvector*) swarmAdvector;
   GeneralSwarm *swarm=NULL;

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

   swarm=self->swarm;

   /* Test if mesh is periodic and a periodic boundaries manager hasn't been given */
   if ( !self->periodicBCsManager && Stg_Class_IsInstance( ((ElementCellLayout*)swarm->cellLayout)->mesh->generator, CartesianGenerator_Type ) ) {
      CartesianGenerator* cartesianGenerator = (CartesianGenerator*) ((ElementCellLayout*)swarm->cellLayout)->mesh->generator;
      if ( cartesianGenerator->periodic[ I_AXIS ] ||
           cartesianGenerator->periodic[ J_AXIS ] ||
           cartesianGenerator->periodic[ K_AXIS ] ) {
         /* Create a periodicBCsManager if there isn't one already */
         self->periodicBCsManager = PeriodicBoundariesManager_New( "periodicBCsManager", (PICelleratorContext*)self->context, (Mesh*)((ElementCellLayout*)swarm->cellLayout)->mesh, (Swarm*)swarm, NULL );
   }


}
	if ( self->periodicBCsManager )
		Stg_Component_Build( self->periodicBCsManager, data, False );
   _TimeIntegrand_Build( self, data );

}
void IntegrationPointsSwarm_RemapIntegrationPointsAndRecalculateWeights( void* swarm ) {   
   IntegrationPointsSwarm* self = (IntegrationPointsSwarm*)swarm;
   double                  mapStartTime, mapTime;
   double                  weightsUpdateStartTime, weightsUpdateTime;

   Journal_DFirewall( self->mapper, global_error_stream,
        "Error in %s: The IntegrationPointsSwarm \'%s\' doesn't have a mapper to a MaterialPointsSwarm"
        "and should not be in this function. Check all instances of where \'%s\' is passed in the xml input file."
        "Most likely in can be replace with an IntegrationPointsSwarm with a mapper\n",
        __func__, self->name, self->name);

   Journal_DPrintf( self->debug, "In %s(): for swarm \"%s\":\n",
      __func__, self->name );
   Stream_IndentBranch( Swarm_Debug );

   Journal_DPrintf( self->debug, "Calling IntegrationPointsMapper \"%s\" (of type %s) to set up mappings\n"
      "\tfrom I.P.s to M.P.s, and calculate local coords:\n", self->mapper->name, self->mapper->type );
   mapStartTime = MPI_Wtime();   
   IntegrationPointMapper_Map( self->mapper );
   mapTime = MPI_Wtime() - mapStartTime;
   Journal_DPrintf( self->debug, "...done - took %g secs.\n", mapTime );

   if ( self->weights != NULL ) {
      Journal_DPrintf( self->debug, "Calling WeightsCalculator \"%s\" (of type %s)\n"
         "\tto calculate and set integration weights:\n",
         self->weights->name, self->weights->type );
      weightsUpdateStartTime = MPI_Wtime();
      WeightsCalculator_CalculateAll(self->weights, self );
      weightsUpdateTime = MPI_Wtime() - weightsUpdateStartTime;
      Journal_DPrintf( self->debug, "...weights updating finished - took %g secs.\n", weightsUpdateTime );
   }   
   else {
      Stream* errorStream = Journal_Register( Error_Type, (Name)self->type );
      Journal_Firewall( Stg_Class_IsInstance( self->mapper, GaussMapper_Type ) ||
         Stg_Class_IsInstance( self->mapper, GaussCoincidentMapper_Type ) ||
         !strcmp(self->mapper->type, "PCDVCGaussMapper"), errorStream,
         "Error - in %s(): for IntegrationPointSwarm \"%s\", no weights calculator provided "
         "and mapper is not a %s.\n", GaussMapper_Type );

      Journal_DPrintf( self->debug, "not recalculating weights since we are using a %s mapper and "
         "assume the points are not being advected.\n", GaussMapper_Type );
   }

   Stream_UnIndentBranch( Swarm_Debug );
   Journal_DPrintf( self->debug, "...done in %s() for swarm \"%s\"\n",
      __func__, self->name );
}
Exemplo n.º 6
0
void _SwarmAdvector_Init(
		SwarmAdvector*                             self,
		FeVariable*                                velocityField,
		GeneralSwarm*                       swarm,
		PeriodicBoundariesManager*                 periodicBCsManager )
{
	self->velocityField = velocityField;
	self->swarm = swarm;

  // check we don't have a GaussSwarm as swarm input (only way to check is by the cellLayout Type)
   Journal_Firewall( !Stg_Class_IsInstance(swarm->cellLayout, SingleCellLayout_Type ),
         NULL,
         "Error in '%s'. Can attach a SwarmAdvector to swarm '%s' because the swarm's cell layout '%s'"
         "is of type '%s' which is incompatible with advection.\nAre you sure you want to advect this swarm?"
         " If you change it's cell layout",
         __func__, swarm->name, swarm->cellLayout->name, swarm->cellLayout->type );

//    if( swarm->swarmAdvector == NULL )
//	   swarm->swarmAdvector = self;	/* Attach ourselves to the swarm */
//    else
//	   Journal_Firewall( 0 ,
//			NULL,
//			"In func - %s.\nSwarm '%s' appears to already have an advector (%s) attached,\n"
//			"but now advector (%s) is trying to attach itself.\n"
//			"Please check your input file, and ensure there is only one advector per swarm.",
//			__func__,
//			swarm->name,
//			swarm->swarmAdvector->name,
//			self->name );

	swarm->isAdvecting = True;
	self->variable = swarm->particleCoordVariable->variable;

   Journal_Firewall(
                    Stg_Class_IsInstance( swarm->cellLayout, ElementCellLayout_Type ),
                    NULL,
                    "Error In func %s: %s expects a materialSwarm with cellLayout of type ElementCellLayout.",
                    __func__, self->type );

	 /* if not regular use quicker algorithm for SwarmAdvection */
	 if( ((ElementCellLayout*)swarm->cellLayout)->mesh->isRegular == False && self->type == SwarmAdvector_Type ) {
	    self->_calculateTimeDeriv = _SwarmAdvector_TimeDeriv_Quicker4IrregularMesh;
	 }
	self->periodicBCsManager = periodicBCsManager;
}
Exemplo n.º 7
0
Fn::SwarmInput::SwarmInput( void* positionVariable )
    : IOIterator(), _positionVariable(positionVariable)
{
    if(!Stg_Class_IsInstance( positionVariable, SwarmVariable_Type ))
        throw std::invalid_argument("Provided 'positionVariable' does not appear to be of 'SwarmVariable' type.");

    // get number of particles
    _size = ((SwarmVariable*)positionVariable)->swarm->particleLocalCount;
}
void _IntegrationPointsSwarm_AssignFromXML( void* integrationPoints, Stg_ComponentFactory* cf, void* data ) {
   IntegrationPointsSwarm* self = (IntegrationPointsSwarm*) integrationPoints;
   FeMesh*                 mesh;
   TimeIntegrator*         timeIntegrator;
   WeightsCalculator*      weights;
   IntegrationPointMapper* mapper;
   Materials_Register*     materials_Register;
   Bool                    recalculateWeights;
   PICelleratorContext*    context;

   /* This will also call _Swarm_Init */
   _Swarm_AssignFromXML( self, cf, data );

   mesh           = Stg_ComponentFactory_ConstructByKey( cf, self->name, (Dictionary_Entry_Key)"FeMesh", FeMesh, True, data );
   timeIntegrator = Stg_ComponentFactory_ConstructByKey( cf, self->name, (Dictionary_Entry_Key)"TimeIntegrator", TimeIntegrator, False, data );
   weights        = Stg_ComponentFactory_ConstructByKey( cf, self->name, (Dictionary_Entry_Key)"WeightsCalculator", WeightsCalculator, False, data );
   mapper         = Stg_ComponentFactory_ConstructByKey( cf, self->name, (Dictionary_Entry_Key)"IntegrationPointMapper", IntegrationPointMapper, False, data );
   recalculateWeights = Stg_ComponentFactory_GetBool( cf, self->name, (Dictionary_Entry_Key)"recalculateWeights", True );

   if( mapper !=NULL ) {
      Journal_Firewall (
         weights != NULL ||
         (weights == NULL && (Stg_Class_IsInstance( mapper, GaussMapper_Type ) ||
         Stg_Class_IsInstance( mapper, GaussCoincidentMapper_Type) ||
         !strcmp( mapper->type, "PCDVCGaussMapper"))),
         Journal_MyStream( Error_Type, self ),
         "In func %s, %s which is a %s must either have a %s or use %s\n",
         __func__,
         self->name,
         self->type,
         WeightsCalculator_Type,
         GaussMapper_Type );
   }
   
   context = (PICelleratorContext*)self->context;
   assert( Stg_CheckType( context, PICelleratorContext ) );
   materials_Register = context->materials_Register;
   assert( materials_Register );

   _IntegrationPointsSwarm_Init( self, mesh, timeIntegrator, weights, mapper, materials_Register, recalculateWeights );
}
void _PeriodicBoundariesManager_Build( void* periodicBCsManager, void* data ) {	
	PeriodicBoundariesManager* self = (PeriodicBoundariesManager*)periodicBCsManager;
	Dictionary_Entry_Value*    periodicBCsList = NULL;

	Stg_Component_Build( self->swarm, data, False );
	Stg_Component_Build( self->mesh, data, False );
	self->size = 4;
	self->boundaries = Memory_Alloc_Array( PeriodicBoundary, self->size, "PeriodicBoundariesManager->boundaries" );

	if ( self->dictionary ) {
		periodicBCsList = Dictionary_Get( self->dictionary, (Dictionary_Entry_Key)"PeriodicBoundaries" );
		
		/* Dictionary entry is optional - users may prefer to enter in code */
		if ( periodicBCsList ) {
			Index                   numPeriodicBCs = 0;
			Index                   periodicBC_I = 0;
			Dictionary_Entry_Value* periodicBC = NULL;
			char*                   perBCAxis = NULL;
			
			numPeriodicBCs = Dictionary_Entry_Value_GetCount( periodicBCsList );

			for ( periodicBC_I = 0; periodicBC_I < numPeriodicBCs; periodicBC_I++  ) {
				periodicBC = Dictionary_Entry_Value_GetElement( periodicBCsList, periodicBC_I );
				perBCAxis = Dictionary_Entry_Value_AsString( periodicBC );

				if ( 0 == strcmp( perBCAxis, "I_AXIS" ) ) {
					PeriodicBoundariesManager_AddPeriodicBoundary( self, I_AXIS );
				}
				else if ( 0 == strcmp( perBCAxis, "J_AXIS" ) ) {
					PeriodicBoundariesManager_AddPeriodicBoundary( self, J_AXIS );
				}
				else if ( 0 == strcmp( perBCAxis, "K_AXIS" ) ) {
					PeriodicBoundariesManager_AddPeriodicBoundary( self, K_AXIS );
				}
			}
		}
	}
	/* Test if mesh is periodic */
	else if ( Stg_Class_IsInstance( self->mesh->generator, CartesianGenerator_Type ) ) {
		CartesianGenerator* cartesianGenerator = (CartesianGenerator*) self->mesh->generator;
		Dimension_Index dim_I;

		for ( dim_I = 0 ; dim_I < self->swarm->dim ; dim_I++ ) {
			/* Add boundaries straight from mesh generator */
			if ( cartesianGenerator->periodic[ dim_I ] ) 
				PeriodicBoundariesManager_AddPeriodicBoundary( self, dim_I );
		}		
	}
}
Exemplo n.º 10
0
void lecode_tools_Isostasy_AverageBody(lecode_tools_Isostasy *self,
                                       double** _avg_density, double** _rho_zero_density,
                                       double** _phi)
{
   FeMesh *mesh;
   ElementType *el_type;
   IntegrationPointsSwarm *swarm;
   double *local_density, *global_density;
   double *local_vol, *global_vol;
   double *local_rho_zero_vol, *global_rho_zero_vol;
   double *local_rho_zero_density, *global_rho_zero_density;
   double *local_phi, *global_phi, temp, tempDot;
   int cell, num_particles, num_dims, num_els;
   IntegrationPoint *particle;
   double jac_det;
   double density, alpha, densityFinal;
   Material *mat;
   Bool oneToMany;
   Grid* elGrid;
   int elInds[3], arraySize, arrayPos;
   int ii, jj;

   mesh = self->mesh;
   elGrid = *Mesh_GetExtension( mesh, Grid**,  mesh->elGridId );
   num_dims = Mesh_GetDimSize(mesh);
   swarm = self->swarm;
   num_els = FeMesh_GetElementLocalSize(mesh);

   arraySize=0;
   if ( num_dims == 2 ) arraySize = elGrid->sizes[0];
   else if ( num_dims == 3 ) arraySize = elGrid->sizes[0]*elGrid->sizes[self->zontalAxis];
   else assert(0);

   /* Allocate for the column values. */
   local_vol = (double*)malloc( arraySize*sizeof(double) );
   memset( local_vol, 0, arraySize*sizeof(double) );
   local_density = (double*)malloc( arraySize*sizeof(double) );
   memset( local_density, 0, arraySize*sizeof(double) );
   local_rho_zero_vol = (double*)malloc( arraySize*sizeof(double) );
   memset( local_rho_zero_vol, 0, arraySize*sizeof(double) );
   local_rho_zero_density = (double*)malloc( arraySize*sizeof(double) );
   memset( local_rho_zero_density, 0, arraySize*sizeof(double) );
   local_phi = (double*)malloc( arraySize*sizeof(double) );
   memset( local_phi, 0, arraySize*sizeof(double) );

   /* Initialise temperature. */
   temp = 0.0;

   oneToMany = Stg_Class_IsInstance(swarm->mapper, OneToManyMapper_Type);

   for (ii = 0; ii < num_els; ii++)
   {

      /* Make sure the element is beneath the surface. */
      Grid_Lift( elGrid, FeMesh_ElementDomainToGlobal( mesh, ii ), elInds );
      if ( self->surfaceIdx != -1 && elInds[self->vertAxis] >= self->surfaceIdx )
         continue;

      el_type = FeMesh_GetElementType(mesh, ii);
      cell = CellLayout_MapElementIdToCellId(swarm->cellLayout, ii);
      num_particles = swarm->cellParticleCountTbl[cell];

      for (jj = 0; jj < num_particles; jj++)
      {

         particle = (IntegrationPoint*)Swarm_ParticleInCellAt(swarm, cell, jj);
         jac_det = ElementType_JacobianDeterminant(el_type, mesh, ii, particle->xi, num_dims);

         if(!self->ppcManager){
            density = IntegrationPointMapper_GetDoubleFromMaterial(
                         swarm->mapper, particle, self->buoyancy->materialExtHandle,
                         offsetof(BuoyancyForceTerm_MaterialExt, density) );
            alpha = IntegrationPointMapper_GetDoubleFromMaterial(
                       swarm->mapper, particle, self->buoyancy->materialExtHandle,
                       offsetof(BuoyancyForceTerm_MaterialExt, alpha) );

            if (self->tempField)
            {
               FeVariable_InterpolateFromMeshLocalCoord(self->tempField, self->tempField->feMesh,
                     ii, particle->xi, &temp);
               FeVariable_InterpolateFromMeshLocalCoord(self->tempDotField, self->tempDotField->feMesh,
                     ii, particle->xi, &tempDot);
            }

            densityFinal = density*(1.0 - alpha*temp);

         } else {
            int err;
            /* Density */
            err = PpcManager_Get( self->ppcManager, ii, particle, self->densityID, &densityFinal );
            assert(!err);
         }

         arrayPos = elInds[0];
         if ( num_dims == 3 ) arrayPos += elInds[self->zontalAxis]*elGrid->sizes[0];

         local_vol[arrayPos] += particle->weight*jac_det;
         local_density[arrayPos] += particle->weight*jac_det*densityFinal;

         if (!oneToMany)
         {
            mat = IntegrationPointsSwarm_GetMaterialOn(swarm, particle);
            if (mat->index == self->rho_zero_mat->index)
            {
               local_rho_zero_vol[arrayPos] += particle->weight*jac_det;
               local_rho_zero_density[arrayPos] += particle->weight*jac_det*densityFinal;
            }
         }
         else
         {
            OneToManyRef *ref;
            int cnt;
            int kk;

            ref = OneToManyMapper_GetMaterialRef(swarm->mapper, particle);
            cnt = 0;
            for (kk = 0; kk < ref->numParticles; kk++)
            {
               mat = MaterialPointsSwarm_GetMaterialAt(((OneToManyMapper*)swarm->mapper)->materialSwarm, ref->particleInds[kk]);
               if (mat->index == self->rho_zero_mat->index)
                  cnt++;
            }

            if (2*cnt > ref->numParticles)
            {
               local_rho_zero_vol[arrayPos] += particle->weight*jac_det;
               local_rho_zero_density[arrayPos] += particle->weight*jac_det*densityFinal;
            }
         }

         if (_phi)
         {
            local_phi[arrayPos] += particle->weight*jac_det*(-density*alpha*tempDot);
         }
      }
   }

   /* Allocate for the global column values. */
   global_vol = (double*)malloc( arraySize*sizeof(double) );
   global_density = (double*)malloc( arraySize*sizeof(double) );
   global_rho_zero_vol = (double*)malloc( arraySize*sizeof(double) );
   global_rho_zero_density = (double*)malloc( arraySize*sizeof(double) );
   global_phi = (double*)malloc( arraySize*sizeof(double) );

   MPI_Allreduce(local_vol, global_vol, arraySize, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD);
   MPI_Allreduce(local_density, global_density, arraySize, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD);
   MPI_Allreduce(local_rho_zero_vol, global_rho_zero_vol, arraySize, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD);
   MPI_Allreduce(local_rho_zero_density, global_rho_zero_density, arraySize, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD);
   if (_phi)
      MPI_Allreduce(local_phi, global_phi, arraySize, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD);

   free( local_vol );
   free( local_density );
   free( local_rho_zero_vol );
   free( local_rho_zero_density );
   free( local_phi );

   if ( self->avg )
   {
      for ( ii = 1; ii < arraySize; ii++ )
      {
         global_vol[0] += global_vol[ii];
         global_density[0] += global_density[ii];
         global_rho_zero_vol[0] += global_rho_zero_vol[ii];
         global_rho_zero_density[0] += global_rho_zero_density[ii];
         if ( _phi )
            global_phi[0] += global_phi[ii];
      }
   }

   /* Calculate results. */
   *_avg_density = (double*)malloc( arraySize*sizeof(double) );
   *_rho_zero_density = (double*)malloc( arraySize*sizeof(double) );
   if (_phi)
      *_phi = (double*)malloc( arraySize*sizeof(double) );
   for ( ii = 0; ii < arraySize; ii++ )
   {
      (*_avg_density)[ii] = (global_vol[ii] > 1e-7) ? global_density[ii]/global_vol[ii] : 0.0;
      (*_rho_zero_density)[ii] = (global_rho_zero_vol[ii] > 1e-7) ? global_rho_zero_density[ii]/global_rho_zero_vol[ii] : 0.0;
      if (_phi)
         (*_phi)[ii] = (global_vol[ii] > 1e-7) ? global_phi[ii]/global_vol[ii] : 0.0;
      if ( self->avg )
         break;
   }

   /*
       printf("Global mean density: %g\n", (*_avg_density)[0]);
       printf("Global mean rho_0 density: %g\n", (*_rho_zero_density)[0]);
       printf("Global phi/vol: %g\n", (*_phi)[0]);
   */

   free( global_vol );
   free( global_density );
   free( global_rho_zero_vol );
   free( global_rho_zero_density );
   free( global_phi );
}
Exemplo n.º 11
0
Bool _SwarmAdvector_TimeDeriv( void* swarmAdvector, Index array_I, double* timeDeriv ) {
  SwarmAdvector*      self          = (SwarmAdvector*) swarmAdvector;
  GeneralSwarm*       swarm         = self->swarm;
  CellLayout*         layout        = swarm->cellLayout;
  FeVariable*         velocityField = (FeVariable*) self->velocityField;
  FeMesh*             mesh          = velocityField->feMesh;
  double*             coord;
  InterpolationResult result;

  /* Get Coordinate of Object using Variable */
  coord = StgVariable_GetPtrDouble( self->variable, array_I );

  // if a non regular mesh and ElementCellLayout use the particle and mesh information to optimise search
  if( !mesh->isRegular &&
      Stg_Class_IsInstance(layout, ElementCellLayout_Type) )
  {
    GlobalParticle*     particle = (GlobalParticle*)Swarm_ParticleAt( swarm, array_I );
    FeMesh_ElementType* eType;
    unsigned            cellID;
    double              xi[3];

    // find the cell/element the particle is in
    cellID = CellLayout_CellOf( layout, particle );

    if( cellID >= CellLayout_CellLocalCount( layout ) ) return False; // if not on local proc report False
    /*
       CellLayout_CellOf() will actually evaulate the local coordinate and store it
       on a temporary valiable (on 'FeMesh_ElementType->local[]'). Below we exploit that
    */

    // get particle's local coordinate - HACKY but efficient
    eType = (FeMesh_ElementType*)mesh->elTypes[mesh->elTypeMap[cellID]];
    FeMesh_ElementTypeGetLocal( eType, xi );

    // do interpoplation
    FeVariable_InterpolateWithinElement( velocityField, cellID, xi, timeDeriv );
    return True;
  }
  else
  {
    // if mesh is regular
    result = FieldVariable_InterpolateValueAt( velocityField, coord, timeDeriv );
  }

  if ( result == OTHER_PROC || result == OUTSIDE_GLOBAL || isinf(timeDeriv[0]) || isinf(timeDeriv[1]) ||
     ( swarm->dim == 3 && isinf(timeDeriv[2]) ) )
  {
    /* construct error message */
    int rank;
    MPI_Comm_rank( MPI_COMM_WORLD, &rank );

    char* coordchar;
    if ( swarm->dim == 2 )
        Stg_asprintf(&coordchar, "(%f,%f)", coord[0], coord[1] );
    else
        Stg_asprintf(&coordchar, "(%f,%f,%f)", coord[0], coord[1], coord[2] );

    char* message;
    if ( result == OTHER_PROC )
        Stg_asprintf( &message, "Coordinate appears to belong to another process's domain" );
    else if ( result == OUTSIDE_GLOBAL )
        Stg_asprintf( &message, "Coordinate appears to be outside the global domain" );
    else
        Stg_asprintf( &message, "Velocity appears infinite" );

    free(self->error_msg);
    Stg_asprintf(&self->error_msg, "Unable to determine valid velocity for particle of local id %i "
                                          "with coordinate %s on process rank %i. %s.", array_I, coordchar, rank, message );
    free(message);
    free(coordchar);
    return False;
  }

  return True;
}
Fn::GradFeVariableFn::GradFeVariableFn( void* fevariable ):Function(), _fevariable(fevariable){
    if(!Stg_Class_IsInstance( _fevariable, FeVariable_Type ))
        throw std::invalid_argument("Provided variable does not appear to be of 'MeshVariable' type.");


}
Exemplo n.º 13
0
unsigned GeneralSwarm_IntegrationPointMap( void* _self, void* _intSwarm, unsigned elementId, unsigned intPtCellId ){
    GeneralSwarm* self  = (GeneralSwarm*)_self;
    IntegrationPointsSwarm*	intSwarm = (IntegrationPointsSwarm*)_intSwarm;
    Mesh*	                intMesh  = (Mesh*)intSwarm->mesh;
    SwarmMap* map = NULL;

    // first, lets check if the int swarm is mirroring a general swarm
    if (intSwarm->mirroredSwarm == (Swarm*)self)
    {
        // ok, it is a mirrored swarm
        return Swarm_ParticleCellIDtoLocalID(
                                        self,
                                        CellLayout_MapElementIdToCellId( self->cellLayout, elementId ),
                                        intPtCellId );
    } else if ( self->previousIntSwarmMap && self->previousIntSwarmMap->swarm==intSwarm ) { /* next check if previous swarmmap */
        map = self->previousIntSwarmMap;
    } else {
        /* ok, previous is not our guy, check other existing: */
        int ii;
        for (ii=0; ii<List_GetSize(self->intSwarmMapList); ii++) {
            map = *(SwarmMap**)List_GetItem(self->intSwarmMapList, ii);
            if ( map->swarm==intSwarm ){
                self->previousIntSwarmMap = map;
                break;
            }
        }
        // if we've gotten to this point, there is no corresponding map.. let's create one */
        map = SwarmMap_New( intSwarm );
        // add to list
        List_Append( self->intSwarmMapList, (void*)&map );
        self->previousIntSwarmMap = map;
        // also add to int swarm incase it moves
        List_Append( intSwarm->swarmsMappedTo, (void*)&map );

    }
    
    unsigned matPointLocalIndex;
    if ( SwarmMap_Map(map,elementId,intPtCellId,&matPointLocalIndex) ) {
        /* ok, map found, return value */
        return matPointLocalIndex;
    } else {
        /* not found... damn.. lets go ahead and find nearest neighbour */
        
        /* lets check some things */
        Journal_Firewall(
            Stg_Class_IsInstance( self->cellLayout, ElementCellLayout_Type ),
            NULL,
            "Error In func %s: %s expects a materialSwarm with cellLayout of type ElementCellLayout.",
            __func__, self->type
        );

        Journal_Firewall(
            intSwarm->mesh==(FeMesh*)((ElementCellLayout*)self->cellLayout)->mesh,
            Journal_Register( Error_Type, (Name)self->type  ),
            "Error - in %s(): Mapper requires both the MaterialSwarm and\n"
            "the IntegrationSwarm to live on the same mesh.\n"
            "Here the MaterialSwarm %s lives in the mesh %s\n"
            "and the IntegrationSwarm %s lives in the mesh %s.",
            self->name, ((ElementCellLayout*)self->cellLayout)->mesh->name,
            intSwarm->name, intSwarm->mesh->name
        );
        
        Cell_Index cell_I = CellLayout_MapElementIdToCellId( intSwarm->cellLayout, elementId );
        Cell_Index cell_M = CellLayout_MapElementIdToCellId(     self->cellLayout, elementId );

        IntegrationPoint* integrationPoint = (IntegrationPoint*)Swarm_ParticleInCellAt( intSwarm, cell_I, intPtCellId );
        
        /* Convert integration point local to global coordinates */
        Coord global;
        FeMesh_CoordLocalToGlobal( intMesh, elementId, integrationPoint->xi, (double*) &global );

        /* now lets sweep material points to find our closest friend */
        double         distance2_min = DBL_MAX;
        double         distance2;
        Particle_Index particle_M;
        unsigned cellPartCount = self->cellParticleCountTbl[ cell_M ];
        
        Journal_Firewall( cellPartCount,
            Journal_Register( Error_Type, (Name)self->type  ),
            "Error - in %s(): There doesn't appear to be any particles\n"
            "within the current cell (%u).\n",
            self->name, cell_M );

        for ( particle_M = 0; particle_M < cellPartCount; particle_M++ ) {
            GlobalParticle* materialPoint = (GlobalParticle*)Swarm_ParticleInCellAt( self, cell_M, particle_M );
            distance2 = pow( global[0] - materialPoint->coord[0], 2 ) + pow( global[1] - materialPoint->coord[1], 2 );
            if( self->dim == 3 )
                distance2 += pow( global[2] - materialPoint->coord[2], 2 );
            if ( distance2 < distance2_min ){
                distance2_min = distance2;
                matPointLocalIndex = Swarm_ParticleCellIDtoLocalID( self, cell_M, particle_M );
            }
        }
        
        /* ok, we've found our nearest friend. record to mapping */
        SwarmMap_Insert(map,elementId,intPtCellId,matPointLocalIndex);

    }
    
    return matPointLocalIndex;
}
Exemplo n.º 14
0
void _GeneralSwarm_Initialise( void* swarm, void* data )
{
   GeneralSwarm*	self 	= (GeneralSwarm*) swarm;
   AbstractContext* 	context = (AbstractContext*)self->context;
   Index            	var_I	= 0;

   _Swarm_Initialise( self, data );

   if( self->escapedRoutine != NULL) Stg_Component_Initialise( self->escapedRoutine, data , False );

   for( var_I = 0 ; var_I < self->nSwarmVars ; var_I++ )
   {
      Stg_Component_Initialise( self->swarmVars[var_I], data , False );
   }


   /** if loading from checkpoint, particle materials etc have already been loaded in Swarm_Build() - */
   /** possibly need to check for empty cells (and populate) if performing a interpolation restart */
   if ( context && True == context->loadFromCheckPoint )
   {
      if ( (True == self->isSwarmTypeToCheckPointAndReload) && (True == context->interpolateRestart) )
      {
         Particle_InCellIndex cParticle_I         = 0;
         Particle_InCellIndex particle_I          = 0;
         GlobalParticle*      particle            = NULL;
         double               minDistance         = HUGE_VAL;
         double               distanceToParticle;
         Dimension_Index      dim = self->dim;
         Cell_DomainIndex     dCell_I;
         Cell_LocalIndex      lCell_I;
         Cell_DomainIndex     belongsToCell_I = 0;
         GlobalParticle*       matNewParticle;
         GlobalParticle*       matParticleToSplit;
         Particle_Index       matNewParticle_IndexOnCPU;
         Coord                xi;
         Coord                coord;
         unsigned             nEmptyCells = 0;
         Index*				   cellID = NULL;
         Index*				   particleCPUID = NULL;
         unsigned             count;
         unsigned             ii;

         /** first determine how many local cells are empty */
         for( lCell_I = 0 ; lCell_I < self->cellLocalCount ; lCell_I++ )
            if (self->cellParticleCountTbl[lCell_I] == 0) nEmptyCells++;

         /** create arrays which will be later used to populate cells */
         cellID        = Memory_Alloc_Array( Index, nEmptyCells, "Cell ID for cell to be populated" );
         particleCPUID = Memory_Alloc_Array( Index, nEmptyCells, "particle ID for particle to populate cell" );

         count = 0;
         for( lCell_I = 0 ; lCell_I < self->cellLocalCount ; lCell_I++ )
         {
            minDistance = HUGE_VAL;
            if (self->cellParticleCountTbl[lCell_I] == 0)
            {
               /** select the centre of the current cell */
               xi[0] = 0;
               xi[1] = 0;
               xi[2] = 0;

               Journal_Firewall(
                                Stg_Class_IsInstance( self->cellLayout, ElementCellLayout_Type ),
                                NULL,
                                "Error In func %s: When performing interpolation restart, cellLayout must be of type ElementCellLayout.",
                                __func__ );

               /** get global coord */
               FeMesh_CoordLocalToGlobal( ((ElementCellLayout*)self->cellLayout)->mesh, lCell_I, xi, coord );

               for( dCell_I = 0 ; dCell_I < self->cellDomainCount ; dCell_I++ )
               {
                  /** Loop over particles find closest to cell centre */
                  for( cParticle_I = 0 ; cParticle_I < self->cellParticleCountTbl[dCell_I] ; cParticle_I++ )
                  {
                     particle = (GlobalParticle*)Swarm_ParticleInCellAt( self, dCell_I, cParticle_I );

                     /** Calculate distance to particle */
                     distanceToParticle =
                        (particle->coord[ I_AXIS ] - coord[ I_AXIS ]) *
                        (particle->coord[ I_AXIS ] - coord[ I_AXIS ]) +
                        (particle->coord[ J_AXIS ] - coord[ J_AXIS ]) *
                        (particle->coord[ J_AXIS ] - coord[ J_AXIS ]) ;

                     if (dim == 3)
                     {
                        distanceToParticle +=
                           (particle->coord[ K_AXIS ] - coord[ K_AXIS ]) *
                           (particle->coord[ K_AXIS ] - coord[ K_AXIS ]) ;
                     }
                     /** Don't do square root here because it is unnessesary: i.e. a < b <=> sqrt(a) < sqrt(b) */
                     /** Check if this is the closest particle */
                     if (minDistance > distanceToParticle)
                     {
                        particle_I       = cParticle_I;
                        minDistance      = distanceToParticle;
                        belongsToCell_I  = dCell_I;
                     }
                  }
               }

               /** create new particle which will be placed at centre of empty cell */
               matNewParticle      = (GlobalParticle*) Swarm_CreateNewParticle( self, &matNewParticle_IndexOnCPU );
               /** grab closest particle, which we will copy */
               matParticleToSplit  = (GlobalParticle*) Swarm_ParticleInCellAt( self, belongsToCell_I, particle_I );
               /** copy - even though self->particleExtensionMgr->finalSize maybe biger than sizeof(GlobalParticle)
                   the addressing of the copy is the important part
                */
               memcpy( matNewParticle, matParticleToSplit, self->particleExtensionMgr->finalSize );
               /** set the owningCell to the cellDomainCount so that its owningCell will be reinitialised (not sure if necessary) */
               matNewParticle->owningCell = self->cellDomainCount;
               /** Copy new global position (cell centre) to coord on new mat particle */
               memcpy( matNewParticle->coord, coord, sizeof(Coord) );

               /** we now store the required information to populate empty cells */
               /** note that cells are not populated at this point, as this may interfere
                   with the 0th order interpolation we are performing */
               cellID[count]        = lCell_I;
               particleCPUID[count] = matNewParticle_IndexOnCPU;
               count++;

            }
         }
         /** populate empty cells */
         for(ii = 0 ; ii < count ; ii++)
            Swarm_AddParticleToCell( self, cellID[ii], particleCPUID[ii] );
         Memory_Free( cellID );
         Memory_Free( particleCPUID );
      }
      /* TODO: print info / debug message */
   }

}