void TriaxialCompressionEngine::updateParameters ()
{
	UnbalancedForce=ComputeUnbalancedForce ();

	if (  (currentState!=STATE_TRIAX_LOADING && currentState==STATE_ISO_COMPACTION) || currentState==STATE_ISO_UNLOADING || currentState==STATE_FIXED_POROSITY_COMPACTION || autoCompressionActivation)
	{
		if (UnbalancedForce<=StabilityCriterion && abs ( ( meanStress-sigma_iso ) /sigma_iso ) <0.005 && fixedPoroCompaction==false )
		{
			// only go to UNLOADING if it is needed
			if ( currentState==STATE_ISO_COMPACTION && autoUnload && sigmaLateralConfinement!=sigmaIsoCompaction ) {
				doStateTransition (STATE_ISO_UNLOADING );
				computeStressStrain (); // update stress and strain
			}
			else if((currentState==STATE_ISO_COMPACTION || currentState==STATE_ISO_UNLOADING || currentState==STATE_LIMBO) && autoCompressionActivation){
				doStateTransition (STATE_TRIAX_LOADING );
				computeStressStrain (); // update stress and strain
			}
		}
		else if ( porosity<=fixedPorosity && currentState==STATE_FIXED_POROSITY_COMPACTION )
		{
// 			Omega::instance().pause();
			return;
		}
	}
}
Пример #2
0
void TriaxialStressController::action()
{
	// sync thread storage of ForceContainer
	scene->forces.sync();
	if (first) {// sync boundaries ids in the table
		wall_id[wall_bottom] = wall_bottom_id;
 		wall_id[wall_top] = wall_top_id;
 		wall_id[wall_left] = wall_left_id;
 		wall_id[wall_right] = wall_right_id;
 		wall_id[wall_front] = wall_front_id;
 		wall_id[wall_back] = wall_back_id;}

	if(thickness<0) thickness=2.0*YADE_PTR_CAST<Box>(Body::byId(wall_bottom_id,scene)->shape)->extents.y();
	State* p_bottom=Body::byId(wall_bottom_id,scene)->state.get();
	State* p_top=Body::byId(wall_top_id,scene)->state.get();
	State* p_left=Body::byId(wall_left_id,scene)->state.get();
	State* p_right=Body::byId(wall_right_id,scene)->state.get();
	State* p_front=Body::byId(wall_front_id,scene)->state.get();
	State* p_back=Body::byId(wall_back_id,scene)->state.get();
	height = p_top->se3.position.y() - p_bottom->se3.position.y() - thickness;
	width = p_right->se3.position.x() - p_left->se3.position.x() - thickness;
	depth = p_front->se3.position.z() - p_back->se3.position.z() - thickness;

	boxVolume = height * width * depth;
	if ( (first) || (updatePorosity) ) {
		BodyContainer::iterator bi = scene->bodies->begin();
		BodyContainer::iterator biEnd = scene->bodies->end();

		particlesVolume = 0;
		for ( ; bi!=biEnd; ++bi ) {
			const shared_ptr<Body>& b = *bi;
			if (b->isClump()) {
				const shared_ptr<Clump>& clump = YADE_PTR_CAST<Clump>(b->shape);
				const shared_ptr<Body>& member = Body::byId(clump->members.begin()->first,scene);
				particlesVolume += b->state->mass / member->material->density;
			}
			else if (b->isDynamic() && !b->isClumpMember()) {
				const shared_ptr<Sphere>& sphere = YADE_PTR_CAST<Sphere> ( b->shape );
				particlesVolume += 1.3333333*Mathr::PI*pow ( sphere->radius, 3 );
			}
		}
		first = false;
		updatePorosity = false;
	}
	max_vel1=3 * width /(height+width+depth)*max_vel;
	max_vel2=3 * height /(height+width+depth)*max_vel;
	max_vel3 =3 * depth /(height+width+depth)*max_vel;

	porosity = ( boxVolume - particlesVolume ) /boxVolume;
	position_top = p_top->se3.position.y();
	position_bottom = p_bottom->se3.position.y();
	position_right = p_right->se3.position.x();
	position_left = p_left->se3.position.x();
	position_front = p_front->se3.position.z();
	position_back = p_back->se3.position.z();

	// must be done _after_ height, width, depth have been calculated
	//Update stiffness only if it has been computed by StiffnessCounter (see "stiffnessUpdateInterval")
	if (scene->iter % stiffnessUpdateInterval == 0 || scene->iter<100) updateStiffness();
	bool isARadiusControlIteration = (scene->iter % radiusControlInterval == 0);

	if (scene->iter % computeStressStrainInterval == 0 ||
		 (internalCompaction && isARadiusControlIteration) )
		computeStressStrain();

	if (!internalCompaction) {
		Vector3r wallForce (0, goal2*width*depth, 0);
		if (wall_bottom_activated) {
			if (stressMask & 2)  controlExternalStress(wall_bottom, -wallForce, p_bottom, max_vel2);
			else p_bottom->vel[1] += (-normal[wall_bottom][1]*0.5*goal2*height -p_bottom->vel[1])*(1-strainDamping);
		} else p_bottom->vel=Vector3r::Zero();
		if (wall_top_activated) {
			if (stressMask & 2)  controlExternalStress(wall_top, wallForce, p_top, max_vel2);
			else p_top->vel[1] += (-normal[wall_top][1]*0.5*goal2*height -p_top->vel[1])*(1-strainDamping);
		} else p_top->vel=Vector3r::Zero();
		
		wallForce = Vector3r(goal1*height*depth, 0, 0);
		if (wall_left_activated) {
			if (stressMask & 1) controlExternalStress(wall_left, -wallForce, p_left, max_vel1);
			else p_left->vel[0] += (-normal[wall_left][0]*0.5*goal1*width -p_left->vel[0])*(1-strainDamping);
		} else p_left->vel=Vector3r::Zero();
		if (wall_right_activated) {
			if (stressMask & 1) controlExternalStress(wall_right, wallForce, p_right, max_vel1);
			else p_right->vel[0] += (-normal[wall_right][0]*0.5*goal1*width -p_right->vel[0])*(1-strainDamping);
		} else p_right->vel=Vector3r::Zero();

		wallForce = Vector3r(0, 0, goal3*height*width);
		if (wall_back_activated) {
			if (stressMask & 4) controlExternalStress(wall_back, -wallForce, p_back, max_vel3);
			else p_back->vel[2] += (-normal[wall_back][2]*0.5*goal3*depth -p_back->vel[2])*(1-strainDamping);
		} else p_back->vel=Vector3r::Zero();
		if (wall_front_activated) {
			if (stressMask & 4) controlExternalStress(wall_front, wallForce, p_front, max_vel3);
			else p_front->vel[2] += (-normal[wall_front][2]*0.5*goal3*depth -p_front->vel[2])*(1-strainDamping);
		} else p_front->vel=Vector3r::Zero();
	}
	else //if internal compaction
	{
		p_bottom->vel=Vector3r::Zero(); p_top->vel=Vector3r::Zero(); p_left->vel=Vector3r::Zero(); p_right->vel=Vector3r::Zero(); p_back->vel=Vector3r::Zero(); p_front->vel=Vector3r::Zero();
		if (isARadiusControlIteration) {
			Real sigma_iso_ = bool(stressMask & 1)*goal1 +  bool(stressMask & 2)*goal2 +  bool(stressMask & 4)*goal3;
			sigma_iso_ /=  bool(stressMask & 1) +  bool(stressMask & 2) +  bool(stressMask & 4);
			if (sigma_iso_<=meanStress) maxMultiplier = finalMaxMultiplier;
			if (meanStress==0) previousMultiplier = maxMultiplier;
			else {
				//     		previousMultiplier = 1+0.7*(sigma_iso-s)*(previousMultiplier-1.f)/(s-previousStress); // = (Dsigma/apparentModulus)*0.7
				//     		previousMultiplier = std::max(2-maxMultiplier, std::min(previousMultiplier, maxMultiplier));
				previousMultiplier = 1.+(sigma_iso_-meanStress)/sigma_iso_*(maxMultiplier-1.); // = (Dsigma/apparentModulus)*0.7
			}
			previousStress = meanStress;
			//Real apparentModulus = (s-previousStress)/(previousMultiplier-1.f);
			controlInternalStress(previousMultiplier);
		}
	}
}
Пример #3
0
void TriaxialStressController::action()
{
	// sync thread storage of ForceContainer
	scene->forces.sync();
	if (first) {// sync boundaries ids in the table
		wall_id[wall_bottom] = wall_bottom_id;
 		wall_id[wall_top] = wall_top_id;
 		wall_id[wall_left] = wall_left_id;
 		wall_id[wall_right] = wall_right_id;
 		wall_id[wall_front] = wall_front_id;
 		wall_id[wall_back] = wall_back_id;}

	if(thickness<0) thickness=2.0*YADE_PTR_CAST<Box>(Body::byId(wall_bottom_id,scene)->shape)->extents.y();
	State* p_bottom=Body::byId(wall_bottom_id,scene)->state.get();
	State* p_top=Body::byId(wall_top_id,scene)->state.get();
	State* p_left=Body::byId(wall_left_id,scene)->state.get();
	State* p_right=Body::byId(wall_right_id,scene)->state.get();
	State* p_front=Body::byId(wall_front_id,scene)->state.get();
	State* p_back=Body::byId(wall_back_id,scene)->state.get();
	height = p_top->se3.position.y() - p_bottom->se3.position.y() - thickness;
	width = p_right->se3.position.x() - p_left->se3.position.x() - thickness;
	depth = p_front->se3.position.z() - p_back->se3.position.z() - thickness;

	boxVolume = height * width * depth;
	if (first) {
		BodyContainer::iterator bi = scene->bodies->begin();
		BodyContainer::iterator biEnd = scene->bodies->end();
		spheresVolume = 0;
		for ( ; bi!=biEnd; ++bi )
		{
			if((*bi)->isClump()) continue;
			const shared_ptr<Body>& b = *bi;
			if ( b->isDynamic() || b->isClumpMember() ) {
				const shared_ptr<Sphere>& sphere = YADE_PTR_CAST<Sphere> ( b->shape );
				spheresVolume += 1.3333333*Mathr::PI*pow ( sphere->radius, 3 );
			}
		}
		max_vel1=3 * width /(height+width+depth)*max_vel;
		max_vel2=3 * height /(height+width+depth)*max_vel;
		max_vel3 =3 * depth /(height+width+depth)*max_vel;
		first = false;
	}

	// NOT JUST at the first run, since sigma_iso may be changed
	// if the TriaxialCompressionEngine is used, sigma_iso is attributed to sigma1, sigma2 and sigma3
	if (isAxisymetric){
		sigma1=sigma2=sigma3=sigma_iso;
	}

	porosity = ( boxVolume - spheresVolume ) /boxVolume;
	position_top = p_top->se3.position.y();
	position_bottom = p_bottom->se3.position.y();
	position_right = p_right->se3.position.x();
	position_left = p_left->se3.position.x();
	position_front = p_front->se3.position.z();
	position_back = p_back->se3.position.z();

	// must be done _after_ height, width, depth have been calculated
	//Update stiffness only if it has been computed by StiffnessCounter (see "stiffnessUpdateInterval")
	if (scene->iter % stiffnessUpdateInterval == 0 || scene->iter<100) updateStiffness();
	bool isARadiusControlIteration = (scene->iter % radiusControlInterval == 0);

	if (scene->iter % computeStressStrainInterval == 0 ||
		 (internalCompaction && isARadiusControlIteration) )
		computeStressStrain();

	if (!internalCompaction) {
		Vector3r wallForce (0, sigma2*width*depth, 0);
		if (wall_bottom_activated) controlExternalStress(wall_bottom, -wallForce, p_bottom, max_vel2);
		else p_bottom->vel=Vector3r::Zero();
		if (wall_top_activated) controlExternalStress(wall_top, wallForce, p_top, max_vel2);
		else p_top->vel=Vector3r::Zero();
		wallForce = Vector3r(sigma1*height*depth, 0, 0);
		if (wall_left_activated) controlExternalStress(wall_left, -wallForce, p_left, max_vel1);
		else p_left->vel=Vector3r::Zero();
		if (wall_right_activated) controlExternalStress(wall_right, wallForce, p_right, max_vel1);
		else p_right->vel=Vector3r::Zero();

		wallForce = Vector3r(0, 0, sigma3*height*width);
		if (wall_back_activated) controlExternalStress(wall_back, -wallForce, p_back, max_vel3);
		else p_back->vel=Vector3r::Zero();
		if (wall_front_activated) controlExternalStress(wall_front, wallForce, p_front, max_vel3);
		else p_front->vel=Vector3r::Zero();
	}
	else //if internal compaction
	{
		p_bottom->vel=Vector3r::Zero(); p_top->vel=Vector3r::Zero(); p_left->vel=Vector3r::Zero(); p_right->vel=Vector3r::Zero(); p_back->vel=Vector3r::Zero(); p_front->vel=Vector3r::Zero();
		if (isARadiusControlIteration) {
			//Real s = computeStressStrain(scene);
			if (sigma_iso<=meanStress) maxMultiplier = finalMaxMultiplier;
			if (meanStress==0) previousMultiplier = maxMultiplier;
			else {
				//     		previousMultiplier = 1+0.7*(sigma_iso-s)*(previousMultiplier-1.f)/(s-previousStress); // = (Dsigma/apparentModulus)*0.7
				//     		previousMultiplier = std::max(2-maxMultiplier, std::min(previousMultiplier, maxMultiplier));
				previousMultiplier = 1.+(sigma_iso-meanStress)/sigma_iso*(maxMultiplier-1.); // = (Dsigma/apparentModulus)*0.7
			}
			previousStress = meanStress;
			//Real apparentModulus = (s-previousStress)/(previousMultiplier-1.f);
			controlInternalStress(previousMultiplier);
		}
	}
}