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 | } |