Exemple #1
0
void _SnacRestartOld_Construct( void* component, Stg_ComponentFactory* cf, void* data ) {
	Snac_Context*	context;
	char fname[PATH_MAX];
	FILE *fp;

	/* Retrieve context. */
	context = (Snac_Context*)Stg_ComponentFactory_ConstructByName( cf, "context", Snac_Context, True, data ); 

#ifdef DEBUG
	printf( "In: _SnacRestartOld_Register( void* )\n" );
#endif

	if( context->rank == 0 ) {
		sprintf( fname, "%s/coord.%d", context->outputPath, context->rank );
		Journal_Firewall( ( ( fp = fopen( fname, "r") ) == NULL ), 
				  context->snacError, 
				  "\n\n ###### RESTARTER ERROR ######\n Do NOT restart in %s!!\n All the existing outputs will be overwritten !!\n If absolutely sure, remove the existing outputs first.\n #############################\n\n", 
				  context->outputPath );
	}

	/*
	 *  Shift the time step range to start from the restart time step
	 *    - this doesn't seem to work since the changes don't appear to propagate into StGermain
	 *     far enough to cause the maxTimeSteps to stop the simulation when desired
	 */
/* 	context->timeStep += context->restartStep; */
/* 	context->maxTimeSteps += context->restartStep; */

	EntryPoint_InsertBefore(
		Context_GetEntryPoint( context, AbstractContext_EP_Initialise ),
		"SnacTimeStepZero",
		SnacRestartOld_Type,
		_SnacRestartOld_resetMinLengthScale,
		SnacRestartOld_Type );
	EntryPoint_InsertBefore(
		Context_GetEntryPoint( context, AbstractContext_EP_Initialise ),
		"SnacTimeStepZero",
		SnacRestartOld_Type,
		_SnacRestartOld_InitialCoords,
		SnacRestartOld_Type );
	EntryPoint_InsertBefore(
		Context_GetEntryPoint( context, AbstractContext_EP_Initialise ),
		"SnacTimeStepZero",
		SnacRestartOld_Type,
		_SnacRestartOld_InitialVelocities,
		SnacRestartOld_Type );
	EntryPoint_InsertBefore(
		Context_GetEntryPoint( context, AbstractContext_EP_Initialise ),
		"SnacTimeStepZero",
		SnacRestartOld_Type,
		_SnacRestartOld_InitialStress,
		SnacRestartOld_Type );

/* 	_SnacRestartOld_resetMinLengthScale(context,data); */
/* 	_SnacRestartOld_InitialCoords(context,data); */
/* 	_SnacRestartOld_InitialVelocities(context,data); */
/* 	_SnacRestartOld_InitialStress(context,data); */
}
Exemple #2
0
void _SnacPlastic_Construct( void* component, Stg_ComponentFactory* cf, void* data ) {
	Snac_Context*	context;
	EntryPoint* 	interpolateElementEP;

	/* Retrieve context. */
	context = (Snac_Context*)Stg_ComponentFactory_ConstructByName( cf, "context", Snac_Context, True, data ); 

	#ifdef DEBUG
		printf( "In: _SnacPlastic_Register( void*, void* )\n" );
	#endif
	
	/* Add extensions to nodes, elements and the context */
	SnacPlastic_ElementHandle = ExtensionManager_Add( context->mesh->elementExtensionMgr, SnacPlastic_Type, sizeof(SnacPlastic_Element) );
	SnacPlastic_ContextHandle = ExtensionManager_Add( context->extensionMgr, SnacPlastic_Type, sizeof(SnacPlastic_Context) );
	
	#ifdef DEBUG
		printf( "\tcontext extension handle: %u\n", SnacPlastic_ContextHandle );
		printf( "\telement extension handle: %u\n", SnacPlastic_ElementHandle );
	#endif
	
	/* Add extensions to the entry points */
	EntryPoint_Append( 
		Context_GetEntryPoint( context,	Snac_EP_Constitutive ),
		SnacPlastic_Type, 
		SnacPlastic_Constitutive, 
		SnacPlastic_Type );
	EntryPoint_InsertBefore( 
		Context_GetEntryPoint( context,	AbstractContext_EP_Initialise ),
		"SnacTimeStepZero",
		SnacPlastic_Type, 
		SnacPlastic_InitialConditions,
		SnacPlastic_Type );
	EntryPoint_Prepend( /* Dump the initial plastic strain */
		Context_GetEntryPoint( context, AbstractContext_EP_Execute ),
		"SnacPlastic_Write",
		_SnacPlastic_WritePlasticStrain,
		SnacPlastic_Type );
	EntryPoint_Append( /* and dump each loop */
		Context_GetEntryPoint( context, Snac_EP_CalcStresses ),
		"SnacPlastic_Write",
		_SnacPlastic_WritePlasticStrain,
		SnacPlastic_Type );
	
	/* Add extensions to the interpolate element entry point, but it will only exist if the remesher is loaded. */
	interpolateElementEP = Context_GetEntryPoint( context,	"SnacRemesher_EP_InterpolateElement" );
	if( interpolateElementEP ) {
		EntryPoint_Append( 
			interpolateElementEP,
			SnacPlastic_Type, 
			_SnacPlastic_InterpolateElement, 
			SnacPlastic_Type );
	}


	/* Construct. */
	_SnacPlastic_ConstructExtensions( context, data );
}
Exemple #3
0
void _SnacHillSlope_Construct( void* component, Stg_ComponentFactory* cf, void* data ) {
	Snac_Context*	context;

	#ifdef DEBUG
	fprintf(stderr, "Entering Register.c...\n");
	#endif

	/* Retrieve context. */
	context = (Snac_Context*)Stg_ComponentFactory_ConstructByName( cf, "context", Snac_Context, True, data ); 
	
	Journal_Printf( context->debug, "In: %s\n", __func__ );
	
	
	/* Add extensions to nodes, elements and the context */
	SnacHillSlope_ContextHandle = ExtensionManager_Add(
		context->extensionMgr,
		SnacHillSlope_Type,
		sizeof(SnacHillSlope_Context) );
	
	/* Add extensions to the entry points */
	EntryPoint_Append(
		Context_GetEntryPoint( context, AbstractContext_EP_Build ),
		SnacHillSlope_Type,
		_SnacHillSlope_Build,
		SnacHillSlope_Type );
	EntryPoint_Append(
		Context_GetEntryPoint( context, AbstractContext_EP_Initialise ),
		SnacHillSlope_Type,
		_SnacHillSlope_InitialConditions,
		SnacHillSlope_Type );

/* 	EntryPoint_Append( */
/* 		Context_GetEntryPoint( context, Snac_EP_Constitutive ), */
/* 		SnacHillSlope_Type, */
/* 		_SnacHillSlope_Constitutive, */
/* 		SnacHillSlope_Type ); */
	EntryPoint_Append(
		Context_GetEntryPoint( context, AbstractContext_EP_DestroyExtensions ),
		SnacHillSlope_Type,
		_SnacHillSlope_DeleteExtensions,
		SnacHillSlope_Type );


	/* Construct. */
	_SnacHillSlope_ConstructExtensions( context, data );

	#ifdef DEBUG
	fprintf(stderr, "In Register.c\n");
	#endif

	#ifdef DEBUG
	fprintf(stderr, "...leaving Register.c\n");
	#endif


}
void _TimeIntegrator_Init( 
	void*						timeIntegrator, 
	unsigned int			order, 
	Bool						simultaneous, 
	EntryPoint_Register*	entryPoint_Register,
	AbstractContext*		context )
{
	TimeIntegrator* self = (TimeIntegrator*)timeIntegrator;

	self->context = (DomainContext*)context;
	self->debug = Journal_Register( Debug_Type, (Name)self->type  );
	self->info = Journal_Register( Info_Type, (Name)self->type );
		
	self->integrandRegister = NamedObject_Register_New( );
	self->order = order;
	self->simultaneous = simultaneous;

	/* Entry Point Stuff */
	Stg_asprintf( &self->_setupEPName, "%s-Setup", self->name );
	Stg_asprintf( &self->_finishEPName, "%s-Finish", self->name );
	self->setupEP  = EntryPoint_New( self->_setupEPName,  EntryPoint_VoidPtr_CastType );
	self->finishEP = EntryPoint_New( self->_finishEPName, EntryPoint_VoidPtr_CastType );

	if ( entryPoint_Register ) {
		EntryPoint_Register_Add( entryPoint_Register, self->setupEP );
		EntryPoint_Register_Add( entryPoint_Register, self->finishEP );
	}

	self->setupData = Stg_ObjectList_New();
	self->finishData = Stg_ObjectList_New();

	if ( context ) {
		EP_AppendClassHook( Context_GetEntryPoint( context, AbstractContext_EP_UpdateClass ), TimeIntegrator_UpdateClass, self );
	}
}
void _ImportersToolbox_SurfaceProcessCoupler_AssignFromXML( void* component, Stg_ComponentFactory* cf, void* data ) {
   ImportersToolbox_SurfaceProcessCoupler* self = (ImportersToolbox_SurfaceProcessCoupler*) component;
   UnderworldContext* uw_context=NULL;

   uw_context              = (UnderworldContext*)  Stg_ComponentFactory_PluginConstructByKey( cf, self, (Name)"Context", AbstractContext, True, data  ); 
   self->ms                = (MaterialPointsSwarm*)Stg_ComponentFactory_PluginConstructByKey( cf, self, (Name)"MaterialPointsSwarm", MaterialPointsSwarm, True, data  ); 
   self->pts               = (MaterialPointsSwarm*)Stg_ComponentFactory_PluginConstructByKey( cf, self, (Name)"UWDeformationTrackingSwarm", MaterialPointsSwarm, True, data  ); 
   self->belowSurfaceShape = (BelowHeightField*)   Stg_ComponentFactory_PluginConstructByKey( cf, self, (Name)"BelowSurfaceShape", BelowHeightField, True, data  ); 
   self->air_material      = (RheologyMaterial*)   Stg_ComponentFactory_PluginConstructByKey( cf, self, (Name)"air_material", RheologyMaterial, True, data  ); 
   self->sediment_material = (RheologyMaterial*)   Stg_ComponentFactory_PluginConstructByKey( cf, self, (Name)"sediment_material", RheologyMaterial, True, data  ); 
   self->sync_folder       = Stg_ComponentFactory_PluginGetString(      cf, self, (Dictionary_Entry_Key)"sync_folder", "./" );
   self->sleep_interval    = Stg_ComponentFactory_PluginGetUnsignedInt( cf, self, (Dictionary_Entry_Key)"sleep_interval", 5 );
   self->sync_time         = Stg_ComponentFactory_PluginGetDouble(      cf, self, (Dictionary_Entry_Key)"sync_time", -1 );
   self->vertAxis          = Stg_ComponentFactory_PluginGetInt(         cf, self, (Dictionary_Entry_Key)"VerticalAxis", 1 );
   self->SP_tracer_height  = Stg_ComponentFactory_PluginGetDouble(      cf, self, (Dictionary_Entry_Key)"SP_tracer_vertical_coord", 0 );
   self->SP_globalid_var   = Stg_ComponentFactory_PluginConstructByKey( cf, self, (Dictionary_Entry_Key)"SP_globalid_SwarmVariable", SwarmVariable, True, data );

   if( self->sync_time < 0 ) {
      Journal_Printf( NULL, "Error in function %s\n. The 'sync_time' input parameters is invalid\n" );
      abort();
   }

   global_self = self;
   self->context = (AbstractContext*)uw_context;
   self->start_time = self->context->currentTime;
   self->absolute_sync_time = self->start_time + self->sync_time;
   self->poll_maestro=1;

   /* create hooks on entry points */
   // hook for waiting for SP 
   EP_AppendClassHook( AbstractContext_GetEntryPoint( self->context, AbstractContext_EP_PreSolveClass),
         _ImportersToolbox_SurfaceProcessCoupler_wait_for_SP, self );

   assert( uw_context->calcDtEP );
   EP_AppendClassHook( uw_context->calcDtEP, _ImportersToolbox_SurfaceProcessCoupler_dt_limiter, self );

   // hook for generating I/O for SP 
   EP_AppendClassHook( Context_GetEntryPoint( self->context, AbstractContext_EP_UpdateClass), 
         _ImportersToolbox_SurfaceProcessCoupler_write_for_SP, self);


   /* setup path for maestro file */
   self->maestro_path=Memory_Alloc_Array( char, sizeof(char)*( strlen(self->sync_folder)+8 ), Name_Invalid );
   assert( self->maestro_path );
   sprintf( self->maestro_path, "%s/maestro", self->sync_folder );

   /* setup path for ascii file */
   self->ascii_path=Memory_Alloc_Array( char, sizeof(char)*( strlen(self->sync_folder)+16 ), Name_Invalid );
   assert( self->ascii_path );
   sprintf( self->ascii_path, "%s/uw_output.ascii", self->sync_folder );

}
Exemple #6
0
void _SnacHetero_Construct( void* component, Stg_ComponentFactory* cf, void* data ) {
	Snac_Context*	context;
	context = (Snac_Context*)Stg_ComponentFactory_ConstructByName( cf, "context", Snac_Context, True, data ); 
        Journal_Printf( context->snacInfo, "In: %s\n", __func__ );

       EntryPoint_InsertBefore(
                Context_GetEntryPoint( context, AbstractContext_EP_Initialise ),
                "SnacTimeStepZero",
                SnacHetero_Type,
                _SnacHetero_InitialCondition,
                SnacHetero_Type );

       /* ConditionFunction_Register_Add(
               context->condFunc_Register,
               ConditionFunction_New(_SnacHetero_node,"SnacHeteroNode" ) );
        ConditionFunction_Register_Add(
               context->condFunc_Register,
               ConditionFunction_New( _SnacHetero_element,"SnacHeteroElement" ) );*/
}
void _HeatingForce_AssignFromXML( void* heatingForce, Stg_ComponentFactory* cf, void* data ) {
	HeatingForce*			self 	= (HeatingForce*)heatingForce;
	IntegrationPointsSwarm*		swarm;

	_FeVariable_AssignFromXML( self, cf, data );

	swarm = Stg_ComponentFactory_ConstructByKey( cf, self->name, "Swarm", IntegrationPointsSwarm, True, data );

	self->buoyancyMaterial = Stg_ComponentFactory_ConstructByKey( cf, self->name, "BuoyancyMaterial", BuoyancyMaterial, True, data );
	self->sle = Stg_ComponentFactory_ConstructByKey( cf, self->name, "SLE", SLE, True, data );
	self->materialIndex = Stg_ComponentFactory_GetUnsignedInt( cf, self->name, "materialIndex", 0 );
	self->cmm = Stg_ComponentFactory_ConstructByKey( cf, self->name, "MaterialsManager", ConductivityMaterialManager, False, data );

	/* need to do this evaluation BEFORE solve, since the heat field we derive will be used as a force term */
	EP_InsertClassHookBefore( Context_GetEntryPoint( self->context, self->sle->executeEPName ), "MatrixSetup", 
				  _ParticleFeVariable_Execute, self );

	_ParticleFeVariable_Init( self, swarm, False );
}
Exemple #8
0
void _SwarmDump_Init( 
		SwarmDump*                                         self,
		void*                                              context,
		Swarm**                                            swarmList,
		Index                                              swarmCount,
		Bool                                               newFileEachTime )
{
	self->isConstructed = True;

	self->swarmList = Memory_Alloc_Array( Swarm*, swarmCount, "swarmList" );
	memcpy( self->swarmList, swarmList, swarmCount * sizeof(Swarm*) );
	self->swarmCount = swarmCount;

	self->newFileEachTime = newFileEachTime;
		
	/* Only append hook to context's save EP if context is given */
	if ( context ) {
		EP_AppendClassHook( Context_GetEntryPoint( context, AbstractContext_EP_SaveClass ), SwarmDump_Execute, self );
	}
}
Exemple #9
0
void SnacViscoPlastic_Constitutive( void* _context, Element_LocalIndex element_lI ) {
	Snac_Context* context = (Snac_Context*)_context;
	Snac_Element* element = Snac_Element_At( context, element_lI );
	SnacViscoPlastic_Element* viscoplasticElement = ExtensionManager_Get( context->mesh->elementExtensionMgr, element, SnacViscoPlastic_ElementHandle );
	SnacTemperature_Element* temperatureElement = ExtensionManager_Get( context->mesh->elementExtensionMgr, element, SnacTemperature_ElementHandle );
	const Snac_Material* material = &context->materialProperty[element->material_I];

	/*ccccc*/
	MeshLayout*			meshLayout = (MeshLayout*)context->meshLayout;
	HexaMD*				decomp = (HexaMD*)meshLayout->decomp;
	IJK				ijk;
	Element_GlobalIndex		element_gI = _MeshDecomp_Element_LocalToGlobal1D( decomp, element_lI );
	EntryPoint* 			temperatureEP;

	RegularMeshUtils_Element_1DTo3D( decomp, element_gI, &ijk[0], &ijk[1], &ijk[2] );
	/*ccccc*/

	temperatureEP = Context_GetEntryPoint( context,	"Snac_EP_LoopElementsEnergy" );

	/* If this is a ViscoPlastic material, calculate its stress. */
	if ( material->rheology & Snac_Material_ViscoPlastic ) {
		Tetrahedra_Index	tetra_I;
		Node_LocalIndex		node_lI;

		/* viscoplastic material properties */
		const double		bulkm = material->lambda + 2.0f * material->mu/3.0f;
		StressTensor*		stress;
		StrainTensor*		strain;
		Strain				plasticStrain;
		double*				viscosity;
		double				straind0,straind1,straind2,stressd0,stressd1,stressd2;
		double				Stress0[3][3];
		double				trace_strain;
		double				trace_stress;
		double				temp;
		double				vic1;
		double				vic2;
		double				VolumicStress;
		double				rviscosity=material->refvisc;
		double				rmu= material->mu;
		double				srJ2;
		double				avgTemp;
		plModel				yieldcriterion=material->yieldcriterion;

		/* For now reference values of viscosity, second invariant of deviatoric */
		/* strain rate and reference temperature  are being hard wired ( these specific */
		/* values are from paper by Hall et. al., EPSL, 2003 */
		double				rstrainrate = material->refsrate;
		double				rTemp = material->reftemp;
		double				H = material->activationE; // kJ/mol
		double				srexponent = material->srexponent;
		double				srexponent1 = material->srexponent1;
		double				srexponent2 = material->srexponent2;
		const double		R=8.31448;  // J/mol/K
		/* elasto-plastic material properties */
		double				cohesion = 0.0f;
		double				frictionAngle = 0.0f;
		double				dilationAngle = 0.0f;
		double				hardening = 0.0f;
		double				tension_cutoff=0.0;
		const double		degrad = PI / 180.0f;
		double				totalVolume=0.0f,depls=0.0f;
		unsigned int		i;
		double				tmp=0.0;
		const double		a1 = material->lambda + 2.0f * material->mu ;
		const double		a2 = material->lambda ;
		int					ind=0;

		int principal_stresses(StressTensor* stress,double sp[],double cn[3][3]);
		int principal_stresses_orig(StressTensor* stress, double sp[3], double cn[3][3]);

		/*    printf("Entered ViscoPlastic update \n"); */

		/* Work out the plastic material properties of this element */
		for( tetra_I = 0; tetra_I < Tetrahedra_Count; tetra_I++ ) {
			double			cn[3][3] = {{0.0,0.0,0.0},{0.0,0.0,0.0},{0.0,0.0,0.0}};
			double			s[3] = {0.0,0.0,0.0};
			double			alam, dep1, dep2, dep3, depm;
			/*ccccc*/

			stress = &element->tetra[tetra_I].stress;
			strain = &element->tetra[tetra_I].strain;
			plasticStrain = viscoplasticElement->plasticStrain[tetra_I];
			viscosity = &viscoplasticElement->viscosity[tetra_I];

			if( context->computeThermalStress ) {
				(*stress)[0][0] += temperatureElement->thermalStress[tetra_I];
				(*stress)[1][1] += temperatureElement->thermalStress[tetra_I];
				(*stress)[2][2] += temperatureElement->thermalStress[tetra_I];
			}

			/* storing original stress in local array */
			Stress0[0][0] = (*stress)[0][0];
			Stress0[1][1] = (*stress)[1][1];
			Stress0[2][2] = (*stress)[2][2];
			Stress0[0][1] = (*stress)[0][1];
			Stress0[0][2] = (*stress)[0][2];
			Stress0[1][2] = (*stress)[1][2];
			trace_stress = (*stress)[0][0] + (*stress)[1][1] + (*stress)[2][2];
			/*  trace_strain = element->tetra[tetra_I].volume/element->tetra[tetra_I].old_volume-1.0f; */
			trace_strain = (*strain)[0][0] + (*strain)[1][1] + (*strain)[2][2];

			/*     printf(" Trace strain=%g\t Trace Stress=%g\n",trace_strain,trace_stress); */

			/* Deviatoric Stresses and Strains */
			straind0 =  (*strain)[0][0] -  (trace_strain) / 3.0f;
			straind1 =  (*strain)[1][1] -  (trace_strain) / 3.0f;
			straind2 =  (*strain)[2][2] -  (trace_strain) / 3.0f;

			stressd0 =  (*stress)[0][0] -  (trace_stress) / 3.0f;
			stressd1 =  (*stress)[1][1] -  (trace_stress) / 3.0f;
			stressd2 =  (*stress)[2][2] -  (trace_stress) / 3.0f;

			/* compute viscosity and add thermal stress */
			if( temperatureEP ) {

				srJ2 = sqrt(fabs(straind1*straind2+straind2*straind0+straind0*straind1 -(*strain[0][1])*(*strain[0][1])-(*strain[0][2])*(*strain[0][2])-(*strain[1][2])*(*strain[1][2])))/context->dt;
				if(srJ2 == 0.0f) srJ2 = rstrainrate; // temporary. should be vmax/length_scale

				avgTemp=0.0;
				for(node_lI=0; node_lI<4; node_lI++) {
					Snac_Node* contributingNode = Snac_Element_Node_P(
																	  context,
																	  element_lI,
																	  TetraToNode[tetra_I][node_lI] );
					SnacTemperature_Node* temperatureNodeExt = ExtensionManager_Get(
																					context->mesh->nodeExtensionMgr,contributingNode,
																					SnacTemperature_NodeHandle );

					avgTemp += 0.25 * temperatureNodeExt->temperature;
					assert( !isnan(avgTemp) && !isinf(avgTemp) );
				}
				// Hall et. al., 2004, G3
				(*viscosity)= rviscosity*pow((srJ2/rstrainrate),(1./srexponent-1.))
					*exp(H/R*(1./(avgTemp+273.15)-1./(rTemp+273.15)));
				if((*viscosity) < material->vis_min) (*viscosity) = material->vis_min;
				if((*viscosity) > material->vis_max) (*viscosity) = material->vis_max;
				Journal_Firewall(
								 !isnan((*viscosity)) && !isinf((*viscosity)),
								 context->snacError,
								 "rvisc=%e Erattio=%e pow(E)=%e, dT=%e exp=%e\n",
								 rviscosity,
								 (srJ2/rstrainrate),
								 pow((srJ2/rstrainrate),
									 (1./srexponent-1.)),
								 exp(H/R*(1./(avgTemp+273.15)-1./(rTemp+273.15))),
								 (1./(avgTemp+273.15)-1./(rTemp+273.15)) );
#if 0
				// Lavier and Buck, JGR, 2002
				(*viscosity) = pow(rviscosity,-1.0/srexponent1)*pow(srJ2,1.0/srexponent2-1)*exp(H/R/(avgTemp+273.15));
#endif
			}
			else {
				(*viscosity) = rviscosity;
				Journal_Firewall(
								 !isnan((*viscosity)) && !isinf((*viscosity)),
								 context->snacError,
								 "(*viscosity) is nan or inf\n" );
			}

			/* Non dimensional parameters elastic/viscous */
			temp = rmu / (2.0f* (*viscosity)) * context->dt;

			vic1 = 1.0f - temp;
			vic2 = 1.0f / (1.0f + temp);
			/*    printf("temp=%g\t rmu=%g\t viscosity=%g\t\n",temp,rmu,*viscosity); */
			/*                          printf("trace_stress=%g\t trace_strain=%g\t vic1=%g\t vic2=%g\n",trace_stress,trace_strain,vic1,vic2); */
			/* Deviatoric Stress Update */

			stressd0 =  (stressd0 * vic1 + 2.0f * rmu * straind0) * vic2 ;
			stressd1 =  (stressd1 * vic1 + 2.0f * rmu * straind1) * vic2 ;
			stressd2 =  (stressd2 * vic1 + 2.0f * rmu * straind2) * vic2 ;

			(*stress)[0][1] =((*stress)[0][1] * vic1 + 2.0f * rmu * (*strain)[0][1]) * vic2;
			(*stress)[0][2] =((*stress)[0][2] * vic1 + 2.0f * rmu * (*strain)[0][2]) * vic2;
			(*stress)[1][2] =((*stress)[1][2] * vic1 + 2.0f * rmu * (*strain)[1][2]) * vic2;

			/* Isotropic stress is elastic,
			   WARNING:volumic Strain may be better defined as
			   volumique change in the mesh */
			VolumicStress = trace_stress / 3.0f + bulkm * trace_strain;

			(*stress)[0][0] = stressd0 + VolumicStress;
			(*stress)[1][1] = stressd1 + VolumicStress;
			(*stress)[2][2] = stressd2 + VolumicStress;

			principal_stresses(stress,s,cn);

			/* compute friction and dilation angles based on accumulated plastic strain in tetrahedra */
			/* Piece-wise linear softening */
			/* Find current properties from linear interpolation */
#if 0
			/*ccccc*/
			if(material->putSeeds && context->loop <= 1) {
				if(ijk[1] >= decomp->elementGlobal3DCounts[1]-2)
					if(ijk[0] == decomp->elementGlobal3DCounts[0]/2 ) {
						//if(ijk[0] >= 10 && ijk[0] <= 14 ) {
						viscoplasticElement->plasticStrain[tetra_I] = 1.1*material->plstrain[1];
						plasticStrain = viscoplasticElement->plasticStrain[tetra_I];
						fprintf(stderr,"loop=%d ijk=%d %d %d aps=%e plasticE=%e\n",
								context->loop,ijk[0],ijk[1],ijk[2],plasticStrain,
								viscoplasticElement->plasticStrain[tetra_I]);
					}
			}
			/*ccccc*/
#endif
			for( i = 0; i < material->nsegments; i++ ) {
				const double pl1 = material->plstrain[i];
				const double pl2 = material->plstrain[i+1];

				if( plasticStrain >= pl1 && plasticStrain <= pl2 ) {
					const double	tgf = (material->frictionAngle[i+1] - material->frictionAngle[i]) / (pl2 - pl1);
					const double	tgd = (material->dilationAngle[i+1] - material->dilationAngle[i]) / (pl2 - pl1);
					const double	tgc = (material->cohesion[i+1] - material->cohesion[i]) / (pl2 - pl1);

					frictionAngle = material->frictionAngle[i] + tgf * (plasticStrain - pl1);
					dilationAngle = material->dilationAngle[i] + tgd * (plasticStrain - pl1);
					cohesion = material->cohesion[i] + tgc * (plasticStrain - pl1);
					hardening = tgc;
				}
			}

			if( frictionAngle > 0.0f ) {
				tension_cutoff = material->ten_off;
				if( frictionAngle > 0.0) {
					tmp = cohesion / tan( frictionAngle * degrad);
					if(tmp < tension_cutoff) tension_cutoff=tmp;
				}
			}
			else {
				if( plasticStrain < 0.0 ) {
					viscoplasticElement->plasticStrain[tetra_I] = 0.0;
					plasticStrain = viscoplasticElement->plasticStrain[tetra_I];
					fprintf(stderr,"Warning: negative plastic strain. Setting to zero, but check if remesher is on and this happended for an external tet. rank:%d elem:%d tet:%d plasticStrain=%e frictionAngle=%e\n",context->rank,element_lI,tetra_I,plasticStrain,frictionAngle);
					frictionAngle = material->frictionAngle[0];
					dilationAngle = material->dilationAngle[0];
					cohesion = material->cohesion[0];
				}
				else {
					/* frictionAngle < 0.0 violates second law of thermodynamics */
					fprintf(stderr,"Error due to an unknown reason: rank:%d elem:%d tet:%d plasticStrain=%e frictionAngle=%e\n",context->rank,element_lI,tetra_I,plasticStrain,frictionAngle);
					assert(0);
				}
			}

			if( yieldcriterion == mohrcoulomb )
				{

					double sphi = sin( frictionAngle * degrad );
					double spsi = sin( dilationAngle * degrad );
					double anphi = (1.0f + sphi) / (1.0f - sphi);
					double anpsi = (1.0f + spsi) / (1.0f - spsi);
					double fs = s[0] - s[2] * anphi + 2 * cohesion * sqrt( anphi );
					double ft = s[2] - tension_cutoff;
					/* CHECK FOR COMPOSITE YIELD CRITERION  */
					ind=0;
					if( fs < 0.0f || ft > 0.0f ) {
						/*! Failure: shear or tensile */
						double aP = sqrt( 1.0f + anphi * anphi ) + anphi;
						double sP = tension_cutoff * anphi - 2 * cohesion * sqrt( anphi );
						double h = s[2] - tension_cutoff + aP * ( s[0] - sP );

						ind=1;

						if( h < 0.0f ) {
							/* !shear failure  */
							alam = fs / ( a1 - a2 * anpsi + a1 * anphi * anpsi - a2 * anphi + 2.0*sqrt(anphi)*hardening );
							s[0] -= alam * ( a1 - a2 * anpsi );
							s[1] -= alam * a2 * ( 1.0f - anpsi );
							s[2] -= alam * ( a2 - a1 * anpsi );
							dep1 = alam;
							dep2 = 0.0f;
							dep3 = -alam * anpsi;
						}
						else {
							/* tensile failure */
							alam = ft / a1;
							s[0] -= alam * a2;
							s[1] -= alam * a2;
							s[2] -= alam * a1;
							dep1 = 0.0f;
							dep2 = 0.0f;
							dep3 = alam;
						}
					}
					else {
						/* ! no failure - just elastic increment */

						dep1 = 0.0f;
						dep2 = 0.0f;
						dep3 = 0.0f;
					}
					if(ind) {
						unsigned int k,m,n;
						/* Second invariant of accumulated plastic increment  */
						depm = ( dep1 + dep2 + dep3 ) / 3.0f;
						viscoplasticElement->plasticStrain[tetra_I] += sqrt( 0.5f * ((dep1-depm) * (dep1-depm) + (dep2-depm) * (dep2-depm) + (dep3-depm) * (dep3-depm) + depm*depm) );

						/* Stress projection back to euclidean coordinates */
						memset( stress, 0, sizeof((*stress)) );
						/* Resolve back to global axes  */
						for( m = 0; m < 3; m++ ) {
							for( n = m; n < 3; n++ ) {
								for( k = 0; k < 3; k++ ) {
									/* (*stress)[m][n] += cn[k][m] * cn[k][n] * s[k]; */
									(*stress)[m][n] += cn[m][k] * cn[n][k] * s[k];
								}
							}
						}
					}
				}
			else
				Journal_Firewall( (0>1), "In %s: \"mohrcoulomb\" is the only available yield criterion.\n", __func__ );

			/* linear healing: applied whether this tet has yielded or not. 
			   Parameters are hardwired for now, but should be given through an input file. */
			/* viscoplasticElement->plasticStrain[tetra_I] *= (1.0/(1.0+context->dt/1.0e+12)); */
			viscoplasticElement->plasticStrain[tetra_I] *= (1.0/(1.0+context->dt/(ind?1.0e+13:5.0e+11)));

			depls += viscoplasticElement->plasticStrain[tetra_I]*element->tetra[tetra_I].volume;
			totalVolume += element->tetra[tetra_I].volume;
		}
		/* volume-averaged accumulated plastic strain, aps */
		viscoplasticElement->aps = depls/totalVolume;
	}
}
Exemple #10
0
void _SnacMaxwell_Constitutive( void* _context, Element_LocalIndex element_lI ) {
	Snac_Context*			context = (Snac_Context*)_context;
	Snac_Element*			element = Snac_Element_At( context, element_lI );
	SnacMaxwell_Element*		elementExt = ExtensionManager_Get(
						context->mesh->elementExtensionMgr,
						element,
						SnacMaxwell_ElementHandle );
	SnacTemperature_Element* temperatureElement = ExtensionManager_Get(
						context->mesh->elementExtensionMgr,
						element,
						SnacTemperature_ElementHandle );
	const Snac_Material*		material = &context->materialProperty[element->material_I];

	EntryPoint* 			temperatureEP;
	temperatureEP = Context_GetEntryPoint( context,	"Snac_EP_LoopElementsEnergy" );

	/* If this is a Maxwell material, calculate its stress. */
	if( material->rheology & Snac_Material_Maxwell ) {
		Tetrahedra_Index		tetra_I;

		for( tetra_I = 0; tetra_I < Tetrahedra_Count; tetra_I++ ) {
			const double			bulkm = material->lambda + 2.0f * material->mu/3.0f;
			StressTensor*			stress = &element->tetra[tetra_I].stress;
			StrainTensor*			strain = &element->tetra[tetra_I].strain;
			Maxwell*			viscosity = &elementExt->viscosity[tetra_I];
			double				straind0,straind1,straind2,stressd0,stressd1,stressd2;
			double				trace_strain;
			double				trace_stress;
			double				temp;
			double				vic1;
			double				vic2;
			double				VolumicStress;
			double				rviscosity=material->refvisc;
                        double                          rmu= material->mu;
			double				srJ2;
			double				avgTemp;

			Node_LocalIndex			node_lI;
			/* For now reference values of viscosity, second invariant of deviatoric */
			/* strain rate and reference temperature  are being hard wired ( these specific */
			/* values are from paper by Hall et. al., EPSL, 2003 */
			double				rstrainrate = material->refsrate;
			double				rTemp = material->reftemp;
			double				H = material->activationE; // kJ/mol
			double				srexponent = material->srexponent;
			const double			R=8.31448;  // J/mol/K
#if 0
			double				a2 = material->lambda;
			double				sh2 = 2.0 * material->mu;
			double				s00,s11,s22,s01,s02,s12;

			/*	elastic update */
		/* 	s00=(*stress)[0][0] + sh2 * (*strain)[0][0] + a2 * (trace_strain ); */
/*  			s11=(*stress)[1][1] + sh2 * (*strain)[1][1] + a2 * (trace_strain ); */
/* 			s22=(*stress)[2][2] + sh2 * (*strain)[2][2] + a2 * (trace_strain ); */
/* 			s01=(*stress)[0][1] + sh2 * (*strain)[0][1]; */
/* 			s02=(*stress)[0][2] + sh2 * (*strain)[0][2]; */
/* 			s12=(*stress)[1][2] + sh2 * (*strain)[1][2]; */
#endif
			if( context->computeThermalStress ) {
				(*stress)[0][0] += temperatureElement->thermalStress[tetra_I];
				(*stress)[1][1] += temperatureElement->thermalStress[tetra_I];
				(*stress)[2][2] += temperatureElement->thermalStress[tetra_I];
			}

			trace_stress = (*stress)[0][0] + (*stress)[1][1] + (*stress)[2][2];
			trace_strain = element->tetra[tetra_I].volume/element->tetra[tetra_I].old_volume-1.0f;

			/* Deviatoric Stresses and Strains */
			straind0 =  (*strain)[0][0] -  (trace_strain) / 3.0f;
			straind1 =  (*strain)[1][1] -  (trace_strain) / 3.0f;
			straind2 =  (*strain)[2][2] -  (trace_strain) / 3.0f;

			stressd0 =  (*stress)[0][0] -  (trace_stress) / 3.0f;
			stressd1 =  (*stress)[1][1] -  (trace_stress) / 3.0f;
			stressd2 =  (*stress)[2][2] -  (trace_stress) / 3.0f;
			if( temperatureEP ) {
				srJ2 = sqrt(fabs(straind1*straind2+straind2*straind0+straind0*straind1 -(*strain[0][1])*(*strain[0][1])-(*strain[0][2])*(*strain[0][2])-(*strain[1][2])*(*strain[1][2])))/context->dt;
				if(srJ2 == 0.0f) srJ2 = rstrainrate; // temporary. should be vmax/length_scale

				avgTemp=0.0;
				for(node_lI=0; node_lI<4; node_lI++) {
					Snac_Node* contributingNode = Snac_Element_Node_P( context, element_lI, TetraToNode[tetra_I][node_lI] );
					SnacTemperature_Node* temperatureNodeExt = ExtensionManager_Get(
												 context->mesh->nodeExtensionMgr,contributingNode,
												 SnacTemperature_NodeHandle );

					avgTemp += 0.25 * temperatureNodeExt->temperature;
					assert( !isnan(avgTemp) && !isinf(avgTemp) );
				}

				(*viscosity)= rviscosity*pow((srJ2/rstrainrate),(1./srexponent-1.))
					*exp(H/R*(1./(avgTemp+273.15)-1./(rTemp+273.15)));
				if((*viscosity) < material->vis_min) (*viscosity) = material->vis_min;
				if((*viscosity) > material->vis_max) (*viscosity) = material->vis_max;

				if( isnan((*viscosity)) || isinf((*viscosity))) {
					fprintf(stderr,"rvisc=%e Erattio=%e pow(E)=%e, dT=%e exp=%e\n",
						rviscosity,(srJ2/rstrainrate),pow((srJ2/rstrainrate),(1./srexponent-1.)),
						exp(H/R*(1./(avgTemp+273.15)-1./(rTemp+273.15))),(1./(avgTemp+273.15)-1./(rTemp+273.15)) );
				}
				assert(!isnan((*viscosity)) && !isinf((*viscosity)));
			}
			else
				(*viscosity) = rviscosity;
			assert(!isnan((*viscosity)) && !isinf((*viscosity)));

                       /*   *viscosity=material->refvisc; */
			/* Non dimensional parameters elastic/viscous */
			temp = rmu / (2.0f* (*viscosity)) * context->dt;


			vic1 = 1.0f - temp;
			vic2 = 1.0f / (1.0f + temp);
                       /*   printf("temp=%g\t rmu=%g\t viscosity=%g\t\n",temp,rmu,*viscosity); */
/*                          printf("trace_stress=%g\t trace_strain=%g\t vic1=%g\t vic2=%g\n",trace_stress,trace_strain,vic1,vic2); */

			/* Deviatoric Stress Update */

			stressd0 =  (stressd0 * vic1 + 2.0f * rmu * straind0) * vic2 ;
			stressd1 =  (stressd1 * vic1 + 2.0f * rmu * straind1) * vic2 ;
			stressd2 =  (stressd2 * vic1 + 2.0f * rmu * straind2) * vic2 ;

			(*stress)[0][1] =((*stress)[0][1] * vic1 + 2.0f * rmu * (*strain)[0][1]) * vic2;
			(*stress)[0][2] =((*stress)[0][2] * vic1 + 2.0f * rmu * (*strain)[0][2]) * vic2;
			(*stress)[1][2] =((*stress)[1][2] * vic1 + 2.0f * rmu * (*strain)[1][2]) * vic2;

			/* Isotropic stress is elastic,
			   WARNING:volumic Strain may be better defined as
			   volumique change in the mesh */
			VolumicStress = trace_stress / 3.0f + bulkm * trace_strain;

			(*stress)[0][0] = stressd0 + VolumicStress;
			(*stress)[1][1] = stressd1 + VolumicStress;
			(*stress)[2][2] = stressd2 + VolumicStress;
		}
	}
}
void _GALEDruckerPrager_Init(
		GALEDruckerPrager*                                     self,
		FeVariable*                                        pressureField,
		SwarmVariable*                                     swarmPressure,
		MaterialPointsSwarm*                               materialPointsSwarm,
		double                                             frictionCoefficient,
		double                                             frictionCoefficientAfterSoftening,
                double                    boundaryCohesion,
                double                    boundaryCohesionAfterSoftening,
                double                    boundaryFrictionCoefficient,
                double                    boundaryFrictionCoefficientAfterSoftening,
                Bool                      boundaryBottom,
                Bool                      boundaryTop,
                Bool                      boundaryLeft,
                Bool                      boundaryRight,
                Bool                      boundaryFront,
                Bool                      boundaryBack,
                double                    minimumYieldStress,
                double                    minimumViscosity,
                HydrostaticTerm*          hydrostaticTerm )
{
	GALEDruckerPrager_Particle*   particleExt;
	StandardParticle          materialPoint;
	
	self->particleExtHandle = ExtensionManager_Add( materialPointsSwarm->particleExtensionMgr, (Name)GALEDruckerPrager_Type, sizeof(GALEDruckerPrager_Particle) );
		
	/* Assign Pointers */
	self->pressureField       = pressureField;
	self->frictionCoefficient = frictionCoefficient;
	self->minimumYieldStress  = minimumYieldStress;
	self->minimumViscosity    = minimumViscosity;
	self->swarmPressure       = swarmPressure;
	
	/* Strain softening of Cohesion and friction - (linear
           weakening is assumed) needs a softening factor between +0
           and 1 and a reference strain > 0 */
	self->frictionCoefficientAfterSoftening = frictionCoefficientAfterSoftening;
	self->boundaryCohesion = boundaryCohesion;
	self->boundaryFrictionCoefficient = boundaryFrictionCoefficient;
	self->boundaryCohesionAfterSoftening = boundaryCohesionAfterSoftening;
	self->boundaryFrictionCoefficientAfterSoftening = boundaryFrictionCoefficientAfterSoftening;
        self->boundaryBottom=boundaryBottom;
        self->boundaryTop=boundaryTop;
        self->boundaryLeft=boundaryLeft;
        self->boundaryRight=boundaryRight;
        self->boundaryFront=boundaryFront;
        self->boundaryBack=boundaryBack;

	self->minimumYieldStress = minimumYieldStress;
	self->minimumViscosity = minimumViscosity;
        self->hydrostaticTerm=hydrostaticTerm;

	/* Update Drawing Parameters */
	EP_PrependClassHook( Context_GetEntryPoint( self->context, AbstractContext_EP_DumpClass ),
								_GALEDruckerPrager_UpdateDrawParameters, self );
	
	particleExt = (GALEDruckerPrager_Particle*)ExtensionManager_Get( materialPointsSwarm->particleExtensionMgr, &materialPoint, self->particleExtHandle );
	
	/* Setup Variables for Visualisation */
	self->brightness = Swarm_NewScalarVariable( materialPointsSwarm, (Name)"GALEDruckerPragerBrightness", (ArithPointer) &particleExt->brightness - (ArithPointer) &materialPoint, Variable_DataType_Float  );
	
	self->opacity = Swarm_NewScalarVariable( materialPointsSwarm, (Name)"GALEDruckerPragerOpacity", (ArithPointer) &particleExt->opacity - (ArithPointer) &materialPoint, Variable_DataType_Float  );
	
	self->diameter = Swarm_NewScalarVariable( materialPointsSwarm, (Name)"GALEDruckerPragerDiameter", (ArithPointer) &particleExt->diameter - (ArithPointer) &materialPoint, Variable_DataType_Float  );

	/* The tensileFailure variable allows to check whether a materialPoint has failed in tensile mode or not */
	self->tensileFailure = Swarm_NewScalarVariable( materialPointsSwarm, (Name)"GALEDruckerPragerTensileFailure", (ArithPointer) &particleExt->tensileFailure - (ArithPointer) &materialPoint, Variable_DataType_Char );

        self->curFrictionCoef = 0.0;
}
Exemple #12
0
void _SnacTemperature_Construct( void* component, Stg_ComponentFactory* cf, void* data ) {
	Snac_Context*	context;
	EntryPoint* 	interpolateNodeEP;

	/* Retrieve context. */
	context = (Snac_Context*)Stg_ComponentFactory_ConstructByName( cf, "context", Snac_Context, True, data ); 

	#ifdef DEBUG
		printf( "In: _SnacTemperature_Register( void*, void* )\n" );
	#endif

	/* Add extensions to nodes, elements and the context */
	SnacTemperature_NodeHandle = ExtensionManager_Add( context->mesh->nodeExtensionMgr, SnacTemperature_Type, sizeof(SnacTemperature_Node) );
	SnacTemperature_ElementHandle = ExtensionManager_Add( context->mesh->elementExtensionMgr, SnacTemperature_Type, sizeof(SnacTemperature_Element) );
	SnacTemperature_ContextHandle = ExtensionManager_Add( context->extensionMgr, SnacTemperature_Type, sizeof(SnacTemperature_Context) );

	#ifdef DEBUG
		printf( "\tcontext extension handle: %u\n", SnacTemperature_ContextHandle );
		printf( "\telement extension handle: %u\n", SnacTemperature_ElementHandle );
		printf( "\tnode extension handle: %u\n", SnacTemperature_NodeHandle );
	#endif


	/* Add extensions to the entry points */
	EntryPoint_Append(
		Context_GetEntryPoint( context, AbstractContext_EP_Build ),
		SnacTemperature_Type,
		_SnacTemperature_Build,
		SnacTemperature_Type );
	EntryPoint_InsertBefore(
		Context_GetEntryPoint( context, AbstractContext_EP_Initialise ),
		"SnacTimeStepZero",
		SnacTemperature_Type,
		_SnacTemperature_InitialConditions,
		SnacTemperature_Type );
	EntryPoint_Append(
		Context_GetEntryPoint( context, Snac_EP_LoopNodesEnergy ),
		SnacTemperature_Type,
		SnacTemperature_LoopNodes,
		SnacTemperature_Type );
	EntryPoint_Append(
		Context_GetEntryPoint( context, Snac_EP_LoopElementsEnergy ),
		SnacTemperature_Type,
		SnacTemperature_LoopElements,
		SnacTemperature_Type );
	EntryPoint_Prepend( /* Dump the initial temperature */
		Context_GetEntryPoint( context, AbstractContext_EP_Execute ),
		"SnacTemperature_Write",
		_SnacTemperature_WriteTemp,
		SnacTemperature_Type );
	EntryPoint_Append( /* and dump each loop */
		Context_GetEntryPoint( context, Snac_EP_LoopNodesEnergy ),
		"SnacTemperature_Write",
		_SnacTemperature_WriteTemp,
		SnacTemperature_Type );
	EntryPoint_Append(
		Context_GetEntryPoint( context, AbstractContext_EP_DestroyExtensions ),
		SnacTemperature_Type,
		_SnacTemperature_DeleteExtensions,
		SnacTemperature_Type );

	/* Add extensions to the interpolate element entry point, but it will only exist if the remesher is loaded. */
	interpolateNodeEP = Context_GetEntryPoint( context, "SnacRemesher_EP_InterpolateNode" );
	if( interpolateNodeEP ) {
		EntryPoint_Append(
			interpolateNodeEP,
			SnacTemperature_Type,
			_SnacTemperature_InterpolateNode,
			SnacTemperature_Type );
	}

	/* Construct. */
	_SnacTemperature_ConstructExtensions( context, data );
}
Exemple #13
0
void _SnacRemesher_Construct( void* component, Stg_ComponentFactory* cf, void* data ) {
	Snac_Context*	context;

	/* Retrieve context. */
	context = (Snac_Context*)Stg_ComponentFactory_ConstructByName( cf, "context", Snac_Context, True, data ); 
	
	Journal_Printf( context->debug, "In: %s\n", __func__ );

	/* Add extensions to nodes, elements and the context */
	SnacRemesher_ContextHandle = ExtensionManager_Add(
		context->extensionMgr,
		SnacRemesher_Type,
		sizeof(SnacRemesher_Context) );
	SnacRemesher_MeshHandle = ExtensionManager_Add(
		context->meshExtensionMgr,
		SnacRemesher_Type,
		sizeof(SnacRemesher_Mesh) );

	Journal_Printf( context->debug, "\tcontext extension handle: %u\n", SnacRemesher_ContextHandle );
	Journal_Printf( context->debug, "\tmesh extension handle: %u\n", SnacRemesher_MeshHandle );

	/* Register new entry points to the context (which manages them) */
	Context_AddEntryPoint(
		context,
		SnacRemesher_EntryPoint_New( SnacRemesher_EP_InterpolateNode, SnacRemesher_InterpolateNode_CastType ) );
	Context_AddEntryPoint(
		context,
		SnacRemesher_EntryPoint_New( SnacRemesher_EP_InterpolateElement, SnacRemesher_InterpolateElement_CastType ) );
	Context_AddEntryPoint(
		context,
		SnacRemesher_EntryPoint_New( SnacRemesher_EP_CopyElement, SnacRemesher_CopyElement_CastType ) );

	/* Add extensions to the entry points */
	EntryPoint_Append(
		Context_GetEntryPoint( context, AbstractContext_EP_Build ),
		SnacRemesher_Type,
		_SnacRemesher_Build,
		SnacRemesher_Type );
	EntryPoint_Append(
		Context_GetEntryPoint( context, AbstractContext_EP_Initialise ),
		SnacRemesher_Type,
		_SnacRemesher_InitialConditions,
		SnacRemesher_Type );
	EntryPoint_Append(
		Context_GetEntryPoint( context, AbstractContext_EP_Sync ),
		SnacRemesher_Type,
		_SnacRemesher_Remesh,
		SnacRemesher_Type );
	EntryPoint_Append(
		Context_GetEntryPoint( context, SnacRemesher_EP_InterpolateNode ),
		SnacRemesher_Type,
		_SnacRemesher_InterpolateNode,
		SnacRemesher_Type );
	EntryPoint_Append(
		Context_GetEntryPoint( context, SnacRemesher_EP_InterpolateElement ),
		SnacRemesher_Type,
		_SnacRemesher_InterpolateElement,
		SnacRemesher_Type );
	EntryPoint_Append(
		Context_GetEntryPoint( context, SnacRemesher_EP_CopyElement ),
		SnacRemesher_Type,
		_SnacRemesher_CopyElement,
		SnacRemesher_Type );
	EntryPoint_Append(
		Context_GetEntryPoint( context, AbstractContext_EP_DestroyExtensions ),
		SnacRemesher_Type,
		_SnacRemesher_DeleteExtensions,
		SnacRemesher_Type );

	/* Construct. */
	_SnacRemesher_ConstructExtensions( context, data );
}
void _Pouliquen_etal_Init(
		Pouliquen_etal*                                     self,
		FeVariable*                                        pressureField,
		FeVariable*                                        strainRateInvField,
		MaterialPointsSwarm*                               materialPointsSwarm,
		double                                             minimumYieldStress,
		double                                             frictionCoefficient,
		double                                             frictionCoefficientAfterSoftening,
		double                                             grainDiameter,
		double                                             Io,
		double                                             rho_s,
		double                                             mu_2,
		double                                             mu_s,
		double                                             mu_2_afterSoftening,
		double                                             mu_s_afterSoftening,
		double                                             maxViscosity,
		double                                             minViscosity )
{
	Pouliquen_etal_Particle*   particleExt;
	StandardParticle          materialPoint;
	
	self->particleExtHandle = ExtensionManager_Add( materialPointsSwarm->particleExtensionMgr, (Name)Pouliquen_etal_Type, sizeof(Pouliquen_etal_Particle) );
		
	/* Assign Pointers */
	self->pressureField       = pressureField;
	self->strainRateInvField    = strainRateInvField;

	self->frictionCoefficient = frictionCoefficient;
	self->minimumYieldStress  = minimumYieldStress;
	
	/* Strain softening of Friction - (linear weakening is assumed ) */
	/* needs a softening factor between +0 and 1 and a reference strain > 0 */
	self->frictionCoefficientAfterSoftening = frictionCoefficientAfterSoftening;

	self->grainDiameter = grainDiameter;
	self->Io = Io;
	self->rho_s = rho_s;
	self->mu_2 = mu_2;
	self->mu_s = mu_s;
	self->mu_2_afterSoftening = mu_2_afterSoftening;
	self->mu_s_afterSoftening = mu_s_afterSoftening;
	self->maxViscosity = maxViscosity;
	self->minViscosity = minViscosity;

	/* Update Drawing Parameters */
	EP_PrependClassHook( Context_GetEntryPoint( self->context, AbstractContext_EP_DumpClass ),
								_Pouliquen_etal_UpdateDrawParameters, self );
	
	particleExt = (Pouliquen_etal_Particle*)ExtensionManager_Get( materialPointsSwarm->particleExtensionMgr, &materialPoint, self->particleExtHandle );
	
	/* Setup Variables for Visualisation */
	self->brightness = Swarm_NewScalarVariable( materialPointsSwarm, (Name)"Pouliquen_etalBrightness", (ArithPointer) &particleExt->brightness - (ArithPointer) &materialPoint, Variable_DataType_Float  );
	
	self->opacity = Swarm_NewScalarVariable( materialPointsSwarm, (Name)"Pouliquen_etalOpacity", (ArithPointer) &particleExt->opacity - (ArithPointer) &materialPoint, Variable_DataType_Float  );
	
	self->diameter = Swarm_NewScalarVariable( materialPointsSwarm, (Name)"Pouliquen_etalDiameter", (ArithPointer) &particleExt->diameter - (ArithPointer) &materialPoint, Variable_DataType_Float  );

	/* The tensileFailure variable allows to check whether a materialPoint has failed in tensile mode or not */
	self->tensileFailure = Swarm_NewScalarVariable( materialPointsSwarm, (Name)"Pouliquen_etalTensileFailure", (ArithPointer) &particleExt->tensileFailure - (ArithPointer) &materialPoint, Variable_DataType_Char );

}
void _ParticleMelting_Build( void* _self, void* data ) {
	ParticleMelting* self = (ParticleMelting*) _self;
	Materials_Register* matReg = self->materialSwarm->materials_Register;
	ParticleMelting_MatExt *matExt = NULL;
	unsigned materialCount, mat_i;
	Material* material = NULL;

	Stg_Component_Build( self->temperatureField, data, False );
	Stg_Component_Build( self->materialSwarm, data, False );
	if( self->pressureField )
	  Stg_Component_Build( self->pressureField, data, False );
	if( self->scaling ) {
	  Stg_Component_Build( self->scaling, data, False );
	  self->refRho = Scaling_Scale( self->scaling, 3400, sDensity );
	  self->gravity = Scaling_Scale( self->scaling, 9.81, sAcceleration );
	} else {
	  self->refRho = 1.0;
	  self->gravity = 1.0;
	}

	/* now we extend the materials with ParticleMelting_MatExt */
	self->materialExtHandle = Materials_Register_AddMaterialExtension( matReg, self->type, sizeof(ParticleMelting_MatExt) );

	materialCount = Materials_Register_GetCount( matReg );
	for( mat_i = 0 ; mat_i < materialCount ; mat_i++ ) {
		material = Materials_Register_GetByIndex( matReg, mat_i );
		matExt = ExtensionManager_Get( material->extensionMgr, material, self->materialExtHandle );

		/* get latent heat and specific heat from the material dictionary */
		matExt->lhf = Dictionary_GetDouble_WithDefault( material->dictionary, (Dictionary_Entry_Key)"latentHeat_Fusion", 0.0  );
		matExt->Cp = Dictionary_GetDouble_WithDefault( material->dictionary, (Dictionary_Entry_Key)"Cp", 1.0  );

		matExt->TurnMeltOn = Dictionary_GetBool_WithDefault( material->dictionary, (Dictionary_Entry_Key)"TurnMeltOn", 0.0  );

      /* read in values from xml file for solidus polynomial */
		matExt->sCoeff[0] = Dictionary_GetDouble_WithDefault( material->dictionary, (Dictionary_Entry_Key)"solidus_coeff0", 0.0  );
		matExt->sCoeff[1] = Dictionary_GetDouble_WithDefault( material->dictionary, (Dictionary_Entry_Key)"solidus_coeff1", 0.0  );
		matExt->sCoeff[2] = Dictionary_GetDouble_WithDefault( material->dictionary, (Dictionary_Entry_Key)"solidus_coeff2", 0.0  );
		matExt->sCoeff[3] = Dictionary_GetDouble_WithDefault( material->dictionary, (Dictionary_Entry_Key)"solidus_coeff3", 0.0  );

      /* read in values from xml file for liquidus polynomial */
		matExt->lCoeff[0] = Dictionary_GetDouble_WithDefault( material->dictionary, (Dictionary_Entry_Key)"liquidus_coeff0", 0.0  );
		matExt->lCoeff[1] = Dictionary_GetDouble_WithDefault( material->dictionary, (Dictionary_Entry_Key)"liquidus_coeff1", 0.0  );
		matExt->lCoeff[2] = Dictionary_GetDouble_WithDefault( material->dictionary, (Dictionary_Entry_Key)"liquidus_coeff2", 0.0  );
		matExt->lCoeff[3] = Dictionary_GetDouble_WithDefault( material->dictionary, (Dictionary_Entry_Key)"liquidus_coeff3", 0.0  );

		matExt->deepPressure = Dictionary_GetDouble_WithDefault( material->dictionary, (Dictionary_Entry_Key)"deepPressure", 0.0  );

      /* read in values from xml file for solidus polynomial (deep)*/
		matExt->sCoeffDeep[0] = Dictionary_GetDouble_WithDefault( material->dictionary, (Dictionary_Entry_Key)"solidus_coeff0_deep", matExt->sCoeff[0]  );
		matExt->sCoeffDeep[1] = Dictionary_GetDouble_WithDefault( material->dictionary, (Dictionary_Entry_Key)"solidus_coeff1_deep", matExt->sCoeff[1]  );
		matExt->sCoeffDeep[2] = Dictionary_GetDouble_WithDefault( material->dictionary, (Dictionary_Entry_Key)"solidus_coeff2_deep", matExt->sCoeff[2]  );
		matExt->sCoeffDeep[3] = Dictionary_GetDouble_WithDefault( material->dictionary, (Dictionary_Entry_Key)"solidus_coeff3_deep", matExt->sCoeff[3]  );

      /* read in values from xml file for liquidus polynomial */
		matExt->lCoeffDeep[0] = Dictionary_GetDouble_WithDefault( material->dictionary, (Dictionary_Entry_Key)"liquidus_coeff0_deep", matExt->lCoeff[0]  );
		matExt->lCoeffDeep[1] = Dictionary_GetDouble_WithDefault( material->dictionary, (Dictionary_Entry_Key)"liquidus_coeff1_deep", matExt->lCoeff[1]  );
		matExt->lCoeffDeep[2] = Dictionary_GetDouble_WithDefault( material->dictionary, (Dictionary_Entry_Key)"liquidus_coeff2_deep", matExt->lCoeff[2]  );
		matExt->lCoeffDeep[3] = Dictionary_GetDouble_WithDefault( material->dictionary, (Dictionary_Entry_Key)"liquidus_coeff3_deep", matExt->lCoeff[3]  );
	}

   EP_PrependClassHook_AlwaysFirst( 
         Context_GetEntryPoint( self->context, AbstractContext_EP_UpdateClass ),
         ParticleMelting_MeltFrationUpdate, 
         self );

   /*
	EP_InsertClassHookBefore( 
		Context_GetEntryPoint( self->context, AbstractContext_EP_UpdateClass ), 
		"_ParticleFeVariable_Execute",
		ParticleMelting_MeltFrationUpdate, 
		self );
      */
}