bridging.cpp

Go to the documentation of this file.
00001 /* ./bridging/bridging.cpp 
00002 **********************************
00003 Copyright INRIA and CEA 
00004 
00005 author : Guillaume ANCIAUX (anciaux@labri.fr, g.anciaux@laposte.net)
00006 
00007 The LibMultiScale is a C++ parallel framework for the multiscale
00008 coupling methods dedicated to material simulations. This framework
00009 provides an API which makes it possible to program coupled simulations
00010 and integration of already existing codes.
00011 
00012 This Project is done in a collaboration between INRIA Futurs Bordeaux
00013 within ScAlApplix team and CEA/DPTA Ile de France. 
00014 
00015 This software is governed by the CeCILL-C license under French law and
00016 abiding by the rules of distribution of free software.  You can  use, 
00017 modify and/ or redistribute the software under the terms of the CeCILL-C
00018 license as circulated by CEA, CNRS and INRIA at the following URL
00019 "http://www.cecill.info". 
00020 
00021 As a counterpart to the access to the source code and  rights to copy,
00022 modify and redistribute granted by the license, users are provided only
00023 with a limited warranty  and the software's author,  the holder of the
00024 economic rights,  and the successive licensors  have only  limited
00025 liability. 
00026 
00027 In this respect, the user's attention is drawn to the risks associated
00028 with loading,  using,  modifying and/or developing or reproducing the
00029 software by the user in light of its specific status of free software,
00030 that may mean  that it is complicated to manipulate,  and  that  also
00031 therefore means  that it is reserved for developers  and  experienced
00032 professionals having in-depth computer knowledge. Users are therefore
00033 encouraged to load and test the software's suitability as regards their
00034 requirements in conditions enabling the security of their systems and/or 
00035 data to be ensured and,  more generally, to use and operate it in the 
00036 same conditions as regards security. 
00037 
00038 The fact that you are presently reading this means that you have had
00039 knowledge of the CeCILL-C license and that you accept its terms.
00040 ***********************************/
00041 
00042 //#define TIMER
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   /* ici demarre la methode de pondération des noeuds du maillage
00105      qui se trouvent dans la zone de recouvrement.
00106 
00107      On va parcourir les elements si on trouve un element qui
00108      intersecte la geometrie alors on ajoute celui ci .
00109 
00110      Deuxieme passage pour calculer les pondérations 
00111      et oui ! on ne connaissait pas la taille avant !
00112 
00113      ZONE : continu 
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   //  grid->Dump("grid.vtu");
00139   //grid_fictifs->Dump("grid-fictifs.vtu");
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         //ajout concret du noeud dans la liste des noeuds
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           //j'agrandi la geometrie locale
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 &it;
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   // grid->Dump("grid.vtu");
00233   //grid_fictifs->Dump("grid-fictifs.vtu");
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   /* j'alloue ici le vecteur alpha pour continu */
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   /* ici demmarre la fonction de pondération des atomes.
00277      on parcours de la meme manière les atomes .
00278      s'ils sont dans la geometrie on les notes
00279 
00280      deuxieme passage pour ponderer
00281 
00282      ZONE : atoms
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   //  int index = 0;
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         //j'agrandi la geometrie locale
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         //      ++index;
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   /* j'alloue ici le vecteur de poids */
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 &it;
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   /* ici demarre l'algo de recoupement des éléments 
00444 
00445   On associe dans un tableau de taille nbElementRec 
00446   des petites matrices de taille nb_atome_par_element x connectivite 
00447   
00448   qui vont conenir un bloc de la  ShapeMatrix 
00449 
00450   pour cela on commence par creer un tableau qui donne l'element conteneur 
00451   pour chaque atome
00452 
00453   ensuite il nous faut le nombre de d'atomes par elements
00454 
00455   ensuite on parcours les elements et on creer la matrice
00456   aux bonnes dimensions et on la remplie !!
00457 
00458   ZONE : FE
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   //  unsigned int j=0;
00474   
00475   std::vector<unsigned int> nb_atome_par_element;
00476   nb_atome_par_element.resize(elems_rec.nbElem());  
00477 
00478   /* construction du tableau d'assoc atoms elem */
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 //        if (i == 39) {
00533 //          DUMP("moi j'ai l'atome 39 (x = " << x << " y = " << y << " z = " << z << ") ! et voici l'element ");
00534 //          MechaContLibMesh<Dim> & model = static_cast<MechaContLibMesh<Dim> &>(domC.getModel());
00535 //          _Vec_ & p0 = domC.getDofs().P0();
00536             
00537 //          std::vector< unsigned int > nodes;
00538 
00539 //          model.GlobalIndexes(el,nodes);
00540 //          unsigned int nb = nodes.size();
00541 
00542 //          double x=0.0,y=0.0,z=0.0;
00543      
00544 //          for (unsigned int i=0; i< nb ; ++i)
00545 //            {
00546 //              x = p0[nodes[i]*Dim];
00547 //              y = p0[nodes[i]*Dim+1];
00548 //              z = p0[nodes[i]*Dim+2];
00549 //              DUMP("node "  << i << " x = " << x << " y = " << y 
00550 //                   << " z = " << z);
00551 //            }
00552 //        }
00553           ++assoc_found;
00554           break;
00555         }
00556 
00557     }
00558     
00559     if (it == subset_elts.end()){
00560 //       int a=1;
00561 //       while (a){}
00562       //      DumpAtome(x,y,z);
00563       //FATAL("l atome " << i << " du recouvrement a la position " << x 
00564         //    << "," << y << "," << z << " n'a pas trouve son element");
00565 
00566       assoc[i]=-1;
00567     }
00568   }
00569   STOPTIMER("Construction association");
00570 
00571   delete grid;
00572 
00573   /* construction du nombre d'atomes par elements */ 
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   /* allocation des subshapematrices */
00581 
00582   filterContenerElemsAndNodes(nb_atome_par_element,elems_rec,noeuds_rec,assoc,lambdasC);
00583 
00584   //  for (unsigned int i=0;i < elems_rec.nbElem() ; ++i){std::cout << "nb_atome_par_element["<< i << "] = " << nb_atome_par_element[i] << endl;}
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   //fait l'allocation effective qui sera contigue (de preference !!)
00601   Smatrix->Allocate();
00602 
00603   /* mise en place de l'indirection et les shapes*/
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 //     if (i%10000 == 0)
00614 //       DUMP("computing shapes " << i << "/" << nb_atoms);
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   /* meme chose mais pour les atomes fictifs seulement 
00652   ZONE : FE
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   /* construction du tableau d'assoc atoms elem */
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       //      DumpAtome(x,y,z);
00719       //FATAL("l'atome " << i << " du recouvrement a la position " << x << " " << y << " " << z
00720         //    << " n'a pas trouve son element");
00721       assoc_fictifs[i] = -1;
00722     }
00723     
00724     
00725   }  
00726 
00727   delete grid_fictifs;
00728   
00729   /* construction du nombre d'atomes par elements */ 
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   /* allocation des subshapematrices */
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   //fait lallocation reelle des coeficients
00754   Smatrix_fictifs->Allocate();
00755 
00756   /* mise en place de l'indirection et les shapes*/
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 //     if (i%10000 == 0)
00766 //       DUMP("computing shapes " << i << "/" << nb_atoms);
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   /* Dans la geometrie Boule je met les atomes soumis aux effets de surface */
00817   /* je les interpole du maillage justement pour eviter les effets indésirables */
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       //je zappe un atome a indirection invalide
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       /* je fait du dump */
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         // at.position0(0) +
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 //      at.position(1) = //Smatrix_fictifs->InterpolateAtom(at_index,p0,assoc_tmp[at_index],1)
00851 //        at.position0(1) + Smatrix_fictifs->InterpolateAtom(at_index,u,assoc_tmp[at_index],1);
00852       }//  else{
00853 //      at.force(1) = 0;
00854 //      at.vitesse(1) = 0;
00855 //      at.position(1) = 0;
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 //      at.position(2) = //Smatrix_fictifs->InterpolateAtom(at_index,p0,assoc_tmp[at_index],2) 
00862 //        at.position0(2) + Smatrix_fictifs->InterpolateAtom(at_index,u,assoc_tmp[at_index],2);
00863       }
00864 //       else{
00865 //      at.force(2) = 0;
00866 //      at.vitesse(2) = 0;
00867 //      at.position(2) = 0;
00868 //       }
00869       
00870 //       at = itfictif.GetNext();
00871 //       ++at_index;
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   //  MechaContLibMesh<Dim> & model = static_cast<MechaContLibMesh<Dim> &>(domC.getModel());
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 //       RefElt elem = elems.Get(i);
00903 //       model.GlobalIndexes(elem,nodeIndexes);
00904 
00905 //       for (unsigned int j = 0 ; j < nodeIndexes.size() ; ++j){
00906 //      vector<unsigned int>::iterator it;
00907 //      if(new_t_nodes.Recherche(nodeIndexes[j])==-1){
00908 //        if (lambda)
00909 //          lambda[new_t_nodes.nbElem()] = lambda[nodes.Recherche(nodeIndexes[j])];
00910 
00911 //        new_t_nodes.Ajouter(nodeIndexes[i]);
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   //  nodes.Empty();
00924   
00925   for (unsigned int i = 0 ; i < new_t.nbElem();++i)
00926     elems.Ajouter(new_t.Get(i));
00927 
00928 //   for (unsigned int i = 0 ; i < new_t_nodes.nbElem();++i)
00929 //     nodes.Ajouter(new_t_nodes.Get(i));
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   //TODO fair un algo un peu mieux que cette merde de copie
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   //TODO fair un algo un peu mieux que cette merde de copie
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   /* je fait le dump des poids des atomes */
01021   /***************************************************/
01022 
01023   //  IteratorAtomsRec & itrec = atomes_fictifs.GetIterator();
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   //unsigned int nb = atomes_fictifs.nbElem();
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   /* je fait le dump des poids des atomes */
01136   /***************************************************/
01137 
01138   //  IteratorAtomsRec & itrec = atomes_fictifs.GetIterator();
01139   if (atomes.size() == 0)
01140     return;
01141 
01142 //   std::vector<double>::iterator itrec = atomes.begin();
01143 //   std::vector<double>::iterator last = atomes.end();
01144 
01145   LMFile file;
01146   unsigned int nb = atomes.size()/3;
01147   //unsigned int nb = atomes_fictifs.nbElem();
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   /* je fait le dump des poids du maillage */
01246   /***************************************************/
01247 
01248   /* definition des types */
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   /* structures pour manipuler les noeuds dans le grands vecteur */
01257 
01258   _Model_ & model = static_cast<_Model_ &>(domC.getModel());
01259   
01260   _Vec_ & p0 = domC.getDofs().P0();
01261   nb = noeuds.nbElem();
01262 
01263   /* structures pour manipuler les elements */
01264 
01265   IteratorElemsRec & itc = elems.GetIterator();
01266   RefElt el = itc.GetFirst();
01267 
01268   std::vector<unsigned int> nodes;
01269   int compteur;
01270 
01271   /* start */
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   //un atome tout seul dans un fichier vtu
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>;

Generated on Fri Sep 7 13:12:32 2007 for LibMultiScale by  doxygen 1.5.2