void _DruckerPrager_Extra_Initialise( void* rheology, void* data ) { DruckerPrager_Extra* self = (DruckerPrager_Extra*) rheology; Particle_Index lParticle_I; Particle_Index particleLocalCount; XYZ slip = { 0.0,0.0,0.0 }; double* ptr; _VonMises_Initialise( self, data ); /* We should only set initial conditions if in regular non-restart mode. If in restart mode, then the particle-based variables will be set correcty when we re-load the Swarm. */ if ( self->context->loadSwarmsFromCheckpoint == False ) { Stg_Component_Initialise( self->tensileFailure, data, False ); Stg_Component_Initialise( self->slip, data, False ); Stg_Component_Initialise( self->slipRate, data, False ); Stg_Component_Initialise( self->fullySoftened, data, False ); /* We don't need to Initialise hasYieldedVariable because it's a parent variable and _YieldRheology_Initialise * has already been called */ particleLocalCount = self->hasYieldedVariable->variable->arraySize; for ( lParticle_I = 0 ; lParticle_I < particleLocalCount ; lParticle_I++ ) { Variable_SetValueChar( self->hasYieldedVariable->variable, lParticle_I, False ); Variable_SetValueChar( self->tensileFailure->variable,lParticle_I, False ); Variable_SetValueDouble( self->plasticStrainRate->variable, lParticle_I, 0.0 ); Variable_SetValueDouble( self->backgroundStrainRate->variable, lParticle_I, 0.0 ); ptr = Variable_GetPtrDouble( self->slip->variable, lParticle_I ); memcpy( ptr, slip, sizeof(Coord) ); Variable_SetValueDouble( self->slipRate->variable, data, 0.0 ); Variable_SetValueInt( self->fullySoftened->variable, data, 0 ); } } }
void TimeIntegrand_Add2TimesTimeDeriv( void* timeIntegrand, Variable* timeDerivVariable ) { TimeIntegrand* self = (TimeIntegrand*)timeIntegrand; Variable* variable = self->variable; double* timeDerivPtr; double* timeDeriv; Index component_I; Index componentCount = *variable->dataTypeCounts; Index array_I; Index arrayCount; timeDeriv = Memory_Alloc_Array( double, componentCount, "Time Deriv" ); memset( timeDeriv, 0, componentCount * sizeof( double ) ); /* Update Variables */ Variable_Update( variable ); Variable_Update( timeDerivVariable ); arrayCount = variable->arraySize; for ( array_I = 0 ; array_I < arrayCount ; array_I++ ) { TimeIntegrand_CalculateTimeDeriv( self, array_I, timeDeriv ); timeDerivPtr = Variable_GetPtrDouble( timeDerivVariable, array_I ); for ( component_I = 0 ; component_I < componentCount ; component_I++ ) { timeDerivPtr[ component_I ] += 2.0 * timeDeriv[ component_I ]; } } Memory_Free( timeDeriv ); }
/** This function assumes that * the ODE that we are solving is \dot \phi = u(x,y) * the velocity Field Variable is stored in data[0] * the variable being updated is the global coordinate of the object */ Bool _TimeIntegrand_AdvectionTimeDeriv( void* timeIntegrand, Index array_I, double* timeDeriv ) { TimeIntegrand* self = (TimeIntegrand*) timeIntegrand; FieldVariable* velocityField = (FieldVariable*) self->data[0]; double* coord; InterpolationResult result; /* Get Coordinate of Object using Variable */ coord = Variable_GetPtrDouble( self->variable, array_I ); result = FieldVariable_InterpolateValueAt( velocityField, coord, timeDeriv ); if ( result == OTHER_PROC || result == OUTSIDE_GLOBAL || isinf(timeDeriv[0]) || isinf(timeDeriv[1]) || ( velocityField->dim == 3 && isinf(timeDeriv[2]) ) ) { #if 0 Journal_Printf( Journal_Register( Error_Type, (Name)self->type ), "Error in func '%s' for particle with index %u.\n\tPosition (%g, %g, %g)\n\tVelocity here is (%g, %g, %g)." "\n\tInterpolation result is %s.\n", __func__, array_I, coord[0], coord[1], coord[2], timeDeriv[0], timeDeriv[1], ( velocityField->dim == 3 ? timeDeriv[2] : 0.0 ), InterpolationResultToStringMap[result] ); return False; #endif } return True; }
void _SwarmVariable_ValueAtDouble( void* swarmVariable, Particle_Index lParticle_I, double* value ) { SwarmVariable* self = (SwarmVariable*)swarmVariable; double* dataPtr; dataPtr = Variable_GetPtrDouble( self->variable, lParticle_I ); memcpy( value, dataPtr, sizeof(double) * self->dofCount ); }
/* +++ Virtual Functions +++ */ void TimeIntegrand_FirstOrder( void* timeIntegrand, Variable* startValue, double dt ) { TimeIntegrand* self = (TimeIntegrand*)timeIntegrand; Variable* variable = self->variable; double* arrayDataPtr; double* startDataPtr; double** timeDeriv; Index component_I; Index componentCount = *variable->dataTypeCounts; Index array_I; Index arrayCount; Bool successFlag = False; Stream* errorStream = Journal_Register( Error_Type, (Name)self->type ); Journal_DPrintf( self->debug, "In func %s for %s '%s'\n", __func__, self->type, self->name ); /* Update Variables */ Variable_Update( variable ); Variable_Update( startValue ); arrayCount = variable->arraySize; timeDeriv = Memory_Alloc_2DArray( double, arrayCount, componentCount, (Name)"Time Deriv" ); for( array_I = 0; array_I < arrayCount; array_I++ ) { successFlag = TimeIntegrand_CalculateTimeDeriv( self, array_I, timeDeriv[array_I] ); if(!successFlag) { successFlag = TimeIntegrand_CalculateTimeDeriv( self, array_I, timeDeriv[array_I] ); } Journal_Firewall( True == successFlag, errorStream, "Error - in %s(), for TimeIntegrand \"%s\" of type %s: When trying to find time " "deriv for item %u in step %u, *failed*.\n", __func__, self->name, self->type, array_I, 1 ); } for ( array_I = 0 ; array_I < arrayCount ; array_I++ ) { arrayDataPtr = Variable_GetPtrDouble( variable, array_I ); startDataPtr = Variable_GetPtrDouble( startValue, array_I ); for ( component_I = 0 ; component_I < componentCount ; component_I++ ) { arrayDataPtr[ component_I ] = startDataPtr[ component_I ] + dt * timeDeriv[array_I][ component_I ]; } TimeIntegrand_Intermediate( self, array_I ); } Memory_Free( timeDeriv ); }
void TimeIntegrand_FourthOrderFinalStep( void* timeIntegrand, Variable* startData, Variable* timeDerivVariable, double dt ) { TimeIntegrand* self = (TimeIntegrand*)timeIntegrand; Variable* variable = self->variable; double* k4; double* k1_2k2_2k3; double* startPtr; double* arrayPtr; Index component_I; Index componentCount = *variable->dataTypeCounts; Index array_I; Index arrayCount; k4 = Memory_Alloc_Array( double, componentCount, "k4 Time Deriv" ); memset( k4, 0, componentCount * sizeof( double ) ); /* Update Variables */ Variable_Update( variable ); Variable_Update( startData ); Variable_Update( timeDerivVariable ); arrayCount = variable->arraySize; for ( array_I = 0 ; array_I < arrayCount ; array_I++ ) { TimeIntegrand_CalculateTimeDeriv( self, array_I, k4 ); k1_2k2_2k3 = Variable_GetPtrDouble( timeDerivVariable, array_I ); arrayPtr = Variable_GetPtrDouble( variable, array_I ); startPtr = Variable_GetPtrDouble( startData, array_I ); for ( component_I = 0 ; component_I < componentCount ; component_I++ ) { arrayPtr[ component_I ] = startPtr[ component_I ] + dt/6.0 * ( k4[ component_I ] + k1_2k2_2k3[ component_I ] ); } TimeIntegrand_Intermediate( self, array_I ); } Memory_Free( k4 ); }
/* +++ Public Functions +++ */ void TimeIntegrand_StoreTimeDeriv( void* timeIntegrand, Variable* timeDeriv ) { TimeIntegrand* self = (TimeIntegrand*)timeIntegrand; double* arrayDataPtr; Index array_I; Index arrayCount; /* Update Variable */ Variable_Update( timeDeriv ); arrayCount = timeDeriv->arraySize; for ( array_I = 0 ; array_I < arrayCount ; array_I++ ) { arrayDataPtr = Variable_GetPtrDouble( timeDeriv, array_I ); TimeIntegrand_CalculateTimeDeriv( self, array_I, arrayDataPtr ); } }
void TimeIntegrand_FourthOrder( void* timeIntegrand, Variable* startValue, double dt ) { TimeIntegrand* self = (TimeIntegrand*)timeIntegrand; Variable* variable = self->variable; double* arrayDataPtr; double* startDataPtr; double* timeDeriv; double* finalTimeDeriv; double* startData; Index component_I; Index componentCount = *variable->dataTypeCounts; Index array_I; Index arrayCount; double startTime = TimeIntegrator_GetTime( self->timeIntegrator ); Bool successFlag = False; Stream* errorStream = Journal_Register( Error_Type, (Name)self->type ); timeDeriv = Memory_Alloc_Array( double, componentCount, "Time Deriv" ); startData = Memory_Alloc_Array( double, componentCount, "StartData" ); finalTimeDeriv = Memory_Alloc_Array( double, componentCount, "StartData" ); memset( timeDeriv, 0, componentCount * sizeof( double ) ); memset( startData, 0, componentCount * sizeof( double ) ); memset( finalTimeDeriv, 0, componentCount * sizeof( double ) ); /* Update Variables */ Variable_Update( variable ); Variable_Update( startValue ); arrayCount = variable->arraySize; for ( array_I = 0 ; array_I < arrayCount ; array_I++ ) { arrayDataPtr = Variable_GetPtrDouble( variable, array_I ); startDataPtr = Variable_GetPtrDouble( startValue, array_I ); TimeIntegrator_SetTime( self->timeIntegrator, startTime ); /* Store Original Value in case startValue == self->variable */ memcpy( startData, startDataPtr, sizeof( double ) * componentCount ); /* Do first Step - store K1 in finalTimeDeriv and update for next step */ successFlag = TimeIntegrand_CalculateTimeDeriv( self, array_I, finalTimeDeriv ); Journal_Firewall( True == successFlag, errorStream, "Error - in %s(), for TimeIntegrand \"%s\" of type %s: When trying to find time " "deriv for item %u in step %u, *failed*.\n", __func__, self->name, self->type, array_I, 1 ); for ( component_I = 0 ; component_I < componentCount ; component_I++ ) arrayDataPtr[ component_I ] = startData[ component_I ] + 0.5 * dt * finalTimeDeriv[ component_I ]; TimeIntegrand_Intermediate( self, array_I ); TimeIntegrator_SetTime( self->timeIntegrator, startTime + 0.5 * dt ); /* Do Second Step - add 2xK2 value to finalTimeDeriv and update for next step */ successFlag = TimeIntegrand_CalculateTimeDeriv( self, array_I, timeDeriv ); if ( True == successFlag ) { for ( component_I = 0 ; component_I < componentCount ; component_I++ ) { arrayDataPtr[ component_I ] = startData[ component_I ] + 0.5 * dt * timeDeriv[ component_I ]; finalTimeDeriv[ component_I ] += 2.0 * timeDeriv[ component_I ]; } TimeIntegrand_Intermediate( self, array_I ); } else { Journal_Firewall( True == self->allowFallbackToFirstOrder, errorStream, "Error - in %s(), for TimeIntegrand \"%s\" of type %s: When trying to find time " "deriv for item %u in step %u, *failed*, and self->allowFallbackToFirstOrder " "not enabled.\n", __func__, self->name, self->type, array_I, 2 ); _TimeIntegrand_RewindToStartAndApplyFirstOrderUpdate( self, arrayDataPtr, startData, startTime, dt, timeDeriv, array_I ); } /* Do Third Step - add 2xK3 value to finalTimeDeriv and update for next step */ successFlag = TimeIntegrand_CalculateTimeDeriv( self, array_I, timeDeriv ); if ( True == successFlag ) { for ( component_I = 0 ; component_I < componentCount ; component_I++ ) { arrayDataPtr[ component_I ] = startData[ component_I ] + dt * timeDeriv[ component_I ]; finalTimeDeriv[ component_I ] += 2.0 * timeDeriv[ component_I ]; } TimeIntegrand_Intermediate( self, array_I ); } else { Journal_Firewall( True == self->allowFallbackToFirstOrder, errorStream, "Error - in %s(), for TimeIntegrand \"%s\" of type %s: When trying to find time " "deriv for item %u in step %u, *failed*, and self->allowFallbackToFirstOrder " "not enabled.\n", __func__, self->name, self->type, array_I, 3 ); _TimeIntegrand_RewindToStartAndApplyFirstOrderUpdate( self, arrayDataPtr, startData, startTime, dt, timeDeriv, array_I ); } TimeIntegrator_SetTime( self->timeIntegrator, startTime + dt ); /* Do Fourth Step - 'K1 + 2K2 + 2K3' and K4 finalTimeDeriv to find final value */ successFlag = TimeIntegrand_CalculateTimeDeriv( self, array_I, timeDeriv ); if ( True == successFlag ) { for ( component_I = 0 ; component_I < componentCount ; component_I++ ) { arrayDataPtr[ component_I ] = startData[ component_I ] + dt/6.0 * (timeDeriv[ component_I ] + finalTimeDeriv[ component_I ] ); } TimeIntegrand_Intermediate( self, array_I ); } else { Journal_Firewall( True == self->allowFallbackToFirstOrder, errorStream, "Error - in %s(), for TimeIntegrand \"%s\" of type %s: When trying to find time " "deriv for item %u in step %u, *failed*, and self->allowFallbackToFirstOrder " "not enabled.\n", __func__, self->name, self->type, array_I, 4 ); _TimeIntegrand_RewindToStartAndApplyFirstOrderUpdate( self, arrayDataPtr, startData, startTime, dt, timeDeriv, array_I ); } } Memory_Free( timeDeriv ); Memory_Free( startData ); Memory_Free( finalTimeDeriv ); }