Пример #1
0
void _RefinedRegionsGeometry_Init( RefinedRegionsGeometry* self, IJK size ) {
    Dimension_Index		dim_I;
    Dictionary_Entry_Value*	regionsList = NULL;

    /* General and Virtual info should already be set */

    /* RefinedRegionsGeometry info */
    self->isConstructed = False;

    self->min[ I_AXIS ] = Dictionary_GetDouble_WithDefault( self->dictionary, "minX", 0.0f );
    self->min[ J_AXIS ] = Dictionary_GetDouble_WithDefault( self->dictionary, "minY", 0.0f );
    self->min[ K_AXIS ] = Dictionary_GetDouble_WithDefault( self->dictionary, "minZ", 0.0f );

    self->max[ I_AXIS ] = Dictionary_GetDouble_WithDefault( self->dictionary, "maxX", 1.0f );
    self->max[ J_AXIS ] = Dictionary_GetDouble_WithDefault( self->dictionary, "maxY", 1.0f );
    self->max[ K_AXIS ] = Dictionary_GetDouble_WithDefault( self->dictionary, "maxZ", 1.0f );

    if ( size ) {
        memcpy( self->countPerDim, size, sizeof(IJK) );
    }
    else {
        self->countPerDim[ I_AXIS ] = Dictionary_GetUnsignedInt_WithDefault( self->dictionary, "meshSizeI", 2 );
        self->countPerDim[ J_AXIS ] = Dictionary_GetUnsignedInt_WithDefault( self->dictionary, "meshSizeJ", 2 );
        self->countPerDim[ K_AXIS ] = Dictionary_GetUnsignedInt_WithDefault( self->dictionary, "meshSizeK", 2 );
    }

    for ( dim_I = 0; dim_I < 3; dim_I++ ) {
        self->refinedRegionDeltas[dim_I] = 4;
    }

    /* Now Read in the refined regions */
    regionsList = Dictionary_Get( self->dictionary, "RefinedRegions" );
    if ( regionsList ) {
        Index				entryCount = Dictionary_Entry_Value_GetCount( regionsList );
        Index				entry_I = 0;
        Dictionary_Entry_Value*		regionEntry;
        Dictionary*			regionDict;
        Dimension_Index			dim = 0;
        double				regionStart = 0;
        double				regionEnd = 0;
        unsigned int			refinementFactor = 1;

        for( entry_I = 0; entry_I < entryCount; entry_I++ ) {
            regionEntry = Dictionary_Entry_Value_GetElement( regionsList, entry_I );
            regionDict = Dictionary_Entry_Value_AsDictionary( regionEntry );
            dim = Dictionary_GetUnsignedInt_WithDefault( regionDict, "dim", 0 );
            regionStart = Dictionary_GetDouble_WithDefault( regionDict, "regionStart", 0.0 );
            regionEnd = Dictionary_GetDouble_WithDefault( regionDict, "regionEnd", 1.0 );
            refinementFactor = Dictionary_GetUnsignedInt_WithDefault( regionDict, "refinementFactor", 2 );
            _RefinedRegionsGeometry_AddRefinedRegion( self, dim, regionStart, regionEnd, refinementFactor );
        }
    }

    self->pointCount = self->countPerDim[I_AXIS] * self->countPerDim[J_AXIS] *
                       self->countPerDim[K_AXIS];

    assert( self->pointCount );

}
Пример #2
0
void _DomainContext_AssignFromXML( void* context, Stg_ComponentFactory* cf, void* data ) {
   DomainContext* self = (DomainContext*)context;
   Dictionary     *contextDict = NULL;

   _AbstractContext_AssignFromXML( context, cf, data );

   self->dim          = Dictionary_GetUnsignedInt_WithDefault( self->dictionary, "dim", 2 );
   self->verticalAxis = Dictionary_GetUnsignedInt_WithDefault( self->dictionary, "VerticalAxis", 1 );

   /* try grab the scaling component and put it on the context 
    * check for the contextDict first as ConstructByKey NEEDS the conextDict 
    * and in units tests the contextDict sometime doesn't exist */
   contextDict = Dictionary_GetDictionary( cf->componentDict, self->name );
   if( contextDict ) {
      self->scaling = Stg_ComponentFactory_ConstructByKey(
         cf,
         self->name, 
         (Dictionary_Entry_Key)"Scaling",
         Scaling,
         False,
         data );
   }
   if( !self->scaling ) {
      self->scaling = Stg_ComponentFactory_ConstructByName(
         cf,
         (Name)"default_scaling", 
         Scaling, False, data ); 
   }

       /* The following is for backward compatiblity with old (GALE) xml files. */
   {
      /* Post change 1d3dc4e00549 in this repositroy, the old style of DofLayout 
       * XML definition was illegal. This change allows for the old style.
       *
       * Here we build all 'MeshVariable' components first.
       *
       * This is a hack, selective construction of general component over other is
       * a weakness to the object model and should be avoided. This section should
       * be removed in future and xml files updated in accordance with change 1d3dc4e00549  
       */

      Stg_Component *component=NULL;
      Index         component_I;
      for( component_I = 0; component_I < LiveComponentRegister_GetCount( cf->LCRegister ); component_I++ ){
         /* Grab component from register */
         component = LiveComponentRegister_At( cf->LCRegister, component_I ); 
         /* if not a "MeshVariable" do nothing */
         if( strcmp( component->type, MeshVariable_Type ) ) continue;

         if( component && !component->isConstructed ){
            Journal_Printf( cf->infoStream, "Constructing %s as %s\n", component->type, component->name );
            Stg_Component_AssignFromXML( component, cf, data, True );
         }

      }
   }

   _DomainContext_Init( self );
}
Пример #3
0
unsigned int _Stg_ComponentFactory_GetRootDictUnsignedInt( void* cf, Dictionary_Entry_Key key, const unsigned int defaultVal ) {
   Stg_ComponentFactory*    self              = (Stg_ComponentFactory*)cf;
   
   Journal_PrintfL( self->infoStream,2, "Getting unsigned int from root dictionary with key '%s' and default value '%u'\n",
         key, defaultVal );

   assert( self->rootDict );
   return Dictionary_GetUnsignedInt_WithDefault( self->rootDict, key, defaultVal );
}   
void _StGermain_SingleAttractor_AssignFromXML( void* component, Stg_ComponentFactory* cf, void* data ) {
	DomainContext*   context;

	context = Stg_ComponentFactory_ConstructByName( cf, (Name)"context", DomainContext, True, data  );
	Stream_SetPrintingRank( 
		Journal_Register( Info_Type, (Name)"Context"  ),
		Dictionary_GetUnsignedInt_WithDefault( context->dictionary, "procToWatch", 0 ) );
	
	ContextEP_ReplaceAll( context, AbstractContext_EP_Solve, StGermain_SingleAttractor_UpdatePositions );
}
void DictionarySuite_TestShortcuts( DictionarySuiteData* data ) {

   DictionarySuite_PopulateDictWithTestValues( data->dict, data->testDD );

   /* Testing GetString_WithDefault. If an entry with that key already exists, then
    *  the value of the existing key should be returned, and the default passed in
    *  ignored. However if the given key _doesn't_ exist, the default should be 
    *  returned, and a new entry with the given key added to the dict. */
   pcu_check_streq( data->testDD->testString, Dictionary_GetString_WithDefault( data->dict, "test_cstring", "heya" ) );
   pcu_check_streq( "heya", Dictionary_GetString_WithDefault( data->dict, "test_cstring2", "heya" ) );
   pcu_check_true( NULL != Dictionary_Get( data->dict, (Dictionary_Entry_Key)"test_cstring2" )  );
	data->testDD->testDouble = Dictionary_GetDouble_WithDefault( data->dict, (Dictionary_Entry_Key)"test_double", 2.8 );
   pcu_check_true( data->testDD->testDouble );
   pcu_check_true( 2.8 == Dictionary_GetDouble_WithDefault( data->dict, (Dictionary_Entry_Key)"test_double2", 2.8 )  );

   /* test_placeholder refers to test_double which equals 45.567 */
   pcu_check_true( 45.567 == Dictionary_GetDouble_WithScopeDefault( data->dict, (Dictionary_Entry_Key)"test_placeholder", -1 )  );
   
   pcu_check_true( NULL != Dictionary_Get( data->dict, (Dictionary_Entry_Key)"test_double2" )  );
   data->testDD->testUint = Dictionary_GetUnsignedInt_WithDefault( data->dict, "test_uint", 33 );
	pcu_check_true( data->testDD->testUint );
   pcu_check_true( 33 == Dictionary_GetUnsignedInt_WithDefault( data->dict, "test_uint2", 33 ) );
   pcu_check_true( NULL != Dictionary_Get( data->dict, (Dictionary_Entry_Key)"test_uint2" )  );
   data->testDD->testInt = Dictionary_GetInt_WithDefault( data->dict, (Dictionary_Entry_Key)"test_int", -24 );
	pcu_check_true( data->testDD->testInt );
   pcu_check_true( -24 == Dictionary_GetInt_WithDefault( data->dict, (Dictionary_Entry_Key)"test_int2", -24 )  );
   pcu_check_true( NULL != Dictionary_Get( data->dict, (Dictionary_Entry_Key)"test_int2" )  );
   data->testDD->testUnsignedlong = Dictionary_GetUnsignedLong_WithDefault( data->dict, "test_unsignedlong", 32433 );
	pcu_check_true( data->testDD->testUnsignedlong );
   pcu_check_true( 32433 == Dictionary_GetUnsignedLong_WithDefault( data->dict, "test_unsignedlong2", 32433 ) );
   pcu_check_true( NULL != Dictionary_Get( data->dict, (Dictionary_Entry_Key)"test_unsignedlong2" )  );
   data->testDD->testBool = Dictionary_GetBool_WithDefault( data->dict, (Dictionary_Entry_Key)"test_bool", False );
	pcu_check_true( data->testDD->testBool );
   pcu_check_true( False == Dictionary_GetBool_WithDefault( data->dict, (Dictionary_Entry_Key)"test_bool2", False )  );
   pcu_check_true( NULL != Dictionary_Get( data->dict, (Dictionary_Entry_Key)"test_bool2" )  );

   pcu_check_streq( data->testDD->testString, Dictionary_GetString_WithPrintfDefault( data->dict, "test_cstring", "heya%s%u", "hey", 3 ) );
   pcu_check_streq( "heyahey3", Dictionary_GetString_WithPrintfDefault( data->dict, "test_cstring3", "heya%s%u", "hey", 3 ) );
   pcu_check_true( NULL != Dictionary_Get( data->dict, (Dictionary_Entry_Key)"test_cstring3" ) );
}
void SemiLagrangianIntegratorSuite_UpdatePositions( void* data, FiniteElementContext* context ) {
   Index                   reverseTimeStep = Dictionary_GetUnsignedInt_WithDefault( context->dictionary, "reverseTimeStep", 100 );
   FeVariable*		velocityField	= (FeVariable*) LiveComponentRegister_Get( context->CF->LCRegister, (Name)"VelocityField" );
   FeMesh*			mesh		= velocityField->feMesh;
   unsigned		node_I;
   Index			dim_I;
   unsigned		nDims		= Mesh_GetDimSize( mesh );
   double			velocity[3];
   double			phi;
   SemiLagrangianIntegrator*	slIntegrator;
   FeVariable*		phiField;
   FeVariable*		phiStarField;

   _FeVariable_SyncShadowValues( velocityField );

   /* reverse the numerically advected particles (& the semi lagrangian field also) */
   if( context->timeStep == reverseTimeStep + 1  ) {
      for( node_I = 0; node_I < Mesh_GetLocalSize( mesh, MT_VERTEX ); node_I++ ) {
         _FeVariable_GetValueAtNode( velocityField, node_I, velocity );

         for( dim_I = 0; dim_I < nDims; dim_I++ ) {
            velocity[dim_I] *= -1;
         }

         FeVariable_SetValueAtNode( velocityField, node_I, velocity );
      }
   }

   slIntegrator = (SemiLagrangianIntegrator*)LiveComponentRegister_Get( context->CF->LCRegister, (Name)"integrator" );
   phiField     = (FeVariable* )LiveComponentRegister_Get( context->CF->LCRegister, (Name)"PhiField" );
   phiStarField = (FeVariable* )LiveComponentRegister_Get( context->CF->LCRegister, (Name)"PhiStarField"  );
   SemiLagrangianIntegrator_Solve( slIntegrator, phiField, phiStarField );

   for( node_I = 0; node_I < Mesh_GetLocalSize( mesh, MT_VERTEX ); node_I++ ) {
      FeVariable_GetValueAtNode( phiStarField, node_I, &phi );
      FeVariable_SetValueAtNode( phiField, node_I, &phi );
   }
}
Пример #7
0
int main(int argc, char *argv[])
{
	MPI_Comm		CommWorld;
	int			rank;
	int			procCount;
	int			procToWatch;
	Dictionary*		dictionary;
	Topology*		nTopology;
	ElementLayout*		eLayout;
	NodeLayout*		nLayout;
	HexaMD*			decompCorner;
	HexaMD*			decompBody;
	Stream*                 stream;
	Index			decompDims;
	XML_IO_Handler*         ioHandler;
	Dimension_Index         dim_I;
	
	/* Initialise MPI, get world info */
	MPI_Init(&argc, &argv);
	MPI_Comm_dup( MPI_COMM_WORLD, &CommWorld );
	MPI_Comm_size(CommWorld, &procCount);
	MPI_Comm_rank(CommWorld, &rank);

	Base_Init( &argc, &argv );
	
	DiscretisationGeometry_Init( &argc, &argv );
	DiscretisationShape_Init( &argc, &argv );
	DiscretisationMesh_Init( &argc, &argv );
	MPI_Barrier( CommWorld ); /* Ensures copyright info always come first in output */
	
	procToWatch = argc >= 2 ? atoi(argv[1]) : 0;

	Journal_Enable_TypedStream( DebugStream_Type, False );
	stream = Journal_Register( DebugStream_Type, HexaMD_Type );
	Stream_EnableBranch( stream, True );
	Stream_SetLevelBranch( stream, 3 );
	
	dictionary = Dictionary_New();

	Dictionary_Add( dictionary, "rank", Dictionary_Entry_Value_FromUnsignedInt( rank ) );
	Dictionary_Add( dictionary, "numProcessors", Dictionary_Entry_Value_FromUnsignedInt( procCount ) );
	Dictionary_Add( dictionary, "meshSizeI", Dictionary_Entry_Value_FromUnsignedInt( 5 ) );
	Dictionary_Add( dictionary, "meshSizeJ", Dictionary_Entry_Value_FromUnsignedInt( 5 ) );
	Dictionary_Add( dictionary, "meshSizeK", Dictionary_Entry_Value_FromUnsignedInt( 5 ) );
	Dictionary_Add( dictionary, "allowUnusedCPUs", Dictionary_Entry_Value_FromBool( True ) );
	Dictionary_Add( dictionary, "allowPartitionOnElement", Dictionary_Entry_Value_FromBool( False ) );
	Dictionary_Add( dictionary, "allowPartitionOnNode", Dictionary_Entry_Value_FromBool( True ) );
	Dictionary_Add( dictionary, "allowUnbalancing", Dictionary_Entry_Value_FromBool( False ) );
	Dictionary_Add( dictionary, "shadowDepth", Dictionary_Entry_Value_FromUnsignedInt( 1 ) );

	/* Moved afterwards to allow command line to over-ride */
	ioHandler = XML_IO_Handler_New();
	IO_Handler_ReadAllFromCommandLine( ioHandler, argc, argv, dictionary );

	decompDims = Dictionary_GetUnsignedInt_WithDefault( dictionary, "decompDims", 1 );
	
	nTopology = (Topology*)IJK6Topology_New( "IJK6Topology", dictionary );
	eLayout = (ElementLayout*)ParallelPipedHexaEL_New( "PPHexaEL", 3, dictionary );
	nLayout = (NodeLayout*)CornerNL_New( "CornerNL", dictionary, eLayout, nTopology );
	decompCorner = HexaMD_New_All( "HexaMD", dictionary, MPI_COMM_WORLD, eLayout, nLayout, decompDims );

	if( rank == procToWatch ) {
		printf( "Corner Node Layout\n" );
		PrintDecompInfoOfHexaMD( decompCorner, rank );
		printf( "\n" );
	}

	/* Do a run with body nodes */
	Stg_Class_Delete( nLayout );
	/* TODO: the following is a bit of a hack because of the weird way mesh size is defined by default in
	the dictionary (assumes a corner mesh ) */
	for ( dim_I = 0; dim_I < 3; dim_I++ ) {
		if ( ((IJKTopology*)nTopology)->size[dim_I] > 1 ) {
			((IJKTopology*)nTopology)->size[dim_I]--;
		}
	}	
	nLayout = (NodeLayout*)BodyNL_New( "BodyNL", dictionary, eLayout, nTopology );
	decompBody = HexaMD_New_All( "HexaMD", dictionary, MPI_COMM_WORLD, eLayout, nLayout, decompDims );
	if( rank == procToWatch ) {
		Bool    result;

		printf( "Body Node Layout\n" );
		//PrintDecompInfoOfHexaMD( decompBody, rank );
		printf( "Checking body node decomp has same element decomp as corner node decomp:\n" );
		result = CheckDecompItemsAreDecomposedIdentically( decompCorner, ELEMENT_ITEM_TYPE, 
			decompBody, ELEMENT_ITEM_TYPE, rank );
		if ( result == True ) printf( "\tPassed.\n" );
		else printf( "\tFailed.\n" );

		printf( "Checking body node decomp has same node decomp as it's element decomp:\n" );
		result = CheckDecompItemsAreDecomposedIdentically( decompBody, ELEMENT_ITEM_TYPE, 
			decompBody, NODE_ITEM_TYPE, rank );
		if ( result == True ) printf( "\tPassed.\n" );
		else printf( "\tFailed.\n" );
	}

	Stg_Class_Delete( decompBody );
	Stg_Class_Delete( decompCorner );
	Stg_Class_Delete( nLayout );
	Stg_Class_Delete( eLayout );
	Stg_Class_Delete( nTopology );
	Stg_Class_Delete( dictionary );
	
	DiscretisationMesh_Finalise();
	DiscretisationShape_Finalise();
	DiscretisationGeometry_Finalise();
	
	Base_Finalise();
	
	/* Close off MPI */
	MPI_Finalize();
	
	return EXIT_SUCCESS;
}
void PCDVCSuite_TestExponentialInterface( PCDVCSuiteData* data ) {
   Swarm*             integrationSwarm = (Swarm*)LiveComponentRegister_Get( data->context->CF->LCRegister, (Name)"integrationSwarm" );
   Swarm*             materialSwarm    = (Swarm*)LiveComponentRegister_Get( data->context->CF->LCRegister, (Name)"materialPoints" );
   FeMesh*            mesh             = (FeMesh*)LiveComponentRegister_Get( data->context->CF->LCRegister, (Name)"linearMesh" );
   //WeightsCalculator* weights          = (WeightsCalculator*)LiveComponentRegister_Get( data->context->CF->LCRegister, (Name)"weights" );
   FeVariable*        feVariable;
   Element_LocalIndex lElement_I       = 0;
   double             analyticValue    = 0.0;
   double             integral         = 0.0;
   double             error;
   double             errorSquaredSum  = 0.0;
   double             errorSum         = 0.0;
   Index              loop_I;
   Index              count            = Dictionary_GetUnsignedInt_WithDefault( data->context->dictionary, "SampleSize", 5000 );
   void*              generic          = NULL;
   double             mean;
   double             standardDeviation;

   /* Create FeVariable */
   feVariable = FeVariable_New_Full(
      "feVariable",
      (DomainContext*)data->context,
      mesh,
      NULL,
      NULL,
      NULL,
      NULL,
      NULL, 
      1,
      data->context->dim,
      False,
      False,
      False,
      MPI_COMM_WORLD,
      data->context->fieldVariable_Register );

   feVariable->_interpolateWithinElement = ExponentialInterface;
   analyticValue = 0.05 * (exp(2) - exp(-2)) + 2.0;

   for ( loop_I = 0 ; loop_I < count ; loop_I++ ) {
      /* Layout Particles */
      Swarm_Random_Seed( (long)loop_I );
      _Swarm_InitialiseParticles( materialSwarm, generic );

      _IntegrationPointsSwarm_UpdateHook( NULL, integrationSwarm );
      /* The following function should not be called here as it is already called ultimately via the above function */
      /* calling this function again causes a first iteration in Lloyd's algorithm for the Voronoi cells which we don't want here */
      //WeightsCalculator_CalculateCell( weights, integrationSwarm, lElement_I );

      /* Evaluate Integral */
      integral = FeVariable_IntegrateElement( feVariable, integrationSwarm, lElement_I );

      /* Calculate Error */
      error = fabs( integral - analyticValue )/fabs( analyticValue );
      errorSum += error;
      errorSquaredSum += error*error;
   }

   /* Calculate Mean and Standard Deviation */
   mean = errorSum / (double)count;
   standardDeviation = sqrt( errorSquaredSum / (double)count - mean * mean );
   printf("In %s: Mean %lf SD %lf Sol %lf\n", __func__, mean, standardDeviation, analyticValue);
   Stg_Component_Destroy( feVariable, NULL, True );

   compareAgainstReferenceSolution( data->context, data->stream, mean, standardDeviation, "testPCDVC_ExponentialInterface.expected" );
}
void StGermain_VaryingCornerAttractors_UpdatePositions( DomainContext* context ) {
	Cell_LocalIndex			lCell_I;
	Particle_InCellIndex		cParticle_I;
	Particle* 	        	currParticle;
	Index				dim_I;
	Swarm*                          swarm = (Swarm*) LiveComponentRegister_Get( context->CF->LCRegister, (Name)"swarm"  );
	Coord                           attractorPoint;
	BlockGeometry*                  blockGeometry;
	Stream*                         stream = Journal_Register( Debug_Type, (Name)"particleUpdate" );
	unsigned int                    movementSpeedDivisor = 10;
	int                             movementSign = 1;
	unsigned int                    cornerPeriod = 10;
	unsigned int                    numCorners = (swarm->dim-1 )*4;
	unsigned int                    explosionPeriod = numCorners*cornerPeriod;
	Coord                           cornerCoords[8];
	int                             modValue = 0;
	int                             cornerIndex = 0;

	Stream_SetPrintingRank( stream, Dictionary_GetUnsignedInt_WithDefault( context->dictionary, "procToWatch", 0 ) );
	
	blockGeometry = (BlockGeometry*) LiveComponentRegister_Get( context->CF->LCRegister, (Name)"geometry" );

		/* Bottom left corner */
	cornerCoords[0][I_AXIS] = blockGeometry->min[I_AXIS];
	cornerCoords[0][J_AXIS] = blockGeometry->min[J_AXIS];
	cornerCoords[0][K_AXIS] = blockGeometry->min[K_AXIS];
	/* Bottom right corner */
	cornerCoords[1][I_AXIS] = blockGeometry->max[I_AXIS];
	cornerCoords[1][J_AXIS] = blockGeometry->min[J_AXIS];
	cornerCoords[1][K_AXIS] = blockGeometry->min[K_AXIS];
	/* Top right corner */
	cornerCoords[2][I_AXIS] = blockGeometry->max[I_AXIS];
	cornerCoords[2][J_AXIS] = blockGeometry->max[J_AXIS];
	cornerCoords[2][K_AXIS] = blockGeometry->min[K_AXIS];
	/* Top left corner */
	cornerCoords[3][I_AXIS] = blockGeometry->min[I_AXIS];
	cornerCoords[3][J_AXIS] = blockGeometry->max[J_AXIS];
	cornerCoords[3][K_AXIS] = blockGeometry->min[K_AXIS];
	/* Bottom left corner */
	cornerCoords[4][I_AXIS] = blockGeometry->min[I_AXIS];
	cornerCoords[4][J_AXIS] = blockGeometry->max[J_AXIS];
	cornerCoords[4][K_AXIS] = blockGeometry->max[K_AXIS];
	/* Bottom right corner */
	cornerCoords[5][I_AXIS] = blockGeometry->min[I_AXIS];
	cornerCoords[5][J_AXIS] = blockGeometry->min[J_AXIS];
	cornerCoords[5][K_AXIS] = blockGeometry->max[K_AXIS];
	/* Top right corner */
	cornerCoords[6][I_AXIS] = blockGeometry->max[I_AXIS];
	cornerCoords[6][J_AXIS] = blockGeometry->min[J_AXIS];
	cornerCoords[6][K_AXIS] = blockGeometry->max[K_AXIS];
	/* Top left corner */
	cornerCoords[7][I_AXIS] = blockGeometry->max[I_AXIS];
	cornerCoords[7][J_AXIS] = blockGeometry->max[J_AXIS];
	cornerCoords[7][K_AXIS] = blockGeometry->max[K_AXIS];

	/* calculate which corner */
	modValue = (context->timeStep - 1) % (numCorners * cornerPeriod );
	cornerIndex = modValue / cornerPeriod;
	memcpy( attractorPoint, cornerCoords[cornerIndex], 3 * sizeof(double) );
	Journal_Printf( stream, "Calculated attractor point is at (%f,%f,%f):\n", attractorPoint[0], attractorPoint[1], attractorPoint[2] );
	
	/* Can't really explode in this test as particles go out of box */
	#if 0
	/* Now decide if we are attracting or repelling */
	if ( ( ( (context->timeStep - 1) / explosionPeriod ) % 2 ) == 0 ) {
		Journal_Printf( stream, "Timestep %d - Implosive mode\n", context->timeStep );
		movementSign = 1;
	}
	else {
		Journal_Printf( stream, "Timestep %d - Explosive mode\n", context->timeStep );
		movementSign = -1;
	}	
	#endif

	
	for ( lCell_I=0; lCell_I < swarm->cellLocalCount; lCell_I++ ) {
		Journal_Printf( stream, "\tUpdating Particles positions in local cell %d:\n", lCell_I );
		for ( cParticle_I=0; cParticle_I < swarm->cellParticleCountTbl[lCell_I]; cParticle_I++ ) {
			Coord movementVector = {0,0,0};
			Coord newParticleCoord = {0,0,0};
			Coord* oldCoord;

			currParticle = (Particle*)Swarm_ParticleInCellAt( swarm, lCell_I, cParticle_I );
			oldCoord = &currParticle->coord;
			Journal_Printf( stream, "\t\tUpdating particleInCell %d:\n", cParticle_I );

			for ( dim_I=0; dim_I < 3; dim_I++ ) {
				movementVector[dim_I] = ( attractorPoint[dim_I] - (*oldCoord)[dim_I] ) /
					movementSpeedDivisor;
				movementVector[dim_I] *= movementSign;	
				if ( movementSign == -1 ) {
					movementVector[dim_I] *= (float)movementSpeedDivisor / (movementSpeedDivisor-1); 
				}
				newParticleCoord[dim_I] = (*oldCoord)[dim_I] + movementVector[dim_I];
			}
			memcpy( currParticle->velocity, movementVector, 3*sizeof(double) ); 

			Journal_Printf( stream, "\t\tChanging its coords from (%f,%f,%f) to (%f,%f,%f):\n",
				(*oldCoord)[0], (*oldCoord)[1], (*oldCoord)[2],
				newParticleCoord[0], newParticleCoord[1], newParticleCoord[2] );

			for ( dim_I=0; dim_I < 3; dim_I++ ) {
				currParticle->coord[dim_I] = newParticleCoord[dim_I];
			}
		}
	}

	Swarm_UpdateAllParticleOwners( swarm );
}
void StGermain_SingleAttractor_UpdatePositions( DomainContext* context ) {
	Cell_LocalIndex			lCell_I;
	Particle_InCellIndex		cParticle_I;
	Particle* 	        	currParticle;
	Index				dim_I;
	Swarm*                          swarm = (Swarm*) LiveComponentRegister_Get( context->CF->LCRegister, (Name)"swarm"  );
	Coord                           attractorPoint;
	Mesh*				mesh;
	Stream*                         stream = Journal_Register( Info_Type, (Name)"particleUpdate"  );
	unsigned int                    movementSpeedDivisor = 0;
	int                             movementSign = 1;
	unsigned int                    explosionPeriod = 20;
	double				minCrd[3], maxCrd[3];

	Stream_SetPrintingRank( stream, Dictionary_GetUnsignedInt_WithDefault( context->dictionary, "procToWatch", 0 ) );
	movementSpeedDivisor = Dictionary_GetDouble_WithDefault( context->dictionary, (Dictionary_Entry_Key)"movementSpeedDivisor", 10 );
	
	mesh = (Mesh* )LiveComponentRegister_Get( context->CF->LCRegister, (Name)"mesh-linear"  );
	Mesh_GetGlobalCoordRange( mesh, minCrd, maxCrd );
	for ( dim_I=0; dim_I < 3; dim_I++ ) {
		attractorPoint[dim_I] = (maxCrd[dim_I] - minCrd[dim_I]) / 3;
	}
	Journal_Printf( stream, "Calculated attractor point is at (%f,%f,%f):\n", attractorPoint[0], attractorPoint[1], attractorPoint[2] );
	
	/* Now decide if we are attracting or repelling */
	if ( ( ( (context->timeStep - 1) / explosionPeriod ) % 2 ) == 0 ) {
		Journal_Printf( stream, "Timestep %d - Implosive mode\n", context->timeStep );
		movementSign = 1;
	}
	else {
		Journal_Printf( stream, "Timestep %d - Explosive mode\n", context->timeStep );
		movementSign = -1;
	}	

	
	for ( lCell_I=0; lCell_I < swarm->cellLocalCount; lCell_I++ ) {
		Journal_Printf( stream, "\tUpdating Particles positions in local cell %d:\n", lCell_I );
		for ( cParticle_I=0; cParticle_I < swarm->cellParticleCountTbl[lCell_I]; cParticle_I++ ) {
			Coord movementVector = {0,0,0};
			Coord newParticleCoord = {0,0,0};
			Coord* oldCoord;

			currParticle = (Particle*)Swarm_ParticleInCellAt( swarm, lCell_I, cParticle_I );
			oldCoord = &currParticle->coord;
			Journal_Printf( stream, "\t\tUpdating particleInCell %d:\n", cParticle_I );

			for ( dim_I=0; dim_I < 3; dim_I++ ) {
				movementVector[dim_I] = ( attractorPoint[dim_I] - (*oldCoord)[dim_I] ) /
					movementSpeedDivisor;
				movementVector[dim_I] *= movementSign;	
				if ( movementSign == -1 ) {
					movementVector[dim_I] *= (float)movementSpeedDivisor / (movementSpeedDivisor-1); 
				}
				newParticleCoord[dim_I] = (*oldCoord)[dim_I] + movementVector[dim_I];
			}
			memcpy( currParticle->velocity, movementVector, 3*sizeof(double) ); 

			Journal_Printf( stream, "\t\tChanging its coords from (%f,%f,%f) to (%f,%f,%f):\n",
				(*oldCoord)[0], (*oldCoord)[1], (*oldCoord)[2],
				newParticleCoord[0], newParticleCoord[1], newParticleCoord[2] );

			for ( dim_I=0; dim_I < 3; dim_I++ ) {
				currParticle->coord[dim_I] = newParticleCoord[dim_I];
			}
		}
	}

	Swarm_UpdateAllParticleOwners( swarm );
}
Пример #11
0
void StGermain_Bouncer_UpdatePositions( DomainContext* context ) {
	Cell_LocalIndex			lCell_I;
	Particle_InCellIndex		cParticle_I;
	Particle* 	        	currParticle;
	Index				dim_I;
	Swarm*                          swarm = (Swarm*) LiveComponentRegister_Get( context->CF->LCRegister, (Name)"swarm"  );
	BlockGeometry*                  blockGeom;
	Stream*                         stream = Journal_Register( Debug_Type, (Name)"particleUpdate"  );
	unsigned int                    movementSpeedDivisor = 5;
	Particle_Index                  lParticle_I = 0;

	Stream_SetPrintingRank( stream, Dictionary_GetUnsignedInt_WithDefault( context->dictionary, "procToWatch", 0 ) );
	
	blockGeom = (BlockGeometry*) LiveComponentRegister_Get( context->CF->LCRegister, (Name)"geometry" );

	if ( context->timeStep == 1  ) {
		/* for each particle, set a random velocity */
		for ( lParticle_I=0; lParticle_I < swarm->particleLocalCount; lParticle_I++ ) {
			currParticle = (Particle*)Swarm_ParticleAt( swarm, lParticle_I );
			for ( dim_I=0; dim_I < 3; dim_I++ ) {
				currParticle->velocity[dim_I] = ((double) ( rand() - (double)(RAND_MAX)/2 )) / RAND_MAX * 0.1;
			}	
		}
	}
	
	for ( lCell_I=0; lCell_I < swarm->cellLocalCount; lCell_I++ ) {
		Journal_Printf( stream, "\tUpdating Particles positions in local cell %d:\n", lCell_I );
		for ( cParticle_I=0; cParticle_I < swarm->cellParticleCountTbl[lCell_I]; cParticle_I++ ) {
			Coord movementVector = {0,0,0};
			Coord newParticleCoord = {0,0,0};
			Coord* oldCoord;

			currParticle = (Particle*)Swarm_ParticleInCellAt( swarm, lCell_I, cParticle_I );
			oldCoord = &currParticle->coord;
			Journal_Printf( stream, "\t\tUpdating particleInCell %d:\n", cParticle_I );

			for ( dim_I=0; dim_I < 3; dim_I++ ) {
				movementVector[dim_I] = currParticle->velocity[dim_I] / movementSpeedDivisor;
				if ( ( currParticle->velocity[dim_I] < 0 ) 
					&& ( fabs(currParticle->velocity[dim_I] ) > ((*oldCoord)[dim_I] - blockGeom->min[dim_I]) ) )
				{
					Journal_Printf( stream, "\t\tFlipping vel in %d dir\n", dim_I );
					movementVector[dim_I] *= -1;
					currParticle->velocity[dim_I] *= -1;
				}	
				if ( ( currParticle->velocity[dim_I] > 0 ) 
					&& ( fabs(currParticle->velocity[dim_I] ) > ( blockGeom->max[dim_I] - (*oldCoord)[dim_I] ) ) )
				{
					Journal_Printf( stream, "\t\tFlipping vel in %d dir\n", dim_I );
					movementVector[dim_I] *= -1;
					currParticle->velocity[dim_I] *= -1;
				}	
				
				newParticleCoord[dim_I] = (*oldCoord)[dim_I] + movementVector[dim_I];
			}

			Journal_Printf( stream, "\t\tChanging its coords from (%f,%f,%f) to (%f,%f,%f):\n",
				(*oldCoord)[0], (*oldCoord)[1], (*oldCoord)[2],
				newParticleCoord[0], newParticleCoord[1], newParticleCoord[2] );

			for ( dim_I=0; dim_I < 3; dim_I++ ) {
				currParticle->coord[dim_I] = newParticleCoord[dim_I];
			}
		}
	}

	Swarm_UpdateAllParticleOwners( swarm );
}