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); } } }
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); } } }