qboxstack.cpp

来自「算断裂的」· C++ 代码 · 共 693 行 · 第 1/2 页

CPP
693
字号
// ------------------------------------------------------------------// qboxstack.cpp//// This file contains member functions qboxstack.h.  These are classes// for boxes in the mesh generator, and vectors of boxes.// ------------------------------------------------------------------// Author: Stephen A. Vavasis// Copyright (c) 1999 by Cornell University.  All rights reserved.// // See the accompanying file 'Copyright' for authorship information,// the terms of the license governing this software, and disclaimers// concerning this software.// ------------------------------------------------------------------// This file is part of the QMG software.  // Version 2.0 of QMG, release date September 3, 1999.// ------------------------------------------------------------------#ifdef _MSC_VER#if _MSC_VER == 1200#include "qmatvec.h"#endif#endif#include "qboxstack.h"namespace QMG {  namespace MG {    using namespace QMG;        //global function in this file    void boxstack_init_static_data(int di);   }}// File scope functions.namespace {  using namespace QMG;  using namespace QMG::MG;#ifdef DEBUGGING  ostream* debug_ostream;    bool dump_everything;  int create_subbox_invocation_count;#endif  // ------------------------------------------------------------------  // Routine to compute a random point in the unit octahedron.  // Selection is not uniform -- I don't know an easy way to do this uniformly.  Point select_rand_point_in_unit_octahedron(int di) {    Point p;    {      for (int i = 0; i < di; ++i)        p[i] = random_real() * 2.0 - 1.0;    }    Real t = random_real();    {      for (int i = 0; i < di; ++i)        t += fabs(p[i]);    }    {      for (int i = 0; i < di; ++i)        p[i] /= t;    }    return p;  }}// ------------------------------------------------------------------// contains_point_in_ex// This routine determines whether a point is contained in the expanded// version of a box.bool QMG::MG::ActiveBox::contains_point_in_ex(const Point& pt,                                          Real param_uncertainty,                                         Real scfac) const {   Real l1dist = 0.0;  Real mult = BoxAddress::multiplier();  Real rwidth = mult / (1<<iwidth());  for (int actualdim = 0; actualdim < di_; ++actualdim) {    Real lower = ((Real) this -> boxaddress().lowerleft(actualdim)) * mult /       (1 << MAXLEV) + BoxAddress::global_coordinate_origin(actualdim);    Real upper = lower + ( (flatdim(actualdim)) ? 0 : rwidth);    if (pt[actualdim] < lower)      l1dist += lower - pt[actualdim];    else if (pt[actualdim] > upper)      l1dist += pt[actualdim] - upper;  }  return (l1dist <= rwidth * expa() - scfac * param_uncertainty);}// ------------------------------------------------------------------// This routine selects a random point in the expanded neighborhood// of a box.QMG::MG::Point QMG::MG::ActiveBox::select_rand_point() const {  Real mult = BoxAddress::multiplier();  Real rwidth = mult / (1<<iwidth());  Point pt =  select_rand_point_in_unit_octahedron(di_);#ifdef DEBUGGING  if (dump_everything) {    *debug_ostream << " in select rand initalpt = " << pt << "expa = " << expa()       << " mult = " << mult << " rwidth = " << rwidth << '\n';  }#endif  for (int actualdim = 0; actualdim < di_; ++actualdim) {    Real lower = ((Real) this -> boxaddress().lowerleft(actualdim)) * mult /       (1 << MAXLEV) + BoxAddress::global_coordinate_origin(actualdim);    Real thisw =  (flatdim(actualdim)) ? 0.0: rwidth;    pt[actualdim] = pt[actualdim] * rwidth * expa() +       random_real() * thisw + lower;  }  return pt;}// ------------------------------------------------------------------// This routine computes the real coordinates of the lower left corner// of the box.QMG::MG::PointQMG::MG::BoxAddress::real_lowerleft() const {  Point p;  for (int ii = 0; ii < di_; ++ii) {    p[ii] = lowerleft_[ii] * multiplier_ / (1 << MAXLEV) +      global_coordinate_origin_[ii];  }  return p;}// ------------------------------------------------------------------// This routine computes the real coordinates of the lower left// corner of a face of a box.QMG::MG::Point QMG::MG::ActiveBox::face_real_lowerleft(Base3 rindex) const {  int bdim = this -> dim();  int actual_dim = -1;  BoxAddress bxa = this -> boxaddress();  int iwidth = this -> iwidth();  for (int ii = 0; ii < bdim; ++ii) {    while (this -> boxaddress().flatdim(++actual_dim));    if (rindex[ii] == 1)      bxa.lowerleft().increment(actual_dim,iwidth);  }  return bxa.real_lowerleft();}// ------------------------------------------------------------------// This routine computes the weight of a box face.  Use the static// weights for fulldimensional boxes, properly adjusted if the box// lies at the boundary of the top box.  Else use the weights stored// in the box vector.QMG::MG::Weight_tQMG::MG::ActiveBox::weight(Base3 rindex) const {#ifdef RANGECHECK  if ((UInt32) rindex >= Base3::power3(this -> dim())) {    throw_error("Arg out of range in weight()");  }#endif  if (this -> dim() == di_) {    Weight_t w = fulldim_weights_[rindex];    UInt32 rightmost = (1 << MAXLEV) - (1 << (MAXLEV - this -> iwidth()));    for (int j = 0; j < di_; ++j) {      int ri = rindex[j];      if (ri == 0 && this -> boxaddress().lowerleft(j) == 0)        w *= 2;      else if (ri == 1 && this -> boxaddress().lowerleft(j) == rightmost)        w *= 2;    }    return w;  }  else {    return (this -> owner_).weights_[(this -> owner_).boxvec_[this -> idx_].weights_begin +       (UInt32) rindex];  }}// ------------------------------------------------------------------// Initialize static data in this file.void QMG::MG::ActiveBox::init_static_data(int di) {  di_ = di;  active_box_count_ = 0;  for (Base3 rindex = 0; rindex < Base3::power3(di); ++rindex) {    int d = rindex.dim();    fulldim_weights_[rindex] = 1.0 / ((Weight_t) (1 << (di - d)));  }}// ------------------------------------------------------------------// Returns the weight of a box face as a nonconstant reference (so// that it can be updated).  Valid only for non-full-dimensional boxes.QMG::MG::Weight_t& QMG::MG::NonConstActiveBox::weight_nonconst(Base3 rindex) {#ifdef RANGECHECK  if ((UInt32) rindex >= Base3::power3(this -> dim())) {    throw_error("Arg out of range in weight_nonconst()");  }#endif#ifdef DEBUGGING  if (this -> dim() == di_) {    throw_error("Attempt to set weight for fulldimensional box");  }#endif  return (const_cast<ActiveBoxVec&>(this -> owner_)).    weights_[(this -> owner_).boxvec_[this -> idx_].weights_begin +     (UInt32) rindex];} // ------------------------------------------------------------------// Loop_over_vertices: class for looping over the vertices of a box.void QMG::MG::ActiveBox::Loop_over_vertices::operator++() {  this -> ind_++;  int reldim = 0;  for (int j = 0; j < this -> di_; ++j) {    int bit = (this -> bflatdim_[j])? 0 : ((ind_ >> (reldim++)) & 1);    this -> intcoord_[j] = this -> baseintcoord_[j];    this -> realcoord_[j] = this -> baserealcoord_[j];    if (bit) {      this -> intcoord_.increment(j, this -> bwidth_);      this -> realcoord_[j] += brealwidth_;    }  }}Base3 QMG::MG::ActiveBox::Loop_over_vertices::rindex() const {  UInt32 rind = 0;  for (int j = 0; j < this -> bdim_; ++j) {    if ((this -> ind_ >> j) & 1)      rind += Base3::power3(j);  }  return (Base3) rind;}// ------------------------------------------------------------------// Loop_over_incidences// Class for looping over incidences of a box.QMG::MG::ActiveBox::Loop_over_incidences::Loop_over_incidences(const ActiveBox& ab,                                                               const PatchTable& patchtable,                                                               const Brep::Face_Spec& fspec) :ab_(ab),patchtable_(patchtable),fspec_(fspec) {  for (this -> relnum_ = 0;   this -> relnum_ < (this -> ab_).num_patch();   ++(this -> relnum_)) {    PatchTable::Index p = (this -> ab_).patch(this -> relnum_).patchind();    if ((this ->patchtable_).owner(p) == (this -> fspec_) &&       (this -> ab_).patch(this -> relnum_).num_incidence() > 0)      break;  }  this -> ii_ = 0;}void QMG::MG::ActiveBox::Loop_over_incidences::operator++() {  this -> ii_++;  if (this -> ii_ < (this -> ab_).patch(this -> relnum_).num_incidence())    return;  for (++(this ->relnum_);   (this -> relnum_) < (this -> ab_).num_patch();   ++(this -> relnum_)) {    PatchTable::Index p = (this -> ab_).patch((this -> relnum_)).patchind();    if ((this -> patchtable_).owner(p) == (this -> fspec_) &&      (this -> ab_).patch(this -> relnum_).num_incidence() > 0)      break;  }  this -> ii_ = 0;}QMG::MG::ActiveBox QMG::MG::ActiveBoxVec::get_last_box_() const {  return ActiveBox(*this, this -> boxvec_.size() - 1);} void QMG::MG::boxstack_init_static_data(int di) {  ActiveBoxVec::init_static_data(di);  ActiveBox::init_static_data(di);  BoxAddress::init_static_data(di);}#ifdef NSF_DEMOnamespace QMG {  namespace Nsf_Demo {    using namespace QMG;    using namespace QMG::MG;    extern void show_box(const ActiveBox& b, int code);  }}#endif// ------------------------------------------------------------------// push_top_box// This routine computes the initial (top) box of the quadtree and// pushes it into an ActiveBoxVec.  This is how mesh generation// is initiated.void QMG::MG::ActiveBoxVec::push_top_box(const Brep& g,                                         IncidenceTable& inc_table,

⌨️ 快捷键说明

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