00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042 #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
00073
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
00094
00095
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
00116 unsigned int taille = Parent::noeuds_rec.nbElem();
00117 PM = new FullMatrix(taille,taille);
00118
00119 PM->zero();
00120
00121
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
00190 A->PrintToFile("constraint.mat");
00191
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
00283
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
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>;