double Hamiltonian::computeLocalEnergy(std::vector<Particle*> particles) {

    if (m_useNumerical) {
        m_kineticEnergy = computeKineticEnergy(particles);
    } else {
        m_kineticEnergy = computeAnalyticalKineticEnergy(particles);
    }

    m_potentialEnergy = computePotentialEnergy(particles);
    return m_kineticEnergy + m_potentialEnergy;
}
double InteractingHarmonicOscillator::computeLocalEnergy(std::vector<Particle *> particles)
{
    double potentialEnergy = 0;
    double kineticEnergy   = 0;

    // Compute external potential energy
    double r2 = 0;
    for (int i=0; i<m_system->getNumberOfParticles(); i++){
        for (int j=0; j<m_system->getNumberOfDimensions(); j++){
            if (j<2){
                r2 += particles[i]->getPosition()[j] * particles[i]->getPosition()[j];
            }
            else{
                r2 += particles[i]->getPosition()[j] * particles[i]->getPosition()[j] * m_gamma2;
            }
        }
    }

    potentialEnergy = 0.5*r2;

    // Compute internal potential energy
    double dr2 = 0;
    for (int i=0; i<m_system->getNumberOfParticles(); i++){
        for (int j=i+1; j<m_system->getNumberOfParticles(); j++){
            dr2=0;
            for (int k=0; k<m_system->getNumberOfDimensions(); k++){
                dr2 += (particles[j]->getPosition()[k] - particles[i]->getPosition()[k]) *
                       (particles[j]->getPosition()[k] - particles[i]->getPosition()[k]) ;
            }
            double absdr = sqrt(dr2);
            if (absdr < m_a){
                potentialEnergy += 1e10;
            }
        }
    }

    kineticEnergy = computeKineticEnergy(particles);

    //cout << setw(10) << " kinetic: "   << setw(10) << setprecision(3) << left << kineticEnergy;
    //cout << setw(12) << " potential: " << setw(10) << setprecision(3) << left << potentialEnergy;
    //cout << setw(8) <<  " total: "     << setw(10) << setprecision(3) << left << kineticEnergy + potentialEnergy << endl;


    return kineticEnergy + potentialEnergy;
}
double TwoBodyQuantumDotHamiltonian::computeLocalEnergy(std::vector<Particle *> particles)
{

    double kinetic = computeKineticEnergy(particles);

    double r1 = 0;
    double r2 = 0;
    double r12 = 0;
    for (int i=0; i<m_system->getNumberOfDimensions(); i++){
        r1 += particles[0]->getPosition()[i]*particles[0]->getPosition()[i];
        r2 += particles[1]->getPosition()[i]*particles[1]->getPosition()[i];
        r12 += (particles[0]->getPosition()[i]-particles[1]->getPosition()[i])*
                (particles[0]->getPosition()[i]-particles[1]->getPosition()[i]);
    }
    r12 = sqrt(r12);

    return kinetic + 0.5*m_omega*m_omega*(r1+r2) + 1/r12;
}
//! Compute the global kinetic energy
int PeridigmNS::Compute_Global_Kinetic_Energy::compute( Teuchos::RCP< std::vector<PeridigmNS::Block> > blocks  ) const
{
  	bool storeLocal = false;
  	int result = computeKineticEnergy(blocks, storeLocal);
  	return result;
}
bool Law2_ScGeom_JCFpmPhys_JointedCohesiveFrictionalPM::go(shared_ptr<IGeom>& ig, shared_ptr<IPhys>& ip, Interaction* contact){

	const int &id1 = contact->getId1();
	const int &id2 = contact->getId2();
	ScGeom* geom = static_cast<ScGeom*>(ig.get()); 
	JCFpmPhys* phys = static_cast<JCFpmPhys*>(ip.get());
	
	Body* b1 = Body::byId(id1,scene).get();
	Body* b2 = Body::byId(id2,scene).get();

	Real Dtensile=phys->FnMax/phys->kn;
	
	string fileCracks = "cracks_"+Key+".txt";
	string fileMoments = "moments_"+Key+".txt";
	/// Defines the interparticular distance used for computation
	Real D = 0;

	/*this is for setting the equilibrium distance between all cohesive elements at the first contact detection*/
	if ( contact->isFresh(scene) ) { 
	  phys->normalForce = Vector3r::Zero(); 
	  phys->shearForce = Vector3r::Zero();
	  if ((smoothJoint) && (phys->isOnJoint)) {
	    phys->jointNormal = geom->normal.dot(phys->jointNormal)*phys->jointNormal; //to set the joint normal colinear with the interaction normal
	    phys->jointNormal.normalize();
	    phys->initD = std::abs((b1->state->pos - b2->state->pos).dot(phys->jointNormal)); // to set the initial gap as the equilibrium gap
	  } else { 
	    phys->initD = geom->penetrationDepth; 
	  }
	}
	
	if ( smoothJoint && phys->isOnJoint ) {
	  if ( phys->more || ( phys-> jointCumulativeSliding > (2*min(geom->radius1,geom->radius2)) ) ) { 
	    if (!neverErase) return false; 
	    else {
	      phys->shearForce = Vector3r::Zero();
	      phys->normalForce = Vector3r::Zero();
	      phys->isCohesive =0;
	      phys->FnMax = 0;
	      phys->FsMax = 0;
	      return true;
	      }
	  } else { 
	    D = phys->initD - std::abs((b1->state->pos - b2->state->pos).dot(phys->jointNormal)); 
	  }
	} else { 
	  D = geom->penetrationDepth - phys->initD; 
	}
	
	phys->crackJointAperture = D<0? -D : 0.; // for DFNFlow

	if (!phys->momentBroken  && useStrainEnergy) phys->strainEnergy = 0.5*((pow(phys->normalForce.norm(),2)/phys->kn) + (pow(phys->shearForce.norm(),2)/phys->ks));
	else if (!phys->momentBroken && !useStrainEnergy) computeKineticEnergy(phys, b1, b2);

//Compute clustered acoustic emission events:
	if (recordMoments && !neverErase){ 
			cerr << "Acoustic emissions algorithm requires neverErase=True, changing value from False to True" << endl;
			neverErase=true;
	}
		
	if (phys->momentBroken && recordMoments && !phys->momentCalculated){
		if (phys->originalClusterEvent && !phys->computedCentroid) computeCentroid(phys);
		if (phys->originalClusterEvent) computeClusteredMoment(phys);
		
		if (phys->momentCalculated && phys->momentMagnitude!=0){
			std::ofstream file (fileMoments.c_str(), !momentsFileExist ? std::ios::trunc : std::ios::app);
			if(file.tellp()==0){ file <<"i p0 p1 p2 moment numInts eventNum time beginTime"<<endl; }
			file << boost::lexical_cast<string> ( scene->iter )<<" "<< boost::lexical_cast<string> ( phys->momentCentroid[0] ) <<" "<< boost::lexical_cast<string> ( phys->momentCentroid[1] ) <<" "<< boost::lexical_cast<string> ( phys->momentCentroid[2] ) <<" "<< boost::lexical_cast<string> ( phys->momentMagnitude ) << " " << boost::lexical_cast<string> ( phys->clusterInts.size() ) << " " << boost::lexical_cast<string> ( phys->eventNumber ) << " " << boost::lexical_cast<string> (scene->time) << " " << boost::lexical_cast<string> (phys->eventBeginTime) << endl;
			momentsFileExist=true;
		}
		
	}

	/* Determination of interaction */
	if (D < 0) { //tensile configuration
	  if ( !phys->isCohesive) {
	    if (!neverErase) return false;
	    else {
	      phys->shearForce = Vector3r::Zero();
	      phys->normalForce = Vector3r::Zero();
	      phys->isCohesive =0;
	      phys->FnMax = 0;
	      phys->FsMax = 0;
	      return true;
	    }
	  }
	  
	  if ( phys->isCohesive && (phys->FnMax>0) && (std::abs(D)>Dtensile) ) {
	    
	    nbTensCracks++;
	    phys->isCohesive = 0;
	    phys->FnMax = 0;
	    phys->FsMax = 0;
	    /// Do we need both the following lines?
	    phys->breakOccurred = true;  // flag to trigger remesh for DFNFlowEngine
	    phys->isBroken = true; // flag for DFNFlowEngine
	    
            // update body state with the number of broken bonds -> do we really need that?
	    JCFpmState* st1=dynamic_cast<JCFpmState*>(b1->state.get());
	    JCFpmState* st2=dynamic_cast<JCFpmState*>(b2->state.get());
            st1->nbBrokenBonds++;
	    st2->nbBrokenBonds++;
	    st1->damageIndex+=1.0/st1->nbInitBonds;
	    st2->damageIndex+=1.0/st2->nbInitBonds;
		phys->momentBroken = true;
            
            Real scalarNF=phys->normalForce.norm();
	    Real scalarSF=phys->shearForce.norm();
	    totalTensCracksE+=0.5*( ((scalarNF*scalarNF)/phys->kn) + ((scalarSF*scalarSF)/phys->ks) );
            totalCracksSurface += phys->crossSection;
	    
	    if (recordCracks){
                std::ofstream file (fileCracks.c_str(), !cracksFileExist ? std::ios::trunc : std::ios::app);
                if(file.tellp()==0){ file <<"iter time p0 p1 p2 type size norm0 norm1 norm2 nrg onJnt"<<endl; }
                Vector3r crackNormal=Vector3r::Zero();
                if ((smoothJoint) && (phys->isOnJoint)) { crackNormal=phys->jointNormal; } else {crackNormal=geom->normal;}
                file << boost::lexical_cast<string> ( scene->iter ) << " " << boost::lexical_cast<string> ( scene->time ) <<" "<< boost::lexical_cast<string> ( geom->contactPoint[0] ) <<" "<< boost::lexical_cast<string> ( geom->contactPoint[1] ) <<" "<< boost::lexical_cast<string> ( geom->contactPoint[2] ) <<" "<< 1 <<" "<< boost::lexical_cast<string> ( 0.5*(geom->radius1+geom->radius2) ) <<" "<< boost::lexical_cast<string> ( crackNormal[0] ) <<" "<< boost::lexical_cast<string> ( crackNormal[1] ) <<" "<< boost::lexical_cast<string> ( crackNormal[2] ) <<" "<< boost::lexical_cast<string> ( 0.5*( ((scalarNF*scalarNF)/phys->kn) + ((scalarSF*scalarSF)/phys->ks) ) ) <<" "<< boost::lexical_cast<string> ( phys->isOnJoint ) << endl;
	    }
        if (recordMoments && !phys->momentCalculated){
        	checkForCluster(phys, geom, b1, b2, contact);
			clusterInteractions(phys, contact);
			computeTemporalWindow(phys, b1, b2);
        }
	    cracksFileExist=true;
            
	    if (!neverErase) return false; 
	    else {
	      phys->shearForce = Vector3r::Zero();
	      phys->normalForce = Vector3r::Zero();
	      return true;
	    }
	  }
	}
	
	/* NormalForce */
	Real Fn = 0;
	Fn = phys->kn*D; 
        
	/* ShearForce */
	Vector3r& shearForce = phys->shearForce; 
	Real jointSliding=0;

	if ((smoothJoint) && (phys->isOnJoint)) {
	  
	  /// incremental formulation (OK?)
	  Vector3r relativeVelocity = (b2->state->vel - b1->state->vel); // angVel are not taken into account as particles on joint don't rotate ????
	  Vector3r slidingVelocity = relativeVelocity - phys->jointNormal.dot(relativeVelocity)*phys->jointNormal; 
	  Vector3r incrementalSliding = slidingVelocity*scene->dt;
	  shearForce -= phys->ks*incrementalSliding;
	  
	  jointSliding = incrementalSliding.norm();
	  phys->jointCumulativeSliding += jointSliding;
  
	} else {

	  shearForce = geom->rotate(phys->shearForce);
	  const Vector3r& incrementalShear = geom->shearIncrement();
	  shearForce -= phys->ks*incrementalShear;
	  
	}
	
	/* Mohr-Coulomb criterion */
	Real maxFs = phys->FsMax + Fn*phys->tanFrictionAngle;
	Real scalarShearForce = shearForce.norm();
               
	if (scalarShearForce > maxFs) {
	  if (scalarShearForce != 0)
	    shearForce*=maxFs/scalarShearForce;
	  else
	    shearForce=Vector3r::Zero();
	  if ((smoothJoint) && (phys->isOnJoint)) {phys->dilation=phys->jointCumulativeSliding*phys->tanDilationAngle-D; phys->initD+=(jointSliding*phys->tanDilationAngle);}

// 	  if (!phys->isCohesive) {
//             nbSlips++;
//             totalSlipE+=((1./phys->ks)*(trialForce-shearForce))/*plastic disp*/.dot(shearForce)/*active force*/;
//             
// 	    if ( (recordSlips) && (maxFs!=0) ) {
// 	    std::ofstream file (fileCracks.c_str(), !cracksFileExist ? std::ios::trunc : std::ios::app);
// 	    if(file.tellp()==0){ file <<"iter time p0 p1 p2 type size norm0 norm1 norm2 nrg"<<endl; }
// 	    Vector3r crackNormal=Vector3r::Zero();
// 	    if ((smoothJoint) && (phys->isOnJoint)) { crackNormal=phys->jointNormal; } else {crackNormal=geom->normal;}
// 	    file << boost::lexical_cast<string> ( scene->iter ) <<" " << boost::lexical_cast<string> ( scene->time ) <<" "<< boost::lexical_cast<string> ( geom->contactPoint[0] ) <<" "<< boost::lexical_cast<string> ( geom->contactPoint[1] ) <<" "<< boost::lexical_cast<string> ( geom->contactPoint[2] ) <<" "<< 0 <<" "<< boost::lexical_cast<string> ( 0.5*(geom->radius1+geom->radius2) ) <<" "<< boost::lexical_cast<string> ( crackNormal[0] ) <<" "<< boost::lexical_cast<string> ( crackNormal[1] ) <<" "<< boost::lexical_cast<string> ( crackNormal[2] ) <<" "<< boost::lexical_cast<string> ( ((1./phys->ks)*(trialForce-shearForce)).dot(shearForce) ) << endl;
// 	    }
// 	    cracksFileExist=true;    
// 	  }

	  if ( phys->isCohesive ) { 

	    nbShearCracks++;
	    phys->isCohesive = 0;
	    phys->FnMax = 0;
	    phys->FsMax = 0;
	    /// Do we need both the following lines?
	    phys->breakOccurred = true;  // flag to trigger remesh for DFNFlowEngine
	    phys->isBroken = true; // flag for DFNFlowEngine
	    phys->momentBroken = true;
	    // update body state with the number of broken bonds -> do we really need that?
	    JCFpmState* st1=dynamic_cast<JCFpmState*>(b1->state.get());
	    JCFpmState* st2=dynamic_cast<JCFpmState*>(b2->state.get());
	    st1->nbBrokenBonds++;
	    st2->nbBrokenBonds++;
	    st1->damageIndex+=1.0/st1->nbInitBonds;
	    st2->damageIndex+=1.0/st2->nbInitBonds;
          
	    Real scalarNF=phys->normalForce.norm();
	    Real scalarSF=phys->shearForce.norm();
	    totalShearCracksE+=0.5*( ((scalarNF*scalarNF)/phys->kn) + ((scalarSF*scalarSF)/phys->ks) );
            totalCracksSurface += phys->crossSection;
    
	    if (recordCracks){
	      std::ofstream file (fileCracks.c_str(), !cracksFileExist ? std::ios::trunc : std::ios::app);
	      if(file.tellp()==0){ file <<"iter time p0 p1 p2 type size norm0 norm1 norm2 nrg onJnt"<<endl; }
	      Vector3r crackNormal=Vector3r::Zero();
	      if ((smoothJoint) && (phys->isOnJoint)) { crackNormal=phys->jointNormal; } else {crackNormal=geom->normal;}
	      file << boost::lexical_cast<string> ( scene->iter ) << " " << boost::lexical_cast<string> ( scene->time ) <<" "<< boost::lexical_cast<string> ( geom->contactPoint[0] ) <<" "<< boost::lexical_cast<string> ( geom->contactPoint[1] ) <<" "<< boost::lexical_cast<string> ( geom->contactPoint[2] ) <<" "<< 2 <<" "<< boost::lexical_cast<string> ( 0.5*(geom->radius1+geom->radius2) ) <<" "<< boost::lexical_cast<string> ( crackNormal[0] ) <<" "<< boost::lexical_cast<string> ( crackNormal[1] ) <<" "<< boost::lexical_cast<string> ( crackNormal[2] ) <<" "<< boost::lexical_cast<string> ( 0.5*( ((scalarNF*scalarNF)/phys->kn) + ((scalarSF*scalarSF)/phys->ks) ) ) <<" "<< boost::lexical_cast<string> ( phys->isOnJoint ) << endl;
	    }
	    cracksFileExist=true;
	    
// 	    // option 1: delete contact whatsoever (if in compression, it will be detected as a new contact at the next timestep -> actually, not necesarily because of the near neighbour interaction: there could be a gap between the bonded particles and thus a broken contact may not be frictional at the next timestep if the detection is done for strictly contacting particles...) -> to TEST
//             if (!neverErase) return false;
//             else {
//                 phys->shearForce = Vector3r::Zero();
// 		phys->normalForce = Vector3r::Zero();
// 		return true;
//             }

        if (recordMoments && !phys->momentCalculated){
        	checkForCluster(phys, geom, b1, b2, contact);
			clusterInteractions(phys, contact);
			computeTemporalWindow(phys, b1, b2);
        }
            
            // option 2: delete contact if in tension
//	    shearForce *= Fn*phys->tanFrictionAngle/scalarShearForce; // now or at the next timestep? should not be very different -> to TEST
	    if ( D < 0 ) { // spheres do not touch
                if (!neverErase) return false;
                else {
                    phys->shearForce = Vector3r::Zero();
                    phys->normalForce = Vector3r::Zero();
                    return true;
                }
	    }
	    
	  }
	}
	
	/* Apply forces */
	if ((smoothJoint) && (phys->isOnJoint)) { phys->normalForce = Fn*phys->jointNormal; } else { phys->normalForce = Fn*geom->normal; }
	
	Vector3r f = phys->normalForce + shearForce;
	
	/// applyForceAtContactPoint computes torque also and, for now, we don't want rotation for particles on joint (some errors in calculation due to specific geometry) 
 	//applyForceAtContactPoint(f, geom->contactPoint, I->getId2(), b2->state->pos, I->getId1(), b1->state->pos, scene);
	scene->forces.addForce (id1,-f);
	scene->forces.addForce (id2, f);
	
	// simple solution to avoid torque computation for particles interacting on a smooth joint 
	if ( (phys->isOnJoint)&&(smoothJoint) ) return true;
	
	/// those lines are needed if rootBody->forces.addForce and rootBody->forces.addMoment are used instead of applyForceAtContactPoint -> NOTE need to check for accuracy!!!
	scene->forces.addTorque(id1,(geom->radius1-0.5*geom->penetrationDepth)* geom->normal.cross(-f));
	scene->forces.addTorque(id2,(geom->radius2-0.5*geom->penetrationDepth)* geom->normal.cross(-f));
	return true;
	
}
Example #6
0
//==============================================================================
double MetaSkeleton::getKineticEnergy() const
{
  return computeKineticEnergy();
}
Example #7
0
//==============================================================================
double MetaSkeleton::computeLagrangian() const
{
  return computeKineticEnergy() - computePotentialEnergy();
}
Example #8
0
scalar TwoDScene::computeTotalEnergy() const
{
  return computeKineticEnergy()+computePotentialEnergy();
}