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