Ejemplo n.º 1
0
ErrorCode DeformMeshRemap::read_file(int m_or_s, string &fname, EntityHandle &seth)
{
  // Create meshset
  ErrorCode rval = mbImpl->create_meshset(0, seth);MB_CHK_SET_ERR(rval, "Couldn't create master/slave set");
  ostringstream options;
#ifdef USE_MPI
  ParallelComm *pc = (m_or_s == MASTER ? pcMaster : pcSlave);
  if (pc && pc->size() > 1) {
    if (debug) options << "DEBUG_IO=1;CPUTIME;";
    options << "PARALLEL=READ_PART;PARTITION=PARALLEL_PARTITION;PARALLEL_RESOLVE_SHARED_ENTS;"
            << "PARALLEL_GHOSTS=2.0.1;PARALLEL_COMM=" << pc->get_id();
  }
#endif  
  rval = mbImpl->load_file(fname.c_str(), &seth, options.str().c_str());MB_CHK_SET_ERR(rval, "Couldn't load master/slave mesh");

  if (*solidSetNos[m_or_s].begin() == -1 || *fluidSetNos[m_or_s].begin() == -1) return MB_SUCCESS;

  // Get material sets for solid/fluid
  Tag tagh;
  rval = mbImpl->tag_get_handle(MATERIAL_SET_TAG_NAME, tagh);MB_CHK_SET_ERR(rval, "Couldn't get material set tag name");
  for (set<int>::iterator sit = solidSetNos[m_or_s].begin(); sit != solidSetNos[m_or_s].end(); ++sit) {
    Range sets;
    int set_no = *sit;
    const void *setno_ptr = &set_no;
    rval = mbImpl->get_entities_by_type_and_tag(seth, MBENTITYSET, &tagh, &setno_ptr, 1, sets);
    if (MB_SUCCESS != rval || sets.empty()) {
      MB_SET_ERR(MB_FAILURE, "Couldn't find solid set #" << *sit);
    }
    else
      solidSets[m_or_s].merge(sets);
  }

  // Get solid entities, and dimension
  Range tmp_range;
  for (Range::iterator rit = solidSets[m_or_s].begin(); rit != solidSets[m_or_s].end(); ++rit) {
    rval = mbImpl->get_entities_by_handle(*rit, tmp_range, true);MB_CHK_SET_ERR(rval, "Failed to get entities in solid");
  }
  if (!tmp_range.empty()) {
    int dim = mbImpl->dimension_from_handle(*tmp_range.rbegin());
    assert(dim > 0 && dim < 4);
    solidElems[m_or_s] = tmp_range.subset_by_dimension(dim);
  }

  if (debug)
    cout << "Read " << solidElems[m_or_s].size() << " solid elements from " << solidSets[m_or_s].size() <<
    " sets in " << (m_or_s == MASTER ? "master" : "slave") << " mesh." << endl;

  for (set<int>::iterator sit = fluidSetNos[m_or_s].begin(); sit != fluidSetNos[m_or_s].end(); ++sit) {
    Range sets;
    int set_no = *sit;
    const void *setno_ptr = &set_no;
    rval = mbImpl->get_entities_by_type_and_tag(seth, MBENTITYSET, &tagh, &setno_ptr, 1, sets);
    if (MB_SUCCESS != rval || sets.empty()) {
      MB_SET_ERR(MB_FAILURE, "Couldn't find fluid set #" << *sit);
    }
    else
      fluidSets[m_or_s].merge(sets);
  }

  // Get fluid entities, and dimension
  tmp_range.clear();
  for (Range::iterator rit = fluidSets[m_or_s].begin(); rit != fluidSets[m_or_s].end(); ++rit) {
    rval = mbImpl->get_entities_by_handle(*rit, tmp_range, true);MB_CHK_SET_ERR(rval, "Failed to get entities in fluid");
  }
  if (!tmp_range.empty()) {
    int dim = mbImpl->dimension_from_handle(*tmp_range.rbegin());
    assert(dim > 0 && dim < 4);
    fluidElems[m_or_s] = tmp_range.subset_by_dimension(dim);
  }

  if (debug)
    cout << "Read " << fluidElems[m_or_s].size() << " fluid elements from " << fluidSets[m_or_s].size() <<
      " sets in " << (m_or_s == MASTER ? "master" : "slave") << " mesh." << endl;

  return rval;
}
Ejemplo n.º 2
0
ErrorCode DeformMeshRemap::execute() 
{
  // Read master/slave files and get fluid/solid material sets
  ErrorCode rval = read_file(MASTER, masterFileName, masterSet);MB_CHK_ERR(rval);

  if (solidSetNos[MASTER].empty() || fluidSetNos[MASTER].empty()) {
    rval = find_other_sets(MASTER, masterSet);MB_CHK_SET_ERR(rval, "Failed to find other sets in master mesh");
  }

  bool have_slave = !(slaveFileName == "none");
  if (have_slave) {
    rval = read_file(SLAVE, slaveFileName, slaveSet);MB_CHK_ERR(rval);

    if (solidSetNos[SLAVE].empty() || fluidSetNos[SLAVE].empty()) {
      rval = find_other_sets(SLAVE, slaveSet);MB_CHK_SET_ERR(rval, "Failed to find other sets in slave mesh");
    }
  }

  if (debug) cout << "Constructing data coupler/search tree on master mesh..." << endl;

  Range src_elems = solidElems[MASTER];
  src_elems.merge(fluidElems[MASTER]);

  // Initialize data coupler on source elements
  DataCoupler dc_master(mbImpl, src_elems, 0, NULL);

  Range tgt_verts;
  if (have_slave) {
    // Locate slave vertices in master, orig coords; do this with a data coupler, so you can
    // later interpolate
    Range tmp_range = solidElems[SLAVE];
    tmp_range.merge(fluidElems[SLAVE]);
    rval = mbImpl->get_adjacencies(tmp_range, 0, false, tgt_verts, Interface::UNION);MB_CHK_SET_ERR(rval, "Failed to get target verts");

    // Locate slave vertices, caching results in dc
    if (debug) cout << "Locating slave vertices in master mesh..." << endl;
    rval = dc_master.locate_points(tgt_verts);MB_CHK_SET_ERR(rval, "Point location of tgt verts failed");
    int num_located = dc_master.spatial_locator()->local_num_located();
    if (num_located != (int)tgt_verts.size()) {
      rval = MB_FAILURE;
      cout << "Only " << num_located << " out of " << tgt_verts.size() << " target points successfully located." << endl;
      return rval;
    }
  }

  // Deform the master's solid mesh, put results in a new tag
  if (debug) cout << "Deforming fluid elements in master mesh..." << endl;
  rval = deform_master(fluidElems[MASTER], solidElems[MASTER], "xnew");MB_CHK_ERR(rval);

  { // To isolate the lloyd smoother & delete when done
    if (debug) {
      // Output the skin of smoothed elems, as a check
      // Get the skin; get facets, because we might need to filter on shared entities
      Skinner skinner(mbImpl);
      Range skin;
      rval = skinner.find_skin(0, fluidElems[MASTER], false, skin);MB_CHK_SET_ERR(rval, "Unable to find skin");
      EntityHandle skin_set;
      cout << "Writing skin_mesh.g and fluid_mesh.g." << endl;
      rval = mbImpl->create_meshset(MESHSET_SET, skin_set);MB_CHK_SET_ERR(rval, "Failed to create skin set");
      rval = mbImpl->add_entities(skin_set, skin);MB_CHK_SET_ERR(rval, "Failed to add skin entities to set");
      rval = mbImpl->write_file("skin_mesh.vtk", NULL, NULL, &skin_set, 1);MB_CHK_SET_ERR(rval, "Failure to write skin set");
      rval = mbImpl->remove_entities(skin_set, skin);MB_CHK_SET_ERR(rval, "Failed to remove skin entities from set");
      rval = mbImpl->add_entities(skin_set, fluidElems[MASTER]);MB_CHK_SET_ERR(rval, "Failed to add fluid entities to set");
      rval = mbImpl->write_file("fluid_mesh.vtk", NULL, NULL, &skin_set, 1);MB_CHK_SET_ERR(rval, "Failure to write fluid set");
      rval = mbImpl->delete_entities(&skin_set, 1);MB_CHK_SET_ERR(rval, "Failed to delete skin set");
    }

    // Smooth the master mesh
    if (debug) cout << "Smoothing fluid elements in master mesh..." << endl;
    LloydSmoother ll(mbImpl, NULL, fluidElems[MASTER], xNew);
    rval = ll.perform_smooth();MB_CHK_SET_ERR(rval, "Failed in lloyd smoothing");
    cout << "Lloyd smoothing required " << ll.num_its() << " iterations." << endl;
  }

  // Transfer xNew to coords, for master
  if (debug) cout << "Transferring coords tag to vertex coordinates in master mesh..." << endl;
  rval = write_to_coords(solidElems[MASTER], xNew);MB_CHK_SET_ERR(rval, "Failed writing tag to master fluid verts");
  rval = write_to_coords(fluidElems[MASTER], xNew);MB_CHK_SET_ERR(rval, "Failed writing tag to master fluid verts");

  if (have_slave) {
    // Map new locations to slave
    // Interpolate xNew to slave points
    if (debug) cout << "Interpolating new coordinates to slave vertices..." << endl;
    rval = dc_master.interpolate((int)DataCoupler::VOLUME, "xnew");MB_CHK_SET_ERR(rval, "Failed to interpolate target solution");
    // Transfer xNew to coords, for slave
    if (debug) cout << "Transferring coords tag to vertex coordinates in slave mesh..." << endl;
    rval = write_to_coords(tgt_verts, xNew);MB_CHK_SET_ERR(rval, "Failed writing tag to slave verts");
  }

  if (debug) {
    string str;
#ifdef USE_MPI
    if (pcMaster && pcMaster->size() > 1) 
      str = "PARALLEL=WRITE_PART";
#endif
    if (debug) cout << "Writing smoothed_master.h5m..." << endl;
    rval = mbImpl->write_file("smoothed_master.h5m", NULL, str.c_str(), &masterSet, 1);

    if (have_slave) {
#ifdef USE_MPI
      str.clear();
      if (pcSlave && pcSlave->size() > 1) 
        str = "PARALLEL=WRITE_PART";
#endif
      if (debug) cout << "Writing slave_interp.h5m..." << endl;
      rval = mbImpl->write_file("slave_interp.h5m", NULL, str.c_str(), &slaveSet, 1);
    } // if have_slave
  } // if debug

  if (debug) 
    dc_master.spatial_locator()->get_tree()->tree_stats().print();

  return MB_SUCCESS;
}