moab
DeformMeshRemap.cpp
Go to the documentation of this file.
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 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines