Statistiques
| Révision :

root / AFM / AFM.cpp @ 1

Historique | Voir | Annoter | Télécharger (10,4 ko)

1 1 rmalgat
#include <sofa/simulation/graph/DAGSimulation.h>
2 1 rmalgat
#include <plugins/SofaPython/SceneLoaderPY.h>
3 1 rmalgat
#include <sofa/helper/system/PluginManager.h>
4 1 rmalgat
#include <sofa/defaulttype/Mat.h>
5 1 rmalgat
#include <SofaBaseLinearSolver/FullVector.h>
6 1 rmalgat
#include <sofa/simulation/common/MechanicalVisitor.h>
7 1 rmalgat
#include <SofaComponentMain/init.h>
8 1 rmalgat
#include <../MyDefaultContactManager.h>
9 1 rmalgat
#include <sofa/core/objectmodel/BaseObject.h>
10 1 rmalgat
#include <SofaBoundaryCondition/ConstantForceField.h>
11 1 rmalgat
#include <sofa/simulation/common/FindByTypeVisitor.h>
12 1 rmalgat
#include <SofaBaseMechanics/MechanicalObject.h>
13 1 rmalgat
#include <sofa/helper/accessor.h>
14 1 rmalgat
#include <sofa/defaulttype/DataTypeInfo.h>
15 1 rmalgat
#include <SofaBoundaryCondition/ProjectToLineConstraint.h>
16 1 rmalgat
#include <cmath>
17 1 rmalgat
#include <cstdlib>
18 1 rmalgat
#include <fstream>
19 1 rmalgat
#include <vector>
20 1 rmalgat
21 1 rmalgat
using namespace sofa;
22 1 rmalgat
using namespace simulation;
23 1 rmalgat
24 1 rmalgat
typedef sofa::component::linearsolver::FullVector<double> FullVector;
25 1 rmalgat
typedef defaulttype::Vec3dTypes::Deriv Deriv;
26 1 rmalgat
typedef defaulttype::Vec3d myVec3d;
27 1 rmalgat
28 1 rmalgat
 /// return the maximum difference between corresponding entries, or the infinity if the vectors have different sizes
29 1 rmalgat
template< typename Vector1, typename Vector2>
30 1 rmalgat
static double vectorCompare( const Vector1& m1, const Vector2& m2 )
31 1 rmalgat
{
32 1 rmalgat
    if( m1.size()!=m2.size() ) {
33 1 rmalgat
         printf("Comparison between vectors of different sizes\n");
34 1 rmalgat
                 std::fflush(stdout);
35 1 rmalgat
        return std::numeric_limits<double>::infinity();
36 1 rmalgat
        }
37 1 rmalgat
    double result = 0;
38 1 rmalgat
    for( unsigned i=0; i<m1.size(); i++ ){
39 1 rmalgat
        double diff = fabs(m1.element(i)-m2.element(i));
40 1 rmalgat
        if( diff>result  ) result=diff;
41 1 rmalgat
    }
42 1 rmalgat
    return result;
43 1 rmalgat
}
44 1 rmalgat
45 1 rmalgat
 /** fill the vector with the positions.
46 1 rmalgat
      @param x the position vector
47 1 rmalgat
      */
48 1 rmalgat
void getAssembledPositionVector( FullVector* x, unsigned xSize,
49 1 rmalgat
    std::vector<component::container::MechanicalObject<defaulttype::Vec3dTypes> *> DOFs )
50 1 rmalgat
{
51 1 rmalgat
    x->resize(xSize);
52 1 rmalgat
        unsigned offset = 0;
53 1 rmalgat
54 1 rmalgat
        for (unsigned i = 0; i < DOFs.size(); i++){
55 1 rmalgat
        helper::ReadAccessor< Data<defaulttype::Vec3dTypes::VecCoord> > vSrc =  DOFs[i]->readPositions();
56 1 rmalgat
57 1 rmalgat
                for (unsigned j=0; j < vSrc.size(); j++){
58 1 rmalgat
                        double tmp = 0.0;
59 1 rmalgat
            tmp = vSrc[j][0];
60 1 rmalgat
            //            defaulttype::Vec3dTypes::Coord getValue(vSrc[j], 0, tmp);
61 1 rmalgat
            x->set(offset + 3*j,tmp);
62 1 rmalgat
           // DataTypeInfo<defaulttype::Vec3dTypes::Coord>::getValue(vSrc[j], 1, tmp);
63 1 rmalgat
            tmp = vSrc[j][1];
64 1 rmalgat
            x->set(offset + 3*j+1,tmp);
65 1 rmalgat
            //DataTypeInfo<defaulttype::Vec3dTypes::Coord>::getValue(vSrc[j], 2, tmp);
66 1 rmalgat
            tmp = vSrc[j][2];
67 1 rmalgat
            x->set(offset + 3*j+2,tmp);
68 1 rmalgat
                }
69 1 rmalgat
                offset += DOFs[i]->getSize() * 3;
70 1 rmalgat
        }
71 1 rmalgat
}
72 1 rmalgat
73 1 rmalgat
    /** fill the vector with the velocities.
74 1 rmalgat
      @param v the velocity vector
75 1 rmalgat
      */
76 1 rmalgat
void getAssembledVelocityVector( FullVector* v, unsigned vSize,
77 1 rmalgat
    std::vector<component::container::MechanicalObject<defaulttype::Vec3dTypes> *> DOFs )
78 1 rmalgat
{
79 1 rmalgat
    v->resize(vSize);
80 1 rmalgat
        unsigned offset = 0;
81 1 rmalgat
82 1 rmalgat
        for (unsigned i = 0; i < DOFs.size(); i++){
83 1 rmalgat
        helper::ReadAccessor< Data<defaulttype::Vec3dTypes::VecDeriv> > vSrc =  DOFs[i]->readVelocities();
84 1 rmalgat
                for (unsigned j=0; j < vSrc.size(); j++){
85 1 rmalgat
                        double tmp = 0.0;
86 1 rmalgat
            //DataTypeInfo<defaulttype::Vec3dTypes::Deriv>::getValue(vSrc[j], 0, tmp);
87 1 rmalgat
            tmp = vSrc[j][0];
88 1 rmalgat
            v->set(offset + 3*j,tmp);
89 1 rmalgat
            //DataTypeInfo<defaulttype::Vec3dTypes::Deriv>::getValue(vSrc[j], 1, tmp);
90 1 rmalgat
            tmp = vSrc[j][1];
91 1 rmalgat
            v->set(offset + 3*j+1,tmp);
92 1 rmalgat
            //DataTypeInfo<defaulttype::Vec3dTypes::Deriv>::getValue(vSrc[j], 2, tmp);
93 1 rmalgat
            tmp = vSrc[j][2];
94 1 rmalgat
            v->set(offset + 3*j+2,tmp);
95 1 rmalgat
                }
96 1 rmalgat
                offset += DOFs[i]->getSize() * 3;
97 1 rmalgat
        }
98 1 rmalgat
99 1 rmalgat
}
100 1 rmalgat
101 1 rmalgat
102 1 rmalgat
int main()
103 1 rmalgat
{
104 1 rmalgat
    //the file in which the resulting curve will be put
105 1 rmalgat
    std::ofstream fileResult("./AFM-results.txt");
106 1 rmalgat
    fileResult << "### first the force then the depth ###\n\n" ;
107 1 rmalgat
108 1 rmalgat
        //load the required plugins
109 1 rmalgat
    std::string pluginPath = "Flexible";
110 1 rmalgat
    std::string pluginPath1 = "AFM_plane";
111 1 rmalgat
112 1 rmalgat
    sofa::helper::system::PluginRepository.addLastPath("../../../../build_release/lib/");
113 1 rmalgat
    if (sofa::helper::system::PluginManager::getInstance().loadPlugin(pluginPath) &&
114 1 rmalgat
            sofa::helper::system::PluginManager::getInstance().loadPlugin(pluginPath1))
115 1 rmalgat
        sofa::helper::system::PluginManager::getInstance().init();
116 1 rmalgat
117 1 rmalgat
118 1 rmalgat
119 1 rmalgat
        unsigned xsize; ///< size of assembled position vector,
120 1 rmalgat
    unsigned vsize; ///< size of assembled velocity vector,
121 1 rmalgat
122 1 rmalgat
123 1 rmalgat
    // loading the scene which is in the file examples/AFM-plane.py
124 1 rmalgat
        setSimulation(new simulation::graph::DAGSimulation());
125 1 rmalgat
    sofa::component::init();
126 1 rmalgat
    Node::SPtr root = getSimulation()->createNewGraph("root");
127 1 rmalgat
128 1 rmalgat
        SceneLoaderPY LoaderPy;
129 1 rmalgat
    root = LoaderPy.load("./AFM-plane.py");
130 1 rmalgat
        getSimulation()->init(root.get());
131 1 rmalgat
132 1 rmalgat
        //we take the direction of the force
133 1 rmalgat
    sofa::component::forcefield::ConstantForceField<defaulttype::Vec3dTypes>::SPtr CFF;
134 1 rmalgat
        root->getContext()->get(CFF, sofa::core::objectmodel::BaseContext::SearchRoot);
135 1 rmalgat
136 1 rmalgat
        Deriv forceInit = CFF->force.getValue();
137 1 rmalgat
138 1 rmalgat
        Deriv forceActu;
139 1 rmalgat
        forceActu[0] = 0;
140 1 rmalgat
        forceActu[1] = 0;
141 1 rmalgat
        forceActu[2] = 0;
142 1 rmalgat
        CFF->force = forceActu;
143 1 rmalgat
144 1 rmalgat
145 1 rmalgat
        // first find the size of the DOFs
146 1 rmalgat
        core::ExecParams* params = core::ExecParams::defaultInstance();
147 1 rmalgat
    FindByTypeVisitor<component::container::MechanicalObject<defaulttype::Vec3dTypes> > FBTVisitor(params);
148 1 rmalgat
        root->execute(FBTVisitor);
149 1 rmalgat
150 1 rmalgat
    std::vector<component::container::MechanicalObject<defaulttype::Vec3dTypes> *> allPoints;
151 1 rmalgat
        allPoints = FBTVisitor.found;
152 1 rmalgat
153 1 rmalgat
    std::vector<component::container::MechanicalObject<defaulttype::Vec3dTypes> *> DOFs, mObject;
154 1 rmalgat
        for (unsigned i=0; i<allPoints.size();i++)
155 1 rmalgat
        if (allPoints[i]->getName() == "DOFs" || allPoints[i]->getName() == "indentor" )
156 1 rmalgat
                        DOFs.push_back(allPoints[i]);
157 1 rmalgat
158 1 rmalgat
        for (unsigned i=0; i<allPoints.size();i++)
159 1 rmalgat
                if (allPoints[i]->getName() == "DOFs")
160 1 rmalgat
                        mObject.push_back(allPoints[i]);
161 1 rmalgat
162 1 rmalgat
        unsigned xInitSize = mObject[0]->getSize();
163 1 rmalgat
164 1 rmalgat
        xsize = DOFs[0]->getSize() * DOFs[0]->getCoordDimension() +  DOFs[1]->getSize() * DOFs[1]->getCoordDimension();
165 1 rmalgat
        vsize = DOFs[0]->getMatrixSize() + DOFs[1]->getMatrixSize();
166 1 rmalgat
167 1 rmalgat
        FullVector x0, x1, v0, v1, xinit, xend;
168 1 rmalgat
    getAssembledPositionVector(&x0, xsize, DOFs); // cerr<<"My_test, initial positions : " << x0 << endl;
169 1 rmalgat
    getAssembledVelocityVector(&v0, vsize, DOFs); // cerr<<"My_test, initial velocities: " << v0 << endl;
170 1 rmalgat
171 1 rmalgat
    double dx, dv;
172 1 rmalgat
    unsigned n=0;
173 1 rmalgat
    const double  precision = 1.e-4;
174 1 rmalgat
        unsigned const nmax = 1000;
175 1 rmalgat
    // first loop to stabilize the plane growth under pressure
176 1 rmalgat
177 1 rmalgat
    do {
178 1 rmalgat
        getSimulation()->animate(root.get(),0.01);
179 1 rmalgat
180 1 rmalgat
        getAssembledPositionVector(&x1, xsize, DOFs); // cerr<<"My_test, new positions : " << x1 << endl;
181 1 rmalgat
        getAssembledVelocityVector(&v1, vsize, DOFs); // cerr<<"My_test, new velocities: " << v1 << endl;
182 1 rmalgat
183 1 rmalgat
        dx = vectorCompare(x0,x1);
184 1 rmalgat
        dv = vectorCompare(v0,v1);
185 1 rmalgat
        x0 = x1;
186 1 rmalgat
        v0 = v1;
187 1 rmalgat
        n++;
188 1 rmalgat
189 1 rmalgat
        } while((dx>precision || dv>precision) && n < nmax);           //
190 1 rmalgat
191 1 rmalgat
    printf("\n %i iterations to stabilize the plane \n",n);
192 1 rmalgat
        std::fflush(stdout);
193 1 rmalgat
194 1 rmalgat
        getAssembledPositionVector(&xinit, xInitSize*3, mObject);
195 1 rmalgat
196 1 rmalgat
        //second loop : to detect a collision
197 1 rmalgat
198 1 rmalgat
        //we place the indentor first and calculate the force
199 1 rmalgat
        forceInit[0] = 0;
200 1 rmalgat
        forceInit[1] = 0;
201 1 rmalgat
    forceInit[2] = -0.1;
202 1 rmalgat
203 1 rmalgat
204 1 rmalgat
205 1 rmalgat
        //we put the position of indentor
206 1 rmalgat
    component::container::MechanicalObject<defaulttype::Vec3dTypes> *indentor = NULL ;
207 1 rmalgat
        if (DOFs[0]->getName()=="DOFs")
208 1 rmalgat
                indentor = DOFs[1];
209 1 rmalgat
        else indentor = DOFs[0];
210 1 rmalgat
211 1 rmalgat
        helper::vector<double> centerPos;
212 1 rmalgat
213 1 rmalgat
    centerPos.push_back(0.5);
214 1 rmalgat
    centerPos.push_back(0.5);
215 1 rmalgat
    centerPos.push_back(2);
216 1 rmalgat
217 1 rmalgat
        indentor->forcePointPosition(0,centerPos);
218 1 rmalgat
219 1 rmalgat
        myVec3d indentPos;
220 1 rmalgat
        myVec3d indentForce;
221 1 rmalgat
    indentPos.set(0.5 ,0.5, 2);
222 1 rmalgat
    indentForce.set(0,0,1);
223 1 rmalgat
224 1 rmalgat
    component::projectiveconstraintset::ProjectToLineConstraint<defaulttype::Vec3dTypes>::SPtr constraint;
225 1 rmalgat
        root->getContext()->get(constraint, sofa::core::objectmodel::BaseContext::SearchRoot);
226 1 rmalgat
        constraint->f_origin.setValue(indentPos);
227 1 rmalgat
        constraint->f_direction.setValue(indentForce);
228 1 rmalgat
229 1 rmalgat
    forceActu[2] = -0.1;
230 1 rmalgat
231 1 rmalgat
        CFF->force = forceActu;
232 1 rmalgat
233 1 rmalgat
        component::collision::MyDefaultContactManager::SPtr MDCM;
234 1 rmalgat
        root->getContext()->get(MDCM, sofa::core::objectmodel::BaseContext::SearchRoot);
235 1 rmalgat
        while (!MDCM->CollisionDetected())
236 1 rmalgat
        {
237 1 rmalgat
                getSimulation()->animate(root.get(),0.01);
238 1 rmalgat
                root->getContext()->get(MDCM, sofa::core::objectmodel::BaseContext::SearchRoot);
239 1 rmalgat
        }
240 1 rmalgat
241 1 rmalgat
242 1 rmalgat
        //third loop : until the end we increment the force
243 1 rmalgat
        n = 0;
244 1 rmalgat
        unsigned compteur = 0;
245 1 rmalgat
246 1 rmalgat
        getAssembledPositionVector(&x0, xsize, DOFs); // cerr<<"My_test, initial positions : " << x0 << endl;
247 1 rmalgat
    getAssembledVelocityVector(&v0, vsize, DOFs); // cerr<<"My_test, initial velocities: " << v0 << endl;
248 1 rmalgat
249 1 rmalgat
250 1 rmalgat
    while (forceActu.norm() < 150 &&  MDCM->getDepth() < 0.15 ){
251 1 rmalgat
                n = 0;
252 1 rmalgat
                fileResult << forceActu.norm() <<" " ;
253 1 rmalgat
                printf("new force %f : ",forceActu.norm());
254 1 rmalgat
                std::fflush(stdout);
255 1 rmalgat
256 1 rmalgat
                do {
257 1 rmalgat
                        getSimulation()->animate(root.get(),0.01);
258 1 rmalgat
259 1 rmalgat
                getAssembledPositionVector(&x1, xsize, DOFs); // cerr<<"My_test, new positions : " << x1 << endl;
260 1 rmalgat
                    getAssembledVelocityVector(&v1, vsize, DOFs); // cerr<<"My_test, new velocities: " << v1 << endl;
261 1 rmalgat
262 1 rmalgat
                        dx = vectorCompare(x0,x1);
263 1 rmalgat
                        dv = vectorCompare(v0,v1);
264 1 rmalgat
                        x0 = x1;
265 1 rmalgat
                    v0 = v1;
266 1 rmalgat
                        n++;
267 1 rmalgat
268 1 rmalgat
                } while((dx>precision || dv>precision) && n < nmax);           //
269 1 rmalgat
270 1 rmalgat
        printf("%i iterations, depth: %f \n",n,MDCM->getDepth());
271 1 rmalgat
                std::fflush(stdout);
272 1 rmalgat
273 1 rmalgat
                compteur++;
274 1 rmalgat
                fileResult << MDCM->getDepth() << std::endl;
275 1 rmalgat
                forceActu += forceInit;
276 1 rmalgat
                CFF->force = forceActu;
277 1 rmalgat
        }
278 1 rmalgat
279 1 rmalgat
280 1 rmalgat
281 1 rmalgat
        //forth loop to decrement the force
282 1 rmalgat
283 1 rmalgat
    /*while (forceActu.norm() > 0.1){
284 1 rmalgat
                n = 0;
285 1 rmalgat
                fileResult << forceActu.norm() <<" " ;
286 1 rmalgat
                printf("new force %f : ",forceActu.norm());
287 1 rmalgat
                std::fflush(stdout);
288 1 rmalgat

289 1 rmalgat
                do {
290 1 rmalgat
                        getSimulation()->animate(root.get(),0.01);
291 1 rmalgat

292 1 rmalgat
                getAssembledPositionVector(&x1, xsize, DOFs); // cerr<<"My_test, new positions : " << x1 << endl;
293 1 rmalgat
                    getAssembledVelocityVector(&v1, vsize, DOFs); // cerr<<"My_test, new velocities: " << v1 << endl;
294 1 rmalgat

295 1 rmalgat
                        dx = vectorCompare(x0,x1);
296 1 rmalgat
                        dv = vectorCompare(v0,v1);
297 1 rmalgat
                        x0 = x1;
298 1 rmalgat
                    v0 = v1;
299 1 rmalgat
                        n++;
300 1 rmalgat

301 1 rmalgat
                } while((dx>precision || dv>precision) && n < nmax);           //
302 1 rmalgat

303 1 rmalgat
        printf("%i iterations, depth : %f \n",n,MDCM->getDepth() );
304 1 rmalgat
                std::fflush(stdout);
305 1 rmalgat

306 1 rmalgat
                compteur++;
307 1 rmalgat
                fileResult << MDCM->getDepth() << std::endl;
308 1 rmalgat
                forceActu -= forceInit;
309 1 rmalgat
                CFF->force = forceActu;
310 1 rmalgat
        }
311 1 rmalgat
        */
312 1 rmalgat
313 1 rmalgat
        return 0;
314 1 rmalgat
}