00001
00002
00003
00004
00005
00006
00007
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
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