formefaible.cpp

Go to the documentation of this file.
00001 /* ./bridging/formefaible.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 NEED_STAMP
00043 #define NEED_LAMMPS
00044 #define NEED_LIBMESH
00045 #define NEED_MD1D
00046 
00047 #define ORDRE LINEAR
00048 #define ZERO_LIMIT 1e-5
00049 
00050 #define LOCAL_MODULE MOD_COUPLING
00051 
00052 template <typename DomainA, typename DomainC,unsigned int Dim>
00053 void FormeFaible<DomainA,DomainC,Dim>::Init(){
00054 
00055   DUMP("Computing freedom degrees weight",DBG_INFO);
00056   Parent::BuildAtomsWeight();
00057   Parent::BuildContinuWeight();  
00058 
00059   DUMP("Computing initial constraint",DBG_INFO);
00060   unsigned int taille = Parent::noeuds_rec.nbElem();
00061 
00062   DUMP("Building Shape matrix",DBG_INFO);
00063 
00064   Parent::BuildPositions();
00065   Parent::BuildShapeMatrix(Parent::positions,Parent::atomes_rec.nbElem());
00066   delete [] Parent::positions;
00067 
00068   Parent::BuildFictifsPositions();
00069   Parent::BuildShapeMatrix(Parent::positions,Parent::atomes_fictifs.nbElem());
00070   delete [] Parent::positions;
00071 
00072   /* corrige les pondération pour tenir compte de la masse */
00073   /* aussi pour mettre en place l'offset minimal */
00074 
00075   DUMP("Correcting weights",DBG_INFO);
00076   CorrectWeights();
00077 
00078   A = new FullMatrix(taille,taille);
00079   A->zero();
00080   rhs = new Vector(taille);
00081   rhs->zero();
00082 
00083   DUMP("Computing Continu Constraint Matrix",DBG_INFO);
00084   BuildContinuConstraintMatrix();
00085 
00086   DUMP("Computing Atoms Constraint Matrix",DBG_INFO);
00087   BuildAtomsConstraintMatrix();
00088 
00089 }
00090 
00091 template <typename DomainA, typename DomainC,unsigned int Dim>
00092 void FormeFaible<DomainA,DomainC,Dim>::Stucking(){
00093   /* c l'implementation de la methode generique qui
00094      colle les deux domaines ensemble sur la zone de 
00095      recouvrement */
00096 
00097    STARTTIMER();
00098    BuildContinuRHS();
00099    BuildAtomsRHS();
00100    STOPTIMER("BuildRHS");
00101   
00102    STARTTIMER();
00103    SolveConstraint();
00104    STOPTIMER("Solving constraint");
00105   
00106    STARTTIMER();
00107    ApplyContinuCorrection();
00108    ApplyAtomsCorrection();
00109    STOPTIMER("Correcting");
00110 }
00111 
00112 template <typename DomainA, typename DomainC,unsigned int Dim>
00113  void FormeFaible<DomainA,DomainC,Dim>::BuildContinuConstraintMatrix(){
00114 
00115   // creation de la matrice de pseudo mass (mass matric without rho coef)
00116   unsigned int taille = Parent::noeuds_rec.nbElem();
00117   PM = new FullMatrix(taille,taille);
00118   //zeroing
00119   PM->zero();
00120 
00121   // preparing course on elements in bridging zone
00122   typename Parent::IteratorElemsRec & itc = Parent::elems_rec.GetIterator();
00123   typename Parent::RefElt el = itc.GetFirst();
00124   MechaContLibMesh<Dim> & model = static_cast<MechaContLibMesh<Dim>&>(Parent::domC.getModel());
00125 
00126   std::vector<double> JxW;
00127   std::vector<std::vector<double> > shapes;
00128   std::vector<unsigned int> nodes;
00129 
00130   while (!itc.end()){
00131 
00132     model.ComputeShapesForIntegration(el,JxW,shapes);
00133     unsigned int integ_size = JxW.size();    
00134     
00135     model.GlobalIndexes(el,nodes);
00136     unsigned int nb_nodes = nodes.size();
00137 
00138     for (unsigned int i=0; i<nb_nodes; i++)
00139       for (unsigned int j=0; j<nb_nodes; j++)
00140         {
00141           int i_rec = Parent::noeuds_rec.Recherche(nodes[i]);
00142           int j_rec = Parent::noeuds_rec.Recherche(nodes[j]);
00143 
00144           if (i_rec == -1 || j_rec == -1){
00145             int tmp=-1;
00146             if (i_rec == -1)
00147               tmp = nodes[i];
00148             if (j_rec == -1)
00149               tmp = nodes[j];
00150                     
00151             FATAL("huge pbroblem here for index " << tmp);
00152           }
00153 
00154           for (unsigned int qp=0; qp<integ_size; qp++)
00155             {
00156               
00157               
00158               DUMP("PM(" << i_rec << "," << j_rec << ") += " << JxW[qp] << "*" << shapes[i][qp] 
00159                    << "*" << shapes[j][qp] << "=" << JxW[qp]*shapes[i][qp]*shapes[j][qp],DBG_ALL);
00160               (*PM)(i_rec,j_rec) += JxW[qp]*shapes[i][qp]*shapes[j][qp];
00161               
00162             }
00163         }
00164     el = itc.GetNext();
00165   }
00166 
00167   PM->PrintToFile("PM.mat");
00168 
00169   for (unsigned int i = 0; i < taille ; ++i)
00170     for (unsigned int j = 0; j < taille ; ++j)
00171       for (unsigned int k = 0; k < taille ; ++k)
00172       {
00173         (*A)(i,j) += (*PM)(i,k)*(*PM)(j,k)/Parent::lambdasC[k];
00174       }
00175 
00176 
00177   A->PrintToFile("A.mat");
00178 
00179 
00180 
00181 }
00182 
00183 template <typename DomainA, typename DomainC,unsigned int Dim>
00184  void FormeFaible<DomainA,DomainC,Dim>::BuildAtomsConstraintMatrix(){
00185 
00186   A->zero();
00187   Parent::Smatrix->buildFormeFaibleCMatrix(*A,Parent::lambdasA);
00188 
00189   //#if PRIORITY<=5
00190   A->PrintToFile("constraint.mat");
00191   //#endif
00192 
00193   A->FactoLU();
00194 }
00195 
00196 
00197 template <typename DomainA, typename DomainC,unsigned int Dim>
00198 void FormeFaible<DomainA,DomainC,Dim>::BuildContinuRHS(){
00199 
00200   rhs->zero();
00201   
00202   typename Parent::RefNode n;
00203   typename Parent::_Vec_ & v = Parent::domC.getDofs().V();
00204 
00205   unsigned int taille = Parent::noeuds_rec.nbElem();
00206 
00207   for (unsigned int i = 0 ; i < taille ; ++i)
00208     for (unsigned int j = 0 ; j < taille ; ++j)
00209     {
00210       n = Parent::noeuds_rec.Get(j);
00211       (*rhs)(i) -= v(n)*(*PM)(i,j);
00212     }
00213 
00214 
00215 }
00216 
00217  template <typename DomainA, typename DomainC,unsigned int Dim>  
00218  void FormeFaible<DomainA,DomainC,Dim>::BuildAtomsRHS(){
00219 
00220    Parent::CorrectSurfaceEffect();
00221   
00222    typename Parent::IteratorAtomsRec & itrec = Parent::atomes_rec.GetIterator();
00223    typename Parent::RefAtom at;
00224    
00225    at = itrec.GetFirst();
00226    
00227    unsigned int at_index=0;
00228    
00229    while (!itrec.end())
00230      {
00231        Parent::Smatrix->build_least_square_rhs(rhs,at_index,Parent::assoc[at_index],at.vitesse(0));
00232        at = itrec.GetNext();
00233        ++at_index;
00234      }
00235    
00236  }
00237 
00238 template <typename DomainA, typename DomainC,unsigned int Dim>
00239 void FormeFaible<DomainA,DomainC,Dim>::SolveConstraint(){
00240 
00241   A->Solve(rhs);
00242 }
00243 
00244 
00245 template <typename DomainA, typename DomainC,unsigned int Dim>
00246 void FormeFaible<DomainA,DomainC,Dim>::ApplyContinuCorrection(){
00247 
00248   unsigned int taille = Parent::noeuds_rec.nbElem();
00249   typename Parent::_Vec_ & v = Parent::domC.getDofs().V();
00250   typename Parent::RefNode n;
00251 
00252   for (unsigned int i = 0; i < taille ; ++i)
00253     for (unsigned int k = 0; k < taille ; ++k)
00254       {
00255         n = Parent::noeuds_rec.Get(i);
00256         v.add(n,(*PM)(i,k)*(*rhs)(k)/Parent::lambdasC[i]);
00257       }
00258 }
00259 
00260 template <typename DomainA, typename DomainC,unsigned int Dim>
00261 void FormeFaible<DomainA,DomainC,Dim>::ApplyAtomsCorrection(){
00262 
00263    typename Parent::IteratorAtomsRec & itrec = Parent::atomes_rec.GetIterator();
00264    typename Parent::RefAtom at;
00265    
00266    at = itrec.GetFirst();
00267    
00268    unsigned int at_index=0;
00269    
00270    while (!itrec.end())
00271      {
00272        Parent::Smatrix->correct_forme_faible(at.vitesse(0),*rhs,Parent::lambdasA,at_index,Parent::assoc[at_index]);
00273        at = itrec.GetNext();
00274        ++at_index;
00275      }
00276  }
00277 
00278 
00279 
00280 template <typename DomainA, typename DomainC,unsigned int Dim>
00281 void FormeFaible<DomainA,DomainC,Dim>::CorrectWeights(){
00282   /* corrige les pondération pour tenir compte de la masse */
00283   /* aussi pour mettre en place l'offset minimal */
00284 
00285   unsigned int nb = Parent::noeuds_rec.nbElem();
00286 
00287   if (!nb){FATAL("On a trouve aucun noeud dans le recouvrement");}
00288   DUMP("On a trouve " << nb << " noeuds concernes dans " << Parent::elems_rec.nbElem() << " elements",DBG_DETAIL);
00289 
00290   MechaContLibMesh<Dim> & model = static_cast<MechaContLibMesh<Dim> &>(Parent::domC.getModel());
00291 
00292 #ifdef ALPHA_INSIDE
00293   typename Parent::_Vec_ * alpha = NULL;
00294 
00295   if (dynamic_cast<MechaContLibMeshArlequin*>(&model)){
00296     alpha = dynamic_cast<MechaContLibMeshArlequin&>(model).Alpha();
00297   }
00298 #endif
00299 
00300   typename Parent::IteratorNodesRec & itrec = Parent::noeuds_rec.GetIterator();
00301   typename Parent::RefNode n = itrec.GetFirst();
00302   int j = 0;
00303 
00304   while (!itrec.end())
00305     {
00306       if (Parent::lambdasC[j] < ZERO_LIMIT)
00307         Parent::lambdasC[j] = offset_min;
00308       DUMP("lambdasC[" << n << "]=" << Parent::lambdasC[j],DBG_ALL);
00309 
00310 #ifdef ALPHA_INSIDE
00311       if (alpha)
00312         (*alpha).set(n,lambdasC[j]); 
00313 #endif
00314 
00315       Parent::lambdasC[j] *= model.Mass(n); 
00316 
00317       n = itrec.GetNext();
00318       ++j;
00319     }
00320 
00321   //les atomes 
00322 
00323   nb = Parent::atomes_rec.nbElem();
00324   if (!nb){FATAL("On a trouve aucun atome dans le recouvrement");}
00325   DUMP("On a touve " << nb << " atomes concernes",DBG_DETAIL);
00326  
00327   typename Parent::IteratorAtomsRec & itrec2 = Parent::atomes_rec.GetIterator();
00328   typename Parent::RefAtom at = itrec2.GetFirst();
00329   int i = 0;
00330 
00331   while (!itrec2.end())
00332     {
00333       if (Parent::lambdasA[i] < ZERO_LIMIT)
00334         Parent::lambdasA[i] = offset_min;
00335       DUMP("lambdasA[" << i << "]=" << Parent::lambdasA[i],DBG_ALL);
00336 
00337 #ifdef ALPHA_INSIDE
00338       at.alpha() = lambdasA[i];
00339 #endif
00340 
00341       Parent::lambdasA[i] *= at.masse();
00342 
00343       at = itrec2.GetNext();
00344       ++i;
00345     }
00346 
00347 }
00348 
00349 #ifdef USING_STAMP
00350 template class FormeFaible<DomainStamp,DomainLibMesh<1>,1>;
00351 template class FormeFaible<DomainStamp,DomainLibMesh<2>,2>;
00352 #endif
00353 #ifdef USING_LAMMPS
00354 template class FormeFaible<DomainLammps,DomainLibMesh<2>,2>;
00355 template class FormeFaible<DomainLammps,DomainLibMesh<3>,3>;
00356 #endif
00357 template class FormeFaible<DomainMD1D,DomainLibMesh<1>,1>;

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