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 ); }
/* Based on least squares proceedure described in * Eric W. Weisstein. "Least Squares Fitting." From MathWorld--A Wolfram Web Resource. * http://mathworld.wolfram.com/LeastSquaresFitting.html */ void LinearRegression_Calculate( void* linearRegression ) { LinearRegression* self = (LinearRegression*)linearRegression; Variable* xVariable = self->xVariable; Variable* yVariable = self->yVariable; Index array_I; Index arraySize; double xMean = 0.0; double yMean = 0.0; double xValue; double yValue; double SS_xx = 0.0; double SS_yy = 0.0; double SS_xy = 0.0; double slope; double errorVariance; Variable_Update( xVariable ); Variable_Update( yVariable ); arraySize = self->xVariable->arraySize; assert( arraySize == yVariable->arraySize ); for ( array_I = 0 ; array_I < arraySize ; array_I++ ) { xValue = Variable_GetValueDouble( xVariable, array_I ); yValue = Variable_GetValueDouble( yVariable, array_I ); xMean += xValue; yMean += yValue; /* Sum intermediate values - Equations 17, 19, 21 */ SS_xx += xValue * xValue; SS_yy += yValue * yValue; SS_xy += xValue * yValue; } /* Divide by array size to obtain true mean */ xMean /= (double) arraySize; yMean /= (double) arraySize; self->xMean = xMean; self->yMean = yMean; /* Calculate intermediate values - Equations 17, 19, 21 */ SS_xx -= (double) arraySize * xMean * xMean; SS_yy -= (double) arraySize * yMean * yMean; SS_xy -= (double) arraySize * xMean * yMean; /* Finalise calculation coefficients of linear equations y ~= slope * x + interceptor - Equation 27 - 28 */ self->slope = slope = SS_xy / SS_xx; self->interceptor = yMean - slope * xMean; /* Calculate the correlation coefficient r^2 - Equation 29 */ self->correlationCoefficient = SS_xy * SS_xy / ( SS_xx * SS_yy ); /* Calculate Standard errors - Equations 33-35 */ errorVariance = sqrt( ( SS_yy - slope * SS_xy ) / (double) (arraySize - 2 ) ); self->interceptorStandardError = errorVariance * sqrt( 1.0/(double)arraySize + xMean*xMean/SS_xx ); self->slopeStandardError = errorVariance / sqrt( SS_xx ); }
void Variable_SetValueFromDictionary( void* _variable, Index index, Dictionary* dictionary ) { Variable* variable = (Variable*)_variable; Variable_Update( variable ); /* Assign variable from dictionary according to data type */ switch (variable->dataTypes[0]) { case Variable_DataType_Char: Variable_SetValueChar( variable, index, Dictionary_GetUnsignedInt( dictionary, variable->name )); break; case Variable_DataType_Short: Variable_SetValueShort( variable, index, Dictionary_GetUnsignedInt( dictionary, variable->name )); break; case Variable_DataType_Int: Variable_SetValueInt( variable, index, Dictionary_GetInt( dictionary, (Dictionary_Entry_Key)variable->name ) ); break; case Variable_DataType_Float: Variable_SetValueFloat( variable, index, Dictionary_GetDouble( dictionary, variable->name )); break; case Variable_DataType_Double: Variable_SetValueDouble( variable, index, Dictionary_GetDouble( dictionary, variable->name )); break; default: { Journal_Printf( Journal_MyStream( Error_Type, variable ), "In func %s: Unable to set value of %s from dictionary.", __func__, variable->name ); } } }
void _SwarmVariable_Initialise( void* swarmVariable, void* data ) { SwarmVariable* self = (SwarmVariable*)swarmVariable; if ( self->variable ) { Variable_Update( self->variable ); Stg_Component_Initialise( self->variable, data, False ); } }
/* +++ 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 ); } }
Variable* Variable_NewFromOld( Variable* oldVariable, Name name, Bool copyValues ) { Variable* self; Index array_I; SizeT dataOffsets[] = { 0 }; void* myPtr; void* oldPtr; Variable_Update( oldVariable ); self = Variable_New( name, self->context, 1, dataOffsets, oldVariable->dataTypes, oldVariable->dataTypeCounts, NULL, 0, oldVariable->arraySizePtr, oldVariable->arraySizeFunc, NULL, NULL ); self->allocateSelf = True; self->arrayPtrPtr = &self->arrayPtr; if ( oldVariable->isBuilt ) Stg_Component_Build( self, NULL, True ); if ( oldVariable->isInitialised ) Stg_Component_Initialise( self, NULL, True ); assert(self->offsetCount == 1); if ( copyValues ) { for ( array_I = 0 ; array_I < self->arraySize ; array_I++ ) { myPtr = Variable_GetStructPtr( self, array_I ); oldPtr = Variable_GetStructPtr( oldVariable, array_I ); memcpy( myPtr, oldPtr, self->dataSizes[0] ); } } return self; }
void _GALEDruckerPrager_UpdateDrawParameters( void* rheology ) { GALEDruckerPrager* self = (GALEDruckerPrager*) rheology; Particle_Index lParticle_I; Particle_Index particleLocalCount; StrainWeakening* strainWeakening = self->strainWeakening; MaterialPoint* materialPoint; double length; double brightness; double opacity; double strainWeakeningRatio; double localMaxStrainIncrement; double localMeanStrainIncrement; Particle_Index localFailed; double globalMaxStrainIncrement; double globalMeanStrainIncrement; Particle_Index globalFailed; double averagedGlobalMaxStrainIncrement = 0.0; double oneOverGlobalMaxStrainIncrement; double postFailureWeakeningIncrement; int ierr; /* mpi error code */ /* Note : this function defines some drawing parameters (brightness, opacity, diameter) as * functions of the strain weakening - this needs to be improved since most of the parameters * that define this dependency are hard coded here. We need to have a more flexible way * to construct the viz parameters as functions of material parameters */ /* We should only update the drawing parameters if the strain weakening is defined */ if (strainWeakening==NULL) return; localMaxStrainIncrement = 0.0; localMeanStrainIncrement = 0.0; localFailed = 0; /* Update all variables */ Variable_Update( self->hasYieldedVariable->variable ); Variable_Update( self->brightness->variable ); Variable_Update( self->opacity->variable ); Variable_Update( self->diameter->variable ); Variable_Update( strainWeakening->postFailureWeakeningIncrement->variable ); particleLocalCount = self->hasYieldedVariable->variable->arraySize; for ( lParticle_I = 0 ; lParticle_I < particleLocalCount ; lParticle_I++ ) { if ( Variable_GetValueChar( self->hasYieldedVariable->variable, lParticle_I )) { localFailed++; postFailureWeakeningIncrement = Variable_GetValueDouble( strainWeakening->postFailureWeakeningIncrement->variable, lParticle_I ); localMeanStrainIncrement += postFailureWeakeningIncrement; if(localMaxStrainIncrement < postFailureWeakeningIncrement) localMaxStrainIncrement = postFailureWeakeningIncrement; } } ierr = MPI_Allreduce( &localMaxStrainIncrement, &globalMaxStrainIncrement, 1, MPI_DOUBLE, MPI_MAX, MPI_COMM_WORLD ); ierr = MPI_Allreduce( &localMeanStrainIncrement, &globalMeanStrainIncrement, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD ); ierr = MPI_Allreduce( &localFailed, &globalFailed, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD ); if(globalFailed == 0) return; globalMeanStrainIncrement /= (double) globalFailed; averagedGlobalMaxStrainIncrement = 0.5 * averagedGlobalMaxStrainIncrement + 0.25 * globalMeanStrainIncrement + 0.25 * globalMaxStrainIncrement; /* Let's simply assume that twice the mean is a good place to truncate these values */ oneOverGlobalMaxStrainIncrement = 1.0 / averagedGlobalMaxStrainIncrement; for ( lParticle_I = 0 ; lParticle_I < particleLocalCount ; lParticle_I++ ) { materialPoint = (MaterialPoint*)Swarm_ParticleAt( strainWeakening->swarm, lParticle_I ); if ( Variable_GetValueChar( self->hasYieldedVariable->variable, lParticle_I ) == False || StrainWeakening_GetPostFailureWeakening( strainWeakening, materialPoint ) < 0.0 ) { Variable_SetValueFloat( self->brightness->variable, lParticle_I, 0.0 ); Variable_SetValueFloat( self->opacity->variable, lParticle_I, 0.0 ); Variable_SetValueFloat( self->diameter->variable, lParticle_I, 0.0 ); continue; } postFailureWeakeningIncrement = Variable_GetValueDouble( strainWeakening->postFailureWeakeningIncrement->variable, lParticle_I ); strainWeakeningRatio = StrainWeakening_CalcRatio( strainWeakening, materialPoint ); length = 0.001 + 0.003 * strainWeakeningRatio; brightness = strainWeakeningRatio * postFailureWeakeningIncrement * oneOverGlobalMaxStrainIncrement; opacity = 0.5 * brightness; if( brightness > 1.0 ) brightness = 1.0; if( opacity > 0.5 ) opacity = 0.5; if( opacity < 0.1 ) opacity = 0.0; Variable_SetValueFloat( self->brightness->variable, lParticle_I, brightness ); Variable_SetValueFloat( self->opacity->variable, lParticle_I, opacity ); Variable_SetValueFloat( self->diameter->variable, lParticle_I, (float) length ); } }
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 ); }