|
Zoltan2
|
00001 // @HEADER 00002 // 00003 // *********************************************************************** 00004 // 00005 // Zoltan2: A package of combinatorial algorithms for scientific computing 00006 // Copyright 2012 Sandia Corporation 00007 // 00008 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, 00009 // the U.S. Government retains certain rights in this software. 00010 // 00011 // Redistribution and use in source and binary forms, with or without 00012 // modification, are permitted provided that the following conditions are 00013 // met: 00014 // 00015 // 1. Redistributions of source code must retain the above copyright 00016 // notice, this list of conditions and the following disclaimer. 00017 // 00018 // 2. Redistributions in binary form must reproduce the above copyright 00019 // notice, this list of conditions and the following disclaimer in the 00020 // documentation and/or other materials provided with the distribution. 00021 // 00022 // 3. Neither the name of the Corporation nor the names of the 00023 // contributors may be used to endorse or promote products derived from 00024 // this software without specific prior written permission. 00025 // 00026 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY 00027 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00028 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 00029 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE 00030 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 00031 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 00032 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 00033 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 00034 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 00035 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 00036 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00037 // 00038 // Questions? Contact Karen Devine (kddevin@sandia.gov) 00039 // Erik Boman (egboman@sandia.gov) 00040 // Siva Rajamanickam (srajama@sandia.gov) 00041 // 00042 // *********************************************************************** 00043 // 00044 // @HEADER 00045 00050 #ifndef _ZOLTAN2_PAMGENMESHADAPTER_HPP_ 00051 #define _ZOLTAN2_PAMGENMESHADAPTER_HPP_ 00052 00053 #include <Zoltan2_MeshAdapter.hpp> 00054 #include <Zoltan2_StridedData.hpp> 00055 #include <vector> 00056 00057 #include <pamgen_im_exodusII.h> 00058 #include "pamgen_im_ne_nemesisI.h" 00059 00060 namespace Zoltan2 { 00061 00088 template <typename User> 00089 class PamgenMeshAdapter: public MeshAdapter<User> { 00090 00091 public: 00092 00093 typedef typename InputTraits<User>::scalar_t scalar_t; 00094 typedef typename InputTraits<User>::lno_t lno_t; 00095 typedef typename InputTraits<User>::gno_t gno_t; 00096 typedef typename InputTraits<User>::zgid_t zgid_t; 00097 typedef typename InputTraits<User>::part_t part_t; 00098 typedef typename InputTraits<User>::node_t node_t; 00099 typedef MeshAdapter<User> base_adapter_t; 00100 typedef User user_t; 00101 00109 PamgenMeshAdapter(const Comm<int> &comm, std::string typestr="region"); 00110 00111 void print(int); 00112 00114 // The MeshAdapter interface. 00115 // This is the interface that would be called by a model or a problem . 00117 00118 size_t getLocalNumOf(MeshEntityType etype) const 00119 { 00120 if ((MESH_REGION == etype && 3 == dimension_) || 00121 (MESH_FACE == etype && 2 == dimension_)) { 00122 return num_elem_; 00123 } 00124 00125 if (MESH_VERTEX == etype) { 00126 return num_nodes_; 00127 } 00128 00129 return 0; 00130 } 00131 00132 void getIDsViewOf(MeshEntityType etype, const zgid_t *&Ids) const 00133 { 00134 if ((MESH_REGION == etype && 3 == dimension_) || 00135 (MESH_FACE == etype && 2 == dimension_)) { 00136 Ids = element_num_map_; 00137 } 00138 00139 else if (MESH_VERTEX == etype) { 00140 Ids = node_num_map_; 00141 } 00142 00143 else Ids = NULL; 00144 } 00145 00146 void getWeightsViewOf(MeshEntityType etype, const scalar_t *&weights, 00147 int &stride, int idx = 0) const 00148 { 00149 weights = NULL; 00150 stride = 0; 00151 } 00152 00153 int getDimension() const { return dimension_; } 00154 00155 void getCoordinatesViewOf(MeshEntityType etype, const scalar_t *&coords, 00156 int &stride, int dim) const { 00157 if ((MESH_REGION == etype && 3 == dimension_) || 00158 (MESH_FACE == etype && 2 == dimension_)) { 00159 if (dim == 0) { 00160 coords = Acoords_; 00161 } else if (dim == 1) { 00162 coords = Acoords_ + num_elem_; 00163 } else if (dim == 2) { 00164 coords = Acoords_ + 2 * num_elem_; 00165 } 00166 stride = 1; 00167 } else if (MESH_REGION == etype && 2 == dimension_) { 00168 coords = NULL; 00169 stride = 0; 00170 } else if (MESH_VERTEX == etype) { 00171 if (dim == 0) { 00172 coords = coords_; 00173 } else if (dim == 1) { 00174 coords = coords_ + num_nodes_; 00175 } else if (dim == 2) { 00176 coords = coords_ + 2 * num_nodes_; 00177 } 00178 stride = 1; 00179 } else { 00180 coords = NULL; 00181 stride = 0; 00182 Z2_THROW_NOT_IMPLEMENTED_IN_ADAPTER 00183 } 00184 } 00185 00186 bool availAdjs(MeshEntityType source, MeshEntityType target) const { 00187 if ((MESH_REGION == source && MESH_VERTEX == target && 3 == dimension_) || 00188 (MESH_FACE == source && MESH_VERTEX == target && 2 == dimension_)) { 00189 return TRUE; 00190 } 00191 00192 return false; 00193 } 00194 00195 size_t getLocalNumAdjs(MeshEntityType source, MeshEntityType target) const 00196 { 00197 if (availAdjs(source, target)) { 00198 return tnoct_; 00199 } 00200 00201 return 0; 00202 } 00203 00204 void getAdjsView(MeshEntityType source, MeshEntityType target, 00205 const lno_t *&offsets, const zgid_t *& adjacencyIds) const 00206 { 00207 if ((MESH_REGION == source && MESH_VERTEX == target && 3 == dimension_) || 00208 (MESH_FACE == source && MESH_VERTEX == target && 2 == dimension_)) { 00209 offsets = elemOffsets_; 00210 adjacencyIds = elemToNode_; 00211 } else if (MESH_REGION == source && 2 == dimension_) { 00212 offsets = NULL; 00213 adjacencyIds = NULL; 00214 } else { 00215 offsets = NULL; 00216 adjacencyIds = NULL; 00217 Z2_THROW_NOT_IMPLEMENTED_IN_ADAPTER 00218 } 00219 } 00220 00221 bool avail2ndAdjs(MeshEntityType sourcetarget, MeshEntityType through) const 00222 { 00223 if (through == MESH_VERTEX) { 00224 if (sourcetarget == MESH_REGION && dimension_ == 3) return true; 00225 if (sourcetarget == MESH_FACE && dimension_ == 2) return true; 00226 } 00227 return false; 00228 } 00229 00230 size_t getLocalNum2ndAdjs(MeshEntityType sourcetarget, 00231 MeshEntityType through) const 00232 { 00233 if (avail2ndAdjs(sourcetarget, through)) { 00234 return nadj_; 00235 } 00236 00237 return 0; 00238 } 00239 00240 void get2ndAdjsView(MeshEntityType sourcetarget, MeshEntityType through, 00241 const lno_t *&offsets, const zgid_t *& adjacencyIds) const 00242 { 00243 if (avail2ndAdjs(sourcetarget, through)) { 00244 offsets = start_; 00245 adjacencyIds = adj_; 00246 } else { 00247 offsets = NULL; 00248 adjacencyIds = NULL; 00249 Z2_THROW_NOT_IMPLEMENTED_IN_ADAPTER 00250 } 00251 } 00252 00253 private: 00254 int dimension_, num_nodes_, num_elem_; 00255 zgid_t *element_num_map_, *node_num_map_; 00256 int *elemToNode_, tnoct_, *elemOffsets_; 00257 double *coords_, *Acoords_; 00258 lno_t *start_; 00259 zgid_t *adj_; 00260 size_t nadj_; 00261 }; 00262 00264 // Definitions 00266 00267 static 00268 ssize_t in_list(const int value, size_t count, int *vector) 00269 { 00270 for(size_t i=0; i < count; i++) { 00271 if(vector[i] == value) 00272 return i; 00273 } 00274 return -1; 00275 } 00276 00277 template <typename User> 00278 PamgenMeshAdapter<User>::PamgenMeshAdapter(const Comm<int> &comm, 00279 std::string typestr): 00280 dimension_(0) 00281 { 00282 this->setEntityTypes(typestr, "vertex", "vertex"); 00283 00284 int error = 0; 00285 char title[100]; 00286 int exoid = 0; 00287 int num_elem_blk, num_node_sets, num_side_sets; 00288 error += im_ex_get_init(exoid, title, &dimension_, 00289 &num_nodes_, &num_elem_, &num_elem_blk, 00290 &num_node_sets, &num_side_sets); 00291 00292 coords_ = new double [num_nodes_ * dimension_]; 00293 00294 error += im_ex_get_coord(exoid, coords_, coords_ + num_nodes_, 00295 coords_ + 2 * num_nodes_); 00296 00297 element_num_map_ = new int [num_elem_]; 00298 error += im_ex_get_elem_num_map(exoid, element_num_map_); 00299 00300 node_num_map_ = new int [num_nodes_]; 00301 error += im_ex_get_node_num_map(exoid, node_num_map_); 00302 00303 int *elem_blk_ids = new int [num_elem_blk]; 00304 error += im_ex_get_elem_blk_ids(exoid, elem_blk_ids); 00305 00306 int *num_nodes_per_elem = new int [num_elem_blk]; 00307 int *num_attr = new int [num_elem_blk]; 00308 int *num_elem_this_blk = new int [num_elem_blk]; 00309 char **elem_type = new char * [num_elem_blk]; 00310 int **connect = new int * [num_elem_blk]; 00311 00312 for(int i = 0; i < num_elem_blk; i++){ 00313 elem_type[i] = new char [MAX_STR_LENGTH + 1]; 00314 error += im_ex_get_elem_block(exoid, elem_blk_ids[i], elem_type[i], 00315 (int*)&(num_elem_this_blk[i]), 00316 (int*)&(num_nodes_per_elem[i]), 00317 (int*)&(num_attr[i])); 00318 delete[] elem_type[i]; 00319 } 00320 00321 delete[] elem_type; 00322 elem_type = NULL; 00323 delete[] num_attr; 00324 num_attr = NULL; 00325 Acoords_ = new double [num_elem_ * dimension_]; 00326 int a = 0; 00327 std::vector<std::vector<int> > sur_elem; 00328 sur_elem.resize(num_nodes_); 00329 00330 for(int b = 0; b < num_elem_blk; b++) { 00331 connect[b] = new int [num_nodes_per_elem[b]*num_elem_this_blk[b]]; 00332 error += im_ex_get_elem_conn(exoid, elem_blk_ids[b], connect[b]); 00333 00334 for(int i = 0; i < num_elem_this_blk[b]; i++) { 00335 Acoords_[a] = 0; 00336 Acoords_[num_elem_ + a] = 0; 00337 00338 if (3 == dimension_) { 00339 Acoords_[2 * num_elem_ + a] = 0; 00340 } 00341 00342 for(int j = 0; j < num_nodes_per_elem[b]; j++) { 00343 int node = connect[b][i * num_nodes_per_elem[b] + j] - 1; 00344 Acoords_[a] += coords_[node]; 00345 Acoords_[num_elem_ + a] += coords_[num_nodes_ + node]; 00346 00347 if(3 == dimension_) { 00348 Acoords_[2 * num_elem_ + a] += coords_[2 * num_nodes_ + node]; 00349 } 00350 00351 /* 00352 * in the case of degenerate elements, where a node can be 00353 * entered into the connect table twice, need to check to 00354 * make sure that this element is not already listed as 00355 * surrounding this node 00356 */ 00357 if (sur_elem[node].empty() || 00358 element_num_map_[a] != sur_elem[node][sur_elem[node].size()-1]) { 00359 /* Add the element to the list */ 00360 sur_elem[node].push_back(element_num_map_[a]); 00361 } 00362 } 00363 00364 Acoords_[a] /= num_nodes_per_elem[b]; 00365 Acoords_[num_elem_ + a] /= num_nodes_per_elem[b]; 00366 00367 if(3 == dimension_) { 00368 Acoords_[2 * num_elem_ + a] /= num_nodes_per_elem[b]; 00369 } 00370 00371 a++; 00372 } 00373 00374 } 00375 00376 delete[] elem_blk_ids; 00377 elem_blk_ids = NULL; 00378 int nnodes_per_elem = num_nodes_per_elem[0]; 00379 elemToNode_ = new int [num_elem_ * nnodes_per_elem]; 00380 int telct = 0; 00381 elemOffsets_ = new int [num_elem_]; 00382 tnoct_ = 0; 00383 int **reconnect = new int * [num_elem_]; 00384 size_t max_nsur = 0; 00385 00386 for (int b = 0; b < num_elem_blk; b++) { 00387 for (int i = 0; i < num_elem_this_blk[b]; i++) { 00388 elemOffsets_[telct] = tnoct_; 00389 reconnect[telct] = new int [num_nodes_per_elem[b]]; 00390 00391 for (int j = 0; j < num_nodes_per_elem[b]; j++) { 00392 elemToNode_[tnoct_]= 00393 node_num_map_[connect[b][i*num_nodes_per_elem[b] + j]-1]; 00394 reconnect[telct][j] = connect[b][i*num_nodes_per_elem[b] + j]; 00395 ++tnoct_; 00396 } 00397 00398 ++telct; 00399 } 00400 } 00401 00402 delete[] num_nodes_per_elem; 00403 num_nodes_per_elem = NULL; 00404 delete[] num_elem_this_blk; 00405 num_elem_this_blk = NULL; 00406 00407 for(int b = 0; b < num_elem_blk; b++) { 00408 delete[] connect[b]; 00409 } 00410 00411 delete[] connect; 00412 connect = NULL; 00413 00414 int max_side_nodes = nnodes_per_elem; 00415 int *side_nodes = new int [max_side_nodes]; 00416 int *mirror_nodes = new int [max_side_nodes]; 00417 00418 /* Allocate memory necessary for the adjacency */ 00419 start_ = new lno_t [num_elem_+1]; 00420 std::vector<int> adj; 00421 00422 for (int i=0; i < max_side_nodes; i++) { 00423 side_nodes[i]=-999; 00424 mirror_nodes[i]=-999; 00425 } 00426 00427 /* Find the adjacency for a nodal based decomposition */ 00428 nadj_ = 0; 00429 for(int ncnt=0; ncnt < num_nodes_; ncnt++) { 00430 if(sur_elem[ncnt].empty()) { 00431 printf("WARNING: Node = %d has no elements\n", ncnt+1); 00432 } else { 00433 size_t nsur = sur_elem[ncnt].size(); 00434 if (nsur > max_nsur) 00435 max_nsur = nsur; 00436 } 00437 } 00438 00439 int nprocs = comm.getSize(); 00440 00441 if (nprocs > 1) { 00442 int neid = 0, num_internal_nodes, num_border_nodes, num_external_nodes; 00443 int num_internal_elems, num_border_elems, num_node_cmaps, num_elem_cmaps; 00444 int proc = 0; 00445 error += im_ne_get_loadbal_param(neid, &num_internal_nodes, 00446 &num_border_nodes, &num_external_nodes, 00447 &num_internal_elems, &num_border_elems, 00448 &num_node_cmaps, &num_elem_cmaps, proc); 00449 00450 int *node_cmap_ids = new int [num_node_cmaps]; 00451 int *node_cmap_node_cnts = new int [num_node_cmaps]; 00452 int *elem_cmap_ids = new int [num_elem_cmaps]; 00453 int *elem_cmap_elem_cnts = new int [num_elem_cmaps]; 00454 error += im_ne_get_cmap_params(neid, node_cmap_ids, node_cmap_node_cnts, 00455 elem_cmap_ids, elem_cmap_elem_cnts, proc); 00456 delete[] elem_cmap_ids; 00457 elem_cmap_ids = NULL; 00458 delete[] elem_cmap_elem_cnts; 00459 elem_cmap_elem_cnts = NULL; 00460 00461 int **node_ids = new int * [num_node_cmaps]; 00462 int **node_proc_ids = new int * [num_node_cmaps]; 00463 for(int j = 0; j < num_node_cmaps; j++) { 00464 node_ids[j] = new int [node_cmap_node_cnts[j]]; 00465 node_proc_ids[j] = new int [node_cmap_node_cnts[j]]; 00466 error += im_ne_get_node_cmap(neid, node_cmap_ids[j], node_ids[j], 00467 node_proc_ids[j], proc); 00468 } 00469 delete[] node_cmap_ids; 00470 node_cmap_ids = NULL; 00471 int *sendCount = new int [nprocs]; 00472 int *recvCount = new int [nprocs]; 00473 00474 // Post receives 00475 RCP<CommRequest<int> >*requests=new RCP<CommRequest<int> >[num_node_cmaps]; 00476 for (int cnt = 0, i = 0; i < num_node_cmaps; i++) { 00477 try { 00478 requests[cnt++] = 00479 Teuchos::ireceive<int,int>(comm, 00480 rcp(&(recvCount[node_proc_ids[i][0]]), 00481 false), 00482 node_proc_ids[i][0]); 00483 } 00484 Z2_FORWARD_EXCEPTIONS; 00485 } 00486 00487 Teuchos::barrier<int>(comm); 00488 size_t totalsend = 0; 00489 00490 for(int j = 0; j < num_node_cmaps; j++) { 00491 sendCount[node_proc_ids[j][0]] = 1; 00492 for(int i = 0; i < node_cmap_node_cnts[j]; i++) { 00493 sendCount[node_proc_ids[j][i]] += sur_elem[node_ids[j][i]-1].size()+2; 00494 } 00495 totalsend += sendCount[node_proc_ids[j][0]]; 00496 } 00497 00498 // Send data; can use readySend since receives are posted. 00499 for (int i = 0; i < num_node_cmaps; i++) { 00500 try { 00501 Teuchos::readySend<int,int>(comm, sendCount[node_proc_ids[i][0]], 00502 node_proc_ids[i][0]); 00503 } 00504 Z2_FORWARD_EXCEPTIONS; 00505 } 00506 00507 // Wait for messages to return. 00508 try { 00509 Teuchos::waitAll<int>(comm, arrayView(requests, num_node_cmaps)); 00510 } 00511 Z2_FORWARD_EXCEPTIONS; 00512 00513 delete [] requests; 00514 00515 // Allocate the receive buffer. 00516 size_t totalrecv = 0; 00517 int maxMsg = 0; 00518 int nrecvranks = 0; 00519 for(int i = 0; i < num_node_cmaps; i++) { 00520 if (recvCount[node_proc_ids[i][0]] > 0) { 00521 totalrecv += recvCount[node_proc_ids[i][0]]; 00522 nrecvranks++; 00523 if (recvCount[node_proc_ids[i][0]] > maxMsg) 00524 maxMsg = recvCount[node_proc_ids[i][0]]; 00525 } 00526 } 00527 00528 int *rbuf = NULL; 00529 if (totalrecv) rbuf = new int[totalrecv]; 00530 00531 requests = new RCP<CommRequest<int> > [nrecvranks]; 00532 00533 // Error checking for memory and message size. 00534 int OK[2] = {1,1}; 00535 // OK[0] -- true/false indicating whether each message size fits in an int 00536 // (for MPI). 00537 // OK[1] -- true/false indicating whether memory allocs are OK 00538 int gOK[2]; // For global reduce of OK. 00539 00540 if (size_t(maxMsg) * sizeof(int) > INT_MAX) OK[0] = false; 00541 if (totalrecv && !rbuf) OK[1] = 0; 00542 if (!requests) OK[1] = 0; 00543 00544 // Post receives 00545 00546 size_t offset = 0; 00547 00548 if (OK[0] && OK[1]) { 00549 int rcnt = 0; 00550 for (int i = 0; i < num_node_cmaps; i++) { 00551 if (recvCount[node_proc_ids[i][0]]) { 00552 try { 00553 requests[rcnt++] = 00554 Teuchos:: 00555 ireceive<int,int>(comm, 00556 Teuchos::arcp(&rbuf[offset], 0, 00557 recvCount[node_proc_ids[i][0]], 00558 false), 00559 node_proc_ids[i][0]); 00560 } 00561 Z2_FORWARD_EXCEPTIONS; 00562 } 00563 offset += recvCount[node_proc_ids[i][0]]; 00564 } 00565 } 00566 00567 delete[] recvCount; 00568 00569 // Use barrier for error checking 00570 Teuchos::reduceAll<int>(comm, Teuchos::REDUCE_MIN, 2, OK, gOK); 00571 if (!gOK[0] || !gOK[1]) { 00572 delete [] rbuf; 00573 delete [] requests; 00574 if (!gOK[0]) 00575 throw std::runtime_error("Max single message length exceeded"); 00576 else 00577 throw std::bad_alloc(); 00578 } 00579 00580 int *sbuf = NULL; 00581 if (totalsend) sbuf = new int[totalsend]; 00582 a = 0; 00583 00584 for(int j = 0; j < num_node_cmaps; j++) { 00585 sbuf[a++] = node_cmap_node_cnts[j]; 00586 for(int i = 0; i < node_cmap_node_cnts[j]; i++) { 00587 sbuf[a++] = node_num_map_[node_ids[j][i]-1]; 00588 sbuf[a++] = sur_elem[node_ids[j][i]-1].size(); 00589 for(size_t ecnt=0; ecnt < sur_elem[node_ids[j][i]-1].size(); ecnt++) { 00590 sbuf[a++] = sur_elem[node_ids[j][i]-1][ecnt]; 00591 } 00592 } 00593 } 00594 00595 delete[] node_cmap_node_cnts; 00596 node_cmap_node_cnts = NULL; 00597 00598 for(int j = 0; j < num_node_cmaps; j++) { 00599 delete[] node_ids[j]; 00600 } 00601 00602 delete[] node_ids; 00603 node_ids = NULL; 00604 ArrayRCP<int> sendBuf; 00605 00606 if (totalsend) 00607 sendBuf = ArrayRCP<int>(sbuf, 0, totalsend, true); 00608 else 00609 sendBuf = Teuchos::null; 00610 00611 // Send data; can use readySend since receives are posted. 00612 offset = 0; 00613 for (int i = 0; i < num_node_cmaps; i++) { 00614 if (sendCount[node_proc_ids[i][0]]) { 00615 try{ 00616 Teuchos::readySend<int, 00617 int>(comm, 00618 Teuchos::arrayView(&sendBuf[offset], 00619 sendCount[node_proc_ids[i][0]]), 00620 node_proc_ids[i][0]); 00621 } 00622 Z2_FORWARD_EXCEPTIONS; 00623 } 00624 offset += sendCount[node_proc_ids[i][0]]; 00625 } 00626 00627 for(int j = 0; j < num_node_cmaps; j++) { 00628 delete[] node_proc_ids[j]; 00629 } 00630 00631 delete[] node_proc_ids; 00632 node_proc_ids = NULL; 00633 delete[] sendCount; 00634 00635 // Wait for messages to return. 00636 try{ 00637 Teuchos::waitAll<int>(comm, Teuchos::arrayView(requests, nrecvranks)); 00638 } 00639 Z2_FORWARD_EXCEPTIONS; 00640 00641 delete[] requests; 00642 a = 0; 00643 00644 for (int i = 0; i < num_node_cmaps; i++) { 00645 int num_nodes_this_processor = rbuf[a++]; 00646 00647 for (int j = 0; j < num_nodes_this_processor; j++) { 00648 int this_node = rbuf[a++]; 00649 int num_elem_this_node = rbuf[a++]; 00650 00651 for (int ncnt = 0; ncnt < num_nodes_; ncnt++) { 00652 if (node_num_map_[ncnt] == this_node) { 00653 for (int ecnt = 0; ecnt < num_elem_this_node; ecnt++) { 00654 sur_elem[ncnt].push_back(rbuf[a++]); 00655 } 00656 } 00657 } 00658 } 00659 } 00660 00661 delete[] rbuf; 00662 } 00663 00664 for(int ecnt=0; ecnt < num_elem_; ecnt++) { 00665 start_[ecnt] = nadj_; 00666 int nnodes = nnodes_per_elem; 00667 for(int ncnt=0; ncnt < nnodes; ncnt++) { 00668 int node = reconnect[ecnt][ncnt]-1; 00669 for(size_t i=0; i < sur_elem[node].size(); i++) { 00670 int entry = sur_elem[node][i]; 00671 00672 if(element_num_map_[ecnt] != entry && 00673 in_list(entry, 00674 adj.size()-start_[ecnt], 00675 &adj[start_[ecnt]]) < 0) { 00676 adj.push_back(entry); 00677 nadj_++; 00678 } 00679 } 00680 } 00681 } 00682 00683 for(int b = 0; b < num_elem_; b++) { 00684 delete[] reconnect[b]; 00685 } 00686 00687 delete[] reconnect; 00688 reconnect = NULL; 00689 start_[num_elem_] = nadj_; 00690 00691 adj_ = new zgid_t [nadj_]; 00692 00693 for (size_t i=0; i < nadj_; i++) { 00694 adj_[i] = adj[i]; 00695 } 00696 00697 delete[] side_nodes; 00698 side_nodes = NULL; 00699 delete[] mirror_nodes; 00700 mirror_nodes = NULL; 00701 } 00702 00703 template <typename User> 00704 void PamgenMeshAdapter<User>::print(int me) 00705 { 00706 std::string fn(" PamgenMesh "); 00707 std::cout << me << fn 00708 << " dim = " << dimension_ 00709 << " nnodes = " << num_nodes_ 00710 << " nelems = " << num_elem_ 00711 << std::endl; 00712 00713 for (int i = 0; i < num_elem_; i++) { 00714 std::cout << me << fn << i 00715 << " Elem " << element_num_map_[i] 00716 << " Coords: "; 00717 for (int j = 0; j < dimension_; j++) 00718 std::cout << Acoords_[i + j * num_elem_] << " "; 00719 std::cout << std::endl; 00720 } 00721 00722 for (int i = 0; i < num_elem_; i++) { 00723 std::cout << me << fn << i 00724 << " Elem " << element_num_map_[i] 00725 << " Graph: "; 00726 for (int j = start_[i]; j < start_[i+1]; j++) 00727 std::cout << adj_[j] << " "; 00728 std::cout << std::endl; 00729 } 00730 } 00731 00732 } //namespace Zoltan2 00733 00734 #endif
1.7.6.1