⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 align.cpp

📁 算断裂的
💻 CPP
📖 第 1 页 / 共 3 页
字号:
  typedef map<DeduplicationMapKey, ActiveBoxVec::Index> DeduplicationMap;  }void QMG::MG::alignInitStaticData(int di) {  PriorityQueueKey_lastphase::di = di;}#ifdef NSF_DEMOnamespace QMG {  namespace Nsf_Demo {    using namespace QMG;    using namespace QMG::MG;    extern void show_alignment(const ActiveBoxVec& vec,      const vector<ActiveBoxVec::Index>& boxindvec,      const Point& alignpoint);  }}#endif// ------------------------------------------------------------------// align_orbit// This routine aligns an orbit of a brep.  First it puts all the// closefaces in a priority queue.  Then boxes whose closefaces// are completely covered are protected, their subfaces launched,// and a new vertex appears in the simplicial complex.void QMG::MG::align_orbit(ActiveBoxVec& alignvec,                          int closefacedim,                          Real maxwarpdist,                          ActiveBoxVec& idlevec,                          ActiveBoxVec& smallboxvec,                          ActiveBoxVec& small_idle_boxvec,                          const Brep::Face_Spec& alignfspec,                          BoxFaceDag& dag,                          SimpComplex_Under_Construction& sc,                          vector<Brep::Face_Spec>& vtx_owner,                          const vector<Real>& asp_degrade,                          Logstream& logstr,                          Meshgen_gui& gui,                          const PatchTable& patchtable,                           IncidenceTable& inc_table,                          ActiveBoxVec::Create_Subbox_Workspace& wkspa) {  debug_ostream = &logstr.str();  PriorityQueueKey::base_idx = 0;    Real bxwidth = BoxAddress::multiplier() / ( (Real)(1 << alignvec.iwidth()) );  Real maxwarpdist_act = maxwarpdist * bxwidth;    IncidencePriorityQueue ipq(closefacedim, maxwarpdist_act, alignfspec,    patchtable, inc_table, logstr);  // Put box closefaces into the queue.  {    for (ActiveBoxVec::Loop_over_boxes_nonconst loop(alignvec);    loop.notdone();    ++loop) {      NonConstActiveBox b = loop.getbox_nonconst();#ifdef DEBUGGING      if (b.completely_interior()) {        throw_error("Completely interior box in wrong orbit?");        return;      }#endif      ipq.insert_box_closefaces(b);      b.assign_close_face(false);      gui.check_update();    }  }    vector<PriorityQueueKey> boxes_to_align(0);#ifdef NSF_DEMO  vector<ActiveBoxVec::Index> boxind_vec;#endif  bool too_far_detected = false;  int di = patchtable.embedded_dim();  int phase = alignfspec.fdim();  vector<SimpComplex::VertexOrdinalIndex> volist(di + 1);  vector<Real> warp_point_re(di);  vector<Real> warp_point_pa(alignfspec.fdim());  Point warp_point_pa0;  // Loop over the priority queue, either until the distance gets   // so big that an unacceptable warp is found, or the queue is empty.  while (!too_far_detected && ipq.size() > 0) {        gui.check_update();            // Copy all the highest priority box faces with the same incidence index    // to stack boxes_to_align.    boxes_to_align.resize(0);    Mask flatdim1 = ipq.top().flatdim;    IncidenceTable::Index incind1 = ipq.top().incind;    do {      if (!(alignvec.iskilled(ipq.top().boxind)))        boxes_to_align.push_back(ipq.top());      ipq.pop();    } while (ipq.size() > 0 && ipq.top().flatdim == flatdim1 &&      ipq.top().incind == incind1);    int basize = boxes_to_align.size();    if (basize == 0)      continue;    if (logstr.verbosity() >= 2) { ////      logstr.str() << "Attempting to align boxes\n";      for (int jj = 0; jj < basize; ++jj) {        ActiveBoxVec::Index boxind = boxes_to_align[jj].boxind;        const ActiveBox& b1 = alignvec.getbox(boxind);        logstr.str() << "    " << b1 << " ";        boxes_to_align[jj].rindex.output(logstr.str(), b1.dim());      }      logstr.str() << " to incidence incd#" << inc_table.seqno(incind1) << "#\n";    }        // Test all of these boxes for OK aspect ratio.        Real dist1 = boxes_to_align[0].dist;    if (dist1 == BIG_REAL) {      if (logstr.verbosity() >= 2) { ////        logstr.str() << " distance = " << dist1 << " too far\n";      }      too_far_detected = true;      break;    }    // Check if we are trying to align a too low-dimensional box face.    {      for (int jj = 0; jj < basize; ++jj) {        ActiveBoxVec::Index boxind = boxes_to_align[jj].boxind;        const ActiveBox& b1 = alignvec.getbox(boxind);        if (b1.dim() + phase < di) {          too_far_detected = true;#ifdef DEBUGGING          if (dist1 <= maxwarpdist_act * .05 && logstr.verbosity() >= 1) {            logstr.str() << "Warning: warping anomaly may lead to poor aspect ratio.\n"              << "Suggest you re-run QMG with smaller curvature setting.";          }#endif          break;        }      }    }    if (too_far_detected)      break;    Point warp_point = inc_table.real_coord(incind1);    if (dist1 > 0.0) {      for (int jj = 0; jj < basize; ++jj) {        ActiveBox b = alignvec.getbox(boxes_to_align[jj].boxind);        too_far_detected = !warp_ok(dist1, warp_point, b,          boxes_to_align[jj].rindex, dag, b.link_parent(), sc,           asp_degrade[b.dim()], logstr, wkspa.scfac, wkspa.tol, volist);        if (too_far_detected) {          if (logstr.verbosity() >= 2) { ////            logstr.str() << " distance = " << dist1 << " too far detected on " << jj << "th box\n";          }          break;        }      }    }        if (too_far_detected)      break;          // Check if we can align these boxes by adding up their weights.        Weight_t sumweight = 0.0;    for (int kk = 0; kk < basize; ++kk) {      sumweight += alignvec.getbox(boxes_to_align[kk].boxind).weight(boxes_to_align[kk].rindex);    }        if (logstr.verbosity() >= 2) ////      logstr.str() << "weightsum = " << sumweight << '\n';    if (sumweight > 1.00001)      throw_error("Excess weight sum");    // If the weight sum is 1, protect all the boxes, launch subfaces,    // and put a new vertex in the simplicial complex.    if (sumweight > 0.99999) {      PatchTable::Index patchind = inc_table.patchind(incind1);      warp_point_pa0 = inc_table.param_coord(incind1);      for (int ll = 0; ll < di; ++ll)        warp_point_re[ll] = warp_point[ll];      for (int mm = 0; mm < alignfspec.fdim(); ++mm)        warp_point_pa[mm] = warp_point_pa0[mm];      pair<SimpComplex::VertexOrdinalIndex, SimpComplex::VertexGlobalIndex> rval =         sc.add_vertex(warp_point_re);      SimpComplex::VertexOrdinalIndex vertnum_o = rval.first;      SimpComplex::VertexGlobalIndex vertnum = rval.second;      sc.add_vertex_bdryinc(vertnum, alignfspec,        patchtable.orig_index(patchind), warp_point_pa);      if (vtx_owner.size() <= vertnum_o) {        vtx_owner.resize(vertnum_o + 1, alignfspec);      }      else         vtx_owner[vertnum_o] = alignfspec;      if (logstr.verbosity() >= 2) { ////        logstr.str() << "Alignment successful; new vertex vtx#" << vertnum           << "#   ord#" << vertnum_o << " at coords " << warp_point << " on patch " << patchind << '\n';      }#ifdef NSF_DEMO      boxind_vec.resize(basize);      for (int jj2 = 0; jj2 < basize; ++jj2) {        boxind_vec[jj2] = boxes_to_align[jj2].boxind;      }      QMG::Nsf_Demo::show_alignment(alignvec, boxind_vec, warp_point);#endif      for (int jj = 0; jj < basize; ++jj) {        ActiveBoxVec::Index boxind = boxes_to_align[jj].boxind;        ActiveBox b = alignvec.getbox(boxind);        Real maxwarpdist_act = maxwarpdist * b.real_width();        Base3 rindex = boxes_to_align[jj].rindex;        protect_box_and_launch_subfaces(b, vertnum_o, rindex,          alignfspec, alignvec, idlevec, dag, ipq, wkspa);        alignvec.killbox(boxind, logstr);      }    }     else {      // If the weight sum is < 1, then mark the boxes to indicate that they      // had a close face.  This forces them to be split.      for (int jj = 0; jj < basize; ++jj) {        alignvec.getbox_nonconst(boxes_to_align[jj].boxind).assign_close_face(true);        // check_containment(alignvec.getbox(boxes_to_align[jj].boxind), idlevec, logstr.str());      }    }  }      // All the boxes that have a close subface and weren't aligned must be split.  // Must split if this is the last pass.  bool last_pass = closefacedim == di - phase;  {    for (ActiveBoxVec::Loop_over_boxes_nonconst loop(alignvec);    loop.notdone();    ++loop) {      gui.check_update();      ActiveBox b = loop.getbox();      if (b.has_close_face() || last_pass) {        if (b.iwidth() >= MAXLEV)           throw_error("Oversplitting for alignment (1)");        ActiveBoxVec::split_box_and_push_children(phase, alignvec,           smallboxvec, small_idle_boxvec, b,  inc_table,  wkspa);        alignvec.killbox(loop.index(), logstr);      }    }  }}// ------------------------------------------------------------------// align_orbit_lastphase// This aligns boxes during the last phase.  It's quite similar// to align, except there are some simplifications because// there is no warping.void QMG::MG::align_orbit_lastphase(ActiveBoxVec& alignvec,                                    ActiveBoxVec& smallboxvec,                                    const Brep::Face_Spec& alignfspec,                                    BoxFaceDag& dag,                                    SimpComplex_Under_Construction& sc,                                    vector<Brep::Face_Spec>& vtx_owner,                                    Logstream& logstr,                                    Meshgen_gui& gui) {      PriorityQueueKey_lastphase::base_idx = 0;    IncidencePriorityQueue_LastPhase ipq(logstr);  int di = alignfspec.fdim();  // Put all the vertices of the boxes into the priority queue.  {    for (ActiveBoxVec::Loop_over_boxes loop(alignvec);    loop.notdone();    ++loop) {      gui.check_update();      ActiveBox b = loop.getbox();#ifdef DEBUGGING      if (!b.completely_interior()) {        throw_error("Not completely interior box in wrong orbit");        return;      }#endif      ipq.insert_box_closefaces(b);    }  }    vector<PriorityQueueKey_lastphase> boxes_to_align(0);#ifdef NSF_DEMO  vector<ActiveBoxVec::Index> boxind_vec;#endif  BoxAddress bxa;  vector<Real> new_point_re(di);  vector<Real> new_point_pa(0);  while (ipq.size() > 0) {        // Copy all the highest priority box faces with the same incidence index    // to stack boxes_to_align.    gui.check_update();        boxes_to_align.resize(0);    bxa.lowerleft() = ipq.top().position;    do {      if (!alignvec.iskilled(ipq.top().boxind))        boxes_to_align.push_back(ipq.top());      ipq.pop();    } while (ipq.size() > 0 && ipq.top().position == bxa.lowerleft());    int basize = boxes_to_align.size();    if (basize == 0)      continue;    if (logstr.verbosity() >= 2) { ////      logstr.str() << "Attempting to (last phase) align boxes\n";      for (int jj = 0; jj < basize; ++jj) {        ActiveBoxVec::Index boxind = boxes_to_align[jj].boxind;        const ActiveBox& b1 = alignvec.getbox(boxind);        logstr.str() << "    " << b1 << " ";        boxes_to_align[jj].rindex.output(logstr.str(), b1.dim());        logstr.str() << '\n';      }    }        // Check if we can align these boxes by adding up their weights.        Weight_t sumweight = 0.0;    for (int jj = 0; jj < basize; ++jj) {      sumweight += alignvec.getbox(boxes_to_align[jj].boxind).weight(boxes_to_align[jj].rindex);    }            if (logstr.verbosity() >= 2) ////      logstr.str() << "weightsum = " << sumweight << '\n';    if (sumweight > 1.00001)      throw_error("Excess weight sum last phase");    if (sumweight > 0.99999) {      Point pt = bxa.real_lowerleft();      for (int ll = 0; ll < di; ++ll)        new_point_re[ll] = pt[ll];      pair<SimpComplex::VertexOrdinalIndex, SimpComplex::VertexGlobalIndex> rval =         sc.add_vertex(new_point_re);      SimpComplex::VertexOrdinalIndex vertnum_o = rval.first;      SimpComplex::VertexGlobalIndex vertnum = rval.second;      if (vtx_owner.size() <= vertnum_o) {        vtx_owner.resize(vertnum_o + 1, alignfspec);      }      else         vtx_owner[vertnum_o] = alignfspec;      if (logstr.verbosity() >= 2) { ////        logstr.str() << "Alignment successful; new vertex vtx#" << vertnum           << "# ord #" << vertnum_o << " at coords " << pt << '\n';      }#ifdef NSF_DEMO      boxind_vec.resize(basize);      for (int jj2 = 0; jj2 < basize; ++jj2) {        boxind_vec[jj2] = boxes_to_align[jj2].boxind;      }      QMG::Nsf_Demo::show_alignment(alignvec, boxind_vec, pt);#endif      for (int jj = 0; jj < basize; ++jj) {        int boxind = boxes_to_align[jj].boxind;        ActiveBox b = alignvec.getbox(boxind);        protect_box_and_launch_subfaces_lastphase(b, vertnum_o,          boxes_to_align[jj].rindex, alignfspec, alignvec, dag, ipq, logstr);        alignvec.killbox(boxind, logstr);      }    }   }    // All the boxes that have a close subface and weren't aligned must be split.    {    for (ActiveBoxVec::Loop_over_boxes loop(alignvec);    loop.notdone();    ++loop) {      gui.check_update();      ActiveBox b = loop.getbox();      if (b.iwidth() >= MAXLEV)        throw_error("Oversplitting for alignment (2)");      ActiveBoxVec::split_completely_interior_box_and_push_children(b,        smallboxvec, logstr);      alignvec.killbox(loop.index(), logstr);    }  }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -