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; }
//============================================================================== double MetaSkeleton::getKineticEnergy() const { return computeKineticEnergy(); }
//============================================================================== double MetaSkeleton::computeLagrangian() const { return computeKineticEnergy() - computePotentialEnergy(); }
scalar TwoDScene::computeTotalEnergy() const { return computeKineticEnergy()+computePotentialEnergy(); }