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
00036
00037
00038
00039
00040
00041
00042
00043 #define NEED_STAMP
00044 #define NEED_LAMMPS
00045 #define NEED_LIBMESH
00046 #define NEED_MD1D
00047 #define LOCAL_MODULE MOD_COUPLING
00048
00049 #include "../common/common.h"
00050 #include "../dumper/paraview_helper.h"
00051 #include "bridging.h"
00052
00053 #ifdef DEBUG_BRIDGE
00054 unsigned int absolute_lambdasA=0;
00055 unsigned int absolute_lambdasC=0;
00056 unsigned int absolute_positions=0;
00057 #endif
00058
00059 static std::ofstream out_contrainte("contrainte.plot");
00060
00061 template <typename DomainA, typename DomainC,unsigned int Dim,int Pond>
00062 void Bridging<DomainA,DomainC,Dim,Pond>::DumpDistance(){
00063 if (current_step %100> 0)
00064 return;
00065
00066 int taille = atomes_rec.nbElem();
00067 double xI;
00068 MechaContLibMesh<Dim> & model = static_cast<MechaContLibMesh<Dim>&>(domC.getModel());
00069 _Vec_ & v = domC.getDofs().V();
00070
00071 std::vector<unsigned int> nodesI;
00072 std::vector<double> shapesI;
00073
00074 for (int i = 0 ; i < taille ; ++i){
00075 xI = atomes_rec.Get(i).position0(0);
00076 model.GlobalIndexes(elems_rec.Get(assoc[i]),nodesI);
00077 model.ComputeShapes(elems_rec.Get(assoc[i]),shapesI,xI);
00078
00079 out_contrainte << atomes_rec.Get(i).position0(0) << "\t" << v(nodesI[0])*shapesI[0] + v(nodesI[1])*shapesI[1] - atomes_rec.Get(i).vitesse(0) << "\t";
00080 }
00081 out_contrainte << std::endl;
00082 }
00083
00084
00085 template <typename DomainA, typename DomainC,unsigned int Dim,int Pond>
00086 void Bridging<DomainA,DomainC,Dim,Pond>::SetParam(char * key,double value){
00087 if (strcmp(key,"GRID_DIVISIONX")==0){
00088 division_grille[0] = (int)value;
00089 }
00090 if (strcmp(key,"GRID_DIVISIONY")==0){
00091 division_grille[1] = (int)value;
00092 }
00093 if (strcmp(key,"GRID_DIVISIONZ")==0){
00094 division_grille[2] = (int)value;
00095 }
00096 if (strcmp(key,"PARTITION_GENERATION")==0){
00097 nb_partitions = (int)value;
00098 }
00099 }
00100
00101 template <typename DomainA, typename DomainC,unsigned int Dim,int Pond>
00102 void Bridging<DomainA,DomainC,Dim,Pond>::BuildContinuWeight(){
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116 ContenerElems & c = domC.getContenerElems();
00117 IteratorElems & it = c.GetIterator();
00118 RefElt el = it.GetFirst();
00119
00120 unsigned int nb;
00121
00122 MechaContLibMesh<Dim> & model = static_cast<MechaContLibMesh<Dim> &>(domC.getModel());
00123 _Vec_ & p0 = domC.getDofs().P0();
00124
00125 std::vector< unsigned int > nodes;
00126
00127 Cube & cube = GeomTools::GetBoundingBox(geom);
00128 DUMP("la geometrie de la grille ! \n" << cube,DBG_DETAIL);
00129 grid = new SpatialGrid<int,_Vec_,Dim>(cube,division_grille[0],division_grille[1],division_grille[2]);
00130 delete &cube;
00131
00132 Cube & cube1 = GeomTools::GetBoundingBox(geom_fictif);
00133 DUMP("la geometrie de la grille (fictifs) \n" << cube1 << "\n" << geom_fictif,DBG_DETAIL);
00134 grid_fictifs = new SpatialGrid<int,_Vec_,Dim>(cube1,division_grille[0],division_grille[1],division_grille[2]);
00135 delete &cube1;
00136
00137
00138
00139
00140
00141 int nb_elem = 0;
00142 int nb_fictifs = 0;
00143
00144 for(el = it.GetFirst();!it.end();el = it.GetNext())
00145 {
00146 model.GlobalIndexes(el,nodes);
00147 nb = nodes.size();
00148
00149 bool test,test2;
00150 test = false;
00151 test2 = false;
00152
00153 double x=0.0,y=0.0,z=0.0;
00154
00155 for (unsigned int i=0; i< nb ; ++i)
00156 {
00157 DUMP("invalid mass ? " << nodes[i] << " " << model.Mass(nodes[i]),DBG_ALL);
00158
00159 if(model.Mass(nodes[i]) == 0)
00160 continue;
00161
00162 x = p0[nodes[i]*Dim];
00163 if (Dim > 1)
00164 y = p0[nodes[i]*Dim+1];
00165 if(Dim == 3)
00166 z = p0[nodes[i]*Dim+2];
00167
00168 test = test | geom.Contient(x,y,z);
00169 test2 = test2 | geom_fictif.Contient(x,y,z);
00170
00171 DUMP("is " << x << " " << y << " " << z << " inside " << geom_fictif << " ? result = " << test2,DBG_ALL);
00172 }
00173
00174 if (Dim == 3)
00175 if (nb < 4){
00176 test = false;
00177 test2 = false;
00178 }
00179
00180 if(test){
00181 DUMP("element(" << nb_elem << ") added nodes = [ " << nodes[0] << " " << nodes[1] << " " << nodes[2],DBG_ALL);
00182 STARTTIMER("Filling spatial-grid");
00183 grid->add_finiteElement(nb_elem,p0,nodes);
00184 STOPTIMER("Filling spatial-grid");
00185
00186 for (unsigned int i=0;i < nb;++i){
00187 x = p0[nodes[i]*Dim];
00188 if (Dim > 1)
00189 y = p0[nodes[i]*Dim+1];
00190 if(Dim == 3)
00191 z = p0[nodes[i]*Dim+2];
00192
00193
00194 LocalGeom.ExtendBoundingBox(x,y,z);
00195
00196 if (noeuds_rec.Recherche(nodes[i])==-1)
00197 noeuds_rec.Ajouter(nodes[i]);
00198
00199 DUMP("Ajoute le noeuds a la position " << x << " " << y << " " << z,DBG_ALL);
00200 }
00201 ++nb_elem;
00202 elems_rec.Ajouter(el);
00203 }
00204
00205 if (test2){
00206 grid_fictifs->add_finiteElement(nb_fictifs,p0,nodes);
00207 for (unsigned int i=0;i < nb;++i){
00208 x = p0[nodes[i]*Dim];
00209 if (Dim > 1)
00210 y = p0[nodes[i]*Dim+1];
00211 if(Dim == 3)
00212 z = p0[nodes[i]*Dim+2];
00213
00214
00215 if (noeuds_fictifs.Recherche(nodes[i])==-1)
00216 noeuds_fictifs.Ajouter(nodes[i]);
00217
00218
00219 DUMP("Ajoute le noeuds fictif a la position " << x << " " << y << " " << z,DBG_ALL);
00220 }
00221 ++nb_fictifs;
00222 elems_fictifs.Ajouter(el);
00223 }
00224 }
00225
00226 delete ⁢
00227
00228
00229 DUMP("on a trouve " << nb_fictifs << " elements concernes(fictifs)",DBG_INFO);
00230 DUMP("on a en moyenne " << grid->getAverageEltByBlock() << " elements par block",DBG_INFO);
00231 DUMP("on a en moyenne " << grid_fictifs->getAverageEltByBlock() << " elements par block(fictifs)",DBG_INFO);
00232
00233
00234 nb = noeuds_rec.nbElem();
00235 DUMP("on a trouve " << nb_elem << " elements concernes (nb = " << nb << ")",DBG_INFO);
00236 if (!nb){DUMP("On a trouve aucun noeud dans le recouvrement",DBG_INFO);return;}
00237 DUMP("On a trouve " << nb << " noeuds concernes dans " << elems_rec.nbElem() << " elements",DBG_INFO);
00238
00239
00240
00241 lambdasC = new double[nb];
00242 #ifdef DEBUG_BRIDGE
00243 absolute_lambdasC = nb;
00244 #endif
00245
00246
00247 IteratorNodesRec & itrec = noeuds_rec.GetIterator();
00248 RefNode n = itrec.GetFirst();
00249 unsigned int j = 0;
00250
00251 while (!itrec.end())
00252 {
00253 #ifdef DEBUG_BRIDGE
00254 if (j >= absolute_lambdasC) FATAL("depassement detecte");
00255 #endif
00256 if (Dim == 1)
00257 lambdasC[j] = P.weight(CONTINUFLAG,p0[n]);
00258 if (Dim == 2)
00259 lambdasC[j] = P.weight(CONTINUFLAG,p0[n*Dim],p0[n*Dim+1]);
00260 if (Dim == 3)
00261 lambdasC[j] = P.weight(CONTINUFLAG,p0[n*Dim],p0[n*Dim+1],p0[n*Dim+2]);
00262
00263 DUMP("node " << n << " placed in position " << j,DBG_ALL);
00264
00265 n = itrec.GetNext();
00266 ++j;
00267 }
00268
00269
00270
00271 delete &itrec;
00272 }
00273
00274 template <typename DomainA, typename DomainC,unsigned int Dim,int Pond>
00275 void Bridging<DomainA,DomainC,Dim,Pond>::BuildAtomsWeight(){
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286 DUMP("la geometrie du rec (fictifs) \n" << geom_fictif,DBG_INFO);
00287
00288 DUMP("taille de atomes_rec avant de demarrer " << atomes_rec.nbElem(),DBG_INFO);
00289
00290 ContenerAtoms & c = domA.getContener();
00291 IteratorAtoms& it = c.GetIterator();
00292 RefAtom at = it.GetFirst();
00293
00294 bool test,test2;
00295
00296 while (!it.end())
00297 {
00298 DUMP("Testing atom at position " << FORMATREAL(at.position0(0)),DBG_ALL);
00299
00300 test = false;
00301 test2 = false;
00302
00303 if (Dim == 1){
00304 if (geom.Contient(at.position0(0)))
00305 test = true;
00306 if (geom_fictif.Contient(at.position0(0)))
00307 test2 = true;
00308 }
00309
00310 if (Dim == 2){
00311 if (geom.Contient(at.position0(0),at.position0(1)))
00312 test = true;
00313 if (geom_fictif.Contient(at.position0(0),at.position0(1)))
00314 test2 = true;
00315 }
00316
00317
00318 if (Dim == 3){
00319 if (geom.Contient(at.position0(0),at.position0(1),at.position0(2)))
00320 test = true;
00321 if (geom_fictif.Contient(at.position0(0),at.position0(1),at.position0(2)))
00322 test2 = true;
00323 }
00324
00325 if (test){
00326 DUMP("Accepting atom at position " << FORMATREAL(at.position0(0)),DBG_ALL);
00327 atomes_rec.Ajouter(at);
00328
00329 if(Dim == 1)
00330 LocalGeom.ExtendBoundingBox(at.position0(0),0,0);
00331 if(Dim == 2)
00332 LocalGeom.ExtendBoundingBox(at.position0(0),at.position0(1),0);
00333 if(Dim == 3)
00334 LocalGeom.ExtendBoundingBox(at.position0(0),at.position0(1),at.position0(2));
00335
00336 }
00337 if (test2){
00338 atomes_fictifs.Ajouter(at);
00339 if(Dim == 1)
00340 LocalGeom.ExtendBoundingBox(at.position0(0),0,0);
00341 if(Dim == 2)
00342 LocalGeom.ExtendBoundingBox(at.position0(0),at.position0(1),0);
00343 if(Dim == 3)
00344 LocalGeom.ExtendBoundingBox(at.position0(0),at.position0(1),at.position0(2));
00345 DUMP("Accepting atom at position " << at.position0(0) << " " << at.position0(1) << " in boundary",DBG_ALL);
00346 }
00347
00348 at = it.GetNext();
00349 }
00350
00351 int nb = atomes_rec.nbElem();
00352 if (!nb){DUMP("On a trouve aucun atome dans le recouvrement",DBG_INFO);return;}
00353 DUMP("On a touve " << nb << " atomes concernes et " << atomes_fictifs.nbElem() << " atomes qu'il faudra corriger de l'effet de surface",DBG_INFO);
00354
00355
00356 lambdasA = new double[nb+PADDING_ATOMS];
00357 #ifdef DEBUG_BRIDGE
00358 absolute_lambdasA = nb+PADDING_ATOMS;
00359 #endif
00360 IteratorAtomsRec & itrec = atomes_rec.GetIterator();
00361 at = itrec.GetFirst();
00362 unsigned int i = 0;
00363
00364 while (!itrec.end())
00365 {
00366 #ifdef DEBUG_BRIDGE
00367 if (i >= absolute_lambdasA)
00368 FATAL("depassement detecte");
00369 #endif
00370
00371 DUMP("ponderation of rec atom " << i,DBG_ALL);
00372 if (Dim == 1)
00373 lambdasA[i] = P.weight(ATOMEFLAG,at.position0(0));
00374 if (Dim == 2)
00375 lambdasA[i] = P.weight(ATOMEFLAG,at.position0(0),at.position0(1));
00376 if (Dim == 3)
00377 lambdasA[i] = P.weight(ATOMEFLAG,at.position0(0),at.position0(1),at.position0(2));
00378
00379 at = itrec.GetNext();
00380 ++i;
00381 }
00382
00383 delete &itrec;
00384 delete ⁢
00385 }
00386
00387 template <typename DomainA, typename DomainC,unsigned int Dim,int Pond>
00388 void Bridging<DomainA,DomainC,Dim,Pond>::BuildPositions(){
00389
00390 if (atomes_rec.nbElem() == 0){
00391 positions = NULL;
00392 return;
00393 }
00394 positions = new double[Dim*atomes_rec.nbElem()];
00395 DUMP("making positions for " << atomes_rec.nbElem() << " atoms in rec",DBG_INFO);
00396 #ifdef DEBUG_BRIDGE
00397 absolute_positions = atomes_rec.nbElem();
00398 unsigned int nmax = atomes_rec.nbElem();
00399 #endif
00400 for (unsigned int i = 0 ; i < atomes_rec.nbElem() ; ++i)
00401 {
00402 #ifdef DEBUG_BRIDGE
00403 if (i >= nmax) FATAL("depassement detecte");
00404 #endif
00405 positions[Dim*i] = atomes_rec.Get(i).position0(0);
00406 if (Dim > 1)
00407 positions[Dim*i + 1] = atomes_rec.Get(i).position0(1);
00408 if (Dim == 3)
00409 positions[Dim*i + 2]= atomes_rec.Get(i).position0(2);
00410 }
00411 }
00412
00413 template <typename DomainA, typename DomainC,unsigned int Dim,int Pond>
00414 void Bridging<DomainA,DomainC,Dim,Pond>::BuildFictifsPositions(){
00415 if (atomes_fictifs.nbElem() == 0){
00416 positions = NULL;
00417 return;
00418 }
00419 positions = new double[Dim*atomes_fictifs.nbElem()];
00420 DUMP("making positions for " << atomes_fictifs.nbElem() << " atoms in fictifs",DBG_INFO);
00421 #ifdef DEBUG_BRIDGE
00422 unsigned int nmax = atomes_fictifs.nbElem();
00423 absolute_positions = atomes_fictifs.nbElem();
00424 #endif
00425
00426 for (unsigned int i = 0 ; i < atomes_fictifs.nbElem() ; ++i)
00427 {
00428 #ifdef DEBUG_BRIDGE
00429 if (i >= nmax) FATAL("depassement detecte");
00430 #endif
00431 positions[Dim*i] = atomes_fictifs.Get(i).position0(0);
00432 if (Dim > 1)
00433 positions[Dim*i + 1] = atomes_fictifs.Get(i).position0(1);
00434 if (Dim == 3)
00435 positions[Dim*i + 2]= atomes_fictifs.Get(i).position0(2);
00436 }
00437 }
00438
00439
00440 template <typename DomainA, typename DomainC,unsigned int Dim,int Pond>
00441 void Bridging<DomainA,DomainC,Dim,Pond>::BuildShapeMatrix(double * positions,unsigned int nb_atoms){
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461 std::vector<double> atomes_probleme;
00462
00463 MechaContLibMesh<Dim> & model = static_cast<MechaContLibMesh<Dim>&>(domC.getModel());
00464
00465 assoc.resize(nb_atoms);
00466 memset(&assoc[0],-1,sizeof(int)*nb_atoms);
00467
00468 if (elems_rec.nbElem() == 0){
00469 DUMP("elem_rec est vide",DBG_WARNING);
00470 return;
00471 }
00472
00473
00474
00475 std::vector<unsigned int> nb_atome_par_element;
00476 nb_atome_par_element.resize(elems_rec.nbElem());
00477
00478
00479
00480 bool test;
00481
00482 STARTTIMER("Construction association");
00483
00484 for (unsigned int i = 0 ; i < nb_atoms ; ++i){
00485
00486 #ifndef TIMER
00487 if(i%100000==0){
00488 DUMP("construction de l'association - atome " << i << "/" << nb_atoms,DBG_INFO);
00489 }
00490 #endif
00491
00492 #ifdef DEBUG_BRIDGE
00493 if (i >= absolute_positions) FATAL("depassement detecte");
00494 #endif
00495
00496 double x = positions[i*Dim];
00497 double y = 0.0;
00498 double z = 0.0;
00499 if (Dim > 1)
00500 y = positions[i*Dim+1];
00501 if (Dim == 3)
00502 z = positions[i*Dim+2];
00503
00504 std::set<int> & subset_elts = grid->findSet(x,y,z);
00505 std::set<int>::iterator it = subset_elts.begin();
00506
00507 for (it = subset_elts.begin(); it != subset_elts.end();++it){
00508
00509 typename Bridging<DomainA,DomainC,Dim,Pond>::RefElt el = elems_rec.Get(*it);
00510 unsigned int j=*it;
00511
00512 test = false;
00513
00514 if (Dim == 1)
00515 if (el.Contient(x))
00516 test = true;
00517
00518 if (Dim == 2)
00519 if (el.Contient(x,y))
00520 test = true;
00521
00522 if (Dim == 3)
00523 if (el.Contient(x,y,z))
00524 test = true;
00525
00526 if (test)
00527 {
00528 if (assoc[i]!= -1){FATAL("gros soucy qd meme ca fait deux fois que je trouve le meme atome");}
00529
00530 assoc[i] = j;
00531
00532
00533
00534
00535
00536
00537
00538
00539
00540
00541
00542
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552
00553 ++assoc_found;
00554 break;
00555 }
00556
00557 }
00558
00559 if (it == subset_elts.end()){
00560
00561
00562
00563
00564
00565
00566 assoc[i]=-1;
00567 }
00568 }
00569 STOPTIMER("Construction association");
00570
00571 delete grid;
00572
00573
00574
00575 for (unsigned int i = 0 ; i < nb_atoms ; ++i){
00576 if (assoc[i]!=-1)
00577 ++nb_atome_par_element[assoc[i]];
00578 }
00579
00580
00581
00582 filterContenerElemsAndNodes(nb_atome_par_element,elems_rec,noeuds_rec,assoc,lambdasC);
00583
00584
00585
00586 typename Bridging<DomainA,DomainC,Dim,Pond>::IteratorElemsRec & itc = elems_rec.GetIterator();
00587 typename Bridging<DomainA,DomainC,Dim,Pond>::RefElt el = itc.GetFirst();
00588
00589 Smatrix = new ShapeMatrix<_Vec_,Dim>(elems_rec.nbElem());
00590 el = itc.GetFirst();
00591 unsigned int i = 0;
00592 while (!itc.end()){
00593 DUMP("declare la smatrice numero " << i << " qui sera de taille " << nb_atome_par_element[i] << "x" << el.n_nodes(),DBG_ALL);
00594 if (nb_atome_par_element[i]>0)
00595 Smatrix->SetSub(i,nb_atome_par_element[i],el.n_nodes());
00596 ++i;
00597 el = itc.GetNext();
00598 }
00599
00600
00601 Smatrix->Allocate();
00602
00603
00604 std::vector<double> shapes;
00605 std::vector<unsigned int> nodes;
00606 int indirection=0;
00607
00608 for (unsigned int i = 0 ; i < nb_atoms ; ++i){
00609 if (assoc[i]==-1)
00610 continue;
00611
00612
00613
00614
00615
00616 double x = positions[i*Dim];
00617 double y = 0.0;
00618 double z = 0.0;
00619
00620 if (Dim > 1)
00621 y = positions[i*Dim+1];
00622 if (Dim == 3)
00623 z = positions[i*Dim+2];
00624
00625
00626 el = elems_rec.Get(assoc[i]);
00627
00628 if (Dim == 1)
00629 model.ComputeShapes(el,shapes,x);
00630
00631 if (Dim == 2)
00632 model.ComputeShapes(el,shapes,x,y);
00633
00634 if (Dim == 3)
00635 model.ComputeShapes(el,shapes,x,y,z);
00636
00637 model.GlobalIndexes(el,nodes);
00638
00639 for(unsigned int j=0;j<shapes.size();++j){
00640 DUMP("inserting shape of node " << nodes[j] << "(part of elem " << assoc[i] << ") for atom " << i << " (index " << indirection << ")",DBG_ALL);
00641 (*Smatrix)(indirection,nodes[j],noeuds_rec.Recherche(nodes[j]),assoc[i],shapes[j]);
00642 }
00643 ++indirection;
00644 }
00645
00646 delete &itc;
00647 }
00648
00649 template <typename DomainA, typename DomainC,unsigned int Dim,int Pond>
00650 void Bridging<DomainA,DomainC,Dim,Pond>::BuildShapeMatrixFictifs(double * positions,unsigned int nb_atoms){
00651
00652
00653
00654
00655 MechaContLibMesh<Dim> & model = static_cast<MechaContLibMesh<Dim>&>(domC.getModel());
00656
00657
00658 assoc_fictifs.resize(nb_atoms);
00659 memset(&assoc_fictifs[0],-1,sizeof(int)*nb_atoms);
00660
00661 if (elems_fictifs.nbElem() == 0){
00662 DUMP("elem_fictifs est vide",DBG_WARNING);
00663 return;
00664 }
00665
00666 std::vector<unsigned int> nb_atome_par_element;
00667 nb_atome_par_element.resize(elems_fictifs.nbElem());
00668
00669
00670
00671 bool test;
00672
00673 for (unsigned int i = 0 ; i < nb_atoms ; ++i){
00674
00675 if(i%10000==0){
00676 DUMP("construction de l'association - atome(fictifs) " << i << "/" << nb_atoms,DBG_INFO);
00677 }
00678
00679
00680 double x = positions[i*Dim];
00681 double y = 0.0;
00682 double z = 0.0;
00683 if (Dim > 1)
00684 y = positions[i*Dim+1];
00685 if (Dim == 3)
00686 z = positions[i*Dim+2];
00687
00688 std::set<int>::iterator it;
00689 std::set<int> & subset_elts = grid_fictifs->findSet(x,y,z);
00690 for (it = subset_elts.begin(); it != subset_elts.end();it++){
00691
00692 DUMP("accessing element " << *it << " in subset",DBG_ALL);
00693 typename Bridging<DomainA,DomainC,Dim,Pond>::RefElt el = elems_fictifs.Get(*it);
00694 unsigned int j=*it;
00695
00696 test = false;
00697
00698 if (Dim == 1)
00699 if (el.Contient(x))
00700 test = true;
00701
00702 if (Dim == 2)
00703 if (el.Contient(x,y))
00704 test = true;
00705
00706 if (Dim == 3)
00707 if (el.Contient(x,y,z))
00708 test = true;
00709
00710 if (test)
00711 {
00712 assoc_fictifs[i] = j;
00713 ++assoc_found_fictifs;
00714 break;
00715 }
00716 }
00717 if (it == subset_elts.end()){
00718
00719
00720
00721 assoc_fictifs[i] = -1;
00722 }
00723
00724
00725 }
00726
00727 delete grid_fictifs;
00728
00729
00730
00731 for (unsigned int i = 0 ; i < nb_atoms ; ++i){
00732 if (assoc_fictifs[i]!=-1)
00733 ++nb_atome_par_element[assoc_fictifs[i]];
00734 }
00735
00736 filterContenerElemsAndNodes(nb_atome_par_element,elems_fictifs,noeuds_fictifs,assoc_fictifs,NULL);
00737
00738
00739
00740 typename Bridging<DomainA,DomainC,Dim,Pond>::IteratorElemsRec & itc = elems_fictifs.GetIterator();
00741 typename Bridging<DomainA,DomainC,Dim,Pond>::RefElt el = itc.GetFirst();
00742
00743 Smatrix_fictifs = new ShapeMatrix<_Vec_,Dim>(elems_fictifs.nbElem());
00744 el = itc.GetFirst();
00745 int i = 0;
00746 while (!itc.end()){
00747 Smatrix_fictifs->SetSub(i,nb_atome_par_element[i],el.n_nodes());
00748 DUMP("declare la smatrice numero " << i << " qui sera de taille " << nb_atome_par_element[i] << "x" << el.n_nodes(),DBG_DETAIL);
00749 ++i;
00750 el = itc.GetNext();
00751 }
00752
00753
00754 Smatrix_fictifs->Allocate();
00755
00756
00757 std::vector<double> shapes;
00758 std::vector<unsigned int> nodes;
00759 int indirection=0;
00760
00761 for (unsigned int i = 0 ; i < nb_atoms ; ++i){
00762 if(assoc_fictifs[i]==-1)
00763 continue;
00764
00765
00766
00767
00768 double x = positions[i*Dim];
00769 double y = 0.0;
00770 double z = 0.0;
00771
00772 if (Dim > 1)
00773 y = positions[i*Dim+1];
00774 if (Dim == 3)
00775 z = positions[i*Dim+2];
00776
00777
00778 el = elems_fictifs.Get(assoc_fictifs[i]);
00779
00780 if (Dim == 1)
00781 model.ComputeShapes(el,shapes,x);
00782
00783 if (Dim == 2)
00784 model.ComputeShapes(el,shapes,x,y);
00785
00786 if (Dim == 3)
00787 model.ComputeShapes(el,shapes,x,y,z);
00788
00789 model.GlobalIndexes(el,nodes);
00790
00791 for(unsigned int j=0;j<shapes.size();++j){
00792 DUMP("inserting shape of node " << nodes[j] << "(part of elem " << assoc_fictifs[i] << ") for atom " << i,DBG_ALL);
00793 (*Smatrix_fictifs)(indirection,nodes[j],noeuds_fictifs.Recherche(nodes[j]),assoc_fictifs[i],shapes[j]);
00794 }
00795 ++indirection;
00796 }
00797
00798 delete &itc;
00799 }
00800
00801
00802 template <typename DomainA, typename DomainC,unsigned int Dim,int Pond>
00803 void Bridging<DomainA,DomainC,Dim,Pond>::CorrectSurfaceEffect(){
00804
00805 if (elems_fictifs.nbElem() == 0){
00806 DUMP("Warning : elems rec contener is empty -> atoms surface effect correction will not be made(check geometries)",DBG_WARNING);
00807 return;
00808 }
00809
00810 if (atomes_fictifs.nbElem() == 0){
00811 DUMP("Warning : atoms rec contener is empty -> atoms surface effect correction will not be made(check geometries)",DBG_WARNING);
00812 return;
00813 }
00814
00815
00816
00817
00818
00819 _Vec_ & v = domC.getDofs().V();
00820 _Vec_ & u = domC.getDofs().U();
00821 _Vec_ & p0 = domC.getDofs().P0();
00822
00823 typename Bridging<DomainA,DomainC,Dim,Pond>::IteratorAtomsRec & itfictif = atomes_fictifs.GetIterator();
00824 typename Bridging<DomainA,DomainC,Dim,Pond>::RefAtom at = itfictif.GetFirst();
00825 unsigned int at_index = 0;
00826
00827 int * assoc_tmp = &assoc_fictifs[0];
00828
00829 for (at = itfictif.GetFirst(); !itfictif.end() ; ++at_index, at = itfictif.GetNext())
00830 {
00831
00832 if (assoc_tmp[at_index] == -1){
00833 DUMP("Warning : dofs conteners of constraint system have not been filtered (index = " << at_index << ")",DBG_WARNING);
00834 continue;
00835 }
00836
00837
00838 at.force(0) = 0;
00839 at.vitesse(0) = Smatrix_fictifs->InterpolateAtom(at_index,v,assoc_tmp[at_index],0);
00840 at.position(0) = Smatrix_fictifs->InterpolateAtom(at_index,p0,assoc_tmp[at_index],0) +
00841
00842 Smatrix_fictifs->InterpolateAtom(at_index,u,assoc_tmp[at_index],0);
00843
00844 DUMP("correcting surface atom " << at_index
00845 << " for Y dimension with " << Smatrix_fictifs->InterpolateAtom(at_index,v,assoc_tmp[at_index],1),DBG_ALL);
00846
00847 if (Dim > 1){
00848 at.force(1) = 0;
00849 at.vitesse(1) = Smatrix_fictifs->InterpolateAtom(at_index,v,assoc_tmp[at_index],1);
00850
00851
00852 }
00853
00854
00855
00856
00857
00858 if (Dim == 3){
00859 at.force(2) = 0;
00860 at.vitesse(2) = Smatrix_fictifs->InterpolateAtom(at_index,v,assoc_tmp[at_index],2);
00861
00862
00863 }
00864
00865
00866
00867
00868
00869
00870
00871
00872 }
00873
00874 delete &itfictif;
00875 }
00876
00877 template <typename DomainA, typename DomainC,unsigned int Dim,int Pond>
00878 void Bridging<DomainA,DomainC,Dim,Pond>::filterContenerElemsAndNodes(std::vector<unsigned int> & nb_atome_par_element,
00879 ContenerElemsRec & elems,
00880 ContenerNodesRec & nodes,
00881 std::vector<int> & assoc,double * lambda){
00882
00883
00884
00885 ContenerElemsRec new_t;
00886 ContenerNodesRec new_t_nodes;
00887 std::vector<int> new_index;
00888 std::vector<unsigned int> nodeIndexes;
00889
00890 lambda = NULL;
00891
00892 for (unsigned int i = 0 ; i < nb_atome_par_element.size(); ++i){
00893 DUMP("filtering odl index element " << i,DBG_ALL);
00894 if (nb_atome_par_element[i] > 0){
00895 DUMP("for contener, elem " << i << " becomes " << new_t.nbElem(),DBG_ALL);
00896 new_index.push_back(new_t.nbElem());
00897
00898 DUMP("maintenant nb_atome_par_element[" << new_t.nbElem() << "]= " << nb_atome_par_element[i] << " (i=" << i << ")",DBG_ALL);
00899 nb_atome_par_element[new_t.nbElem()] = nb_atome_par_element[i];
00900 new_t.Ajouter(elems.Get(i));
00901
00902
00903
00904
00905
00906
00907
00908
00909
00910
00911
00912
00913
00914
00915 }
00916 else
00917 new_index.push_back(new_t.nbElem());
00918 }
00919
00920 nb_atome_par_element.resize(new_t.nbElem());
00921
00922 elems.Empty();
00923
00924
00925 for (unsigned int i = 0 ; i < new_t.nbElem();++i)
00926 elems.Ajouter(new_t.Get(i));
00927
00928
00929
00930
00931 for (unsigned int i = 0 ; i < assoc.size();++i){
00932 if (assoc[i] != -1)
00933 assoc[i] = new_index[assoc[i]];
00934 }
00935
00936
00937 }
00938
00939 template <typename DomainA, typename DomainC,unsigned int Dim,int Pond>
00940 void Bridging<DomainA,DomainC,Dim,Pond>::filterContener(ContenerAtomsRec & atoms,std::vector<int> & v){
00941
00942 ContenerTableau<RefAtom> new_t;
00943
00944 for (unsigned int i = 0 ; i < v.size();++i)
00945 if(v[i]!=-1){
00946 DUMP("for contener, atom " << i << " becomes " << new_t.nbElem(),DBG_ALL);
00947 new_t.Ajouter(atoms.Get(i));
00948 }
00949
00950 atoms.Empty();
00951 for (unsigned int i = 0 ; i < new_t.nbElem();++i)
00952 atoms.Ajouter(new_t.Get(i));
00953
00954 }
00955
00956 template <typename DomainA, typename DomainC,unsigned int Dim,int Pond>
00957 #ifdef DEBUG_BRIDGE
00958 void Bridging<DomainA,DomainC,Dim,Pond>::filterArray(double * array,unsigned int nmax,std::vector<int> & v){
00959 #else
00960 void Bridging<DomainA,DomainC,Dim,Pond>::filterArray(double * array,std::vector<int> & v){
00961 #endif
00962
00963 unsigned int index=0;
00964
00965 for (unsigned int i = 0 ; i < v.size();++i)
00966 if(v[i]!=-1){
00967 DUMP("for contener, atom " << i << " becomes " << index,DBG_ALL);
00968 #ifdef DEBUG_BRIDGE
00969 if (i >= nmax || index >= nmax)
00970 FATAL("depassement detecte");
00971 #endif
00972 array[index] = array[i];
00973 ++index;
00974 }
00975 }
00976
00977
00978 template <typename DomainA, typename DomainC,unsigned int Dim,int Pond>
00979 void Bridging<DomainA,DomainC,Dim,Pond>::rebuildAssoc(std::vector<int> & v){
00980
00981 std::vector<int> tmp;
00982 for (unsigned int i = 0 ; i < v.size();++i)
00983 if(v[i]!=-1){
00984 DUMP("for assoc, atom " << i << " becomes " << tmp.size() << " value = (" << v[i] << ")",DBG_ALL);
00985 tmp.push_back(v[i]);
00986 }
00987
00988 v.clear();
00989 for (unsigned int i = 0 ; i < tmp.size();++i){
00990 DUMP("pushing " << tmp[i] << " at position " << i,DBG_ALL);
00991 v.push_back(tmp[i]);
00992 }
00993
00994 }
00995
00996 template <typename DomainA, typename DomainC,unsigned int Dim,int Pond>
00997 void Bridging<DomainA,DomainC,Dim,Pond>::Dump(char * prefix){
00998 char filename[256];
00999
01000 snprintf(filename,256,"%s-%s-%s",name,prefix,"recatomes");
01001 Dump(filename,atomes_rec,true);
01002 snprintf(filename,256,"%s-%s-%s",name,prefix,"recelems");
01003 Dump(filename,noeuds_rec,elems_rec,true);
01004 snprintf(filename,256,"%s-%s-%s",name,prefix,"fictifsatomes");
01005 Dump(filename,atomes_fictifs,false);
01006 snprintf(filename,256,"%s-%s-%s",name,prefix,"fictifselems");
01007 Dump(filename,noeuds_fictifs,elems_fictifs,false);
01008 }
01009
01010
01011
01012 template <typename DomainA, typename DomainC,unsigned int Dim,int Pond>
01013 void Bridging<DomainA,DomainC,Dim,Pond>::Dump(char * fichier,ContenerTableau<RefAtom> & atomes,bool dumpWeights){
01014
01015 UnitsConverter unit;
01016 unit.SetReadUnits(UnitsConverter::AtomsUnits);
01017
01018
01019
01020
01021
01022
01023
01024 if (atomes.nbElem() == 0){
01025 DUMP("Warning : not dumping to file Bridged information as atoms contener seems to be empty",DBG_WARNING);
01026 return;
01027 }
01028
01029 IteratorAtomsRec & itrec = atomes.GetIterator();
01030
01031 itrec.GetFirst();
01032 RefAtom at = itrec.GetFirst();
01033
01034 LMFile file;
01035 unsigned int nb = atomes.nbElem();
01036
01037
01038 char filename[256];
01039 sprintf(filename,"%s-atoms_weigth.vtu",fichier);
01040 file.open(filename);
01041
01042 ParaviewHelper paraHelper;
01043 paraHelper.setOutputFile(file);
01044 paraHelper.SetMode(TEXT);
01045
01046 paraHelper.write_header(nb,1);
01047 paraHelper.startDofList();
01048
01049
01050 while (!itrec.end())
01051 {
01052 double x = 0, y = 0 , z = 0;
01053
01054 x = at.position(0)*unit.etalon_metre;
01055 if (Dim > 1)
01056 y = at.position(1)*unit.etalon_metre;
01057 if (Dim > 2)
01058 z = at.position(2)*unit.etalon_metre;
01059
01060 paraHelper.pushDouble(x);
01061 paraHelper.pushDouble(y);
01062 paraHelper.pushDouble(z);
01063 at = itrec.GetNext();
01064 }
01065
01066 paraHelper.endDofList();
01067 paraHelper.startCellsConnectivityList();
01068
01069 for (unsigned int i=0;i < nb;++i)
01070 {
01071 paraHelper.pushInteger(i);
01072 }
01073
01074 paraHelper.endCellsConnectivityList();
01075 paraHelper.startCellsoffsetsList();
01076
01077 paraHelper.pushInteger(nb);
01078
01079 paraHelper.endCellsoffsetsList();
01080 paraHelper.startCellstypesList();
01081
01082 paraHelper.pushInteger(2);
01083
01084 paraHelper.endCellstypesList();
01085
01086 if (dumpWeights){
01087 paraHelper.startPointDataList();
01088
01089 paraHelper.startData("weight",1);
01090
01091 at = itrec.GetFirst();
01092 unsigned int i = 0;
01093 while (!itrec.end())
01094 {
01095 #ifdef DEBUG_BRIDGE
01096 if (i >= absolute_lambdasA)
01097 FATAL("depassement detecte");
01098 #endif
01099 paraHelper.pushDouble(lambdasA[i]);
01100 at = itrec.GetNext();
01101 ++i;
01102 }
01103
01104 paraHelper.endData();
01105 paraHelper.endPointDataList();
01106 }
01107
01108 paraHelper.write_conclusion();
01109
01110 file.close();
01111
01112 delete &itrec;
01113
01114 }
01115
01116 template <typename DomainA, typename DomainC,unsigned int Dim,int Pond>
01117 void Bridging<DomainA,DomainC,Dim,Pond>::Dump(char * fichier,std::vector<double> & atomes,
01118 std::vector<int> & suppfield){
01119 if(suppfield.size()!=atomes.size()/3)
01120 {
01121 FATAL("pour la methode dump le champ supplementaire doit etre de la meme taille modulo la dim 3");
01122 }
01123
01124 Dump(fichier,atomes,&suppfield[0]);
01125 }
01126
01127 template <typename DomainA, typename DomainC,unsigned int Dim,int Pond>
01128 void Bridging<DomainA,DomainC,Dim,Pond>::Dump(char * fichier,std::vector<double> & atomes,
01129 int * suppfield){
01130
01131 UnitsConverter unit;
01132 unit.SetReadUnits(UnitsConverter::AtomsUnits);
01133
01134
01135
01136
01137
01138
01139 if (atomes.size() == 0)
01140 return;
01141
01142
01143
01144
01145 LMFile file;
01146 unsigned int nb = atomes.size()/3;
01147
01148
01149 char filename[256];
01150 sprintf(filename,"%s-atoms_weigth.vtu",fichier);
01151 file.open(filename);
01152
01153 ParaviewHelper paraHelper;
01154 paraHelper.setOutputFile(file);
01155 paraHelper.SetMode(TEXT);
01156
01157 paraHelper.write_header(nb,1);
01158 paraHelper.startDofList();
01159
01160 for (unsigned int it=0 ; it < nb ; ++it)
01161 {
01162 double x = atomes[it*3]*unit.etalon_metre;
01163 double y = atomes[it*3+1]*unit.etalon_metre;
01164 double z = atomes[it*3+2]*unit.etalon_metre;
01165
01166 paraHelper.pushDouble(x);
01167 paraHelper.pushDouble(y);
01168 paraHelper.pushDouble(z);
01169 }
01170
01171 paraHelper.endDofList();
01172 paraHelper.startCellsConnectivityList();
01173
01174 for (unsigned int i=0;i < nb;++i)
01175 {
01176 paraHelper.pushInteger(i);
01177 }
01178
01179 paraHelper.endCellsConnectivityList();
01180 paraHelper.startCellsoffsetsList();
01181
01182 paraHelper.pushInteger(nb);
01183
01184 paraHelper.endCellsoffsetsList();
01185 paraHelper.startCellstypesList();
01186
01187 paraHelper.pushInteger(2);
01188
01189 paraHelper.endCellstypesList();
01190
01191 paraHelper.startPointDataList();
01192
01193 if (suppfield){
01194
01195 paraHelper.startData("suppfield",1);
01196
01197 for (unsigned int it=0 ; it < nb ; ++it)
01198 {
01199 paraHelper.pushDouble(suppfield[it]);
01200 }
01201
01202 paraHelper.endData();
01203 }
01204
01205 paraHelper.endPointDataList();
01206
01207 paraHelper.write_conclusion();
01208
01209 file.close();
01210 }
01211
01212
01213 template <typename DomainA, typename DomainC,unsigned int Dim,int Pond>
01214 void Bridging<DomainA,DomainC,Dim,Pond>::Dump(char * fichier,
01215 ContenerNodesRec & noeuds,
01216 ContenerElemsRec & elems,bool dumpWeights){
01217
01218 if (elems.nbElem() == 0){
01219 DUMP("Warning : not dumping to file Bridged information as elems contener seems to be empty",DBG_WARNING);
01220 return;
01221 }
01222
01223 if (noeuds.nbElem() == 0){
01224 DUMP("Warning : not dumping to file Bridged information as nodes contener seems to be empty",DBG_WARNING);
01225 return;
01226 }
01227
01228 char filename[256];
01229 sprintf(filename,"%s-mesh_weigth.vtu",fichier);
01230
01231 LMFile file;
01232
01233 file.open(filename);
01234
01235 ParaviewHelper paraHelper;
01236 paraHelper.setOutputFile(file);
01237 paraHelper.SetMode(TEXT);
01238
01239 unsigned int nb=0;
01240
01241 UnitsConverter unit;
01242 unit.SetReadUnits(UnitsConverter::AtomsUnits);
01243
01244
01245
01246
01247
01248
01249
01250 typedef typename DomainC::_Vec_ _Vec_;
01251 typedef typename DomainC::_Model_ _Model_;
01252 typedef typename DomainC::RefElt RefElt;
01253 typedef typename DomainC::ContenerElems ContenerElems;
01254 typedef typename DomainC::IteratorElems IteratorElems;
01255
01256
01257
01258 _Model_ & model = static_cast<_Model_ &>(domC.getModel());
01259
01260 _Vec_ & p0 = domC.getDofs().P0();
01261 nb = noeuds.nbElem();
01262
01263
01264
01265 IteratorElemsRec & itc = elems.GetIterator();
01266 RefElt el = itc.GetFirst();
01267
01268 std::vector<unsigned int> nodes;
01269 int compteur;
01270
01271
01272
01273 paraHelper.write_header(nb,elems.nbElem());
01274 paraHelper.startDofList();
01275
01276 for (unsigned int i=0; i < nb; ++i)
01277 {
01278 unsigned int n = noeuds.Get(i);
01279
01280 paraHelper.pushDouble(p0[n*Dim]*unit.etalon_metre);
01281 if (Dim > 1)
01282 paraHelper.pushDouble(p0[n*Dim+1]*unit.etalon_metre);
01283 else
01284 paraHelper.pushDouble(0.);
01285 if (Dim > 2)
01286 paraHelper.pushDouble(p0[n*Dim+2]*unit.etalon_metre);
01287 else
01288 paraHelper.pushDouble(0.);
01289
01290 file.printf("\n");
01291 }
01292
01293 paraHelper.endDofList();
01294 paraHelper.startCellsConnectivityList();
01295
01296 for (el = itc.GetFirst(); !itc.end() ; el = itc.GetNext())
01297 {
01298 model.GlobalIndexes(el,nodes);
01299 for (unsigned int i=0;i < nodes.size();++i)
01300 {
01301 paraHelper.pushInteger(noeuds.Recherche(nodes[i]));
01302 }
01303 file.printf("\n");
01304 }
01305
01306 paraHelper.endCellsConnectivityList();
01307
01308 paraHelper.startCellsoffsetsList();
01309
01310 compteur = 0;
01311 for (el = itc.GetFirst(); !itc.end() ; el = itc.GetNext())
01312 {
01313 model.GlobalIndexes(el, nodes);
01314
01315 compteur += nodes.size();
01316 paraHelper.pushInteger(compteur);
01317
01318 file.printf("\n");
01319 }
01320
01321 paraHelper.endCellsoffsetsList();
01322 paraHelper.startCellstypesList();
01323
01324 int code_type=-1;
01325
01326 for (el = itc.GetFirst(); !itc.end() ; el = itc.GetNext())
01327 {
01328 model.GlobalIndexes(el, nodes);
01329 switch(nodes.size())
01330 {
01331 case 2 : code_type = 3;break;
01332 case 3 : code_type = 5;break;
01333 case 8 : code_type = 12;break;
01334 case 4 : code_type = 10;break;
01335 default: FATAL("Fatal : unable to dump for VTK : " << nodes.size());
01336 }
01337
01338 paraHelper.pushInteger(code_type);
01339 file.printf("\n");
01340 }
01341
01342 paraHelper.endCellstypesList();
01343
01344 if (dumpWeights){
01345 paraHelper.startPointDataList();
01346 paraHelper.startData("weight",1);
01347
01348 for (unsigned int i = 0;i < nb; ++i)
01349 {
01350 #ifdef DEBUG_BRIDGE
01351 if (i >= absolute_lambdasC) FATAL("depassement detecte");
01352 #endif
01353 paraHelper.pushDouble(lambdasC[i]);
01354 }
01355
01356 paraHelper.endData();
01357 paraHelper.endPointDataList();
01358 }
01359
01360 paraHelper.write_conclusion();
01361
01362
01363 file.close();
01364
01365 delete &itc;
01366 }
01367
01368 static int cpt=0;
01369
01370 template <typename DomainA, typename DomainC,unsigned int Dim,int Pond>
01371 void Bridging<DomainA,DomainC,Dim,Pond>::DumpAtome(double x,double y, double z){
01372
01373
01374 UnitsConverter unit;
01375 unit.SetReadUnits(UnitsConverter::AtomsUnits);
01376
01377
01378 char filename[255];
01379 sprintf(filename,"atome-probleme-%d.vtu",cpt);
01380 ++cpt;
01381
01382 LMFile file;
01383
01384 file.open(filename);
01385
01386 ParaviewHelper paraHelper;
01387 paraHelper.setOutputFile(file);
01388 paraHelper.write_header(1,1);
01389 paraHelper.startDofList();
01390
01391 paraHelper.pushDouble(x*unit.etalon_metre);
01392 paraHelper.pushDouble(y*unit.etalon_metre);
01393 paraHelper.pushDouble(z*unit.etalon_metre);
01394
01395 paraHelper.endDofList();
01396 paraHelper.startCellsConnectivityList();
01397
01398 paraHelper.pushInteger(0);
01399
01400 paraHelper.endCellsConnectivityList();
01401 paraHelper.startCellsoffsetsList();
01402
01403 paraHelper.pushInteger(1);
01404
01405 paraHelper.endCellsoffsetsList();
01406 paraHelper.startCellstypesList();
01407
01408 paraHelper.pushInteger(2);
01409
01410 paraHelper.endCellstypesList();
01411
01412 paraHelper.write_conclusion();
01413
01414 file.close();
01415 }
01416
01417
01418 #ifdef USING_STAMP
01419 template class Bridging<DomainStamp,DomainLibMesh<1>,1,LINEAR>;
01420 template class Bridging<DomainStamp,DomainLibMesh<2>,2,LINEAR>;
01421 template class Bridging<DomainStamp,DomainLibMesh<3>,3,LINEAR>;
01422 template class Bridging<DomainStamp,DomainLibMesh<1>,1,CUSTOM>;
01423 #endif
01424 #ifdef USING_LAMMPS
01425 template class Bridging<DomainLammps,DomainLibMesh<2>,2,LINEAR>;
01426 template class Bridging<DomainLammps,DomainLibMesh<3>,3,LINEAR>;
01427 #endif
01428 template class Bridging<DomainMD1D,DomainLibMesh<1>,1,LINEAR>;
01429 template class Bridging<DomainMD1D,DomainLibMesh<1>,1,CUSTOM>;