vtf-logo

StatCPTLevelSet.h

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 
00003 // Copyright (C) 2002 Ralf Deiterding
00004 // Brandenburgische Universitaet Cottbus
00005 //
00006 // Copyright (C) 2003-2007 California Institute of Technology
00007 // Ralf Deiterding, ralf@amroc.net
00008 
00009 #ifndef AMROC_STATCPTLEVELSET_H
00010 #define AMROC_STATCPTLEVELSET_H
00011 
00019 #include "cpt/cpt.h"
00020 
00027 template <class DataType, int dim>
00028 class StatCPTLevelSet : public GFMLevelSet<DataType,dim> {
00029   typedef GFMLevelSet<DataType,dim> base;
00030 
00031 public:
00032   typedef typename base::grid_fct_type grid_fct_type;   
00033   typedef typename base::grid_data_type grid_data_type;   
00034   typedef typename cpt::State<dim,DataType> cpt_type;
00035   typedef ads::FixedArray<dim,DataType> point_type;
00036   typedef ads::FixedArray<dim,int> multi_index_type;
00037 
00038   StatCPTLevelSet() : base(), brep_filetype(0), inverse(0), 
00039                       unsign(0), _FillWidth(0) {
00040     max_distance = std::numeric_limits<DataType>::max();
00041     base::_Stationary = 1;
00042     far_away = 1.e36;
00043   }
00044 
00045   virtual ~StatCPTLevelSet() {}
00046 
00047   virtual void register_at(ControlDevice& Ctrl, const std::string& prefix) {
00048     base::LocCtrl = Ctrl.getSubDevice(prefix+"StatCPT");
00049     RegisterAt(base::LocCtrl,"Brep",brep_filename);
00050     RegisterAt(base::LocCtrl,"FileType",brep_filetype);
00051     RegisterAt(base::LocCtrl,"PlotPhi",base::_PlotPhi);
00052     RegisterAt(base::LocCtrl,"Inverse",inverse);
00053     RegisterAt(base::LocCtrl,"Unsigned",unsign);
00054     RegisterAt(base::LocCtrl,"FillWidth",_FillWidth);
00055   } 
00056   virtual void register_at(ControlDevice& Ctrl) {
00057     register_at(Ctrl, "");
00058   }
00059 
00060   virtual void SetupData(GridHierarchy* gh, const int& ghosts) {
00061     base::SetupData(gh, ghosts);
00062 
00063     std::ifstream brep_file( brep_filename.c_str() );
00064     if ( ! brep_file ) {
00065       std::cerr << "Could not read the b-rep file.  Exiting...\n";
00066       std::exit( 1 );
00067     }
00068 
00069     int num_vertices, num_edges;
00070     point_type* vertices;
00071     multi_index_type* edges;
00072 
00073     // ISS file
00074     if (brep_filetype==1) {
00075       int fdim, mdim;
00076       brep_file >> fdim >> mdim;
00077       if ( fdim!=dim || mdim!=dim-1 ) {
00078         std::cerr << "Mesh in b-rep file has wrong dimension.  Exiting...\n";
00079         std::exit( 1 );
00080       }
00081       brep_file >> num_vertices;
00082       vertices = new point_type[ num_vertices ];
00083       const point_type* point_iter_end = vertices + num_vertices;
00084       for ( point_type* piter = vertices; piter != point_iter_end; ++piter )
00085         brep_file >> *piter;
00086       brep_file >> num_edges;
00087       edges = new multi_index_type[ num_edges ];
00088     }
00089     else {
00090       brep_file >> num_vertices >> num_edges;
00091       vertices = new point_type[ num_vertices ];
00092       edges = new multi_index_type[ num_edges ];
00093       const point_type* point_iter_end = vertices + num_vertices;
00094       for ( point_type* piter = vertices; piter != point_iter_end; ++piter )
00095         brep_file >> *piter;
00096     }
00097       
00098     const multi_index_type* edges_iter_end = edges + num_edges;
00099     for ( multi_index_type* eiter = edges; eiter != edges_iter_end; ++eiter ) 
00100       brep_file >> *eiter;
00101 
00102     assert( brep_file.good() );
00103     brep_file.close();
00104     
00105     BBox wholebb = grow(coarsen(base::GH().wholebbox(),DAGHShadowFactor),base::NGhosts());
00106     DCoords lbcorner = base::GH().worldCoords(wholebb.lower(), wholebb.stepsize());
00107     DCoords ubcorner = base::GH().worldCoords(wholebb.upper()+wholebb.stepsize(), 
00108                                               wholebb.stepsize());
00109     DCoords dist = ubcorner-lbcorner; dist *= dist;
00110     max_distance = 0.;
00111     for (register int n=0; n<dim; n++) {
00112       max_distance += dist(n);
00113       domain[n] = lbcorner(n); domain[dim+n] = ubcorner(n);
00114     }
00115     max_distance = std::sqrt(max_distance);
00116 
00117     state.setParameters( domain, max_distance );
00118     state.setBRepWithNoClipping( num_vertices, reinterpret_cast<const void*>(vertices), 
00119                                  num_edges, reinterpret_cast<const void*>(edges) );
00120 
00121     delete[] vertices;
00122     delete[] edges;
00123     
00124   }
00125 
00126   virtual void SetPhi(grid_fct_type& phi, const int Time, const int Level, double t) { 
00127     if (state.getNumberOfGrids()>0) state.clearGrids();
00128 
00129     if (phi.len(Level)<=0) return;
00130 
00131     Coords ss = phi(Time,Level,0).stepsize();
00132     DCoords dx = base::GH().worldStep(ss);
00133     BBox bb = base::GH().wholebbox();
00134     if (ss(0)>bb.stepsize(0)) bb.coarsen(ss/bb.stepsize());
00135     else bb.refine(bb.stepsize()/ss);
00136     bb.grow(base::NGhosts());
00137 
00138     DCoords dxh2(dx); dxh2 *= static_cast<DataType>(0.5);
00139     DCoords lbcorner = base::GH().worldCoords(bb.lower(), bb.stepsize()) + dxh2;
00140     DCoords ubcorner = base::GH().worldCoords(bb.upper(), bb.stepsize()) + dxh2;
00141     DataType ldomain[2*dim];
00142     for (register int n=0; n<dim; n++) {
00143       ldomain[n] = lbcorner(n); ldomain[dim+n] = ubcorner(n);
00144     }
00145 
00146     state.setLattice(bb.extents(),ldomain);
00147 
00148     forall (phi,Time,Level,c)
00149       grid_data_type& gdphi = phi(Time,Level,c);
00150       Coords lb = gdphi.lower(); 
00151       Coords ub = gdphi.upper()+gdphi.stepsize(); 
00152       lb /= gdphi.stepsize(); ub /= gdphi.stepsize();
00153       lb += base::NGhosts();  ub += base::NGhosts();      
00154       
00155       state.insertGrid( reinterpret_cast<const int*>(lb()), 
00156                         reinterpret_cast<const int*>(ub()), 
00157                         reinterpret_cast<DataType*> (gdphi.data()),     
00158                         reinterpret_cast<DataType*> (0), 
00159                         reinterpret_cast<DataType*> (0), 
00160                         reinterpret_cast<int*> (0) );
00161     end_forall
00162 
00163     if (state.getNumberOfGrids()>0) {
00164       if (_FillWidth>0) {
00165         double distance = 0.;
00166         for (register int n=0; n<dim; n++)
00167           distance += dx[n]*dx[n];
00168         distance = std::sqrt(distance)*_FillWidth;
00169         state.setParameters( domain, distance );
00170       }
00171 
00172       if (unsign) {
00173         if (state.areGridsValidUnsigned()) {
00174           START_WATCH
00175             state.computeClosestPointTransformUnsigned();
00176           END_WATCH(LS_CPT_TRANSFORM)
00177           START_WATCH
00178             state.floodFillUnsigned( far_away );
00179           END_WATCH(LS_CPT_FLOODFILL)
00180         }
00181         else 
00182           std::cout << "Invalid grid for closest point transform on lev=" << Level 
00183                     << " time=" << t << std::endl;
00184       }
00185       else {
00186         if (state.areGridsValid()) {
00187           START_WATCH
00188             state.computeClosestPointTransform();
00189           END_WATCH(LS_CPT_TRANSFORM)
00190           START_WATCH
00191             state.floodFillDetermineSign( far_away );
00192           END_WATCH(LS_CPT_FLOODFILL)
00193           if (inverse) {
00194             forall (phi,Time,Level,c)
00195               grid_data_type& gdphi = phi(Time,Level,c);
00196               gdphi.multiply(-1.0);
00197             end_forall
00198           }
00199         }
00200         else 
00201           std::cout << "Invalid grid for closest point transform on lev=" << Level 
00202                     << " time=" << t << std::endl;
00203       }
00204     }
00205 
00206     START_WATCH
00207       Sync(phi,Time,Level);
00208     END_WATCH(LS_SYNC)
00209     START_WATCH
00210       ExternalBoundaryUpdate(phi,Time,Level);
00211     END_WATCH(BOUNDARIES_EXTERNAL)
00212   }
00213 
00214   virtual void SetGrid(grid_data_type& gdphi, const int& Level, const double& t) {
00215     if (state.getNumberOfGrids()>0) state.clearGrids();
00216 
00217     BBox bb = gdphi.bbox();
00218     Coords ss = bb.stepsize();
00219     DCoords dx = base::GH().worldStep(ss);
00220     DCoords dxh2(dx); dxh2 *= static_cast<DataType>(0.5);
00221     DCoords lbcorner = base::GH().worldCoords(bb.lower(), ss) + dxh2;
00222     DCoords ubcorner = base::GH().worldCoords(bb.upper(), ss) + dxh2;
00223     DataType ldomain[2*dim];
00224     for (register int n=0; n<dim; n++) {
00225       ldomain[n] = lbcorner(n); ldomain[dim+n] = ubcorner(n);
00226     }
00227 
00228     state.setLattice(bb.extents(),ldomain);
00229 
00230     Coords lb = gdphi.lower(); 
00231     Coords ub = gdphi.upper()+ss; 
00232     lb /= ss; ub /= ss;
00233     lb += base::NGhosts();  ub += base::NGhosts();      
00234       
00235     state.insertGrid( reinterpret_cast<const int*>(lb()), 
00236                       reinterpret_cast<const int*>(ub()), 
00237                       reinterpret_cast<DataType*> (gdphi.data()),       
00238                       reinterpret_cast<DataType*> (0), 
00239                       reinterpret_cast<DataType*> (0), 
00240                       reinterpret_cast<int*> (0) );
00241 
00242     if (state.getNumberOfGrids()>0) {
00243       if (_FillWidth>0) {
00244         double distance = 0.;
00245         for (register int n=0; n<dim; n++)
00246           distance += dx[n]*dx[n];
00247         distance = std::sqrt(distance)*_FillWidth;
00248         state.setParameters( domain, distance );
00249       }
00250 
00251       if (unsign) {
00252         if (state.areGridsValidUnsigned()) {
00253           START_WATCH
00254             state.computeClosestPointTransformUnsigned();
00255           END_WATCH(LS_CPT_TRANSFORM)
00256           START_WATCH
00257             state.floodFillUnsigned( far_away );
00258           END_WATCH(LS_CPT_FLOODFILL)
00259         }
00260         else 
00261           std::cout << "Invalid grid for closest point transform on lev=" << Level 
00262                     << " time=" << t << std::endl;
00263       }
00264       else {
00265         if (state.areGridsValid()) {
00266           START_WATCH
00267             state.computeClosestPointTransform();
00268           END_WATCH(LS_CPT_TRANSFORM)
00269           START_WATCH
00270             state.floodFillDetermineSign( far_away );
00271           END_WATCH(LS_CPT_FLOODFILL)
00272           if (inverse)
00273             gdphi.multiply(-1.0);
00274         }
00275         else 
00276           std::cout << "Invalid grid for closest point transform on lev=" << Level 
00277                     << " time=" << t << std::endl;
00278       }
00279     }
00280   }
00281 
00282   inline cpt_type& State() { return state; }
00283   inline const cpt_type& State() const { return state; }
00284   inline void SetFilename(const std::string filename) { brep_filename = filename; }
00285   inline std::string Filename() { return brep_filename; }
00286   inline void SetUnsigned(const int us) { unsign = us; }
00287   inline int Unsigned() const { return unsign; }
00288   inline void SetInverse(const int iv) { inverse = iv; }
00289   inline int Inverse() const { return inverse; }
00290 
00291 protected:
00292   cpt_type state;
00293   std::string brep_filename;
00294   DataType max_distance, far_away;
00295   int brep_filetype, inverse, unsign, _FillWidth; 
00296   DataType domain[2*dim];
00297 };
00298 
00299 
00300 #endif

Generated on Fri Aug 24 13:00:53 2007 for AMROC Fluid-solver Framework - by  doxygen 1.4.7