00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include "QCKimikaPartitioner.hpp"
00019
00020
00021 #include <fstream>
00022 #include <iomanip>
00023 #include <sstream>
00024
00025
00026 #include "QCSystem.hpp"
00027 #include "QCMDSystem.hpp"
00028 #include "QCDistMDSystem.hpp"
00029 #include "QCGlobalSystem.hpp"
00030 #include "QCDCAlgo.hpp"
00031 #include "QCSCFAlgo.hpp"
00032
00033
00034 #define QC_PART_NONE -1
00035
00036
00037
00038
00039
00043 template <class TPSystem>
00044 QCKimikaPartitioner<TPSystem>::QCKimikaPartitioner (void) :
00045 QCPartitioner<TPSystem> (), frag_nexttab(NULL), frag_firsttab(NULL),
00046 sd_nexttab(NULL), sd_firsttab(NULL), parttab_size(0), parttab(NULL),
00047 globtab(NULL), lnumtab(NULL), lcortab(NULL), lovltab(NULL),_fileName("")
00048 {}
00049
00053 template <class TPSystem>
00054 QCKimikaPartitioner<TPSystem>::~QCKimikaPartitioner (void)
00055 {
00056 finalize();
00057 }
00058
00059
00060
00061
00065 template <class TPSystem>
00066 void
00067 QCKimikaPartitioner<TPSystem>::init (const QCGeneralData& data, const QCFiles& Files,
00068 const int * , const int) {
00069 QC_TRACE_PART("BEGIN QCKimikaPartitioner<TPSystem>::init ");
00070 #ifdef DEV_OL
00071 std::cerr << " &&&&&&&&&&&&&&&&&&&& Faut-il passer ici &&&&&&&&&&&&&&&&&"<<std::endl;
00072
00073 #endif
00074 this->_fileName = QCCommon::datadir + PATH_SEPARATOR + Files.getAtomsFile() + ".qci" ;
00075 QC_TRACE_PART("END QCKimikaPartitioner<TPSystem>::init ");
00076 }
00077
00081 template <class TPSystem>
00082 void
00083 QCKimikaPartitioner<TPSystem>::partitioning (TPSystem& mdSystem) {
00084
00085 QC_TRACE_PART("BEGIN QCKimikaPartitioner<TPSystem>::partitioning ");
00089 srand(2);
00090
00091
00092 QCSystem& root = mdSystem.getRootSystem();
00093
00094 AtomsList listdat;
00095 AtomsGraph grandat;
00096 AtomsGraph grafdat;
00097 INT * QCRestrict velotab;
00098 FLOAT dsnbval;
00099
00100 dsnbval = FQCMax(this->radius1, this->radius2);
00104 atomsListInit (&listdat);
00105 atomsGraphInit(&grandat);
00106 atomsGraphInit(&grafdat);
00107
00108
00109 this->initAtomsList(listdat, root);
00110
00111
00112
00113
00114
00118 atomsChainNeighbor (&listdat, &grandat,
00119 0,
00120 ATOMSEDGETYPENGHB, (FLOAT) (dsnbval * dsnbval), NULL, 0);
00121
00122
00123
00124
00128 velotab = this->charge;
00129 this->parttab = new int [listdat.atomnbr];
00130 this->parttab_size = listdat.atomnbr;
00134
00135
00136 atomsPartScotch (&listdat, &grandat, velotab, this->nbPartitions, this->parttab);
00137 #ifdef QC_DEBUG_KIMIKA
00138 this->printPartTab("After atomsPartScotch");
00139 #endif
00140
00143 listdat.flagval = ATOMSLISTFREETABS;
00144 atomsListExit(&listdat);
00145 #ifdef QC_DEBUG_KIMIKA
00146 cout << ">> parttab CONTENT: " << endl;
00147 for (int i = 0; i < root.getNbAtoms(); ++i) {
00148 cout << "(" << i << "," << this->parttab[i] << ") "<<std::endl;
00149 }
00150 cout << endl;
00151 #endif
00152
00155 this->allocStructures();
00159 this->initPartChain();
00160 this->resetStructures();
00164 this->setAtomsInKernel();
00165
00169 this->setAtomsInBuffers(grandat);
00173
00174
00175
00176
00177
00178
00179
00183 this->extractDomains(mdSystem);
00184 this->updateInternalStructure(mdSystem);
00188 grandat.flagval = ATOMSGRAPHFREETABS;
00189 atomsGraphExit(&grandat);
00190 #if defined(QC_INVENTOR_PART)
00191
00194 if (mdSystem.getRank() == 0) {
00195 writeInventorFiles(root);
00196 }
00197 #endif
00198
00199
00200
00204 this->finalize();
00205 QC_TRACE_PART("END QCKimikaPartitioner<TPSystem>::partitioning ");
00206 }
00207
00208
00209
00210
00211
00215 template <class TPSystem>
00216 void
00217 QCKimikaPartitioner<TPSystem>::setAtomsInKernel (void) {
00218
00219 QC_TRACE_PART("BEGIN QCKimikaPartitioner<TPSystem>::setAtomsInKernel ");
00220 #ifndef QC_NO_DEBUG
00221 assert(sd_firsttab && sd_nexttab);
00222 assert(lnumtab);
00223 assert(globtab);
00224 #endif
00225 #ifdef QC_DEBUG_KIMIKA
00226 this->printGlobalTab("Before building core") ;
00227 #endif
00228 int i, j;
00229 for (j = 0; j < this->nbPartitions; ++j) {
00230 for (i = sd_firsttab[j]; i != -1 ; i = sd_nexttab[i]) {
00231 globtab[i*this->nbPartitions + j].typeval = QC_CORE;
00232 lnumtab[j]++;
00233 }
00234 }
00235 #ifdef QC_DEBUG_KIMIKA
00236 this->printGlobalTab("After building core") ;
00237 #endif
00238 QC_TRACE_PART("END QCKimikaPartitioner<TPSystem>::setAtomsInKernel ");
00239 }
00240
00241
00242
00243
00247 template <class TPSystem>
00248 void
00249 QCKimikaPartitioner<TPSystem>::allocStructures (void) {
00250
00251 sd_nexttab = new int [parttab_size];
00252 sd_firsttab = new int [this->nbPartitions];
00253 globtab = new AtomsPartGlobal [parttab_size * this->nbPartitions];
00254 lnumtab = new int [this->nbPartitions];
00255 lcortab = new int [this->nbPartitions];
00256 lovltab = new int [this->nbPartitions];
00257 }
00258
00259
00260
00264 template <class TPSystem>
00265 void
00266 QCKimikaPartitioner<TPSystem>::resetStructures (void) {
00267
00268 #ifndef QC_NO_DEBUG
00269 assert(lnumtab && lcortab && lovltab);
00270 assert(globtab);
00271 #endif
00272
00273 int i, j;
00274
00275 for (i = 0; i < this->nbPartitions; ++i) {
00276 lnumtab[i] = 0;
00277 lcortab[i] = 0;
00278 lovltab[i] = 0;
00279
00280 for (j = 0; j < parttab_size; ++j) {
00281 globtab[j*this->nbPartitions + i].typeval = QC_PART_NONE;
00282 globtab[j*this->nbPartitions + i].atomnum = 0;
00283 }
00284 }
00285 }
00286
00287
00288
00289
00290
00294 template <class TPSystem>
00295 void
00296 QCKimikaPartitioner<TPSystem>::setAtomsInBuffers (const AtomsGraph& grandat) {
00297
00298 QC_TRACE_PART("BEGIN QCKimikaPartitioner<TPSystem>::setAtomsInBuffers ");
00299 switch (this->partType) {
00300
00301 case QC_STANDARD_PART:
00302 this->setAtomsInBuffersStd (grandat);
00303 break;
00304
00305 case QC_DIXON_PART:
00306 this->setAtomsInBuffersDixon (grandat);
00307 break;
00308 }
00309 QC_TRACE_PART("END QCKimikaPartitioner<TPSystem>::setAtomsInBuffers ");
00310 }
00311
00312
00313
00314
00318 template <class TPSystem>
00319 void
00320 QCKimikaPartitioner<TPSystem>::setAtomsInBuffersStd (const AtomsGraph& grandat) {
00321
00322 QC_TRACE_PART("BEGIN QCKimikaPartitioner<TPSystem>::setAtomsInBuffersStd ");
00323 #ifndef QC_NO_DEBUG
00324 assert(lnumtab && lcortab && lovltab);
00325 assert(globtab);
00326 #endif
00327
00328 int edgenum, partnum, vertnum, nghbnbr;
00329 int atomnum, lcornum, lovlnum, nghbnum;
00330 int vertend, partend;
00331
00332 INT * QCRestrict verttax;
00333 INT * QCRestrict edgetax;
00334 INT * QCRestrict vendtax;
00335 FLOAT * QCRestrict eds2tax;
00336 FLOAT dsovva2, dscuva2;
00337
00338 verttax = grandat.verttax;
00339 edgetax = grandat.edgetax;
00340 vendtax = grandat.vendtax;
00341 eds2tax = grandat.eds2tax;
00342 dsovva2 = QCPow<2>(this->radius1);
00343 dscuva2 = QCPow<2>(this->radius2);
00344
00345
00346 #ifdef QC_DEBUG_KIMIKA
00347 this->printGlobalTab("Before building overlap and cut") ;
00348 #endif
00349
00353 for (vertnum = 0; vertnum < parttab_size; ++vertnum) {
00354 partnum = parttab[vertnum];
00355
00356 for (edgenum = verttax[vertnum]; edgenum < vendtax[vertnum]; ++edgenum) {
00357
00358 vertend = edgetax[edgenum];
00359 partend = parttab[vertend];
00360
00361 if ( partend != partnum && vertend > vertnum && eds2tax[edgenum] <= dsovva2) {
00362
00366 if (globtab[vertnum*this->nbPartitions+partnum].typeval == QC_CORE) {
00367 globtab[vertnum*this->nbPartitions+partnum].typeval = QC_SHELL1;
00368 lovltab[partnum]++;
00369 }
00370
00374 if (globtab[vertnum*this->nbPartitions+partend].typeval == QC_PART_NONE) {
00375 globtab[vertnum*this->nbPartitions+partend].typeval = QC_SHELL1;
00376 lovltab[partend]++;
00377 lnumtab[partend]++;
00378 }
00379 }
00380 }
00381 }
00385 for (partnum = 0; partnum < this->nbPartitions; ++partnum) {
00386 lcortab[partnum] = lnumtab[partnum] - lovltab[partnum];
00387 lcornum = 0;
00388 lovlnum = lcortab[partnum];
00389 for (atomnum = 0; atomnum < parttab_size; ++atomnum) {
00390
00391 if (globtab[atomnum*this->nbPartitions+partnum].typeval == QC_CORE) {
00392 globtab[atomnum*this->nbPartitions+partnum].atomnum = lcornum++;
00393
00394 } else if (globtab[atomnum*this->nbPartitions+partnum].typeval == QC_SHELL1) {
00395 globtab[atomnum*this->nbPartitions+partnum].atomnum = lovlnum++;
00396 }
00397 }
00398 }
00399
00400
00401 #ifdef QC_DEBUG_KIMIKA
00402 this->printGlobalTab("After building overlap") ;
00403 #endif
00404
00405
00409 int * QCRestrict nghbtab = new int [this->nbPartitions-1];
00410
00411 for (vertnum = 0; vertnum < parttab_size; ++vertnum) {
00412
00416 for (partnum = 0, nghbnbr = 0; partnum < this->nbPartitions; ++partnum) {
00417 if (globtab[vertnum*this->nbPartitions+partnum].typeval == QC_CORE ||
00418 globtab[vertnum*this->nbPartitions+partnum].typeval == QC_SHELL1) {
00419
00420 nghbtab[nghbnbr++] = partnum;
00421 }
00422 }
00423
00424 for (edgenum = verttax[vertnum]; edgenum < vendtax[vertnum]; ++edgenum) {
00425
00426 if (eds2tax[edgenum] > dscuva2) { continue; }
00427
00428 vertend = edgetax [edgenum];
00429
00430 for (nghbnum = 0; nghbnum < nghbnbr; ++nghbnum) {
00431 partend = nghbtab[nghbnum];
00432
00433 if (globtab[vertend*this->nbPartitions+partend].typeval == QC_PART_NONE) {
00434 globtab[vertend*this->nbPartitions+partend].typeval = QC_SHELL2;
00435 globtab[vertend*this->nbPartitions+partend].atomnum = lnumtab[partend]++;
00436 }
00437 }
00438 }
00439 }
00440
00441 delete [] nghbtab;
00442
00443
00444 #ifdef QC_DEBUG_KIMIKA
00445 this->printGlobalTab("After building overlap and cut") ;
00446 #endif
00447
00448
00449 QC_TRACE_PART("END QCKimikaPartitioner<TPSystem>::setAtomsInBuffersStd ");
00450
00451 }
00455 template <class TPSystem>
00456 void
00457 QCKimikaPartitioner<TPSystem>::setAtomsInBuffersDixon (const AtomsGraph& grandat) {
00458
00459 #ifndef QC_NO_DEBUG
00460 assert(lnumtab && lcortab && lovltab);
00461 assert(globtab);
00462 #endif
00463 QC_TRACE_PART("BEGIN QCKimikaPartitioner<TPSystem>::setAtomsInBuffersDixon ");
00464
00465 int edgenum, partnum, vertnum, nghbnbr;
00466 int atomnum, lcornum, lovlnum, nghbnum;
00467 int vertend, partend;
00468
00469 INT * QCRestrict verttax;
00470 INT * QCRestrict edgetax;
00471 INT * QCRestrict vendtax;
00472 FLOAT * QCRestrict eds2tax;
00473 FLOAT dsovva2, dscuva2;
00474
00475 verttax = grandat.verttax;
00476 edgetax = grandat.edgetax;
00477 vendtax = grandat.vendtax;
00478 eds2tax = grandat.eds2tax;
00479 dsovva2 = QCPow<2>(this->radius1);
00480 dscuva2 = QCPow<2>(this->radius2);
00481
00485 for (vertnum = 0; vertnum < parttab_size; ++vertnum) {
00486 partnum = parttab[vertnum];
00487
00488 for (edgenum = verttax[vertnum];
00489 edgenum < vendtax[vertnum];
00490 edgenum++) {
00491
00492 vertend = edgetax[edgenum];
00493 partend = parttab[vertend];
00494
00495 if ( partend != partnum &&
00496
00497 eds2tax[edgenum] <= dsovva2) {
00498
00508 if (globtab[vertnum*this->nbPartitions+partend].typeval == QC_PART_NONE) {
00509 globtab[vertnum*this->nbPartitions+partend].typeval = QC_SHELL1;
00510 lovltab[partend]++;
00511 lnumtab[partend]++;
00512 }
00513 }
00514 }
00515 }
00516 int checkCore = 0 ;
00517
00521 for (partnum = 0; partnum < this->nbPartitions; ++partnum) {
00522 lcortab[partnum] = lnumtab[partnum] - lovltab[partnum];
00523 lcornum = 0;
00524 lovlnum = lcortab[partnum];
00525 for (atomnum = 0; atomnum < parttab_size; ++atomnum) {
00526
00527 if (globtab[atomnum*this->nbPartitions+partnum].typeval == QC_CORE) {
00528 globtab[atomnum*this->nbPartitions+partnum].atomnum = lcornum++;
00529 }
00530 else if (globtab[atomnum*this->nbPartitions+partnum].typeval == QC_SHELL1) {
00531 globtab[atomnum*this->nbPartitions+partnum].atomnum = lovlnum++;
00532 }
00533 }
00534 checkCore += lcornum ;
00535 }
00536
00537
00538 #ifdef QC_DEBUG_KIMIKA
00539 this->printGlobalTab("After building core overlap") ;
00540 #endif
00541
00545 int * QCRestrict nghbtab = new int [this->nbPartitions-1];
00546
00547 for (vertnum = 0; vertnum < parttab_size; ++vertnum) {
00548
00552 for (partnum = 0, nghbnbr = 0; partnum < this->nbPartitions; ++partnum) {
00553 if (globtab[vertnum*this->nbPartitions+partnum].typeval == QC_CORE ||
00554 globtab[vertnum*this->nbPartitions+partnum].typeval == QC_SHELL1) {
00555
00556 nghbtab[nghbnbr++] = partnum;
00557 }
00558 }
00559
00560 for (edgenum = verttax[vertnum]; edgenum < vendtax[vertnum]; edgenum++) {
00561
00562 if (eds2tax[edgenum] > dscuva2) { continue; }
00563
00564 vertend = edgetax [edgenum];
00565
00566 for (nghbnum = 0; nghbnum < nghbnbr; ++nghbnum) {
00567 partend = nghbtab[nghbnum];
00568
00569 if (globtab[vertend*this->nbPartitions+partend].typeval == QC_PART_NONE) {
00570 globtab[vertend*this->nbPartitions+partend].typeval = QC_SHELL2;
00571 globtab[vertend*this->nbPartitions+partend].atomnum = lnumtab[partend]++;
00572 }
00573 }
00574 }
00575 }
00576
00577 delete [] nghbtab;
00578
00579
00580 #ifdef QC_DEBUG_KIMIKA
00581 this->printGlobalTab("After building overlap and cut") ;
00582 #endif
00583
00584
00585 QC_TRACE_PART("END QCKimikaPartitioner<TPSystem>::setAtomsInBuffersDixon ");
00586 }
00587
00588
00589
00590
00594 template <class TPSystem>
00595 void
00596 QCKimikaPartitioner<TPSystem>::extractDomains (TPSystem& mdSystem) {
00597
00598 QC_TRACE_PART("BEGIN QCKimikaPartitioner<TPSystem>::extractDomains");
00599 int partnum, nghbnum, atomnum, nghbnbr, nbAO, nbsbd;
00600 int * nghbtab;
00601 int * nbshared;
00602 int * domaintab;
00603 int * locatab;
00604 QCSubDomainZone * zonetab;
00605
00606 nghbtab = new int [this->nbPartitions];
00607 nbshared = new int [this->nbPartitions];
00608 zonetab = new QCSubDomainZone [this->nbPartitions];
00609
00610
00611 #ifdef QC_REPORT_DOMAIN_INFO
00612
00615 int * nbaotab = new int [NB_ZONES*this->nbPartitions];
00616 int taotab [NB_ZONES], tnumtab[NB_ZONES], tao, tnum;
00617
00618 string filename = (QCCommon::outdir + PATH_SEPARATOR +
00619 "DomainsInfo@" + QCCommon::getPidStr() + OUTPUT_SUFFIX);
00623 ofstream *log;
00624
00625 if (mdSystem.getRank() == 0) {
00626
00627 log = new ofstream (filename.c_str(), ios::out);
00628
00629 (*log) << "#Created by " << PACKAGE << " " << VERSION << endl
00630 << "#Atoms file:\t\t" << this->files->getAtomsFile() << endl
00631 << "#NB partitions:\t\t" << this->nbPartitions << endl
00632 << "#Partition type:\t" << this->partTypeStr << endl
00633 << "#Buffer radius:\t\t" << this->radius1 << endl
00634 << "#Cut radius:\t\t" << this->radius2 << endl
00635 << endl << endl;
00636 }
00637 for (int i = 0; i < NB_ZONES; ++i) {
00638 taotab[i] = tnumtab[i] = 0;
00639 }
00640 #endif
00641
00643 mdSystem.allocDomains(this->nbPartitions);
00644
00645 for (partnum = 0; partnum < this->nbPartitions; ++partnum) {
00646
00647 for (nghbnum = 0; nghbnum < this->nbPartitions; ++nghbnum) {
00648 nghbtab [nghbnum] = -1;
00649 nbshared[nghbnum] = 0;
00650 }
00651
00655 nbAO = 0;
00656
00657 #ifdef QC_REPORT_DOMAIN_INFO
00658 for (int i = 0; i < NB_ZONES; ++i) {
00659 nbaotab[partnum*NB_ZONES+i] = 0;
00660 }
00661 #endif
00662
00663 for (atomnum = 0; atomnum < parttab_size; ++atomnum) {
00664
00665 if (globtab[atomnum*this->nbPartitions+partnum].typeval == QC_CORE) {
00666 nbAO += this->charge[atomnum];
00667 #ifdef QC_REPORT_DOMAIN_INFO
00668 nbaotab[partnum*NB_ZONES+QC_CORE] += this->charge[atomnum];
00669 #endif
00670 }
00671 if (globtab[atomnum*this->nbPartitions+partnum].typeval == QC_SHELL1) {
00672 nbAO += this->charge[atomnum];
00673 #ifdef QC_REPORT_DOMAIN_INFO
00674 nbaotab[partnum*NB_ZONES+QC_SHELL1] += this->charge[atomnum];
00675 #endif
00676 }
00677 if (globtab[atomnum*this->nbPartitions+partnum].typeval == QC_SHELL2) {
00678 nbAO += this->charge[atomnum];
00679 #ifdef QC_REPORT_DOMAIN_INFO
00680 nbaotab[partnum*NB_ZONES+QC_SHELL2] += this->charge[atomnum];
00681 #endif
00682 }
00683 for (nghbnum = 0; nghbnum < this->nbPartitions; ++nghbnum) {
00684 if (nghbnum != partnum &&
00685 globtab[atomnum*this->nbPartitions+partnum].typeval != QC_PART_NONE &&
00686 globtab[atomnum*this->nbPartitions+nghbnum].typeval != QC_PART_NONE &&
00687 globtab[atomnum*this->nbPartitions+partnum].typeval != QC_CORE &&
00688 globtab[atomnum*this->nbPartitions+nghbnum].typeval != QC_SHELL2 ) {
00689
00690 nghbtab [nghbnum] = 1;
00691 nbshared[nghbnum]++;
00692 }
00693 }
00694 }
00695 #ifdef QC_REPORT_DOMAIN_INFO
00696 taotab [QC_CORE] += nbaotab[partnum*NB_ZONES+QC_CORE];
00697 taotab [QC_SHELL1] += nbaotab[partnum*NB_ZONES+QC_SHELL1];
00698 taotab [QC_SHELL2] += nbaotab[partnum*NB_ZONES+QC_SHELL2];
00699 tnumtab[QC_CORE] += lcortab[partnum];
00700 tnumtab[QC_SHELL1] += lovltab[partnum];
00701 tnumtab[QC_SHELL2] += lnumtab[partnum] - lovltab[partnum] - lcortab[partnum];
00702 #endif
00703
00704 for (nghbnum = 0, nghbnbr = 0; nghbnum < this->nbPartitions; ++nghbnum) {
00705 if (nghbtab[nghbnum] < 0) { continue; }
00706
00707 nghbtab [nghbnbr] = nghbnum;
00708 nbshared[nghbnbr] = nbshared[nghbnum];
00709 ++nghbnbr;
00710 }
00711
00712 #ifdef QC_DEBUG_KIMIKA
00713 std::cout << partnum << " (" << lnumtab[partnum] << " atoms, " << nbAO << " AOs): ";
00714 for (nghbnum = 0; nghbnum < nghbnbr; ++nghbnum) {
00715 std::cout << nghbtab[nghbnum] << " (" << nbshared[nghbnum] << " atoms), ";
00716 }
00717 std::cout << std::endl;
00718 #endif
00719 mdSystem.allocStructures(partnum,lnumtab[partnum], nbAO, nghbnbr, nghbtab, nbshared);
00720
00721 }
00722
00723
00724 #ifdef QC_REPORT_DOMAIN_INFO
00725 tao = (taotab [QC_CORE] + taotab [QC_SHELL1] + taotab [QC_SHELL2]) / this->nbPartitions;
00726 tnum = (tnumtab[QC_CORE] + tnumtab[QC_SHELL1] + tnumtab[QC_SHELL2]) / this->nbPartitions;
00727
00728 taotab [QC_CORE] /= this->nbPartitions;
00729 taotab [QC_SHELL1] /= this->nbPartitions;
00730 taotab [QC_SHELL2] /= this->nbPartitions;
00731 tnumtab[QC_CORE] /= this->nbPartitions;
00732 tnumtab[QC_SHELL1] /= this->nbPartitions;
00733 tnumtab[QC_SHELL2] /= this->nbPartitions;
00734
00735
00736 if (mdSystem.getRank() == 0) {
00737 (*log) << "SD\t\tNbAtT\tNbAtC\tNbAtB1\tNbAtB2\t\t"
00738 << "NbAoT\tNbAoC\tNbAoB1\tNbAoB2"
00739 << endl;
00740
00741 for (partnum = 0; partnum < this->nbPartitions; ++partnum) {
00742 int nbao = (nbaotab[partnum*NB_ZONES+QC_CORE] +
00743 nbaotab[partnum*NB_ZONES+QC_SHELL1] +
00744 nbaotab[partnum*NB_ZONES+QC_SHELL2]);
00745 (*log) << partnum << "\t\t"
00746 << lnumtab[partnum] << "\t"
00747 << lcortab[partnum] << "\t"
00748 << lovltab[partnum] << "\t"
00749 << lnumtab[partnum] - lovltab[partnum] - lcortab[partnum] << "\t\t"
00750 << nbao << "\t"
00751 << nbaotab[partnum*NB_ZONES+QC_CORE] << "\t"
00752 << nbaotab[partnum*NB_ZONES+QC_SHELL1] << "\t"
00753 << nbaotab[partnum*NB_ZONES+QC_SHELL2]
00754 << endl;
00755 }
00756
00757 (*log) << endl
00758 << "#Averages" << endl
00759 << "\t\tAvAtT\tAvAtC\tAvAtB1\tAvAtB2\t\t"
00760 << "AvAoT\tAvAoC\tAvAoB1\tAvAoB2" << endl
00761 << "\t\t" << tnum << "\t"
00762 << tnumtab[QC_CORE] << "\t"
00763 << tnumtab[QC_SHELL1] << "\t"
00764 << tnumtab[QC_SHELL2] << "\t\t"
00765 << tao << "\t"
00766 << taotab [QC_CORE] << "\t"
00767 << taotab [QC_SHELL1] << "\t"
00768 << taotab [QC_SHELL2]
00769 << endl;
00770
00771 (*log) << endl
00772 << "#Diffs" << endl
00773 << "SD\t\tdNbAtT\tdNbAtC\tdNbAtB1\tdNbAtB2\t\t"
00774 << "dNbAoT\tdNbAoC\tdNbAoB1\tdNbAoB2"
00775 << endl;
00776 for (partnum = 0; partnum < this->nbPartitions; ++partnum) {
00777 int nbao = (nbaotab[partnum*NB_ZONES+QC_CORE] +
00778 nbaotab[partnum*NB_ZONES+QC_SHELL1] +
00779 nbaotab[partnum*NB_ZONES+QC_SHELL2]);
00780 (*log) << partnum << "\t\t"
00781 << lnumtab[partnum] - tnum << "\t"
00782 << lcortab[partnum] - tnumtab[QC_CORE] << "\t"
00783 << lovltab[partnum] - tnumtab[QC_SHELL1] << "\t"
00784 << lnumtab[partnum] - lovltab[partnum] - lcortab[partnum] - tnumtab[QC_SHELL2] << "\t\t"
00785 << nbao - tao << "\t"
00786 << nbaotab[partnum*NB_ZONES+QC_CORE] - taotab [QC_CORE] << "\t"
00787 << nbaotab[partnum*NB_ZONES+QC_SHELL1] - taotab [QC_SHELL1] << "\t"
00788 << nbaotab[partnum*NB_ZONES+QC_SHELL2] - taotab [QC_SHELL2]
00789 << endl;
00790 }
00791
00792
00793 }
00794 #endif
00795
00796
00800 domaintab = nghbtab;
00801 locatab = nbshared;
00802
00803
00804 for (atomnum = 0; atomnum < parttab_size; ++atomnum) {
00805
00806 QCPoint3D current;
00807 mdSystem.getRootSystem().getPointAt(atomnum, current);
00808
00809 for (partnum = 0, nbsbd = 0; partnum < this->nbPartitions; ++partnum) {
00810
00811 if (globtab[atomnum*this->nbPartitions+partnum].typeval == QC_PART_NONE) {
00812 continue;
00813 }
00814
00815 domaintab[nbsbd] = partnum;
00816 locatab [nbsbd] = globtab[atomnum*this->nbPartitions+partnum].atomnum;
00817 zonetab [nbsbd] =
00818 static_cast<QCSubDomainZone>(globtab[atomnum*this->nbPartitions+partnum].typeval);
00819
00820 mdSystem.addAtom(current,
00821 mdSystem.getRootSystem().getType(atomnum),
00822 atomnum, domaintab[nbsbd],
00823 zonetab [nbsbd], locatab [nbsbd]);
00824
00825 ++nbsbd;
00826 }
00827
00828 mdSystem.fillMaps(nbsbd, domaintab, zonetab, locatab);
00829 }
00830
00831
00832 delete [] nghbtab;
00833 delete [] locatab;
00834 delete [] zonetab;
00835
00836
00837 #ifdef QC_REPORT_DOMAIN_INFO
00838 delete [] nbaotab;
00839
00840 if (mdSystem.getRank() == 0) {
00841
00842 log->close();
00843 delete log;
00844 }
00845 #endif
00846 QC_TRACE_PART("END QCKimikaPartitioner<TPSystem>::extractDomains");
00847 }
00848
00849
00850
00851
00855 template <class TPSystem>
00856 void
00857 QCKimikaPartitioner<TPSystem>::finalize (void) {
00858
00859 QC_TRACE_PART("BEGIN QCKimikaPartitioner<TPSystem>::finalize");
00860
00861 if (frag_nexttab) {
00862 delete [] this->frag_nexttab;
00863 this->frag_nexttab = NULL;
00864 }
00865 if (this->frag_firsttab) {
00866 delete [] this->frag_firsttab;
00867 this->frag_firsttab = NULL;
00868 }
00869 if (this->sd_nexttab) {
00870 delete [] this->sd_nexttab;
00871 this->sd_nexttab = NULL;
00872 }
00873 if (this->sd_firsttab) {
00874 delete [] this->sd_firsttab;
00875 this->sd_firsttab = NULL;
00876 }
00877 if (this->parttab) {
00878 delete [] this->parttab;
00879 this->parttab = NULL;
00880 }
00881 if (this->globtab) {
00882 delete [] this->globtab;
00883 this->globtab = NULL;
00884 }
00885 if (this->lnumtab) {
00886 delete [] this->lnumtab;
00887 this->lnumtab = NULL;
00888 }
00889 if (this->lcortab) {
00890 delete [] this->lcortab;
00891 this->lcortab = NULL;
00892 }
00893 if (this->lovltab) {
00894 delete [] this->lovltab;
00895 this->lovltab = NULL;
00896 }
00897 QC_TRACE_PART("END QCKimikaPartitioner<TPSystem>::finalize");
00898 }
00899
00900
00901
00902
00906 template <class TPSystem>
00907 void
00908 QCKimikaPartitioner<TPSystem>::initAtomsListTest (AtomsList& listdat, AtomsGraph& grafdata) {
00909
00910 QC_TRACE_PART("BEGIN QCKimikaPartitioner<TPSystem>::initAtomsListTest");
00911 FILE *stream;
00912 std::cout << "LECTURE DANS : "<< this->_fileName <<std::endl ;
00913 stream = fopen(this->_fileName.c_str() , "r");
00914 atomsLoadQCPP(&listdat,&grafdata , stream) ;
00915 fclose(stream);
00916
00917 QC_TRACE_PART("END QCKimikaPartitioner<TPSystem>::initAtomsListTest");
00918 }
00919
00920
00924 template <class TPSystem>
00925 void
00926 QCKimikaPartitioner<TPSystem>::initAtomsList (AtomsList& listdat, const QCSystem& root) {
00927
00928 QC_TRACE_PART("BEGIN QCKimikaPartitioner<TPSystem>::initAtomsList(AtomList, QCSystem)");
00929
00930 listdat.flagval = ATOMSLISTFREEVERT | ATOMSLISTFREEGROUP ;
00931 listdat.flagval = ATOMSLISTFREETABS;
00932 listdat.atomnbr = static_cast<INT>(root.getNbAtoms());
00933 listdat.fragnbr = static_cast<INT>(root.getNbFrags());
00934
00935 listdat.atomtab = new AtomsVert [listdat.atomnbr];
00936 listdat.fragtab = new INT [listdat.atomnbr];
00937
00938 for (int i = 0; i < root.getNbAtoms(); ++i) {
00939 QCFloat * xyz = root.getCoordsAt(i);
00940 listdat.atomtab[i].p.x = xyz[COORDX];
00941 listdat.atomtab[i].p.y = xyz[COORDY];
00942 listdat.atomtab[i].p.z = xyz[COORDZ];
00943 listdat.atomtab[i].typeval = root.getType(i);
00944 listdat.fragtab[i] = static_cast<INT>(root.getFragment(i));
00945 }
00946
00947 QC_TRACE_PART("END QCKimikaPartitioner<TPSystem>::initAtomsList(AtomList, QCSystem)");
00948 }
00949
00950
00951
00952
00953
00954
00955
00956
00957
00958
00959
00960
00961
00962
00963
00964
00965
00966
00967
00968
00969
00970
00971
00972
00973
00974
00975
00976
00977
00978
00979
00980
00981
00982
00983
00984
00985
00986
00987
00988
00989
00990
00991
00992
00993
00994
00995
00996
00997
00998
00999
01000
01001
01002
01003
01004
01005
01006
01007
01008
01009
01010
01011
01012
01013
01014
01015
01016
01017
01018
01019
01020
01021
01022
01026 template <class TPSystem>
01027 void
01028 QCKimikaPartitioner<TPSystem>::initFragChain (const QCSystem& ) {
01029 QC_TRACE_PART("BEGIN QCKimikaPartitioner<TPSystem>::initFragChain");
01030 std::cout << "NOTHING TODO HERE "<< std::endl;
01031 QC_TRACE_PART("END QCKimikaPartitioner<TPSystem>::initFragChain");
01032
01033 }
01034
01035
01036
01040 template <class TPSystem>
01041 void
01042 QCKimikaPartitioner<TPSystem>::initPartChain (void) {
01043 QC_TRACE_PART("BEGIN QCKimikaPartitioner<TPSystem>::initPartChain");
01044
01045 #ifndef QC_NO_DEBUG
01046 assert(sd_firsttab && sd_nexttab);
01047 #endif
01048
01049 int i, sd;
01050
01051 for (i = 0; i < this->nbPartitions; ++i) {
01052 sd_firsttab [i] = -1;
01053 }
01054
01055 for (i = 0; i < parttab_size; ++i) {
01056 sd = parttab[i];
01057 sd_nexttab [i] = sd_firsttab[sd];
01058 sd_firsttab [sd] = i;
01059 }
01060
01061 QC_TRACE_PART("END QCKimikaPartitioner<TPSystem>::initPartChain");
01062 }
01063
01067 template <class TPSystem>
01068 void
01069 QCKimikaPartitioner<TPSystem>::writeInventorFiles (const QCSystem& root) {
01070
01071 QCFloat * xyz;
01072 int nb = root.getNbAtoms();
01073
01074 for (int i = 0; i < this->nbPartitions; ++i) {
01075
01076 ostringstream name;
01077 name << QCCommon::outdir << PATH_SEPARATOR
01078 << this->files->getAtomsFile() << "_sd_" << i
01079 << "@" << QCCommon::getPidStr()
01080 << ".inv";
01081 ofstream out (name.str().c_str(), ios::out);
01082
01083 out << "#Inventor V2.0 ascii" << endl
01084 << "#Created by " << PACKAGE << " " << VERSION << endl
01085 << "#Atoms file:\t" << this->files->getAtomsFile() << endl
01086 << "#Partition :\t" << i << " on " << this->nbPartitions << endl
01087 << "#Partition type:\t" << this->partTypeStr << endl
01088 << "#Buffer radius:\t" << this->radius1 << endl
01089 << "#Cut radius:\t" << this->radius2 << endl
01090 << "Separator {" << endl
01091 << " LightModel {" << endl
01092 << " model\tBASE_COLOR" << endl
01093 << " }" << endl
01094 << " DrawStyle {" << endl
01095 << " style\tPOINTS" << endl
01096 << " pointSize\t3" << endl
01097 << " }" << endl
01098 << " MaterialBinding {" << endl
01099 << " value\tPER_VERTEX" << endl
01100 << " }" << endl
01101 << " Coordinate3 {" << endl
01102 << " point [" << endl;
01103
01104
01105
01106 for (int j = 0; j < nb; ++j) {
01107
01108 if (globtab[j*this->nbPartitions+i].typeval < 0) { continue; }
01109
01110 xyz = root.getCoordsAt(j);
01111 out << "\t"
01112 << xyz[COORDX] << "\t"
01113 << xyz[COORDY] << "\t"
01114 << xyz[COORDZ] << ((i==nb-1)? "" : ",")
01115 << endl;
01116 }
01117
01118 out << " ]" << endl
01119 << " }" << endl
01120 << " BaseColor {" << endl
01121 << " rgb [" << endl;
01122
01123
01124 for (int j = 0; j < nb; ++j) {
01125
01126 if (globtab[j*this->nbPartitions+i].typeval == QC_CORE) {
01127 out << "\t0\t0\t1";
01128
01129 } else if (globtab[j*this->nbPartitions+i].typeval == QC_SHELL1) {
01130 out << "\t1\t0\t0";
01131
01132 } else if (globtab[j*this->nbPartitions+i].typeval == QC_SHELL2) {
01133 out << "\t1\t1\t0";
01134
01135 } else {
01136 continue;
01137 }
01138
01139 out << ((i==nb-1)? "" : ",") << endl;
01140 }
01141
01142
01143 out << " ]" << endl
01144 << " }" << endl
01145 << " PointSet {" << endl
01146 << " numPoints\t" << lnumtab[i] << endl
01147 << " }" << endl
01148 << "}" << endl;
01149 out.close();
01150 }
01151
01152
01155
01156
01157 ostringstream file;
01158 file << QCCommon::outdir << PATH_SEPARATOR
01159 << this->files->getAtomsFile()
01160 << "@" << QCCommon::getPidStr()
01161 << ".inv";
01162 ofstream str (file.str().c_str(), ios::out);
01163
01164
01165 str << "#Inventor V2.0 ascii" << endl
01166 << "#Created by " << PACKAGE << " " << VERSION << endl
01167 << "#Atoms file:\t" << this->files->getAtomsFile() << endl
01168 << "#NB Partitions :\t" << this->nbPartitions << endl
01169 << "#Partition type:\t" << this->partTypeStr << endl
01170 << "#Buffer radius:\t" << this->radius1 << endl
01171 << "#Cut radius:\t" << this->radius2 << endl
01172 << "Separator {" << endl
01173 << " LightModel {" << endl
01174 << " model\tBASE_COLOR" << endl
01175 << " }" << endl
01176 << " DrawStyle {" << endl
01177 << " style\tPOINTS" << endl
01178 << " pointSize\t3" << endl
01179 << " }" << endl
01180 << " MaterialBinding {" << endl
01181 << " value\tPER_VERTEX" << endl
01182 << " }" << endl
01183 << " Coordinate3 {" << endl
01184 << " point [" << endl;
01185
01186 for (int j = 0; j < nb; ++j) {
01187
01188 xyz = root.getCoordsAt(j);
01189 str << "\t"
01190 << xyz[COORDX] << "\t"
01191 << xyz[COORDY] << "\t"
01192 << xyz[COORDZ] << ((j==nb-1)? "" : ",")
01193 << endl;
01194 }
01195
01196 str << " ]" << endl
01197 << " }" << endl
01198 << " BaseColor {" << endl
01199 << " rgb [" << endl;
01200
01201 QCFloat sR = 1, sG = 1, sB = 0;
01202 QCFloat iR = 1, iG = 0, iB = 0;
01203 QCFloat eR = 0, eG = 0, eB = 1;
01204
01205 int h = this->nbPartitions/2;
01206
01207 QCFloat dR1 = (iR - sR) / h;
01208 QCFloat dG1 = (iG - sG) / h;
01209 QCFloat dB1 = (iB - sB) / h;
01210
01211 QCFloat dR2 = (eR - iR) / h;
01212 QCFloat dG2 = (eG - iG) / h;
01213 QCFloat dB2 = (eB - iB) / h;
01214
01215
01216 QCFloat cR, cG, cB;
01217
01218
01219 for (int j = 0; j < nb; ++j) {
01220 if (this->partType == QC_DIXON_PART) {
01221 for (int i = 0; i < this->nbPartitions; ++i) {
01222 if (globtab[j*this->nbPartitions+i].typeval == QC_CORE) {
01223 if (i < h) {
01224 cR = sR + i*dR1;
01225 cG = sG + i*dG1;
01226 cB = sB + i*dB1;
01227 } else {
01228
01229 cR = iR + (i-h)*dR2;
01230 cG = iG + (i-h)*dG2;
01231 cB = iB + (i-h)*dB2;
01232 }
01233 break;
01234 }
01235 }
01236 } else if (this->partType == QC_STANDARD_PART) {
01237 for (int i = 0; i < this->nbPartitions; ++i) {
01238 if (globtab[j*this->nbPartitions+i].typeval == QC_CORE) {
01239 if (i < h) {
01240 cR = sR + i*dR1;
01241 cG = sG + i*dG1;
01242 cB = sB + i*dB1;
01243 } else {
01244
01245 cR = iR + (i-h)*dR2;
01246 cG = iG + (i-h)*dG2;
01247 cB = iB + (i-h)*dB2;
01248 }
01249 }
01250 if (globtab[j*this->nbPartitions+i].typeval == QC_SHELL1) {
01251 cR = 1;
01252 cG = 1;
01253 cB = 1;
01254 break;
01255 }
01256 }
01257 }
01258
01259 str << "\t" << cR << "\t" << cG << "\t" << cB
01260 << ((j==nb-1)? "" : ",") << endl;
01261
01262 }
01263
01264 str << " ]" << endl
01265 << " }" << endl
01266 << " PointSet {" << endl
01267 << " numPoints\t" << nb << endl
01268 << " }" << endl
01269 << "}" << endl;
01270
01271
01272 str.close();
01273
01274 }
01275 #ifdef DEV_OL
01276
01277 template <class TPSystem>
01278 void QCKimikaPartitioner<TPSystem>::writeInFileV1 ( std::ofstream &out, const QCDistMDSystem<QCDCAlgo>& system ){
01279 QC_TRACE_OUT("BEGIN QCKimikaPartitioner<TPSystem>::writeInFileV1 ");
01280
01281
01282
01283
01284
01285
01286
01287
01288
01289
01290 QC_TRACE_OUT("END QCKimikaPartitioner<TPSystem>::writeInFileV1 ");
01291 }
01292 #endif
01293
01294
01295 template <class TPSystem>
01296 void QCKimikaPartitioner<TPSystem>::printPartTab(const std::string & msg){
01297 std::cout << std::endl << ">> "<< msg << std::endl;
01298 for (int vertnum = 0; vertnum < this->parttab_size; ++vertnum) {
01299 std::cout << setw(2) << vertnum << ": "<< this->parttab[vertnum]<<std::endl;
01300 }
01301
01302 }
01303
01304
01305 template <class TPSystem>
01306 void QCKimikaPartitioner<TPSystem>::printGlobalTab(const std::string & msg){
01307
01308 std::cout << std::endl << ">> "<< msg << std::endl;
01309 for (int vertnum = 0; vertnum < this->parttab_size; ++vertnum) {
01310 std::cout << setw(2) << vertnum << ": ";
01311 for (int i = 0; i < this->nbPartitions; ++i) {
01312 INT type = this->globtab[vertnum*this->nbPartitions+i].typeval;
01313 std::cout << "(" ;
01314 if (type == QC_CORE) {
01315 std::cout << " K";
01316 } else if (type == QC_SHELL1) {
01317 std::cout << " O";
01318 } else if (type == QC_SHELL2) {
01319 std::cout << " C";
01320 } else {
01321 std::cout << " ";
01322 }
01323
01324 std::cout << "," << setw(2) << this->globtab[vertnum*this->nbPartitions+i].atomnum
01325 << ") ";
01326 }
01327 std::cout << endl;
01328 }
01329 }
01330
01331
01332
01333
01334
01335
01339 template class QCKimikaPartitioner<TQCMDSystem>;
01340
01341
01342
01343 #if defined(HAVE_MPI) && defined(WITH_MPI_SUPPORT)
01344 template class QCKimikaPartitioner<TQCDistMDSystem>;
01345 #endif