moab
|
00001 00013 #include "moab/Core.hpp" 00014 #include "moab/Range.hpp" 00015 #include "moab/Skinner.hpp" 00016 #include "moab/LloydSmoother.hpp" 00017 #include "moab/ProgOptions.hpp" 00018 #include "moab/BoundBox.hpp" 00019 #include "moab/SpatialLocator.hpp" 00020 #include "MBTagConventions.hpp" 00021 #include "DataCoupler.hpp" 00022 00023 #define IS_BUILDING_MB 00024 #include "moab/Error.hpp" 00025 #undef IS_BUILDING_MB 00026 00027 #ifdef USE_MPI 00028 # include "moab/ParallelComm.hpp" 00029 #endif 00030 00031 #include <iostream> 00032 #include <set> 00033 #include <sstream> 00034 #include <assert.h> 00035 00036 using namespace moab; 00037 using namespace std; 00038 00039 #ifndef MESH_DIR 00040 #define MESH_DIR "." 00041 #endif 00042 00043 ErrorCode read_file(string &fname, EntityHandle &seth, 00044 Range &solids, Range &solid_elems, Range &fluids, Range &fluid_elems); 00045 void deform_func(const BoundBox &bbox, double *xold, double *xnew); 00046 ErrorCode deform_master(Range &fluid_elems, Range &solid_elems, Tag &xnew); 00047 ErrorCode smooth_master(int dim, Tag xnew, EntityHandle &master, Range &fluids); 00048 ErrorCode write_to_coords(Range &elems, Tag tagh); 00049 00050 const int SOLID_SETNO = 100, FLUID_SETNO = 200; 00051 00052 Interface *mb; 00053 #define RR(a) if (MB_SUCCESS != rval) {cout << a << endl; return MB_FAILURE;} 00054 00055 const bool debug = true; 00056 00057 class DeformMeshRemap 00058 { 00059 public: 00060 00062 enum {MASTER=0, SLAVE, SOLID, FLUID}; 00063 00068 DeformMeshRemap(Interface *impl, ParallelComm *master = NULL, ParallelComm *slave = NULL); 00069 00071 ~DeformMeshRemap(); 00072 00074 ErrorCode execute(); 00075 00077 ErrorCode add_set_no(int m_or_s, int fluid_or_solid, int set_no); 00078 00080 ErrorCode remove_set_no(int m_or_s, int fluid_or_solid, int set_no); 00081 00083 ErrorCode get_set_nos(int m_or_s, int fluid_or_solid, std::set<int> &set_nos) const; 00084 00086 inline Tag x_new() const {return xNew;} 00087 00089 std::string x_new_name() const {return xNewName;} 00090 00092 void x_new_name(const std::string &name) {xNewName = name;} 00093 00095 std::string get_file_name(int m_or_s) const; 00096 00098 void set_file_name(int m_or_s, const std::string &name); 00099 00101 std::string xdisp_name(int idx = 0); 00102 void xdisp_name(const std::string &nm, int idx = 0); 00103 00104 private: 00107 ErrorCode deform_master(Range &fluid_elems, Range &solid_elems, const char *tag_name = NULL); 00108 00110 ErrorCode read_file(int m_or_s, string &fname, EntityHandle &seth); 00111 00114 ErrorCode write_to_coords(Range &elems, Tag tagh, Tag tmp_tag = 0); 00115 00118 ErrorCode write_and_save(Range &ents, EntityHandle seth, Tag tagh, const char *filename, 00119 bool restore_coords = false); 00120 00122 ErrorCode find_other_sets(int m_or_s, EntityHandle file_set); 00123 00125 Interface *mbImpl; 00126 00127 Error *mError; 00128 00129 #ifdef USE_MPI 00130 00131 ParallelComm *pcMaster, *pcSlave; 00132 #endif 00133 00135 std::set<int> fluidSetNos[2]; 00136 00138 std::set<int> solidSetNos[2]; 00139 00141 EntityHandle masterSet, slaveSet; 00142 00144 Range fluidSets[2], solidSets[2]; 00145 00147 Range fluidElems[2], solidElems[2]; 00148 00150 std::string masterFileName, slaveFileName; 00151 00153 Tag xDisp[3]; 00154 00156 Tag xNew; 00157 00159 std::string xDispNames[3]; 00160 00162 std::string xNewName; 00163 }; 00164 00166 inline ErrorCode DeformMeshRemap::add_set_no(int m_or_s, int f_or_s, int set_no) 00167 { 00168 std::set<int> *this_set; 00169 assert ((m_or_s == MASTER || m_or_s == SLAVE) && "m_or_s should be MASTER or SLAVE."); 00170 if (m_or_s != MASTER && m_or_s != SLAVE) return MB_INDEX_OUT_OF_RANGE; 00171 00172 switch (f_or_s) { 00173 case FLUID: 00174 this_set = &fluidSetNos[m_or_s]; break; 00175 case SOLID: 00176 this_set = &solidSetNos[m_or_s]; break; 00177 default: 00178 assert(false && "f_or_s should be FLUID or SOLID."); 00179 return MB_FAILURE; 00180 } 00181 00182 this_set->insert(set_no); 00183 00184 return MB_SUCCESS; 00185 } 00186 00188 inline ErrorCode DeformMeshRemap::remove_set_no(int m_or_s, int f_or_s, int set_no) 00189 { 00190 std::set<int> *this_set; 00191 assert ((m_or_s == MASTER || m_or_s == SLAVE) && "m_or_s should be MASTER or SLAVE."); 00192 if (m_or_s != MASTER && m_or_s != SLAVE) return MB_INDEX_OUT_OF_RANGE; 00193 switch (f_or_s) { 00194 case FLUID: 00195 this_set = &fluidSetNos[m_or_s]; break; 00196 case SOLID: 00197 this_set = &solidSetNos[m_or_s]; break; 00198 default: 00199 assert(false && "f_or_s should be FLUID or SOLID."); 00200 return MB_FAILURE; 00201 } 00202 std::set<int>::iterator sit = this_set->find(set_no); 00203 if (sit != this_set->end()) { 00204 this_set->erase(*sit); 00205 return MB_SUCCESS; 00206 } 00207 00208 return MB_FAILURE; 00209 } 00210 00212 inline ErrorCode DeformMeshRemap::get_set_nos(int m_or_s, int f_or_s, std::set<int> &set_nos) const 00213 { 00214 const std::set<int> *this_set; 00215 assert ((m_or_s == MASTER || m_or_s == SLAVE) && "m_or_s should be MASTER or SLAVE."); 00216 if (m_or_s != MASTER && m_or_s != SLAVE) return MB_INDEX_OUT_OF_RANGE; 00217 switch (f_or_s) { 00218 case FLUID: 00219 this_set = &fluidSetNos[m_or_s]; break; 00220 case SOLID: 00221 this_set = &solidSetNos[m_or_s]; break; 00222 default: 00223 assert(false && "f_or_s should be FLUID or SOLID."); 00224 return MB_FAILURE; 00225 } 00226 00227 set_nos = *this_set; 00228 00229 return MB_SUCCESS; 00230 } 00231 00232 inline std::string DeformMeshRemap::xdisp_name(int idx) 00233 { 00234 return xDispNames[idx]; 00235 } 00236 00237 void DeformMeshRemap::xdisp_name(const std::string &nm, int idx) 00238 { 00239 xDispNames[idx] = nm; 00240 } 00241 00242 ErrorCode DeformMeshRemap::execute() 00243 { 00244 // read master/slave files and get fluid/solid material sets 00245 ErrorCode rval = read_file(MASTER, masterFileName, masterSet); 00246 if (MB_SUCCESS != rval) return rval; 00247 00248 if (solidSetNos[MASTER].empty() || fluidSetNos[MASTER].empty()) { 00249 rval = find_other_sets(MASTER, masterSet); RR("Failed to find other sets in master mesh."); 00250 } 00251 00252 bool have_slave = !(slaveFileName == "none"); 00253 if (have_slave) { 00254 rval = read_file(SLAVE, slaveFileName, slaveSet); 00255 if (MB_SUCCESS != rval) return rval; 00256 00257 if (solidSetNos[SLAVE].empty() || fluidSetNos[SLAVE].empty()) { 00258 rval = find_other_sets(SLAVE, slaveSet); RR("Failed to find other sets in slave mesh."); 00259 } 00260 } 00261 00262 if (debug) std::cout << "Constructing data coupler/search tree on master mesh..." << std::endl; 00263 00264 Range src_elems = solidElems[MASTER]; 00265 src_elems.merge(fluidElems[MASTER]); 00266 00267 // initialize data coupler on source elements 00268 DataCoupler dc_master(mbImpl, src_elems, 0, NULL); 00269 00270 Range tgt_verts; 00271 if (have_slave) { 00272 // locate slave vertices in master, orig coords; do this with a data coupler, so you can 00273 // later interpolate 00274 Range tmp_range = solidElems[SLAVE]; 00275 tmp_range.merge(fluidElems[SLAVE]); 00276 rval = mbImpl->get_adjacencies(tmp_range, 0, false, tgt_verts, Interface::UNION); 00277 RR("Failed to get target verts."); 00278 00279 // locate slave vertices, caching results in dc 00280 if (debug) std::cout << "Locating slave vertices in master mesh..." << std::endl; 00281 rval = dc_master.locate_points(tgt_verts); RR("Point location of tgt verts failed."); 00282 int num_located = dc_master.spatial_locator()->local_num_located(); 00283 if (num_located != (int)tgt_verts.size()) { 00284 rval = MB_FAILURE; 00285 std::cout << "Only " << num_located << " out of " << tgt_verts.size() << " target points successfully located." << std::endl; 00286 return rval; 00287 } 00288 } 00289 00290 // deform the master's solid mesh, put results in a new tag 00291 if (debug) std::cout << "Deforming fluid elements in master mesh..." << std::endl; 00292 rval = deform_master(fluidElems[MASTER], solidElems[MASTER], "xnew"); RR(""); 00293 00294 { // to isolate the lloyd smoother & delete when done 00295 if (debug) { 00296 // output the skin of smoothed elems, as a check 00297 // get the skin; get facets, because we might need to filter on shared entities 00298 Skinner skinner(mbImpl); 00299 Range skin; 00300 rval = skinner.find_skin(0, fluidElems[MASTER], false, skin); RR("Unable to find skin."); 00301 EntityHandle skin_set; 00302 std::cout << "Writing skin_mesh.g and fluid_mesh.g." << std::endl; 00303 rval = mbImpl->create_meshset(MESHSET_SET, skin_set); RR("Failed to create skin set."); 00304 rval = mbImpl->add_entities(skin_set, skin); RR("Failed to add skin entities to set."); 00305 rval = mbImpl->write_file("skin_mesh.vtk", NULL, NULL, &skin_set, 1); RR("Failure to write skin set."); 00306 rval = mbImpl->remove_entities(skin_set, skin); RR("Failed to remove skin entities from set."); 00307 rval = mbImpl->add_entities(skin_set, fluidElems[MASTER]); RR("Failed to add fluid entities to set."); 00308 rval = mbImpl->write_file("fluid_mesh.vtk", NULL, NULL, &skin_set, 1); RR("Failure to write fluid set."); 00309 rval = mbImpl->delete_entities(&skin_set, 1); RR("Failed to delete skin set."); 00310 } 00311 00312 // smooth the master mesh 00313 if (debug) std::cout << "Smoothing fluid elements in master mesh..." << std::endl; 00314 LloydSmoother ll(mbImpl, NULL, fluidElems[MASTER], xNew); 00315 rval = ll.perform_smooth(); 00316 RR("Failed in lloyd smoothing."); 00317 cout << "Lloyd smoothing required " << ll.num_its() << " iterations." << endl; 00318 } 00319 00320 // transfer xNew to coords, for master 00321 if (debug) std::cout << "Transferring coords tag to vertex coordinates in master mesh..." << std::endl; 00322 rval = write_to_coords(solidElems[MASTER], xNew); RR("Failed writing tag to master fluid verts."); 00323 rval = write_to_coords(fluidElems[MASTER], xNew); RR("Failed writing tag to master fluid verts."); 00324 00325 if (have_slave) { 00326 // map new locations to slave 00327 // interpolate xNew to slave points 00328 if (debug) std::cout << "Interpolating new coordinates to slave vertices..." << std::endl; 00329 rval = dc_master.interpolate((int)DataCoupler::VOLUME, "xnew"); RR("Failed to interpolate target solution."); 00330 // transfer xNew to coords, for slave 00331 if (debug) std::cout << "Transferring coords tag to vertex coordinates in slave mesh..." << std::endl; 00332 rval = write_to_coords(tgt_verts, xNew); RR("Failed writing tag to slave verts."); 00333 } 00334 00335 if (debug) { 00336 std::string str; 00337 #ifdef USE_MPI 00338 if (pcMaster && pcMaster->size() > 1) 00339 str = "PARALLEL=WRITE_PART"; 00340 #endif 00341 if (debug) std::cout << "Writing smoothed_master.h5m..." << std::endl; 00342 rval = mbImpl->write_file("smoothed_master.h5m", NULL, str.c_str(), &masterSet, 1); 00343 00344 if (have_slave) { 00345 #ifdef USE_MPI 00346 str.clear(); 00347 if (pcSlave && pcSlave->size() > 1) 00348 str = "PARALLEL=WRITE_PART"; 00349 #endif 00350 if (debug) std::cout << "Writing slave_interp.h5m..." << std::endl; 00351 rval = mbImpl->write_file("slave_interp.h5m", NULL, str.c_str(), &slaveSet, 1); 00352 } // if have_slave 00353 } // if debug 00354 00355 if (debug) 00356 dc_master.spatial_locator()->get_tree()->tree_stats().print(); 00357 00358 return MB_SUCCESS; 00359 } 00360 00361 std::string DeformMeshRemap::get_file_name(int m_or_s) const 00362 { 00363 switch (m_or_s) { 00364 case MASTER: 00365 return masterFileName; 00366 case SLAVE: 00367 return slaveFileName; 00368 default: 00369 assert(false && "m_or_s should be MASTER or SLAVE."); 00370 return std::string(); 00371 } 00372 } 00373 00374 void DeformMeshRemap::set_file_name(int m_or_s, const std::string &name) 00375 { 00376 switch (m_or_s) { 00377 case MASTER: 00378 masterFileName = name; break; 00379 case SLAVE: 00380 slaveFileName = name; break; 00381 default: 00382 assert(false && "m_or_s should be MASTER or SLAVE."); 00383 } 00384 } 00385 00386 DeformMeshRemap::DeformMeshRemap(Interface *impl, ParallelComm *master, ParallelComm *slave) 00387 : mbImpl(impl), pcMaster(master), pcSlave(slave), masterSet(0), slaveSet(0), xNew(0), xNewName("xnew") 00388 { 00389 mbImpl->query_interface(mError); 00390 xDisp[0] = xDisp[1] = xDisp[2] = 0; 00391 00392 if (!pcSlave && pcMaster) 00393 pcSlave = pcMaster; 00394 } 00395 00396 DeformMeshRemap::~DeformMeshRemap() 00397 { 00398 mbImpl->release_interface(mError); 00399 } 00400 00401 int main(int argc, char **argv) { 00402 00403 ErrorCode rval; 00404 00405 ProgOptions po("Deformed mesh options"); 00406 po.addOpt<std::string> ("master,m", "Specify the master meshfile name" ); 00407 po.addOpt<std::string> ("worker,w", "Specify the slave/worker meshfile name, or 'none' (no quotes) if master only" ); 00408 po.addOpt<std::string> ("d1,", "Tag name for displacement x or xyz" ); 00409 po.addOpt<std::string> ("d2,", "Tag name for displacement y" ); 00410 po.addOpt<std::string> ("d3,", "Tag name for displacement z" ); 00411 po.addOpt<int> ("fm,", "Specify master fluid material set number(s). If none specified, fluid sets derived from complement of solid sets."); 00412 po.addOpt<int> ("fs,", "Specify master solid material set number(s). If none specified, solid sets derived from complement of fluid sets."); 00413 po.addOpt<int> ("sm,", "Specify slave fluid material set number(s). If none specified, fluid sets derived from complement of solid sets."); 00414 po.addOpt<int> ("ss,", "Specify slave solid material set number(s). If none specified, solid sets derived from complement of fluid sets."); 00415 00416 po.parseCommandLine(argc, argv); 00417 00418 mb = new Core(); 00419 00420 DeformMeshRemap *dfr; 00421 #ifdef USE_MPI 00422 ParallelComm *pc = new ParallelComm(mb, MPI_COMM_WORLD); 00423 dfr = new DeformMeshRemap(mb, pc); 00424 #else 00425 dfr = new DeformMeshRemap(mb); 00426 #endif 00427 00428 00429 std::string masterf, slavef; 00430 if(!po.getOpt("master", &masterf)) 00431 masterf = string(MESH_DIR) + string("/rodquad.g"); 00432 dfr->set_file_name(DeformMeshRemap::MASTER, masterf); 00433 00434 if(!po.getOpt("worker", &slavef)) 00435 slavef = string(MESH_DIR) + string("/rodtri.g"); 00436 dfr->set_file_name(DeformMeshRemap::SLAVE, slavef); 00437 if (slavef.empty()) { 00438 std::cerr << "Empty slave file name; if no slave, use filename 'none' (no quotes)." << std::endl; 00439 return 1; 00440 } 00441 00442 std::vector<int> set_nos; 00443 po.getOptAllArgs("fm", set_nos); 00444 for (std::vector<int>::iterator vit = set_nos.begin(); vit != set_nos.end(); vit++) 00445 dfr->add_set_no(DeformMeshRemap::MASTER, DeformMeshRemap::FLUID, *vit); 00446 set_nos.clear(); 00447 00448 po.getOptAllArgs("fs", set_nos); 00449 for (std::vector<int>::iterator vit = set_nos.begin(); vit != set_nos.end(); vit++) 00450 dfr->add_set_no(DeformMeshRemap::SLAVE, DeformMeshRemap::FLUID, *vit); 00451 set_nos.clear(); 00452 00453 po.getOptAllArgs("sm", set_nos); 00454 for (std::vector<int>::iterator vit = set_nos.begin(); vit != set_nos.end(); vit++) 00455 dfr->add_set_no(DeformMeshRemap::MASTER, DeformMeshRemap::SOLID, *vit); 00456 00457 po.getOptAllArgs("ss", set_nos); 00458 for (std::vector<int>::iterator vit = set_nos.begin(); vit != set_nos.end(); vit++) 00459 dfr->add_set_no(DeformMeshRemap::SLAVE, DeformMeshRemap::SOLID, *vit); 00460 00461 std::string tnames[3]; 00462 po.getOpt("d1", &tnames[0]); 00463 po.getOpt("d2", &tnames[1]); 00464 po.getOpt("d3", &tnames[2]); 00465 for (int i = 0; i < 3; i++) 00466 if (!tnames[i].empty()) dfr->xdisp_name(tnames[i], i); 00467 00468 rval = dfr->execute(); 00469 00470 delete dfr; 00471 delete mb; 00472 00473 return rval; 00474 } 00475 00476 ErrorCode DeformMeshRemap::write_and_save(Range &ents, EntityHandle seth, Tag tagh, const char *filename, 00477 bool restore_coords) 00478 { 00479 Tag tmp_tag = 0; 00480 ErrorCode rval; 00481 if (restore_coords) 00482 rval = mbImpl->tag_get_handle("", 3, MB_TYPE_DOUBLE, tmp_tag, MB_TAG_CREAT|MB_TAG_DENSE); 00483 00484 rval = write_to_coords(ents, tagh, tmp_tag); RR(""); 00485 rval = mbImpl->write_file(filename, NULL, NULL, &seth, 1); RR(""); 00486 if (restore_coords) { 00487 rval = write_to_coords(ents, tmp_tag); RR(""); 00488 rval = mbImpl->tag_delete(tmp_tag); 00489 } 00490 00491 return rval; 00492 } 00493 00494 ErrorCode DeformMeshRemap::write_to_coords(Range &elems, Tag tagh, Tag tmp_tag) 00495 { 00496 // write the tag to coordinates 00497 Range verts; 00498 ErrorCode rval = mbImpl->get_adjacencies(elems, 0, false, verts, Interface::UNION); 00499 RR("Failed to get adj vertices."); 00500 std::vector<double> coords(3*verts.size()); 00501 00502 if (tmp_tag) { 00503 // save the coords to tmp_tag first 00504 rval = mbImpl->get_coords(verts, &coords[0]); RR("Failed to get tmp copy of coords."); 00505 rval = mbImpl->tag_set_data(tmp_tag, verts, &coords[0]); RR("Failed to save tmp copy of coords."); 00506 } 00507 00508 rval = mbImpl->tag_get_data(tagh, verts, &coords[0]); 00509 RR("Failed to get tag data."); 00510 rval = mbImpl->set_coords(verts, &coords[0]); 00511 RR("Failed to set coordinates."); 00512 return MB_SUCCESS; 00513 } 00514 00515 void deform_func(const BoundBox &bbox, double *xold, double *xnew) 00516 { 00517 /* Deformation function based on max delx and dely at top of rod 00518 const double RODWIDTH = 0.2, RODHEIGHT = 0.5; 00519 // function: origin is at middle base of rod, and is .5 high 00520 // top of rod is (0,.55) on left and (.2,.6) on right 00521 double delx = 0.5*RODWIDTH; 00522 00523 double xfrac = (xold[0] + .5*RODWIDTH)/RODWIDTH, yfrac = xold[1]/RODHEIGHT; 00524 xnew[0] = xold[0] + yfrac * delx; 00525 xnew[1] = xold[1] + yfrac * (1.0 + xfrac) * 0.05; 00526 */ 00527 /* Deformation function based on fraction of bounding box dimension in each direction */ 00528 double frac = 0.01; // taken from approximate relative deformation from LLNL Diablo of XX09 assys 00529 CartVect *xo = reinterpret_cast<CartVect*>(xold), *xn = reinterpret_cast<CartVect*>(xnew); 00530 CartVect disp = frac * (*xo - bbox.bMin); 00531 *xn = *xo + disp; 00532 } 00533 00534 ErrorCode DeformMeshRemap::deform_master(Range &fluid_elems, Range &solid_elems, const char *tag_name) 00535 { 00536 // deform elements with an analytic function 00537 ErrorCode rval; 00538 00539 // get all the vertices and coords in the solid 00540 Range solid_verts, fluid_verts; 00541 rval = mbImpl->get_adjacencies(solid_elems, 0, false, solid_verts, Interface::UNION); 00542 RR("Failed to get vertices."); 00543 std::vector<double> coords(3*solid_verts.size()), new_coords(3*solid_verts.size()); 00544 rval = mbImpl->get_coords(solid_verts, &coords[0]); 00545 RR("Failed to get vertex coords."); 00546 unsigned int num_verts = solid_verts.size(); 00547 00548 // get or create the tag 00549 if (!xDispNames[0].empty() && !xDispNames[1].empty() && !xDispNames[2].empty()) { 00550 // 3 tags, specifying xyz individual data, integrate into one tag 00551 rval = mbImpl->tag_get_handle((tag_name ? tag_name : ""), 3, MB_TYPE_DOUBLE, xNew, MB_TAG_CREAT|MB_TAG_DENSE); 00552 RR("Failed to create xnew tag."); 00553 std::vector<double> disps(num_verts); 00554 for (int i = 0; i < 3; i++) { 00555 rval = mbImpl->tag_get_handle(xDispNames[0].c_str(), 1, MB_TYPE_DOUBLE, xDisp[i]); 00556 RR("Failed to get xDisp tag."); 00557 rval = mbImpl->tag_get_data(xDisp[i], solid_verts, &disps[0]); 00558 RR("Failed to get xDisp tag values."); 00559 for (unsigned int j = 0; j < num_verts; j++) 00560 new_coords[3*j+i] = coords[3*j+i] + disps[j]; 00561 } 00562 } 00563 else if (!xDispNames[0].empty()) { 00564 rval = mbImpl->tag_get_handle(xDispNames[0].c_str(), 3, MB_TYPE_DOUBLE, xDisp[0]); 00565 RR("Failed to get first xDisp tag."); 00566 xNew = xDisp[0]; 00567 std::vector<double> disps(3*num_verts); 00568 rval = mbImpl->tag_get_data(xDisp[0], solid_verts, &disps[0]); 00569 for (unsigned int j = 0; j < 3*num_verts; j++) 00570 new_coords[j] = coords[j] + disps[j]; 00571 } 00572 else { 00573 // get the bounding box of the solid mesh 00574 BoundBox bbox; 00575 bbox.update(*mbImpl, solid_elems); 00576 00577 for (unsigned int j = 0; j < num_verts; j++) 00578 deform_func(bbox, &coords[3*j], &new_coords[3*j]); 00579 } 00580 00581 if (debug) { 00582 double len = 0.0; 00583 for (unsigned int i = 0; i < num_verts; i++) { 00584 CartVect dx = CartVect(&new_coords[3*i]) - CartVect(&coords[3*i]); 00585 double tmp_len = dx.length_squared(); 00586 if (tmp_len > len) len = tmp_len; 00587 } 00588 Range tmp_elems(fluid_elems); 00589 tmp_elems.merge(solid_elems); 00590 BoundBox box; 00591 box.update(*mbImpl, tmp_elems); 00592 double max_len = std::max(box.bMax[2]-box.bMin[2], std::max(box.bMax[1]-box.bMin[1], box.bMax[0]-box.bMin[0])); 00593 00594 std::cout << "Max displacement = " << len << " (" << 100.0 * len / max_len << "% of max box length)" << std::endl; 00595 } 00596 00597 if (!xNew) { 00598 rval = mbImpl->tag_get_handle((tag_name ? tag_name : ""), 3, MB_TYPE_DOUBLE, 00599 xDisp[0], MB_TAG_CREAT|MB_TAG_DENSE); 00600 RR("Failed to get xNew tag."); 00601 xNew = xDisp[0]; 00602 } 00603 00604 // set the new tag to those coords 00605 rval = mbImpl->tag_set_data(xNew, solid_verts, &new_coords[0]); 00606 RR("Failed to set tag data."); 00607 00608 // get all the vertices and coords in the fluid, set xnew to them 00609 rval = mbImpl->get_adjacencies(fluid_elems, 0, false, fluid_verts, Interface::UNION); 00610 RR("Failed to get vertices."); 00611 fluid_verts = subtract(fluid_verts, solid_verts); 00612 00613 if (coords.size() < 3*fluid_verts.size()) coords.resize(3*fluid_verts.size()); 00614 rval = mbImpl->get_coords(fluid_verts, &coords[0]); 00615 RR("Failed to get vertex coords."); 00616 rval = mbImpl->tag_set_data(xNew, fluid_verts, &coords[0]); 00617 RR("Failed to set xnew tag on fluid verts."); 00618 00619 if (debug) { 00620 // save deformed mesh coords to new file for visualizing 00621 Range tmp_range(fluidElems[MASTER]); 00622 tmp_range.merge(solidElems[MASTER]); 00623 rval = write_and_save(tmp_range, masterSet, xNew, "deformed_master.h5m", true); RR(""); 00624 } 00625 00626 return MB_SUCCESS; 00627 } 00628 00629 ErrorCode DeformMeshRemap::read_file(int m_or_s, string &fname, EntityHandle &seth) 00630 { 00631 // create meshset 00632 ErrorCode rval = mbImpl->create_meshset(0, seth); 00633 RR("Couldn't create master/slave set."); 00634 ostringstream ostr; 00635 #ifdef USE_MPI 00636 ParallelComm *pc = (m_or_s == MASTER ? pcMaster : pcSlave); 00637 if (pc && pc->size() > 1) { 00638 if (debug) ostr << "DEBUG_IO=1;CPUTIME;"; 00639 ostr << "PARALLEL=READ_PART;PARTITION=PARALLEL_PARTITION;PARALLEL_RESOLVE_SHARED_ENTS;" 00640 << "PARALLEL_GHOSTS=2.0.1;PARALLEL_COMM=" << pc->get_id(); 00641 } 00642 #endif 00643 rval = mbImpl->load_file(fname.c_str(), &seth, ostr.str().c_str()); 00644 RR("Couldn't load master/slave mesh."); 00645 00646 if (*solidSetNos[m_or_s].begin() == -1 || *fluidSetNos[m_or_s].begin() == -1) return MB_SUCCESS; 00647 00648 // get material sets for solid/fluid 00649 Tag tagh; 00650 rval = mbImpl->tag_get_handle(MATERIAL_SET_TAG_NAME, tagh); RR("Couldn't get material set tag name."); 00651 for (std::set<int>::iterator sit = solidSetNos[m_or_s].begin(); sit != solidSetNos[m_or_s].end(); sit++) { 00652 Range sets; 00653 int set_no = *sit; 00654 const void *setno_ptr = &set_no; 00655 ErrorCode tmp_rval = mbImpl->get_entities_by_type_and_tag(seth, MBENTITYSET, &tagh, &setno_ptr, 1, sets); 00656 if (sets.empty() || MB_SUCCESS != tmp_rval) { 00657 rval = MB_FAILURE; 00658 mError->set_last_error("Couldn't find solid set #%d.\n", *sit); 00659 } 00660 else 00661 solidSets[m_or_s].merge(sets); 00662 } 00663 00664 // get solid entities, and dimension 00665 Range tmp_range; 00666 for (Range::iterator rit = solidSets[m_or_s].begin(); rit != solidSets[m_or_s].end(); rit++) { 00667 rval = mbImpl->get_entities_by_handle(*rit, tmp_range, true); 00668 RR("Failed to get entities in solid."); 00669 } 00670 if (!tmp_range.empty()) { 00671 int dim = mbImpl->dimension_from_handle(*tmp_range.rbegin()); 00672 assert(dim > 0 && dim < 4); 00673 solidElems[m_or_s] = tmp_range.subset_by_dimension(dim); 00674 } 00675 00676 if (debug) 00677 std::cout << "Read " << solidElems[m_or_s].size() << " solid elements from " << solidSets[m_or_s].size() << " sets in " << (m_or_s == MASTER ? "master" : "slave") << " mesh." << std::endl; 00678 00679 for (std::set<int>::iterator sit = fluidSetNos[m_or_s].begin(); sit != fluidSetNos[m_or_s].end(); sit++) { 00680 Range sets; 00681 int set_no = *sit; 00682 const void *setno_ptr = &set_no; 00683 ErrorCode tmp_rval = mbImpl->get_entities_by_type_and_tag(seth, MBENTITYSET, &tagh, &setno_ptr, 1, sets); 00684 if (sets.empty() || MB_SUCCESS != tmp_rval) { 00685 rval = MB_FAILURE; 00686 mError->set_last_error("Couldn't find fluid set #%d.\n", *sit); 00687 } 00688 else 00689 fluidSets[m_or_s].merge(sets); 00690 } 00691 00692 // get fluid entities, and dimension 00693 tmp_range.clear(); 00694 for (Range::iterator rit = fluidSets[m_or_s].begin(); rit != fluidSets[m_or_s].end(); rit++) { 00695 rval = mbImpl->get_entities_by_handle(*rit, tmp_range, true); 00696 RR("Failed to get entities in fluid."); 00697 } 00698 if (!tmp_range.empty()) { 00699 int dim = mbImpl->dimension_from_handle(*tmp_range.rbegin()); 00700 assert(dim > 0 && dim < 4); 00701 fluidElems[m_or_s] = tmp_range.subset_by_dimension(dim); 00702 } 00703 00704 if (debug) 00705 std::cout << "Read " << fluidElems[m_or_s].size() << " fluid elements from " << fluidSets[m_or_s].size() << " sets in " << (m_or_s == MASTER ? "master" : "slave") << " mesh." << std::endl; 00706 00707 return rval; 00708 } 00709 00710 ErrorCode DeformMeshRemap::find_other_sets(int m_or_s, EntityHandle file_set) 00711 { 00712 // solid or fluid sets are missing; find the other 00713 Range *filled_sets = NULL, *unfilled_sets = NULL, *unfilled_elems = NULL; 00714 00715 if (fluidSets[m_or_s].empty() && !solidSets[m_or_s].empty()) { 00716 unfilled_sets = &fluidSets[m_or_s]; 00717 filled_sets = &solidSets[m_or_s]; 00718 unfilled_elems = &fluidElems[m_or_s]; 00719 if (debug) 00720 std::cout << "Finding unspecified fluid elements in " << (m_or_s == MASTER ? "master" : "slave") << " mesh..."; 00721 } 00722 else if (!fluidSets[m_or_s].empty() && solidSets[m_or_s].empty()) { 00723 filled_sets = &fluidSets[m_or_s]; 00724 unfilled_sets = &solidSets[m_or_s]; 00725 unfilled_elems = &solidElems[m_or_s]; 00726 if (debug) 00727 std::cout << "Finding unspecified solid elements in " << (m_or_s == MASTER ? "master" : "slave") << " mesh..."; 00728 } 00729 00730 // ok, we know the filled sets, now fill the unfilled sets, and the elems from those 00731 Tag tagh; 00732 ErrorCode rval = mbImpl->tag_get_handle(MATERIAL_SET_TAG_NAME, tagh); RR("Couldn't get material set tag name."); 00733 Range matsets; 00734 rval = mbImpl->get_entities_by_type_and_tag(file_set, MBENTITYSET, &tagh, NULL, 1, matsets); 00735 if (matsets.empty()) rval = MB_FAILURE; 00736 RR("Couldn't get any material sets."); 00737 *unfilled_sets = subtract(matsets, *filled_sets); 00738 if (unfilled_sets->empty()) { 00739 rval = MB_FAILURE; 00740 RR("Failed to find any unfilled material sets."); 00741 } 00742 Range tmp_range; 00743 for (Range::iterator rit = unfilled_sets->begin(); rit != unfilled_sets->end(); rit++) { 00744 rval = mbImpl->get_entities_by_handle(*rit, tmp_range, true); 00745 RR("Failed to get entities in unfilled set."); 00746 } 00747 int dim = mbImpl->dimension_from_handle(*tmp_range.rbegin()); 00748 assert(dim > 0 && dim < 4); 00749 *unfilled_elems = tmp_range.subset_by_dimension(dim); 00750 if (unfilled_elems->empty()) { 00751 rval = MB_FAILURE; 00752 RR("Failed to find any unfilled set entities."); 00753 } 00754 00755 if (debug) 00756 std::cout << "found " << unfilled_sets->size() << " sets and " << unfilled_elems->size() << " elements." << std::endl; 00757 00758 return MB_SUCCESS; 00759 } 00760