Statistiques
| Révision :

root / AFM / AFM.cpp @ 1

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

1
#include <sofa/simulation/graph/DAGSimulation.h>
2
#include <plugins/SofaPython/SceneLoaderPY.h>
3
#include <sofa/helper/system/PluginManager.h>
4
#include <sofa/defaulttype/Mat.h>
5
#include <SofaBaseLinearSolver/FullVector.h>
6
#include <sofa/simulation/common/MechanicalVisitor.h>
7
#include <SofaComponentMain/init.h>
8
#include <../MyDefaultContactManager.h>
9
#include <sofa/core/objectmodel/BaseObject.h>
10
#include <SofaBoundaryCondition/ConstantForceField.h>
11
#include <sofa/simulation/common/FindByTypeVisitor.h>
12
#include <SofaBaseMechanics/MechanicalObject.h>
13
#include <sofa/helper/accessor.h>
14
#include <sofa/defaulttype/DataTypeInfo.h>
15
#include <SofaBoundaryCondition/ProjectToLineConstraint.h>
16
#include <cmath>
17
#include <cstdlib>
18
#include <fstream>
19
#include <vector>
20

    
21
using namespace sofa;
22
using namespace simulation;
23

    
24
typedef sofa::component::linearsolver::FullVector<double> FullVector;
25
typedef defaulttype::Vec3dTypes::Deriv Deriv;
26
typedef defaulttype::Vec3d myVec3d;
27

    
28
 /// return the maximum difference between corresponding entries, or the infinity if the vectors have different sizes
29
template< typename Vector1, typename Vector2>
30
static double vectorCompare( const Vector1& m1, const Vector2& m2 )
31
{
32
    if( m1.size()!=m2.size() ) {
33
         printf("Comparison between vectors of different sizes\n");
34
                 std::fflush(stdout);
35
        return std::numeric_limits<double>::infinity();
36
        }
37
    double result = 0;
38
    for( unsigned i=0; i<m1.size(); i++ ){
39
        double diff = fabs(m1.element(i)-m2.element(i));
40
        if( diff>result  ) result=diff;
41
    }
42
    return result;
43
}
44

    
45
 /** fill the vector with the positions.
46
      @param x the position vector
47
      */
48
void getAssembledPositionVector( FullVector* x, unsigned xSize, 
49
    std::vector<component::container::MechanicalObject<defaulttype::Vec3dTypes> *> DOFs )
50
{
51
    x->resize(xSize);
52
        unsigned offset = 0;
53

    
54
        for (unsigned i = 0; i < DOFs.size(); i++){
55
        helper::ReadAccessor< Data<defaulttype::Vec3dTypes::VecCoord> > vSrc =  DOFs[i]->readPositions();
56

    
57
                for (unsigned j=0; j < vSrc.size(); j++){
58
                        double tmp = 0.0;
59
            tmp = vSrc[j][0];
60
            //            defaulttype::Vec3dTypes::Coord getValue(vSrc[j], 0, tmp);
61
            x->set(offset + 3*j,tmp);
62
           // DataTypeInfo<defaulttype::Vec3dTypes::Coord>::getValue(vSrc[j], 1, tmp);
63
            tmp = vSrc[j][1];
64
            x->set(offset + 3*j+1,tmp);
65
            //DataTypeInfo<defaulttype::Vec3dTypes::Coord>::getValue(vSrc[j], 2, tmp);
66
            tmp = vSrc[j][2];
67
            x->set(offset + 3*j+2,tmp);
68
                }
69
                offset += DOFs[i]->getSize() * 3;
70
        }
71
}
72

    
73
    /** fill the vector with the velocities.
74
      @param v the velocity vector
75
      */
76
void getAssembledVelocityVector( FullVector* v, unsigned vSize, 
77
    std::vector<component::container::MechanicalObject<defaulttype::Vec3dTypes> *> DOFs )
78
{
79
    v->resize(vSize);
80
        unsigned offset = 0;
81

    
82
        for (unsigned i = 0; i < DOFs.size(); i++){
83
        helper::ReadAccessor< Data<defaulttype::Vec3dTypes::VecDeriv> > vSrc =  DOFs[i]->readVelocities();
84
                for (unsigned j=0; j < vSrc.size(); j++){
85
                        double tmp = 0.0;
86
            //DataTypeInfo<defaulttype::Vec3dTypes::Deriv>::getValue(vSrc[j], 0, tmp);
87
            tmp = vSrc[j][0];
88
            v->set(offset + 3*j,tmp);
89
            //DataTypeInfo<defaulttype::Vec3dTypes::Deriv>::getValue(vSrc[j], 1, tmp);
90
            tmp = vSrc[j][1];
91
            v->set(offset + 3*j+1,tmp);
92
            //DataTypeInfo<defaulttype::Vec3dTypes::Deriv>::getValue(vSrc[j], 2, tmp);
93
            tmp = vSrc[j][2];
94
            v->set(offset + 3*j+2,tmp);
95
                }
96
                offset += DOFs[i]->getSize() * 3;
97
        }
98
        
99
}
100

    
101

    
102
int main()
103
{
104
    //the file in which the resulting curve will be put
105
    std::ofstream fileResult("./AFM-results.txt");
106
    fileResult << "### first the force then the depth ###\n\n" ;
107

    
108
        //load the required plugins
109
    std::string pluginPath = "Flexible";
110
    std::string pluginPath1 = "AFM_plane";
111

    
112
    sofa::helper::system::PluginRepository.addLastPath("../../../../build_release/lib/");
113
    if (sofa::helper::system::PluginManager::getInstance().loadPlugin(pluginPath) &&
114
            sofa::helper::system::PluginManager::getInstance().loadPlugin(pluginPath1))
115
        sofa::helper::system::PluginManager::getInstance().init();
116

    
117

    
118

    
119
        unsigned xsize; ///< size of assembled position vector, 
120
    unsigned vsize; ///< size of assembled velocity vector, 
121

    
122

    
123
    // loading the scene which is in the file examples/AFM-plane.py
124
        setSimulation(new simulation::graph::DAGSimulation());
125
    sofa::component::init();
126
    Node::SPtr root = getSimulation()->createNewGraph("root");
127

    
128
        SceneLoaderPY LoaderPy;  
129
    root = LoaderPy.load("./AFM-plane.py");
130
        getSimulation()->init(root.get());
131

    
132
        //we take the direction of the force 
133
    sofa::component::forcefield::ConstantForceField<defaulttype::Vec3dTypes>::SPtr CFF;
134
        root->getContext()->get(CFF, sofa::core::objectmodel::BaseContext::SearchRoot);
135

    
136
        Deriv forceInit = CFF->force.getValue();
137

    
138
        Deriv forceActu;
139
        forceActu[0] = 0;
140
        forceActu[1] = 0;
141
        forceActu[2] = 0;
142
        CFF->force = forceActu;
143

    
144
        
145
        // first find the size of the DOFs
146
        core::ExecParams* params = core::ExecParams::defaultInstance();
147
    FindByTypeVisitor<component::container::MechanicalObject<defaulttype::Vec3dTypes> > FBTVisitor(params);
148
        root->execute(FBTVisitor);
149
        
150
    std::vector<component::container::MechanicalObject<defaulttype::Vec3dTypes> *> allPoints;
151
        allPoints = FBTVisitor.found;
152

    
153
    std::vector<component::container::MechanicalObject<defaulttype::Vec3dTypes> *> DOFs, mObject;
154
        for (unsigned i=0; i<allPoints.size();i++)
155
        if (allPoints[i]->getName() == "DOFs" || allPoints[i]->getName() == "indentor" )
156
                        DOFs.push_back(allPoints[i]);
157

    
158
        for (unsigned i=0; i<allPoints.size();i++)
159
                if (allPoints[i]->getName() == "DOFs")
160
                        mObject.push_back(allPoints[i]);
161
        
162
        unsigned xInitSize = mObject[0]->getSize();
163

    
164
        xsize = DOFs[0]->getSize() * DOFs[0]->getCoordDimension() +  DOFs[1]->getSize() * DOFs[1]->getCoordDimension();
165
        vsize = DOFs[0]->getMatrixSize() + DOFs[1]->getMatrixSize(); 
166

    
167
        FullVector x0, x1, v0, v1, xinit, xend;
168
    getAssembledPositionVector(&x0, xsize, DOFs); // cerr<<"My_test, initial positions : " << x0 << endl;
169
    getAssembledVelocityVector(&v0, vsize, DOFs); // cerr<<"My_test, initial velocities: " << v0 << endl;
170

    
171
    double dx, dv;
172
    unsigned n=0;
173
    const double  precision = 1.e-4;
174
        unsigned const nmax = 1000;
175
    // first loop to stabilize the plane growth under pressure
176
        
177
    do {
178
        getSimulation()->animate(root.get(),0.01);
179

    
180
        getAssembledPositionVector(&x1, xsize, DOFs); // cerr<<"My_test, new positions : " << x1 << endl;
181
        getAssembledVelocityVector(&v1, vsize, DOFs); // cerr<<"My_test, new velocities: " << v1 << endl;
182

    
183
        dx = vectorCompare(x0,x1);
184
        dv = vectorCompare(v0,v1);
185
        x0 = x1;
186
        v0 = v1;
187
        n++;
188

    
189
        } while((dx>precision || dv>precision) && n < nmax);           // 
190
        
191
    printf("\n %i iterations to stabilize the plane \n",n);
192
        std::fflush(stdout);
193

    
194
        getAssembledPositionVector(&xinit, xInitSize*3, mObject);
195

    
196
        //second loop : to detect a collision
197

    
198
        //we place the indentor first and calculate the force
199
        forceInit[0] = 0;
200
        forceInit[1] = 0;
201
    forceInit[2] = -0.1;
202
        
203
        
204

    
205
        //we put the position of indentor
206
    component::container::MechanicalObject<defaulttype::Vec3dTypes> *indentor = NULL ;
207
        if (DOFs[0]->getName()=="DOFs")
208
                indentor = DOFs[1];
209
        else indentor = DOFs[0];
210

    
211
        helper::vector<double> centerPos;
212

    
213
    centerPos.push_back(0.5);
214
    centerPos.push_back(0.5);
215
    centerPos.push_back(2);
216

    
217
        indentor->forcePointPosition(0,centerPos);
218

    
219
        myVec3d indentPos;
220
        myVec3d indentForce;
221
    indentPos.set(0.5 ,0.5, 2);
222
    indentForce.set(0,0,1);
223

    
224
    component::projectiveconstraintset::ProjectToLineConstraint<defaulttype::Vec3dTypes>::SPtr constraint;
225
        root->getContext()->get(constraint, sofa::core::objectmodel::BaseContext::SearchRoot);
226
        constraint->f_origin.setValue(indentPos);
227
        constraint->f_direction.setValue(indentForce);
228

    
229
    forceActu[2] = -0.1;
230

    
231
        CFF->force = forceActu;
232

    
233
        component::collision::MyDefaultContactManager::SPtr MDCM;
234
        root->getContext()->get(MDCM, sofa::core::objectmodel::BaseContext::SearchRoot);
235
        while (!MDCM->CollisionDetected())
236
        {
237
                getSimulation()->animate(root.get(),0.01);
238
                root->getContext()->get(MDCM, sofa::core::objectmodel::BaseContext::SearchRoot);
239
        }
240

    
241
        
242
        //third loop : until the end we increment the force
243
        n = 0;
244
        unsigned compteur = 0;
245

    
246
        getAssembledPositionVector(&x0, xsize, DOFs); // cerr<<"My_test, initial positions : " << x0 << endl;
247
    getAssembledVelocityVector(&v0, vsize, DOFs); // cerr<<"My_test, initial velocities: " << v0 << endl;
248
        
249

    
250
    while (forceActu.norm() < 150 &&  MDCM->getDepth() < 0.15 ){
251
                n = 0;
252
                fileResult << forceActu.norm() <<" " ;
253
                printf("new force %f : ",forceActu.norm());
254
                std::fflush(stdout);
255
                
256
                do {
257
                        getSimulation()->animate(root.get(),0.01);
258

    
259
                getAssembledPositionVector(&x1, xsize, DOFs); // cerr<<"My_test, new positions : " << x1 << endl;
260
                    getAssembledVelocityVector(&v1, vsize, DOFs); // cerr<<"My_test, new velocities: " << v1 << endl;
261

    
262
                        dx = vectorCompare(x0,x1);
263
                        dv = vectorCompare(v0,v1);
264
                        x0 = x1;
265
                    v0 = v1;
266
                        n++;
267

    
268
                } while((dx>precision || dv>precision) && n < nmax);           // 
269
                
270
        printf("%i iterations, depth: %f \n",n,MDCM->getDepth());
271
                std::fflush(stdout);
272

    
273
                compteur++;
274
                fileResult << MDCM->getDepth() << std::endl;
275
                forceActu += forceInit;
276
                CFF->force = forceActu;
277
        }
278

    
279

    
280

    
281
        //forth loop to decrement the force 
282

    
283
    /*while (forceActu.norm() > 0.1){
284
                n = 0;
285
                fileResult << forceActu.norm() <<" " ;
286
                printf("new force %f : ",forceActu.norm());
287
                std::fflush(stdout);
288
                
289
                do {
290
                        getSimulation()->animate(root.get(),0.01);
291

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

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

301
                } while((dx>precision || dv>precision) && n < nmax);           // 
302
                
303
        printf("%i iterations, depth : %f \n",n,MDCM->getDepth() );
304
                std::fflush(stdout);
305

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

    
313
        return 0;
314
}
315