mymethod.cpp

Go to the documentation of this file.
00001 /* ./bridging/mymethod.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 LOCAL_MODULE MOD_COUPLING
00049 
00050 template <typename DomainA, typename DomainC,unsigned int Dim>
00051 void MyMethodFull<DomainA,DomainC,Dim>::Init(){
00052 
00053   DUMP("Computing freedom degrees weight",DBG_INFO);
00054   Parent::BuildAtomsWeight();
00055   Parent::BuildContinuWeight();  
00056 
00057   Parent::BuildPositions();
00058   Parent::BuildShapeMatrix(Parent::positions,Parent::atomes_rec.nbElem());
00059   delete [] Parent::positions;
00060 
00061   Parent::BuildFictifsPositions();
00062   BuildShapeMatrixFictifs(Parent::positions,Parent::atomes_fictifs.nbElem());
00063   delete [] Parent::positions;
00064 
00065   Parent::CorrectSurfaceEffect();
00066 
00067   unsigned int taille = Parent::atomes_rec.nbElem();
00068   dist = new double[taille];
00069   orig_FE = new double[taille];
00070   orig_atom = new double[taille];
00071 
00072   DUMP("Allocating matrix (" << taille << ")",DBG_INFO);  
00073   A = new FullMatrix(taille,taille);
00074   //  A_sav = new FullMatrix(taille,taille);
00075   lagrange2 = new double[taille];
00076 
00077 
00078   DUMP("Allocating vector",DBG_INFO);  
00079   rhs = new Vector(taille);
00080   rhs->zero();
00081   A->zero();
00082   //A_sav->zero();
00083   
00084   DUMP("BuildConstraintMatrices",DBG_INFO);
00085   BuildConstraintMatrix();
00086   DUMP("Init done",DBG_INFO);
00087 }
00088 
00089 template <typename DomainA, typename DomainC,unsigned int Dim>
00090 void MyMethodFull<DomainA,DomainC,Dim>::Stucking(){
00091   /* c l'implementation de la methode generique qui
00092      colle les deux domaines ensemble sur la zone de 
00093      recouvrement */
00094 
00095   STARTTIMER("Correct Surface Effect");
00096   Parent::CorrectSurfaceEffect();
00097   STOPTIMER("Correct Surface Effect");
00098 
00099   STARTTIMER();
00100   BuildRHS();
00101   STOPTIMER("BuildRHS");
00102   
00103   STARTTIMER();
00104   SolveConstraint();
00105   STOPTIMER("Solving constraint");
00106   
00107   STARTTIMER();
00108   ApplyCorrection();
00109   STOPTIMER("Correcting");
00110   
00111 
00112 }
00113 
00114 template <typename DomainA, typename DomainC,unsigned int Dim>
00115 void MyMethodFull<DomainA,DomainC,Dim>::BuildConstraintMatrix(){
00116   /* ici demarre l'algo de recoupement des éléments 
00117 
00118   On associe dans un tableau de taille nbElementRec 
00119   des petites matrices de taille nb_atome_par_element x connectivite 
00120   
00121   qui vont conenir un bloc de la  ShapeMatrix 
00122 
00123   pour cela on commence par creer un tableau qui donne l'element conteneur 
00124   pour chaque atome
00125 
00126   ensuite il nous faut le nombre de d'atomes par elements
00127 
00128   ensuite on parcours les elements et on creer la matrice
00129   aux bonnes dimensions et on la remplie !!
00130 
00131   ZONE : Continu
00132   */
00133 
00134   MechaContLibMesh<Dim> & model = static_cast<MechaContLibMesh<Dim>&>(Parent::domC.getModel());  
00135   double xI,xJ;
00136   std::vector<unsigned int> nodesI;
00137   std::vector<unsigned int> nodesJ;
00138   std::vector<double> shapesI;
00139   std::vector<double> shapesJ;
00140 
00141   A->zero();
00142 
00143   int taille = Parent::atomes_rec.nbElem();
00144 
00145   for (int i = 0; i < taille ; ++i)
00146     for (int j = 0; j < taille ; ++j){
00147 
00148       xI = Parent::atomes_rec.Get(i).position0(0);
00149       xJ = Parent::atomes_rec.Get(j).position0(0);
00150 
00151       model.GlobalIndexes(Parent::elems_rec.Get(Parent::assoc[i]),nodesI);
00152       model.GlobalIndexes(Parent::elems_rec.Get(Parent::assoc[j]),nodesJ);
00153 
00154       model.ComputeShapes(Parent::elems_rec.Get(Parent::assoc[i]),shapesI,xI);
00155       model.ComputeShapes(Parent::elems_rec.Get(Parent::assoc[j]),shapesJ,xJ);
00156 
00157       if (nodesI[0] == nodesJ[0]){
00158         (*A)(i,j) += shapesI[0]*shapesJ[0]/model.Mass(nodesI[0]);
00159         //(*A)(i,j) += shapesI[0]*shapesJ[0];
00160       }
00161 
00162       if (nodesI[1] == nodesJ[1]){
00163         (*A)(i,j) += shapesI[1]*shapesJ[1]/model.Mass(nodesI[1]);
00164         //(*A)(i,j) += shapesI[1]*shapesJ[1];
00165       }
00166 
00167       if (nodesI[0] == nodesJ[1]){
00168         (*A)(i,j) += shapesI[0]*shapesJ[1]/model.Mass(nodesI[0]);
00169         //(*A)(i,j) += shapesI[0]*shapesJ[1];
00170       }
00171 
00172       if (nodesI[1] == nodesJ[0]){
00173         (*A)(i,j) += shapesI[1]*shapesJ[0]/model.Mass(nodesI[1]);
00174         //(*A)(i,j) += shapesI[1]*shapesJ[0];
00175       }
00176     }
00177 
00178   A->PrintToFile("constraint_matrix.mat"); 
00179   //la factoLU
00180   A->FactoLU();
00181 }
00182 
00183 static std::ofstream out_rhs("rhs_matrix.mat");
00184 static std::ofstream out_dist("dist.plot");
00185 
00186 template <typename DomainA, typename DomainC,unsigned int Dim>
00187 void MyMethodFull<DomainA,DomainC,Dim>::BuildRHS(){
00188 
00189   std::vector<unsigned int> nodesI;
00190   std::vector<double> shapesI;
00191 
00192   double xI;
00193   MechaContLibMesh<Dim> & model = static_cast<MechaContLibMesh<Dim>&>(Parent::domC.getModel());  
00194   typename Parent::_Vec_ & v = Parent::domC.getDofs().V();
00195 
00196   rhs->zero();
00197   int taille = Parent::atomes_rec.nbElem();
00198 
00199   for (int i = 0 ; i < taille ; ++i){
00200     xI = Parent::atomes_rec.Get(i).position0(0);      
00201 
00202     model.GlobalIndexes(Parent::elems_rec.Get(Parent::assoc[i]),nodesI);
00203     model.ComputeShapes(Parent::elems_rec.Get(Parent::assoc[i]),shapesI,xI);
00204 
00205     (*rhs)(i) = v(nodesI[0])*shapesI[0] + v(nodesI[1])*shapesI[1] - Parent::atomes_rec.Get(i).vitesse(0);
00206     lagrange2[i] = (*rhs)(i);
00207     (*rhs)(i) *= Parent::lambdasA[i];
00208 
00209     dist[i] = (1-Parent::lambdasA[i])*(v(nodesI[0])*shapesI[0] + v(nodesI[1])*shapesI[1]) + Parent::lambdasA[i]*Parent::atomes_rec.Get(i).vitesse(0);
00210     orig_FE[i] = v(nodesI[0])*shapesI[0] + v(nodesI[1])*shapesI[1];
00211     orig_atom[i] = Parent::atomes_rec.Get(i).vitesse(0);
00212   }
00213 
00214   for (int i=0; i<taille; ++i)
00215     {
00216       out_rhs << i+1 << "\t" << current_step  << "\t" << lagrange2[i] << std::endl;
00217     }
00218 }
00219   
00220 template <typename DomainA, typename DomainC,unsigned int Dim>
00221 void MyMethodFull<DomainA,DomainC,Dim>::SolveConstraint(){
00222   int taille = Parent::atomes_rec.nbElem();
00223 
00224   for (int i=0; i<taille; ++i)
00225     {
00226       DUMP("rhs[" << i << "] = " << (*rhs)(i),DBG_ALL);
00227     }  
00228 
00229   A->Solve(rhs);
00230 
00231   for (int i=0; i<taille; ++i)
00232     {
00233       DUMP("multL[" << i << "] = " << (*rhs)(i),DBG_ALL);
00234     }  
00235 }
00236   
00237 
00238 template <typename DomainA, typename DomainC,unsigned int Dim>
00239 void MyMethodFull<DomainA,DomainC,Dim>::ApplyCorrection(){
00240 
00241   double xI;
00242 
00243   typename Parent::_Vec_ & v = Parent::domC.getDofs().V();
00244   std::vector<unsigned int> nodesI;
00245   std::vector<double> shapesI;
00246   MechaContLibMesh<Dim> & model = static_cast<MechaContLibMesh<Dim>&>(Parent::domC.getModel());  
00247   int taille = Parent::atomes_rec.nbElem();
00248   
00249   for (int i = 0 ; i < taille ; ++i)
00250     {
00251       xI = Parent::atomes_rec.Get(i).position0(0);
00252       //correction des atomes
00253       Parent::atomes_rec.Get(i).vitesse(0) += (1-Parent::lambdasA[i])*lagrange2[i];
00254 
00255       model.GlobalIndexes(Parent::elems_rec.Get(Parent::assoc[i]),nodesI);
00256       
00257       model.ComputeShapes(Parent::elems_rec.Get(Parent::assoc[i]),shapesI,xI);
00258       DUMP(xI << " node1 " << nodesI[0] << " nodes2 " << nodesI[1],DBG_ALL);
00259       DUMP("pour " << xI << " correction = " << -1.0*(*rhs)(i)*shapesI[0]/model.Mass(nodesI[0]) << " et " << 
00260            -1.0*(*rhs)(i)*shapesI[1]/model.Mass(nodesI[1]),DBG_ALL);
00261       v.add(nodesI[0],-1.0*(*rhs)(i)*shapesI[0]/model.Mass(nodesI[0]));
00262       v.add(nodesI[1],-1.0*(*rhs)(i)*shapesI[1]/model.Mass(nodesI[1]));
00263 //      v.add(nodesI[0],-1.0*(*rhs)(i)*shapesI[0]);
00264 //      v.add(nodesI[1],-1.0*(*rhs)(i)*shapesI[1]);
00265     }
00266 
00267   v.close();
00268   for (int i = 0 ; i < taille ; ++i){
00269     xI = Parent::atomes_rec.Get(i).position0(0);
00270     model.GlobalIndexes(Parent::elems_rec.Get(Parent::assoc[i]),nodesI);
00271     model.ComputeShapes(Parent::elems_rec.Get(Parent::assoc[i]),shapesI,xI);
00272     double new_dist = (1-Parent::lambdasA[i])*(v(nodesI[0])*shapesI[0] + v(nodesI[1])*shapesI[1]) + 
00273       Parent::lambdasA[i]*Parent::atomes_rec.Get(i).vitesse(0);
00274     double contrainte = v(nodesI[0])*shapesI[0] + v(nodesI[1])*shapesI[1] - Parent::atomes_rec.Get(i).vitesse(0);
00275     out_dist << current_step << "\t"  << xI << "\t" << dist[i] << "\t" <<  new_dist << "\t" << orig_FE[i] <<  "\t" << orig_atom[i] << "\t" << Parent::atomes_rec.Get(i).vitesse(0) << "\t" << v(nodesI[0])*shapesI[0] + v(nodesI[1])*shapesI[1] << "\t" << (*rhs)(i) << "\t" << Parent::lambdasA[i]*lagrange2[i] << "\t" << contrainte << std::endl;
00276   }
00277 
00278 
00279 
00280 }
00281 
00282 #ifdef USING_STAMP
00283 template class MyMethodFull<DomainStamp,DomainLibMesh<1>,1>;
00284 template class MyMethodFull<DomainStamp,DomainLibMesh<2>,2>;
00285 #endif
00286 #ifdef USING_LAMMPS
00287 template class MyMethodFull<DomainLammps,DomainLibMesh<2>,2>;
00288 template class MyMethodFull<DomainLammps,DomainLibMesh<3>,3>;
00289 #endif
00290 template class MyMethodFull<DomainMD1D,DomainLibMesh<1>,1>;

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