shape_matrix.h

Go to the documentation of this file.
00001 /* ./bridging/shape_matrix.h 
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 #ifndef SMATRIX_H
00043 #define SMATRIX_H
00044 
00045 #include "../math/matrix.h"
00046 
00047 template <typename _Vec_,unsigned int Dim>
00048 class ShapeMatrix{
00049  public:
00050 
00051   ShapeMatrix(int t){
00052     SubMatrix = new FullMatrix *[t]; 
00053     tailles = new unsigned int[2*t];
00054     indirectionAtome[0] = new int *[t];
00055     indirectionAtome[1] = new int *[t];
00056     currentIndirectionAtome = indirectionAtome[0];
00057     newIndirectionAtome = indirectionAtome[1];
00058     indirectionNode = new int *[t];
00059     indirectionGlobalNode = new int *[t];
00060     remplissageA = new int[t];
00061     remplissageN = new int[t];
00062     memset(remplissageA,0,sizeof(int)*t);
00063     memset(remplissageN,0,sizeof(int)*t);
00064 
00065     tab_contigu = NULL;
00066     taille = t;
00067   };
00068 
00069   ~ShapeMatrix(){
00070     for (int i=0;i<taille;++i) 
00071       delete SubMatrix[i]; 
00072     
00073     if (tab_contigu) 
00074       delete [] tab_contigu; 
00075     if (indA_contigu[0]) 
00076       delete [] indA_contigu[0]; 
00077     if (indA_contigu[1]) 
00078       delete [] indA_contigu[1]; 
00079     if (indN_contigu) 
00080       delete [] indN_contigu; 
00081     if (indGN_contigu) 
00082       delete [] indGN_contigu; 
00083     
00084     delete [] remplissageA; 
00085     delete [] remplissageN; 
00086     delete [] indirectionNode; 
00087     delete [] indirectionGlobalNode; 
00088     delete [] indirectionAtome[0]; 
00089     delete [] indirectionAtome[1]; 
00090     delete [] SubMatrix; 
00091     delete [] tailles;
00092   }
00093 
00094   void SetSub(int i,int m,int n){
00095     if (m <= 0 || n <= 0)
00096       FATAL("can not set a smatrix bloc size of zero : m=" << m << " n=" <<n);
00097     tailles[i*2] = m;
00098     tailles[i*2+1] = n;
00099   };
00100 
00101   void Allocate(){
00102     //premier passage pour calculer tout les
00103     //coeficients de la smatrice globale
00104     
00105     int m,n;
00106 
00107     int total_size=0;
00108     int total_atoms=0;
00109     int total_nodes=0;
00110 
00111     for (int i=0;i<taille;++i){
00112       m = tailles[i*2];
00113       n = tailles[i*2+1];
00114       
00115       total_size+= (m+1)*n;
00116       total_atoms+=m;
00117       total_nodes+=n;
00118     }
00119 
00120     //allocation
00121     tab_contigu = new double[total_size];
00122     int index = 0;
00123 
00124     indA_contigu[0] = new int[total_atoms];
00125     indA_contigu[1] = new int[total_atoms];
00126     int index_atoms = 0;
00127 
00128     indN_contigu = new int[total_nodes];
00129     indGN_contigu = new int[total_nodes];
00130     int index_nodes = 0;
00131 
00132     //deuxieme passage pour allouer les structures de control des matrices
00133     for (int i=0;i<taille;++i){
00134       m = tailles[i*2];
00135       n = tailles[i*2+1];
00136 
00137       SubMatrix[i] = new FullMatrix(m+1,n,tab_contigu+index);
00138 
00139       indirectionAtome[0][i] = indA_contigu[0]+index_atoms;
00140       indirectionAtome[1][i] = indA_contigu[1]+index_atoms;
00141       indirectionNode[i] = indN_contigu+index_nodes;
00142       indirectionGlobalNode[i] = indGN_contigu+index_nodes;
00143 
00144       //incrementation des indexs
00145       index += (m+1)*n;
00146       index_atoms += m;
00147       index_nodes += n;
00148     }
00149   }
00150 
00151   void print(){
00152     for (int k=0;k<taille;++k){
00153       if (!remplissageA[k]) return;
00154       FullMatrix & mat = *SubMatrix[k];
00155 
00156       DUMP("affiche les infos de " << k,DBG_DETAIL);
00157 
00158       for (int i =0; i < mat.m() -1; ++i)
00159         std::cout << indirectionAtome[k][i] << "\t";
00160 
00161       std::cout << endl;
00162       
00163       SubMatrix[k]->print();
00164     }
00165   }
00166 
00167   void changeAtomIndirection(int el,int old_ind_atome,int new_ind_atome){
00168     FullMatrix & mat = *SubMatrix[el];
00169     int  * indA = currentIndirectionAtome[el];
00170     int  * indAN = newIndirectionAtome[el];
00171     for (int i = 0 ; i < mat.m()-1;++i)
00172       if (indA[i] == old_ind_atome) {
00173         indAN[i] = new_ind_atome;
00174         break;
00175       }
00176   }
00177 
00178   void operator ()(int atome,int node_global,int node,int el,double value){
00179     int  * indA = currentIndirectionAtome[el];
00180     indA[remplissageA[el]]=atome;
00181 
00182     int  * indN = indirectionNode[el];
00183     indN[remplissageN[el]]=node;
00184 
00185     DUMP("setting shapes for atome " << atome << " and element " << el << " node " << node << " node_global " << node_global << " value " << value,DBG_ALL);
00186     int  * indGN = indirectionGlobalNode[el];
00187     indGN[remplissageN[el]]=node_global;
00188     
00189     // je prend la matrice dense qui correspond a mon element
00190     FullMatrix & m = *SubMatrix[el];
00191     m(remplissageA[el],remplissageN[el]) = value;
00192     // fait les sommes partielles sur les noeuds
00193     m(m.m()-1,remplissageN[el])+= value;
00194 
00195     ++remplissageN[el];
00196     if (remplissageN[el] == m.n()){
00197       remplissageN[el]=0;
00198       ++remplissageA[el];
00199     }
00200   }
00201 
00202   void build_node_shape(double * node_shape){
00203     for (int k =0 ; k < taille ; ++k){
00204       int * indN = indirectionNode[k];
00205       FullMatrix & mat = *SubMatrix[k];
00206       for (int j = 0 ; j < mat.n(); ++j){
00207         DUMP("Summing node_shape[" << indN[j] << " (el= " << k << ", j = " << j << ")] with " << mat(mat.m()-1,j),DBG_ALL);
00208         node_shape[indN[j]] += mat(mat.m()-1,j);
00209       }
00210     }
00211   }
00212 
00213   void buildContinuConstraint(double * A,double * node_shape){
00214     for (int k =0 ; k < taille ; ++k){
00215       int * indA = currentIndirectionAtome[k];
00216       int * indN = indirectionNode[k];
00217       FullMatrix & mat = *SubMatrix[k];
00218       for (int i = 0 ; i < mat.m()-1; ++i)
00219         for (int j = 0 ; j < mat.n(); ++j){
00220           DUMP("Building A[" << indA[i] << "] with " << mat(i,j) << "*" << node_shape[indN[j]] << " = " 
00221               << mat(i,j)*node_shape[indN[j]],DBG_ALL);
00222           A[indA[i]] += mat(i,j)*node_shape[indN[j]];
00223       }
00224     }
00225   }
00226 
00227   void build_rhs(double * rhs,_Vec_ & v){
00228 
00229     //    unsigned int nbT = v.size()/Dim;
00230 
00231     // je parcours tout les blocs    
00232     for (int k =0 ; k < taille ; ++k){
00233       //je chope la sous matrice
00234       FullMatrix & mat = *SubMatrix[k];
00235       //je chope les indirection sur les noeuds globaux comme 
00236       // j'ai un acces direct au grand vecteur
00237       int * indGN = indirectionGlobalNode[k];
00238       int * indA = currentIndirectionAtome[k];
00239       // je parcours tout les atomes du bloc
00240       for (int i = 0 ; i < mat.m()-1; ++i)
00241         //je parcours tout les noeuds
00242         for (int j = 0 ; j < mat.n(); ++j){
00243 
00244           DUMP("Before rhs[" << indA[i] << "]=" << rhs[Dim*indA[i]+1],DBG_ALL);
00245 
00246           rhs[Dim*indA[i]] += v[indGN[j]*Dim] * mat(i,j);
00247 
00248           if (Dim > 1)
00249             rhs[Dim*indA[i]+1] += v[indGN[j]*Dim+1] * mat(i,j);
00250           if (Dim ==3)
00251             rhs[Dim*indA[i]+2] += v[indGN[j]*Dim+2] * mat(i,j);
00252 
00253           DUMP("build rhs to " << Dim*indA[i] << " " << Dim*indA[i]+ 1 << " " << Dim*indA[i]+3,DBG_ALL);
00254           DUMP("Building " << rhs[Dim*indA[i]+1] << "=rhs[" << indA[i] << "] with " << mat(i,j) << "*" << v[indGN[j]*Dim +1] << " = " 
00255               << v[indGN[j]*Dim+1] * mat(i,j) << " (index = " << indGN[j] << ")",DBG_ALL);
00256 
00257         }
00258     }
00259   }
00260 
00261 
00262   void apply_changing(_Vec_ & v,double * multL,double * lambdas){
00263     //    unsigned int nbT = v.size()/Dim;
00264 
00265     // je parcours tout les blocs    
00266     for (int k =0 ; k < taille ; ++k){
00267       //je chope la sous matrice
00268       FullMatrix & mat = *SubMatrix[k];
00269       //je chope les indirection sur les noeuds globaux comme 
00270       // j'ai un acces direct au grand vecteur
00271       int * indGN = indirectionGlobalNode[k];
00272       int * indN = indirectionNode[k];
00273       int * indA = currentIndirectionAtome[k];
00274       // je parcours tout les atomes du bloc
00275       for (int i = 0 ; i < mat.m()-1; ++i)
00276         //je parcours tout les noeuds
00277         for (int j = 0 ; j < mat.n(); ++j){
00278           DUMP("adding v[" << indGN[j] << "] with " << -1.0*mat(i,j) << " * " <<  multL[indA[i]*Dim+1] << " {rhs[" << indA[i] << "]}/ " 
00279               << lambdas[indN[j]]<< " = " << -1.0*mat(i,j)*multL[indA[i]*Dim+1]/lambdas[indN[j]],DBG_ALL);
00280 
00281           v.add(indGN[j]*Dim,-1.0*mat(i,j)*multL[indA[i]*Dim]/lambdas[indN[j]]);
00282           if (Dim > 1)
00283             v.add(indGN[j]*Dim+1,-1.0*mat(i,j)*multL[indA[i]*Dim+1]/lambdas[indN[j]]);
00284           if (Dim == 3)
00285             v.add(indGN[j]*Dim+2,-1.0*mat(i,j)*multL[indA[i]*Dim+2]/lambdas[indN[j]]);
00286         }
00287     }
00288   };
00289 
00290   double InterpolateAtom(int at, _Vec_ & field,int elem,int deg){
00291     double res = 0;
00292     int * indA = currentIndirectionAtome[elem];
00293     int * indGN = indirectionGlobalNode[elem];
00294     FullMatrix & mat = *SubMatrix[elem];
00295 
00296     DUMP("interpolating for elem " << elem << " atom " << at,DBG_ALL);
00297     /*     trouve l'atome concerné */
00298     int i;
00299     for (i = 0 ; i < mat.m()-1; ++i)
00300       if (indA[i] == at) 
00301         break;
00302     
00303     /* effectue l'interpolation */
00304 
00305     //    unsigned int nbT = field.size()/Dim;
00306 
00307     for (int j = 0 ; j < mat.n(); ++j){
00308       res += mat(i,j)*field[indGN[j]*Dim+deg];
00309     }
00310     
00311     return res;
00312     
00313   };
00314 
00315 
00316   void GetRelatedAtomsToElem(int elem,std::vector<unsigned int> & atoms){
00317     int * indA = currentIndirectionAtome[elem];
00318     FullMatrix & mat = *SubMatrix[elem];
00319 
00320     atoms.clear();
00321 
00322     /* parcours les atomes */
00323     int i;
00324     for (i = 0 ; i < mat.m()-1; ++i)
00325       atoms.push_back(indA[i]);
00326   };
00327 
00328 
00329   void GetRelatedNodesToElem(int elem,std::vector<unsigned int> & nodes){
00330     int * indGN = indirectionGlobalNode[elem];
00331     FullMatrix & mat = *SubMatrix[elem];
00332 
00333     nodes.clear();
00334 
00335     /* parcours les noeuds */
00336     int j;
00337     for (j = 0 ; j < mat.n(); ++j)
00338       nodes.push_back(indGN[j]);
00339   };
00340 
00341 
00342   /********************* ici c pour least square *****************/
00343 
00344 /*   void buildLeastSquareMatrix(FullMatrix * A){ */
00345   void buildLeastSquareMatrix(FullMatrix * A){
00346     A->zero();
00347 
00348     /* on veut construire les A(h,k) */
00349 
00350     /* le produit de deux shape sur la position d'un atome
00351        n'est nul que si les deux shapes font partie
00352        d'un element commun : on a une seul boucle pricipale sur
00353        les elements */
00354 
00355 
00356     for (int k =0 ; k < taille ; ++k){
00357       int * indN = indirectionNode[k];
00358       FullMatrix & mat = *SubMatrix[k];    
00359 
00360       /* ici on met la double boucle sur les noeuds pour calculer la sous matrice de la grande */
00361 
00362       
00363       for (int j1 = 0 ; j1 < mat.n() ; ++j1)
00364         for (int j2 = 0 ; j2 < mat.n() ; ++j2)
00365           {
00366             /* ici on met la boucle de la somme sur les atomes */
00367             for (int i = 0 ; i < mat.m()-1 ; ++i){
00368               (*A)(indN[j1],indN[j2]) += mat(i,j1) * mat(i,j2);
00369               DUMP("A[" << indN[j1] << "," << indN[j2] << "] = " << (*A)(indN[j1],indN[j2]),DBG_ALL);
00370             }
00371           }
00372     }
00373 
00374     FILE * f = fopen("least-square-constraint.mat","wb+");
00375     A->PrintToFile(f);
00376     fclose(f);
00377   }
00378 
00379   void build_least_square_rhs(Vector * rhs,int at,int elem,double v){
00380     int * indA = currentIndirectionAtome[elem];
00381     int * indN = indirectionNode[elem];
00382     FullMatrix & mat = *SubMatrix[elem]; 
00383     
00384     /*     trouve l'atome concerné */
00385     int i,j;
00386     for (i = 0 ; i < mat.m()-1; ++i)
00387       if (indA[i] == at) 
00388         break;
00389       
00390     /* construit le second membre de la methode least square */
00391 
00392     for (j = 0 ; j < mat.n(); ++j)
00393       (*rhs)(indN[j]) += mat(i,j)*v;
00394 
00395   };
00396   
00397 
00398   /**************** ici c pour la forme faible **************************/
00399 
00400   void buildFormeFaibleCMatrix(FullMatrix & C,double * lambdas){
00401 
00402 
00403     /* le produit de deux shape sur la position d'un atome
00404        n'est nul que si les deux shapes font partie
00405        d'un element commun : on a une seul boucle pricipale sur
00406        les elements */
00407 
00408 
00409     for (int k =0 ; k < taille ; ++k){
00410       int * indN = indirectionNode[k];
00411       int * indA = currentIndirectionAtome[k];
00412 
00413       FullMatrix & mat = *SubMatrix[k];    
00414 
00415       /* ici on met la double boucle sur les noeuds pour calculer la sous matrice de la grande */
00416 
00417       for (int j1 = 0 ; j1 < mat.n() ; ++j1)
00418         for (int j2 = 0 ; j2 < mat.n() ; ++j2)
00419           {
00420             /* ici on met la boucle de la somme sur les atomes */
00421             for (int i = 0 ; i < mat.m()-1 ; ++i){
00422 
00423               C(indN[j1],indN[j2]) += mat(i,j1) * mat(i,j2) / lambdas[indA[i]];
00424               DUMP("C[" << indN[j1] << "," << indN[j2] << "] = " << C(indN[j1],indN[j2]),DBG_ALL);
00425             }
00426           }
00427     }
00428     
00429   };
00430 
00431 
00432 
00433   void correct_forme_faible(double & v,Vector & rhs,double * lamb,int at,unsigned int elem){
00434     int * indN = indirectionNode[elem];
00435     int * indA = currentIndirectionAtome[elem];
00436     FullMatrix & mat = *SubMatrix[elem];    
00437 
00438     /*     trouve l'atome concerné */
00439     int i,j;
00440     for (i = 0 ; i < mat.m()-1; ++i)
00441       if (indA[i] == at) 
00442         break;
00443 
00444 
00445     for (j = 0 ; j < mat.n() ; ++j){
00446       v -= mat(i,j)*rhs(indN[j])/lamb[at];
00447     }
00448 
00449   };
00450 
00451   //****************************************************************
00452   //network operations
00453   //****************************************************************
00454 
00455 /*   void TransitThroughNetwork(Communicator & communicator,DuoDistributedVecteur & coms,int groupefrom,int groupedest){  */
00456 /*     // premiere chose, je fait une boucle sur les blocks car c'est eux qui conditionnent le nombre d'envois  */
00457 /*     unsigned int nb_coms = coms.nb_blocks();  */
00458 
00459 /*      DUMP("on va faire " << nb_coms << " communications");  */
00460     
00461 /*      for(unsigned int com=0; com < nb_coms ; ++com){  */
00462 /*        int offset=0;  */
00463 /*        int sendsize=0;  */
00464     
00465 /*        // comme les atomes sont rangés par elements et non par atomes on va devoir faire des parcours pour filtrage  */
00466 /*        //on commence le parcours   */
00467       
00468 /*        for (int elem = 0 ; elem < taille ; ++elem){    */
00469 /*      int nb_atoms_for_com=0;  */
00470         
00471 /*      int * indA = indirectionAtome[elem];  */
00472 /*      int m = tailles[elem*2]; */
00473 /*      int n = tailles[elem*2+1]; */
00474 
00475 /*      //je compte les atomes qui sont pour com  */
00476 /*      for (int i = 0 ; i < m;++i)  */
00477 /*        if(coms.isInBlock(indA[i],com))  */
00478 /*          ++nb_atoms_for_com;  */
00479 
00480 /*      //premier cas : la matrice ne contient que des atomes pour le destinataire com   */
00481 /*      //je continue je n'envoi pas de suite  */
00482 /*      if(nb_atoms_for_com==m){  */
00483 /*        //j'augmente la taille a envoyer de 1 element  */
00484 /*        ++sendsize; */
00485 /*        continue; */
00486 /*      }  */
00487 
00488 /*      FullMatrix & mat = *SubMatrix[offset];  */
00489 
00490 /*      //dans les autres cas je commence par envoyer ce qui est en attente  */
00491 /*      //pour cela je commence par le tableau de tailles qui correspond aux matrices en attentes  */
00492 /*      communicator.SendIntegers(&sendsize,1,com,groupedest);  */
00493 /*      communicator.SendIntegers(tailles+2*offset,sendsize*2,com,groupedest);  */
00494 /*      //j'envoie ensuite les vecteur d'indirection  */
00495 /*      communicator.SendIntegers(indirectionAtome[offset], */
00496 /*                                indirectionAtome[offset+sendsize+1]-indirectionAtome[offset], */
00497 /*                                com,groupedest);  */
00498 /*      communicator.SendIntegers(indirectionNode[offset], */
00499 /*                                indirectionNode[offset+sendsize+1]-indirectionNode[offset], */
00500 /*                                com,groupedest);  */
00501 /*      //finalement j'envoie le gros bloc des resultats de shapes */
00502 /*      commnuicator.SendDoubles(&mat(0,0)); */
00503 
00504 /*      //je remet a zero sendsize et je remet l'offset sur l'element courant */
00505 /*      offset = elem; */
00506 /*      sendsize = 0; */
00507 
00508 /*      //deuxieme cas : la matrice ne contient aucun atomes pour le destinataire com */
00509 /*      // je poursuit la boucle */
00510 /*      if(nb_atoms_for_com==0){ */
00511 /*        ++offset; */
00512 /*        continue; */
00513 /*      } */
00514 
00515 /*      //troisieme cas : la matrice contient certain atomes pour le destinataire com */
00516 /*      else{ */
00517 /*        sendsize=1; */
00518 
00519 /*        //alors je reconstruit une matrice que j'envoie */
00520 /*        int new_m = nb_atoms_for_com+1; */
00521 /*        double * mat_tmp = new double[new_m*n]; */
00522 /*        memset(mat_tmp,0,new_m*n); */
00523 
00524 /*        int taille_tmp[2]; */
00525 /*        taille_tmp[0] = mew_m; */
00526 /*        taille_tmp[1] = n; */
00527           
00528 /*        int index = 0; */
00529 
00530 /*        //je rempli la nouvelle matrice */
00531 /*        for (int i = 0 ; i < m;++i)  */
00532 /*          if(coms.isInBlock(indA[i],com)){ */
00533 /*            for (int j=0; j < n ; ++j){ */
00534 /*              mat_tmp[index+new_m*j] = mat(i,j); */
00535 /*              mat_tmp[new_m-1+new_m*j]+=mat(i,j); */
00536 /*            } */
00537 /*            ++index; */
00538 /*          } */
00539           
00540 /*        //je l'envoie de la meme maniere par le reseau */
00541 /*        communicator.SendIntegers(&sendsize,1,com,groupedest); */
00542 /*        communicator.SendIntegers(taille_tmp,2,com,groupedest); */
00543 /*        //j'envoie les vecteurs d'indirection */
00544 
00545 /*        delete [] mat_tmp; */
00546           
00547 /*      } */
00548           
00549           
00550 /*        } */
00551 /*      } */
00552 /*   } */
00553     
00554   int * indirectionAtomTable(){
00555     return indA_contigu;
00556   }
00557 
00558   void swapAtomIndirections(){
00559     int ** temp = currentIndirectionAtome;
00560     currentIndirectionAtome = newIndirectionAtome;
00561     newIndirectionAtome = temp;
00562   }
00563   
00564 
00565  private:
00566 
00567   //  friend class Bridging;  
00568   int taille;
00569 
00570   unsigned int * tailles;
00571 
00572   FullMatrix ** SubMatrix;
00573   int ** currentIndirectionAtome; // indirection vers le vecteur pricipal atomes
00574   int ** newIndirectionAtome; // indirection vers le vecteur pricipal atomes
00575 
00576   int ** indirectionAtome[2]; // indirection vers le vecteur pricipal atomes
00577 
00578   int ** indirectionNode; // indirection vers le vecteur principal noeuds
00579   int ** indirectionGlobalNode; // indirection vers des references de noeuds
00580   int * remplissageA; // indice de remplissage de la matrice locale selon les atomes
00581   int * remplissageN; // indice de remplissage de la matrice locale selon les noeuds
00582 
00583   //ici je place les tableau contigu des données pour etre sur que la structure est bien
00584   //contigu je fait des allocation spéciales
00585   
00586   double * tab_contigu;  
00587   int * indA_contigu[2];
00588 
00589   int * indN_contigu;
00590   int * indGN_contigu;
00591 };
00592 
00593 #endif

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