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; }
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; }