PMLStiffSpringForceField.cpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 #include "PMLStiffSpringForceField.h"
00036
00037 #include "sofa/component/MechanicalObject.h"
00038 #include "sofa/component/mass/UniformMass.h"
00039 #include "sofa/component/mass/DiagonalMass.h"
00040 #include "sofa/component/mapping/IdentityMapping.h"
00041 using namespace sofa::component::mass;
00042 using namespace sofa::component::mapping;
00043 using namespace sofa::component;
00044
00045
00046 #include <PhysicalModel.h>
00047 #include <MultiComponent.h>
00048 #include <CellProperties.h>
00049 #include <PMLTransform.h>
00050
00051 namespace sofa
00052 {
00053
00054 namespace filemanager
00055 {
00056
00057 namespace pml
00058 {
00059
00060 PMLStiffSpringForceField::PMLStiffSpringForceField(StructuralComponent* body, GNode * parent)
00061 {
00062 parentNode = parent;
00063
00064 collisionsON = body->getProperties()->getBool("collision");
00065 name = body->getProperties()->getName();
00066
00067 if(body->getProperties()->getString("mass") != "")
00068 initMass(body->getProperties()->getString("mass"));
00069
00070 if(body->getProperties()->getString("density") != "")
00071 initDensity(body->getProperties()->getString("density"));
00072
00073 ks = body->getProperties()->getDouble("stiffness");
00074 kd = body->getProperties()->getDouble("damping");
00075 solverName = body->getProperties()->getString("solver");
00076
00077
00078 createMechanicalState(body);
00079 createTopology(body);
00080 createMass(body);
00081 createVisualModel(body);
00082 createForceField();
00083 createCollisionModel();
00084 createSolver();
00085 }
00086
00087 PMLStiffSpringForceField::~PMLStiffSpringForceField()
00088 {
00089 if(mmodel) delete mmodel;
00090 if(Sforcefield) delete Sforcefield;
00091 if(tmodel) delete tmodel;
00092
00093
00094 }
00095
00096
00097 void PMLStiffSpringForceField::initMass(string m)
00098 {
00099 int pos;
00100 while(!m.empty()) {
00101 pos = m.find(' ', 0);
00102 if(pos != 0) {
00103 string s=m.substr(0,pos);
00104 SReal d=atof(s.c_str());
00105 massList.push_back(d);
00106 m.erase(0,pos);
00107 }else
00108 m.erase(0,1);
00109 }
00110 }
00111
00112 void PMLStiffSpringForceField::initDensity(string m)
00113 {
00114 int pos;
00115 while(!m.empty()) {
00116 pos = m.find(' ', 0);
00117 if(pos != 0) {
00118 string s=m.substr(0,pos);
00119 SReal d=atof(s.c_str());
00120 density.push_back(d);
00121 m.erase(0,pos);
00122 }else
00123 m.erase(0,1);
00124 }
00125 }
00126
00127
00128
00129
00130 BaseMeshTopology::Line * PMLStiffSpringForceField::hexaToLines(Cell* pCell)
00131 {
00132 BaseMeshTopology::Line *lines = new BaseMeshTopology::Line[16];
00133 Atom *pAtom;
00134 int index[8];
00135
00136 for (int i(0) ; i<8 ; i++) {
00137 pAtom = (Atom*)(pCell->getStructure(i));
00138 index[i] = AtomsToDOFsIndexes[pAtom->getIndex()];
00139 }
00140
00141 lines[0][0]=index[0]; lines[0][1]=index[1];
00142 lines[1][0]=index[1]; lines[1][1]=index[2];
00143 lines[2][0]=index[2]; lines[2][1]=index[3];
00144 lines[3][0]=index[3]; lines[3][1]=index[0];
00145 lines[4][0]=index[4]; lines[4][1]=index[5];
00146 lines[5][0]=index[5]; lines[5][1]=index[6];
00147 lines[6][0]=index[6]; lines[6][1]=index[7];
00148 lines[7][0]=index[7]; lines[7][1]=index[4];
00149 lines[8][0]=index[0]; lines[8][1]=index[4];
00150 lines[9][0]=index[1]; lines[9][1]=index[5];
00151 lines[10][0]=index[2]; lines[10][1]=index[6];
00152 lines[11][0]=index[3]; lines[11][1]=index[7];
00153 lines[12][0]=index[0]; lines[12][1]=index[6];
00154 lines[13][0]=index[1]; lines[13][1]=index[7];
00155 lines[14][0]=index[2]; lines[14][1]=index[4];
00156 lines[15][0]=index[3]; lines[15][1]=index[5];
00157
00158 return lines;
00159 }
00160
00161
00162
00163 BaseMeshTopology::Line * PMLStiffSpringForceField::tetraToLines(Cell* pCell)
00164 {
00165 BaseMeshTopology::Line *lines = new BaseMeshTopology::Line[6];
00166 Atom *pAtom;
00167 int index[8];
00168
00169 for (int i(0) ; i<4 ; i++) {
00170 pAtom = (Atom*)(pCell->getStructure(i));
00171 index[i] = AtomsToDOFsIndexes[pAtom->getIndex()];
00172 }
00173 unsigned int cpt=0;
00174 for (unsigned int l1=0 ; l1<4 ; l1++) {
00175 for (unsigned int l2=l1+1 ; l2<4 ; l2++) {
00176 lines[cpt][0] = index[l1];
00177 lines[cpt][1] = index[l2];
00178 cpt++;
00179 }
00180 }
00181
00182 return lines;
00183 }
00184
00185
00186
00187 BaseMeshTopology::Line * PMLStiffSpringForceField::triangleToLines(Cell* pCell)
00188 {
00189 BaseMeshTopology::Line *lines = new BaseMeshTopology::Line[3];
00190 Atom *pAtom;
00191 int index[3];
00192
00193 for (int i(0) ; i<3 ; i++) {
00194 pAtom = (Atom*)(pCell->getStructure(i));
00195 index[i] = AtomsToDOFsIndexes[pAtom->getIndex()];
00196 }
00197 unsigned int cpt=0;
00198 for (unsigned int l1=0 ; l1<4 ; l1++) {
00199 for (unsigned int l2=l1+1 ; l2<4 ; l2++) {
00200 lines[cpt][0] = index[l1];
00201 lines[cpt][1] = index[l2];
00202 cpt++;
00203 }
00204 }
00205 return lines;
00206 }
00207
00208
00209
00210 BaseMeshTopology::Line * PMLStiffSpringForceField::quadToLines(Cell* pCell)
00211 {
00212 BaseMeshTopology::Line *lines = new BaseMeshTopology::Line[4];
00213 Atom *pAtom;
00214 int index[4];
00215
00216 for (int i(0) ; i<4 ; i++) {
00217 pAtom = (Atom*)(pCell->getStructure(i));
00218 index[i] = AtomsToDOFsIndexes[pAtom->getIndex()];
00219 }
00220 for (unsigned int l1=0 ; l1<4 ; l1++) {
00221 lines[l1][0] = index[l1];
00222 lines[l1][1] = index[(l1+1)%4];
00223 }
00224 return lines;
00225 }
00226
00227
00228
00229
00230 Vector3 PMLStiffSpringForceField::getDOF(unsigned int index)
00231 {
00232 return (*((MechanicalState<Vec3Types>*)mmodel)->getX())[index];
00233 }
00234
00235
00236
00237 void PMLStiffSpringForceField::createMechanicalState(StructuralComponent* body)
00238 {
00239 mmodel = new MechanicalObject<Vec3Types>;
00240 StructuralComponent* atoms = body->getAtoms();
00241 mmodel->resize(atoms->getNumberOfStructures());
00242 Atom* pAtom;
00243
00244 SReal pos[3];
00245 for (unsigned int i(0) ; i<atoms->getNumberOfStructures() ; i++) {
00246 pAtom = (Atom*) (atoms->getStructure(i));
00247 pAtom->getPosition(pos);
00248 AtomsToDOFsIndexes.insert(std::pair <unsigned int, unsigned int>(pAtom->getIndex(),i));
00249 (*((MechanicalState<Vec3Types>*)mmodel)->getX())[i] = Vector3(pos[0],pos[1],pos[2]);
00250 }
00251
00252 parentNode->addObject(mmodel);
00253
00254 }
00255
00256
00257
00258
00259
00260 void PMLStiffSpringForceField::createTopology(StructuralComponent* body)
00261 {
00262 topology = new MeshTopology();
00263 ((BaseMeshTopology*)topology)->clear();
00264
00265 unsigned int p, nbCells = body->getNumberOfCells();
00266 BaseMeshTopology::Line * lines;
00267 BaseMeshTopology::Quad * quad;
00268 Cell * pCell;
00269
00270
00271 for (unsigned int cid(0) ; cid<nbCells ; cid++) {
00272 pCell = body->getCell(cid);
00273 switch(pCell->getProperties()->getType()) {
00274
00275 case StructureProperties::HEXAHEDRON :
00276 lines = hexaToLines(pCell);
00277 for (p=0 ; p<16 ; p++)
00278 ((BaseMeshTopology::SeqLines&)((BaseMeshTopology*)topology)->getLines()).push_back(lines[p]);
00279 break;
00280 case StructureProperties::TETRAHEDRON :
00281 lines = hexaToLines(pCell);
00282 for (p=0 ; p<6 ; p++)
00283 ((BaseMeshTopology::SeqLines&)((BaseMeshTopology*)topology)->getLines()).push_back(lines[p]);
00284 break;
00285 case StructureProperties::TRIANGLE :
00286 lines = triangleToLines(pCell);
00287 for (p=0 ; p<3 ; p++)
00288 ((BaseMeshTopology::SeqLines&)((BaseMeshTopology*)topology)->getLines()).push_back(lines[p]);
00289 break;
00290 case StructureProperties::QUAD :
00291 lines = quadToLines(pCell);
00292 for (p=0 ; p<4 ; p++)
00293 ((BaseMeshTopology::SeqLines&)((BaseMeshTopology*)topology)->getLines()).push_back(lines[p]);
00294 quad = new BaseMeshTopology::Quad;
00295 for (p=0 ; p<4 ; p++)
00296 (*quad)[p] = AtomsToDOFsIndexes[pCell->getStructure(p)->getIndex()];
00297 ((BaseMeshTopology::SeqQuads&)((BaseMeshTopology*)topology)->getQuads()).push_back(*quad);
00298 break;
00299 case StructureProperties::LINE :
00300 lines = new BaseMeshTopology::Line;
00301 (*lines)[0] = AtomsToDOFsIndexes[pCell->getStructure(0)->getIndex()];
00302 (*lines)[1] = AtomsToDOFsIndexes[pCell->getStructure(1)->getIndex()];
00303 ((BaseMeshTopology::SeqLines&)((BaseMeshTopology*)topology)->getLines()).push_back(*lines);
00304 break;
00305
00306 default : break;
00307 }
00308 }
00309
00310
00311 std::vector<BaseMeshTopology::Line>::iterator it1 = ((BaseMeshTopology::SeqLines&)((BaseMeshTopology*)topology)->getLines()).begin();
00312 std::vector<BaseMeshTopology::Line>::iterator it2, tmp;
00313
00314 while(it1 != ((BaseMeshTopology::SeqLines&)((BaseMeshTopology*)topology)->getLines()).end() )
00315 {
00316 it2=it1;
00317 it2++;
00318 while(it2 != ((BaseMeshTopology::SeqLines&)((BaseMeshTopology*)topology)->getLines()).end() )
00319 {
00320 if ( ((*it1)[0] == (*it2)[0] && (*it1)[1] == (*it2)[1]) || ((*it1)[0] == (*it2)[1] && (*it1)[1] == (*it2)[0]) ) {
00321 tmp = it2;
00322 tmp--;
00323 ((BaseMeshTopology::SeqLines&)((BaseMeshTopology*)topology)->getLines()).erase(it2);
00324 it2=tmp;
00325 }
00326
00327 it2++;
00328 }
00329 it1++;
00330 }
00331
00332 parentNode->addObject(topology);
00333 }
00334
00335
00336
00337
00338 void PMLStiffSpringForceField::createMass(StructuralComponent* body)
00339 {
00340
00341 if (massList.size() == 0) {
00342
00343 if (density.size() != 0) {
00344
00345 if (density.size() > 1 && density.size() != ((MechanicalState<Vec3Types>*)mmodel)->getX()->size()) {
00346 cerr<<"WARNING building "<<name<<" object : density property not properly defined."<<endl;
00347 return;
00348 }
00349 else {
00350
00351 for (unsigned int i=0 ; i<((MechanicalState<Vec3Types>*)mmodel)->getX()->size() ; i++)
00352 massList.push_back(0.0);
00353
00354 SReal m;
00355 Cell * pCell;
00356 Atom * pAtom;
00357
00358
00359 for (unsigned int cid(0) ; cid<body->getNumberOfCells(); cid++) {
00360 pCell = body->getCell(cid);
00361 SReal volumeCell = pCell->volume();
00362 for (unsigned int j(0) ; j< pCell->getNumberOfStructures() ; j++) {
00363 pAtom = (Atom*)(pCell->getStructure(j));
00364 SReal dens = density.size()>1?density[AtomsToDOFsIndexes[pAtom->getIndex()]]:density[0];
00365
00366 m = dens * volumeCell / pCell->getNumberOfStructures();
00367 massList[AtomsToDOFsIndexes[pAtom->getIndex()]] += m;
00368 }
00369 }
00370 mass = new DiagonalMass<Vec3Types,SReal>;
00371 for (unsigned int im=0 ; im<massList.size() ; im++) {
00372 ((DiagonalMass<Vec3Types,SReal>*)mass)->addMass( massList[im] );
00373 }
00374 }
00375 }
00376 }
00377 else {
00378
00379 if (massList.size() == 1){
00380 mass = new UniformMass<Vec3Types,SReal>;
00381 ((UniformMass<Vec3Types,SReal>*)mass)->setMass( massList[0] );
00382 }
00383 else {
00384
00385 if (massList.size() == ((MechanicalState<Vec3Types>*)mmodel)->getX()->size()) {
00386 mass = new DiagonalMass<Vec3Types,SReal>;
00387 for (unsigned int i=0 ; i<massList.size() ; i++) {
00388 ((DiagonalMass<Vec3Types,SReal>*)mass)->addMass( massList[i] );
00389 }
00390 }
00391 else
00392 cerr<<"WARNING building "<<name<<" object : mass property not properly defined."<<endl;
00393 }
00394 }
00395 if (mass)
00396 parentNode->addObject(mass);
00397 }
00398
00399
00400 void PMLStiffSpringForceField::createVisualModel(StructuralComponent* body)
00401 {
00402
00403 MultiComponent * mc = PMLTransform::generateExternalSurface(body);
00404 StructuralComponent * extFacets = (StructuralComponent*) mc->getSubComponent(0);
00405
00406 if (!topology)
00407 topology = new MeshTopology();
00408
00409 Cell * pCell;
00410 Atom * pAtom;
00411 BaseMeshTopology::Quad * quad;
00412 BaseMeshTopology::Triangle * triangle;
00413
00414 for (unsigned int i=0 ; i< extFacets->getNumberOfStructures() ; i++)
00415 {
00416 pCell = extFacets->getCell(i);
00417 switch(pCell->getProperties()->getType())
00418 {
00419 case StructureProperties::QUAD :
00420 quad = new BaseMeshTopology::Quad;
00421 for (unsigned int j(0) ; j<4 ; j++) {
00422 pAtom = (Atom*)(pCell->getStructure(j));
00423 (*quad)[j] = AtomsToDOFsIndexes[pAtom->getIndex()];
00424 }
00425 ((BaseMeshTopology::SeqQuads&)((BaseMeshTopology*)topology)->getQuads()).push_back(*quad);
00426 break;
00427
00428 case StructureProperties::TRIANGLE :
00429 triangle = new BaseMeshTopology::Triangle;
00430 for (unsigned int j(0) ; j<3 ; j++) {
00431 pAtom = (Atom*)(pCell->getStructure(j));
00432 (*triangle)[j] = AtomsToDOFsIndexes[pAtom->getIndex()];
00433 }
00434 ((BaseMeshTopology::SeqTriangles&)((BaseMeshTopology*)topology)->getTriangles()).push_back(*triangle);
00435 break;
00436
00437 default : break;
00438 }
00439 }
00440
00441
00442 OglModel * vmodel = new OglModel;
00443
00444 double * color = body->getColor();
00445 vmodel->setColor((float)color[0], (float)color[1], (float)color[2], (float)color[3]);
00446 vmodel->load("","","");
00447 BaseMapping * mapping = new IdentityMapping< Mapping< State<Vec3Types>, MappedModel< ExtVectorTypes< Vec<3,GLfloat>, Vec<3,GLfloat> > > > >((MechanicalState<Vec3Types>*)mmodel, vmodel);
00448 parentNode->addObject(mapping);
00449 parentNode->addObject(vmodel);
00450
00451 }
00452
00453
00454
00455 void PMLStiffSpringForceField::createForceField()
00456 {
00457 Sforcefield = new MeshSpringForceField<Vec3Types>;
00458 if (kd==0.0)kd=5.0;
00459 if (ks==0.0)ks=500.0;
00460 Sforcefield->setLinesDamping(kd);
00461 Sforcefield->setLinesStiffness(ks);
00462 parentNode->addObject(dynamic_cast<BaseObject*>(Sforcefield));
00463 }
00464
00465
00466 void PMLStiffSpringForceField::createCollisionModel()
00467 {
00468 if (collisionsON) {
00469 tmodel = new TriangleModel;
00470
00471
00472
00473 parentNode->addObject( tmodel);
00474
00475
00476
00477 tmodel->init();
00478
00479
00480 }
00481 }
00482
00483
00484 bool PMLStiffSpringForceField::FusionBody(PMLBody* body)
00485 {
00486 PMLStiffSpringForceField * femBody = (PMLStiffSpringForceField * )body;
00487 std::map<unsigned int, unsigned int> oldToNewIndex;
00488
00489
00490 map<unsigned int, unsigned int>::iterator it = femBody->AtomsToDOFsIndexes.begin();
00491 map<unsigned int, unsigned int>::iterator itt;
00492 unsigned int X1size = ((MechanicalState<Vec3Types>*)mmodel)->getX()->size();
00493 while (it != femBody->AtomsToDOFsIndexes.end())
00494 {
00495
00496 if ( (itt = this->AtomsToDOFsIndexes.find( (*it).first)) == this->AtomsToDOFsIndexes.end() ){
00497 int cpt = ((MechanicalState<Vec3Types>*)mmodel)->getX()->size();
00498 mmodel->resize( cpt+1);
00499 this->AtomsToDOFsIndexes.insert(std::pair<unsigned int, unsigned int>((*it).first, cpt ));
00500 oldToNewIndex.insert(std::pair<unsigned int, unsigned int>((*it).second, cpt ));
00501 (*((MechanicalState<Vec3Types>*)mmodel)->getX())[cpt] = (*((MechanicalState<Vec3Types>*)(femBody->getMechanicalState()))->getX())[(*it).second];
00502 }
00503 else
00504 oldToNewIndex.insert(std::pair<unsigned int, unsigned int>((*it).second, (*itt).second) );
00505
00506 it++;
00507 }
00508
00509
00510 BaseMeshTopology * femTopo = (BaseMeshTopology * ) (femBody->getTopology());
00511
00512
00513 for (int i=0 ; i < femTopo->getNbLines() ; i++) {
00514 BaseMeshTopology::Line line = femTopo->getLine(i);
00515 for (unsigned int j(0) ; j<2 ; j++) {
00516 line[j] = oldToNewIndex[line[j] ];
00517 }
00518 ((BaseMeshTopology::SeqLines&)((BaseMeshTopology*)topology)->getLines()).push_back(line);
00519 }
00520
00521 for (int i=0 ; i < femTopo->getNbTriangles() ; i++) {
00522 BaseMeshTopology::Triangle tri = femTopo->getTriangle(i);
00523 for (unsigned int j(0) ; j<3 ; j++) {
00524 tri[j] = oldToNewIndex[tri[j] ];
00525 }
00526 ((BaseMeshTopology::SeqTriangles&)((BaseMeshTopology*)topology)->getTriangles()).push_back(tri);
00527 }
00528
00529 for (int i=0 ; i < femTopo->getNbQuads() ; i++) {
00530 BaseMeshTopology::Quad qua = femTopo->getQuad(i);
00531 for (unsigned int j(0) ; j<4 ; j++) {
00532 qua[j] = oldToNewIndex[qua[j] ];
00533 }
00534 ((BaseMeshTopology::SeqQuads&)((BaseMeshTopology*)topology)->getQuads()).push_back(qua);
00535 }
00536
00537
00538
00539 parentNode->removeObject(mass);
00540 if (mass) delete mass;
00541 mass = new DiagonalMass<Vec3Types,SReal>;
00542 parentNode->addObject(mass);
00543 SReal m1,m2;
00544
00545 for (unsigned int i=0 ; i< ((MechanicalState<Vec3Types>*)mmodel)->getX()->size(); i++) {
00546 m1 = m2 = 0.0;
00547 if (massList.size() >0)
00548 {
00549 if (massList.size() == 1 && i < X1size)
00550 m1 = massList[0];
00551 else if (i < massList.size())
00552 m1 = massList[i];
00553 }
00554
00555 if (femBody->massList.size() >0)
00556 {
00557 if (femBody->massList.size() == 1 ) {
00558 for (unsigned int j=0 ; j<oldToNewIndex.size() ; j++)
00559 if (oldToNewIndex[j] == i)
00560 m2 = femBody->massList[0];
00561 } else {
00562 for (unsigned int j=0 ; j<oldToNewIndex.size() ; j++)
00563 if (oldToNewIndex[j] == i)
00564 m2 = femBody->massList[j];
00565 }
00566 }
00567
00568 ((DiagonalMass<Vec3Types,SReal>*)mass)->addMass( m1+m2 );
00569 cout<<"masse noeud "<<i<<" : "<<m1+m2<<endl;
00570 }
00571
00572
00573
00574 if (!collisionsON && femBody->collisionsON) {
00575 tmodel = femBody->getTriangleModel();
00576
00577
00578 }
00579
00580 return true;
00581 }
00582
00583 }
00584 }
00585 }