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 #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
00103
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
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
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
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
00190 FullMatrix & m = *SubMatrix[el];
00191 m(remplissageA[el],remplissageN[el]) = value;
00192
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
00230
00231
00232 for (int k =0 ; k < taille ; ++k){
00233
00234 FullMatrix & mat = *SubMatrix[k];
00235
00236
00237 int * indGN = indirectionGlobalNode[k];
00238 int * indA = currentIndirectionAtome[k];
00239
00240 for (int i = 0 ; i < mat.m()-1; ++i)
00241
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
00264
00265
00266 for (int k =0 ; k < taille ; ++k){
00267
00268 FullMatrix & mat = *SubMatrix[k];
00269
00270
00271 int * indGN = indirectionGlobalNode[k];
00272 int * indN = indirectionNode[k];
00273 int * indA = currentIndirectionAtome[k];
00274
00275 for (int i = 0 ; i < mat.m()-1; ++i)
00276
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
00298 int i;
00299 for (i = 0 ; i < mat.m()-1; ++i)
00300 if (indA[i] == at)
00301 break;
00302
00303
00304
00305
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
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
00336 int j;
00337 for (j = 0 ; j < mat.n(); ++j)
00338 nodes.push_back(indGN[j]);
00339 };
00340
00341
00342
00343
00344
00345 void buildLeastSquareMatrix(FullMatrix * A){
00346 A->zero();
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356 for (int k =0 ; k < taille ; ++k){
00357 int * indN = indirectionNode[k];
00358 FullMatrix & mat = *SubMatrix[k];
00359
00360
00361
00362
00363 for (int j1 = 0 ; j1 < mat.n() ; ++j1)
00364 for (int j2 = 0 ; j2 < mat.n() ; ++j2)
00365 {
00366
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
00385 int i,j;
00386 for (i = 0 ; i < mat.m()-1; ++i)
00387 if (indA[i] == at)
00388 break;
00389
00390
00391
00392 for (j = 0 ; j < mat.n(); ++j)
00393 (*rhs)(indN[j]) += mat(i,j)*v;
00394
00395 };
00396
00397
00398
00399
00400 void buildFormeFaibleCMatrix(FullMatrix & C,double * lambdas){
00401
00402
00403
00404
00405
00406
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
00416
00417 for (int j1 = 0 ; j1 < mat.n() ; ++j1)
00418 for (int j2 = 0 ; j2 < mat.n() ; ++j2)
00419 {
00420
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
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
00453
00454
00455
00456
00457
00458
00459
00460
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521
00522
00523
00524
00525
00526
00527
00528
00529
00530
00531
00532
00533
00534
00535
00536
00537
00538
00539
00540
00541
00542
00543
00544
00545
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
00568 int taille;
00569
00570 unsigned int * tailles;
00571
00572 FullMatrix ** SubMatrix;
00573 int ** currentIndirectionAtome;
00574 int ** newIndirectionAtome;
00575
00576 int ** indirectionAtome[2];
00577
00578 int ** indirectionNode;
00579 int ** indirectionGlobalNode;
00580 int * remplissageA;
00581 int * remplissageN;
00582
00583
00584
00585
00586 double * tab_contigu;
00587 int * indA_contigu[2];
00588
00589 int * indN_contigu;
00590 int * indGN_contigu;
00591 };
00592
00593 #endif