vtf-logo

CPTLevelSet.h

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 
00003 // Copyright (C) 2003-2007 California Institute of Technology
00004 // Ralf Deiterding, ralf@amroc.net
00005 
00006 #ifndef AMROC_CPTLEVELSET_H
00007 #define AMROC_CPTLEVELSET_H
00008 
00016 #include "cpt/cpt.h"
00017 
00025 template <class DataType, int dim>
00026 class CPTLevelSet : public GFMLevelSet<DataType,dim> {
00027   typedef GFMLevelSet<DataType,dim> base;
00028 
00029 public:
00030   typedef typename base::grid_fct_type grid_fct_type;   
00031   typedef typename base::grid_data_type grid_data_type;   
00032   typedef typename cpt::State<dim,DataType> cpt_type;
00033 
00034   CPTLevelSet() : base(), inverse(0), unsign(0), _FillWidth(0) {
00035     far_away = 1.e36;
00036   }
00037 
00038   virtual ~CPTLevelSet() {}
00039 
00040   virtual void register_at(ControlDevice& Ctrl, const std::string& prefix) {
00041     base::LocCtrl = Ctrl.getSubDevice(prefix+"CPT");
00042     RegisterAt(base::LocCtrl,"PlotPhi",base::_PlotPhi);
00043     RegisterAt(base::LocCtrl,"Inverse",inverse);
00044     RegisterAt(base::LocCtrl,"Unsigned",unsign);
00045     RegisterAt(base::LocCtrl,"FillWidth",_FillWidth);
00046   } 
00047   virtual void register_at(ControlDevice& Ctrl) {
00048     register_at(Ctrl, "");
00049   }
00050 
00051   virtual void SetBrep(const int num_vertices, const DataType* vertices,
00052                        const int num_edges, const int* edges) {
00053     Coords ex(dim,0);
00054     BBox wholebb = grow(coarsen(base::GH().wholebbox(),DAGHShadowFactor),base::NGhosts());
00055     DCoords lbcorner = base::GH().worldCoords(wholebb.lower(), wholebb.stepsize());
00056     DCoords ubcorner = base::GH().worldCoords(wholebb.upper()+wholebb.stepsize(), 
00057                                               wholebb.stepsize());
00058     DCoords dist = ubcorner-lbcorner; dist *= dist;
00059     DataType distance = 0.;
00060     for (register int n=0; n<dim; n++) {
00061       distance += dist(n);
00062       domain[n] = lbcorner(n); domain[dim+n] = ubcorner(n);
00063     }
00064     distance = std::sqrt(distance);
00065     state.setParameters( domain, distance );
00066     state.setBRepWithNoClipping( num_vertices, reinterpret_cast<const void*>(vertices), 
00067                                  num_edges, reinterpret_cast<const void*>(edges) );
00068   }
00069 
00070   virtual void SetPhi(grid_fct_type& phi, const int Time, const int Level, double t) { 
00071     if (state.getNumberOfGrids()>0) state.clearGrids();
00072 
00073     if (phi.len(Level)<=0) return;
00074 
00075     Coords ss = phi(Time,Level,0).stepsize();
00076     DCoords dx = base::GH().worldStep(ss);
00077     BBox bb = base::GH().wholebbox();
00078     if (ss(0)>bb.stepsize(0)) bb.coarsen(ss/bb.stepsize());
00079     else bb.refine(bb.stepsize()/ss);
00080     bb.grow(base::NGhosts());
00081 
00082     DCoords dxh2(dx); dxh2 *= static_cast<DataType>(0.5);
00083     DCoords lbcorner = base::GH().worldCoords(bb.lower(), bb.stepsize()) + dxh2;
00084     DCoords ubcorner = base::GH().worldCoords(bb.upper(), bb.stepsize()) + dxh2;
00085     DataType ldomain[2*dim];
00086     for (register int n=0; n<dim; n++) {
00087       ldomain[n] = lbcorner(n); ldomain[dim+n] = ubcorner(n);
00088     }
00089 
00090     state.setLattice(bb.extents(),ldomain);
00091 
00092     forall (phi,Time,Level,c)
00093       grid_data_type& gdphi = phi(Time,Level,c);
00094       Coords lb = gdphi.lower(); 
00095       Coords ub = gdphi.upper()+gdphi.stepsize(); 
00096       lb /= gdphi.stepsize(); ub /= gdphi.stepsize();
00097       lb += base::NGhosts();  ub += base::NGhosts();      
00098       
00099       state.insertGrid( reinterpret_cast<const int*>(lb()), 
00100                         reinterpret_cast<const int*>(ub()), 
00101                         reinterpret_cast<DataType*> (gdphi.data()),     
00102                         reinterpret_cast<DataType*> (0), 
00103                         reinterpret_cast<DataType*> (0), 
00104                         reinterpret_cast<int*> (0) );
00105     end_forall
00106 
00107     if (state.getNumberOfGrids()>0) {
00108       if (_FillWidth>0) {
00109         double distance = 0.;
00110         for (register int n=0; n<dim; n++)
00111           distance += dx[n]*dx[n];
00112         distance = std::sqrt(distance)*_FillWidth;
00113         state.setParameters( domain, distance );
00114       }
00115 
00116       if (unsign) {
00117         if (state.areGridsValidUnsigned()) {
00118           START_WATCH
00119             state.computeClosestPointTransformUnsigned();
00120           END_WATCH(LS_CPT_TRANSFORM)
00121           START_WATCH
00122             state.floodFillUnsigned( far_away );
00123           END_WATCH(LS_CPT_FLOODFILL)
00124         }
00125         else 
00126           std::cout << "Invalid grid for closest point transform on lev=" << Level 
00127                     << " time=" << t << std::endl;
00128       }
00129       else {
00130         if (state.areGridsValid()) {
00131           START_WATCH
00132             state.computeClosestPointTransform();
00133           END_WATCH(LS_CPT_TRANSFORM)
00134           START_WATCH
00135             state.floodFillDetermineSign( far_away );
00136           END_WATCH(LS_CPT_FLOODFILL)
00137           if (inverse) {
00138             forall (phi,Time,Level,c)
00139               grid_data_type& gdphi = phi(Time,Level,c);
00140               gdphi.multiply(-1.0);
00141             end_forall
00142           }
00143         }
00144         else 
00145           std::cout << "Invalid grid for closest point transform on lev=" << Level 
00146                     << " time=" << t << std::endl;
00147       }
00148     }
00149 
00150     START_WATCH
00151       Sync(phi,Time,Level);
00152     END_WATCH(LS_SYNC)
00153     START_WATCH
00154       ExternalBoundaryUpdate(phi,Time,Level);
00155     END_WATCH(BOUNDARIES_EXTERNAL)
00156   }
00157 
00158   virtual void SetGrid(grid_data_type& gdphi, const int& Level, const double& t) {
00159     if (state.getNumberOfGrids()>0) state.clearGrids();
00160 
00161     BBox bb = gdphi.bbox();
00162     Coords ss = bb.stepsize();
00163     DCoords dx = base::GH().worldStep(ss);
00164     DCoords dxh2(dx); dxh2 *= static_cast<DataType>(0.5);
00165     DCoords lbcorner = base::GH().worldCoords(bb.lower(), ss) + dxh2;
00166     DCoords ubcorner = base::GH().worldCoords(bb.upper(), ss) + dxh2;
00167     DataType ldomain[2*dim];
00168     for (register int n=0; n<dim; n++) {
00169       ldomain[n] = lbcorner(n); ldomain[dim+n] = ubcorner(n);
00170     }
00171 
00172     state.setLattice(bb.extents(),ldomain);
00173 
00174     Coords lb = gdphi.lower(); 
00175     Coords ub = gdphi.upper()+ss; 
00176     lb /= ss; ub /= ss;
00177     lb += base::NGhosts();  ub += base::NGhosts();      
00178       
00179     state.insertGrid( reinterpret_cast<const int*>(lb()), 
00180                       reinterpret_cast<const int*>(ub()), 
00181                       reinterpret_cast<DataType*> (gdphi.data()),       
00182                       reinterpret_cast<DataType*> (0), 
00183                       reinterpret_cast<DataType*> (0), 
00184                       reinterpret_cast<int*> (0) );
00185 
00186     if (state.getNumberOfGrids()>0) {
00187       if (_FillWidth>0) {
00188         double distance = 0.;
00189         for (register int n=0; n<dim; n++)
00190           distance += dx[n]*dx[n];
00191         distance = std::sqrt(distance)*_FillWidth;
00192         state.setParameters( domain, distance );
00193       }
00194 
00195       if (unsign) {
00196         if (state.areGridsValidUnsigned()) {
00197           START_WATCH
00198             state.computeClosestPointTransformUnsigned();
00199           END_WATCH(LS_CPT_TRANSFORM)
00200           START_WATCH
00201             state.floodFillUnsigned( far_away );
00202           END_WATCH(LS_CPT_FLOODFILL)
00203         }
00204         else 
00205           std::cout << "Invalid grid for closest point transform on lev=" << Level 
00206                     << " time=" << t << std::endl;
00207       }
00208       else {
00209         if (state.areGridsValid()) {
00210           START_WATCH
00211             state.computeClosestPointTransform();
00212           END_WATCH(LS_CPT_TRANSFORM)
00213           START_WATCH
00214             state.floodFillDetermineSign( far_away );
00215           END_WATCH(LS_CPT_FLOODFILL)
00216           if (inverse)
00217             gdphi.multiply(-1.0);
00218         }
00219         else 
00220           std::cout << "Invalid grid for closest point transform on lev=" << Level 
00221                     << " time=" << t << std::endl;
00222       }
00223     }
00224   }
00225 
00226   inline cpt_type& State() { return state; }
00227   inline const cpt_type& State() const { return state; }
00228   inline void SetUnsigned(const int us) { unsign = us; }
00229   inline int Unsigned() const { return unsign; }
00230   inline void SetInverse(const int iv) { inverse = iv; }
00231   inline int Inverse() const { return inverse; }
00232 
00233 protected:
00234   cpt_type state;
00235   int inverse, unsign, _FillWidth; 
00236   DataType far_away;
00237   DataType domain[2*dim];
00238 };
00239 
00240 
00241 #endif

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