double AdvectionDiffusionSLE_AdvectiveTimestep( void* advectionDiffusionSLE ) {
	AdvectionDiffusionSLE*    self              = (AdvectionDiffusionSLE*) advectionDiffusionSLE;
	AdvDiffResidualForceTerm* residualForceTerm = self->advDiffResidualForceTerm;
	FeVariable*               velocityField     = residualForceTerm->velocityField;
	Node_LocalIndex           nodeLocalCount    = FeMesh_GetNodeLocalSize( self->phiField->feMesh );
	Node_LocalIndex           node_I;
	Dimension_Index           dim               = self->dim;
	Dimension_Index           dim_I;
	double                    timestep          = HUGE_VAL;
	XYZ                       velocity;
	double                    minSeparation;
	double                    minSeparationEachDim[3];
	double*                   meshCoord;
	
	Journal_DPrintf( self->debug, "In func: %s\n", __func__ );

	FeVariable_GetMinimumSeparation( self->phiField, &minSeparation, minSeparationEachDim );

	for( node_I = 0 ; node_I < nodeLocalCount ; node_I++ ){
		if( self->phiField->feMesh == velocityField->feMesh){
		   FeVariable_GetValueAtNode( velocityField, node_I, velocity );
		} else {
         meshCoord = Mesh_GetVertex( self->phiField->feMesh, node_I );
         FieldVariable_InterpolateValueAt( velocityField, meshCoord, velocity );
      }
		
		for ( dim_I = 0 ; dim_I < dim ; dim_I++ ) {
			if( velocity[ dim_I ] == 0.0 ) 
				continue;
			timestep = MIN( timestep, fabs( minSeparationEachDim[ dim_I ]/velocity[ dim_I ] ) );
		}
	}

	return self->courantFactor * timestep;
}
double AdvectionDiffusionSLE_DiffusiveTimestep( void* advectionDiffusionSLE ) {
	AdvectionDiffusionSLE*    self              = (AdvectionDiffusionSLE*) advectionDiffusionSLE;
	double                    minSeparation;
	double                    minSeparationEachDim[3];

	Journal_DPrintf( self->debug, "In func: %s\n", __func__ );
	
	FeVariable_GetMinimumSeparation( self->phiField, &minSeparation, minSeparationEachDim );

	/* This is quite a conservative estimate */

	return self->courantFactor * minSeparation * minSeparation / self->maxDiffusivity;
}
double Dt( void* _context ) {
   FiniteElementContext*	context		= (FiniteElementContext*) _context;
   double			dt;
   FeVariable*		velocityField	= (FeVariable*) LiveComponentRegister_Get( context->CF->LCRegister, (Name)"VelocityField"  );
   double			velMax;
   double			delta[3], minDelta;

   velMax = FieldVariable_GetMaxGlobalFieldMagnitude( velocityField );
   FeVariable_GetMinimumSeparation( velocityField, &minDelta, delta );

   dt = 0.5 * minDelta / velMax;

   return dt;
}
示例#4
0
double SwarmAdvector_MaxDt( void* swarmAdvector ) {
	SwarmAdvector*	self = (SwarmAdvector*) swarmAdvector;
	double                  velMax        = 0;
	double                  minSeparation = 0;
	double                  minSeparationEachDim[3] = { 0, 0, 0 };
	FeVariable*             velFeVar      = self->velocityField;
	double			localDt;
	double			globalDt;

	velMax = FieldVariable_GetMaxGlobalFieldMagnitude( velFeVar );

	FeVariable_GetMinimumSeparation( velFeVar, &minSeparation, minSeparationEachDim );

	localDt = 0.5 * minSeparation / velMax;
	(void)MPI_Allreduce( &localDt, &globalDt, 1, MPI_DOUBLE, MPI_MIN, MPI_COMM_WORLD );

	return globalDt;
}