~ubuntu-branches/ubuntu/trusty/yade/trusty

« back to all changes in this revision

Viewing changes to pkg/common/Grid.cpp

  • Committer: Package Import Robot
  • Author(s): Anton Gladky, cf3f8d9
  • Date: 2013-10-30 20:56:33 UTC
  • mfrom: (20.1.9 sid)
  • Revision ID: package-import@ubuntu.com-20131030205633-1f01r7hjce17d723
Tags: 1.05.0-2
[cf3f8d9] Pass -ftrack-macro-expansion=0 only if gcc>=4.8. (Closes: #726009)

Show diffs side-by-side

added added

removed removed

Lines of Context:
24
24
ScGridCoGeom::~ScGridCoGeom(){}
25
25
YADE_PLUGIN((ScGridCoGeom));
26
26
 
 
27
GridCoGridCoGeom::~GridCoGridCoGeom(){}
 
28
YADE_PLUGIN((GridCoGridCoGeom));
 
29
 
27
30
void GridNode::addConnection(shared_ptr<Body> GC){
28
31
        ConnList.push_back(GC);
29
32
}
69
72
}
70
73
YADE_PLUGIN((Ig2_GridNode_GridNode_GridNodeGeom6D));
71
74
 
 
75
//!                     \\//
 
76
bool Ig2_GridConnection_GridConnection_GridCoGridCoGeom::go( const shared_ptr<Shape>& cm1, const shared_ptr<Shape>& cm2, const State& state1, const State& state2, const Vector3r& shift2, const bool& force, const shared_ptr<Interaction>& c)
 
77
{
 
78
        /*FIXME : /!\ Note that this geometry doesn't take care of any unwished duplicated contact or shear force following. /!\*/
 
79
        GridConnection* conn1 = YADE_CAST<GridConnection*>(cm1.get());
 
80
        GridConnection* conn2 = YADE_CAST<GridConnection*>(cm2.get());
 
81
        State* stNode11 = conn1->node1->state.get();
 
82
        State* stNode12 = conn1->node2->state.get();
 
83
        State* stNode21 = conn2->node1->state.get();
 
84
        State* stNode22 = conn2->node2->state.get();
 
85
        
 
86
        if(conn1->node1==conn2->node1 || conn1->node1==conn2->node2 || conn1->node2==conn2->node1 || conn1->node2==conn2->node2){
 
87
                //Two connections share at least one node, so they are contiguous => they must not interact.
 
88
                return false;
 
89
        }
 
90
        //There could be a contact between to connections. Check this now.
 
91
        bool isNew = !c->geom;
 
92
        Real k,m;
 
93
        Vector3r A=stNode11->pos, a=stNode12->pos-A; //"A" is an extremity of conn1, "a" is the connection's segment.
 
94
        Vector3r B=stNode21->pos, b=stNode22->pos-B; //"B" is an extremity of conn2, "b" is the connection's segment.
 
95
        B+=shift2;//periodicity.
 
96
        Vector3r N=a.cross(b);  //"N" is orthogonal to "a" and "b". It means that "N" describes the common plan between a and b.
 
97
        if(N.norm()>1e-14){     //If "a" and "b" are colinear, "N==0" and this is a special case.
 
98
                Real dist=N.dot(B-A)/(N.norm());        //here "dist" is oriented, so it's sign depends on the orientation of "N" against "AB".
 
99
                Vector3r pB=B-dist*(N/(N.norm()));      //"pB" is the projection of the point "B" in the plane defined by his normal vector "N".
 
100
                //Now we have pB, so we will compute the intersection of two segments into a plane.
 
101
                int b0, b1; //2 base vectors used to compute the segment intersection. For more accuracy and to avoid det==0, don't choose the axis where N is max.
 
102
                if(abs(N[0])<abs(N[1]) || abs(N[0])<abs(N[2])){b0=0 ; b1=abs(N[1])<abs(N[2])?1:2;}
 
103
                else { b0=1;b1=2;}
 
104
                Real det=a[b0]*b[b1]-a[b1]*b[b0];
 
105
                if (abs(det)>1e-14){
 
106
                        //Now compute k and m, who are the parameters (relative position on the connections) of the intersection on conn1 ("A" and "a") and conn2 ("B" and "b") respectively.
 
107
                        k = (b[b1]*(pB[b0]-A[b0])+b[b0]*(A[b1]-pB[b1]))/det;
 
108
                        m = (a[b0]*(-pB[b1]+A[b1])+a[b1]*(pB[b0]-A[b0]))/det;
 
109
                        //This is a little bit tricky : if we haven't 0<k,m<1, it means that the intersection is not inside both segments,
 
110
                        //but the contact can occurs anyway between a connection's extremity and a connection's edge or between two connection's extremity.
 
111
                        //So the three next lines : don't modify k and m if (0<k,m<1), but modify them otherwise to compute later the right normal and penetrationDepth of the contact.
 
112
                        k = max(min( k,(Real)1.0),(Real)0.0);
 
113
                        m = max(min( (A+a*k-B).dot(b)/(pow(b.norm(),2.0)) ,(Real)1.0),(Real)0.0);
 
114
                        k = max(min( (B+b*m-A).dot(a)/(pow(a.norm(),2.0)) ,(Real)1.0),(Real)0.0);
 
115
                }
 
116
                else {//should never happen
 
117
                        k=0;m=0;
 
118
                        cout<<"Error in Ig2_GridConnection_GridConnection_GridCoGridCoGeom : det=="<<det<<endl;
 
119
                        cout<<"Details : N="<<N<<" b0="<<b0<<" b1="<<b1<<"  a="<<a<<" b="<<b<<endl;
 
120
                }
 
121
        }
 
122
        else{ //this is a special case for perfectly colinear vectors ("a" and "b")
 
123
                Real PA=(A-B).dot(b)/(b.norm()*b.norm()); PA=min((Real)1.0,max((Real)0.0,PA));
 
124
                Real Pa=(A+a-B).dot(b)/(b.norm()*b.norm()); Pa=min((Real)1.0,max((Real)0.0,Pa));
 
125
                Real PB=(B-A).dot(a)/(a.norm()*a.norm()); PB=min((Real)1.0,max((Real)0.0,PB));
 
126
                Real Pb=(B+b-A).dot(a)/(a.norm()*a.norm()); Pb=min((Real)1.0,max((Real)0.0,Pb));
 
127
                k=(PB+Pb)/2. ; m=(PA+Pa)/2.;
 
128
        }
 
129
        
 
130
        //Compute the geometry if "penetrationDepth" is positive.
 
131
        double penetrationDepth = conn1->radius + conn2->radius - (A+k*a - (B+m*b)).norm();
 
132
        shared_ptr<GridCoGridCoGeom> scm;
 
133
        if(isNew){
 
134
                if(penetrationDepth<0)return false;
 
135
                scm=shared_ptr<GridCoGridCoGeom>(new GridCoGridCoGeom());
 
136
                c->geom=scm;
 
137
        }
 
138
        else scm=YADE_PTR_CAST<GridCoGridCoGeom>(c->geom);
 
139
        //k and m are used to compute almost everything...
 
140
        //Fictious states (spheres) are generated at k or m of each connection, they will handle the contact.
 
141
        scm->relPos1=k ; scm->relPos2=m;
 
142
        scm->fictiousState1.pos=A + k*a ; scm->fictiousState2.pos=B + m*b;
 
143
        scm->radius1 = conn1->radius ; scm->radius2 = conn2->radius;
 
144
        scm->fictiousState1.vel = (1-k)*stNode11->vel + k*stNode12->vel;
 
145
        scm->fictiousState2.vel = (1-m)*stNode21->vel + m*stNode22->vel;
 
146
        Vector3r direction = a/(a.norm());
 
147
        scm->fictiousState1.angVel = ((1-k)*stNode11->angVel + k*stNode12->angVel).dot(direction)*direction //twist part : interpolated
 
148
        + a.cross(stNode12->vel - stNode11->vel);// non-twist part : defined from nodes velocities
 
149
        direction = b/(b.norm());
 
150
        scm->fictiousState2.angVel = ((1-m)*stNode21->angVel + m*stNode22->angVel).dot(direction)*direction //twist part : interpolated
 
151
        + b.cross(stNode22->vel - stNode21->vel);// non-twist part : defined from nodes velocities
 
152
        Vector3r normal= scm->fictiousState2.pos - scm->fictiousState1.pos;
 
153
        normal/=normal.norm();
 
154
        scm->contactPoint = scm->fictiousState1.pos + (scm->radius1-0.5*penetrationDepth)*normal;
 
155
        scm->penetrationDepth=penetrationDepth;
 
156
        scm->precompute(scm->fictiousState1,scm->fictiousState2,scene,c,normal,isNew,shift2,true);
 
157
        return true;
 
158
}
 
159
 
 
160
bool Ig2_GridConnection_GridConnection_GridCoGridCoGeom::goReverse( const shared_ptr<Shape>& cm1, const shared_ptr<Shape>& cm2, const State& state1, const State& state2, const Vector3r& shift2, const bool& force, const shared_ptr<Interaction>& c)
 
161
{
 
162
        return go(cm1,cm2,state2,state1,-shift2,force,c);
 
163
}
 
164
YADE_PLUGIN((Ig2_GridConnection_GridConnection_GridCoGridCoGeom));
72
165
 
73
166
//!                     O/
74
167
bool Ig2_Sphere_GridConnection_ScGridCoGeom::go(        const shared_ptr<Shape>& cm1,
403
496
}
404
497
YADE_PLUGIN((Law2_ScGridCoGeom_CohFrictPhys_CundallStrack));
405
498
 
 
499
void Law2_GridCoGridCoGeom_FrictPhys_CundallStrack::go(shared_ptr<IGeom>& ig, shared_ptr<IPhys>& ip, Interaction* contact){
 
500
        int id1 = contact->getId1(), id2 = contact->getId2();
 
501
        id_t id11 = (static_cast<GridConnection*>((&Body::byId(id1)->shape)->get()))->node1->getId();
 
502
        id_t id12 = (static_cast<GridConnection*>((&Body::byId(id1)->shape)->get()))->node2->getId();
 
503
        id_t id21 = (static_cast<GridConnection*>((&Body::byId(id2)->shape)->get()))->node1->getId();
 
504
        id_t id22 = (static_cast<GridConnection*>((&Body::byId(id2)->shape)->get()))->node2->getId();
 
505
        GridCoGridCoGeom*    geom= static_cast<GridCoGridCoGeom*>(ig.get());
 
506
        FrictPhys* phys = static_cast<FrictPhys*>(ip.get());
 
507
        if(geom->penetrationDepth <0){
 
508
                if (neverErase) {
 
509
                        phys->shearForce = Vector3r::Zero();
 
510
                        phys->normalForce = Vector3r::Zero();}
 
511
                else    scene->interactions->requestErase(contact);
 
512
                return;}
 
513
        Real& un=geom->penetrationDepth;
 
514
        phys->normalForce=phys->kn*std::max(un,(Real) 0)*geom->normal;
 
515
 
 
516
        Vector3r& shearForce = geom->rotate(phys->shearForce);
 
517
        const Vector3r& shearDisp = geom->shearIncrement();
 
518
        shearForce -= phys->ks*shearDisp;
 
519
        Real maxFs = phys->normalForce.squaredNorm()*std::pow(phys->tangensOfFrictionAngle,2);
 
520
 
 
521
        if (!scene->trackEnergy  && !traceEnergy){//Update force but don't compute energy terms (see below))
 
522
                // PFC3d SlipModel, is using friction angle. CoulombCriterion
 
523
                if( shearForce.squaredNorm() > maxFs ){
 
524
                        Real ratio = sqrt(maxFs) / shearForce.norm();
 
525
                        shearForce *= ratio;}
 
526
        } else {
 
527
                //almost the same with additional Vector3r instatinated for energy tracing, 
 
528
                //duplicated block to make sure there is no cost for the instanciation of the vector when traceEnergy==false
 
529
                if(shearForce.squaredNorm() > maxFs){
 
530
                        Real ratio = sqrt(maxFs) / shearForce.norm();
 
531
                        Vector3r trialForce=shearForce;//store prev force for definition of plastic slip
 
532
                        //define the plastic work input and increment the total plastic energy dissipated
 
533
                        shearForce *= ratio;
 
534
                        Real dissip=((1/phys->ks)*(trialForce-shearForce))/*plastic disp*/ .dot(shearForce)/*active force*/;
 
535
                        if (traceEnergy) plasticDissipation += dissip;
 
536
                        else if(dissip>0) scene->energy->add(dissip,"plastDissip",plastDissipIx,/*reset*/false);
 
537
                }
 
538
                // compute elastic energy as well
 
539
                scene->energy->add(0.5*(phys->normalForce.squaredNorm()/phys->kn+phys->shearForce.squaredNorm()/phys->ks),"elastPotential",elastPotentialIx,/*reset at every timestep*/true);
 
540
        }
 
541
        Vector3r force = -phys->normalForce-shearForce;
 
542
        Vector3r torque1 = (geom->radius1-0.5*geom->penetrationDepth)* geom->normal.cross(force);
 
543
        Vector3r torque2 = (geom->radius2-0.5*geom->penetrationDepth)* geom->normal.cross(force);
 
544
        
 
545
        scene->forces.addForce(id11,(1-geom->relPos1)*force);
 
546
        scene->forces.addForce(id12,geom->relPos1*force);
 
547
        scene->forces.addForce(id21,-(1-geom->relPos2)*force);
 
548
        scene->forces.addForce(id22,-geom->relPos2*force);
 
549
        
 
550
        scene->forces.addTorque(id11,(1-geom->relPos1)*torque1);
 
551
        scene->forces.addTorque(id12,geom->relPos1*torque1);
 
552
        scene->forces.addTorque(id21,(1-geom->relPos2)*torque2);
 
553
        scene->forces.addTorque(id22,geom->relPos2*torque2);
 
554
}
 
555
YADE_PLUGIN((Law2_GridCoGridCoGeom_FrictPhys_CundallStrack));
406
556
//!##################   Bounds   #####################
407
557
 
408
558
void Bo1_GridConnection_Aabb::go(const shared_ptr<Shape>& cm, shared_ptr<Bound>& bv, const Se3r& se3, const Body* b){