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 );
}
Beispiel #2
0
/* 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 );
		}
	}
}
Beispiel #4
0
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 );
}