moab
SweptElementData.hpp
Go to the documentation of this file.
00001 
00016 #ifndef SWEPT_ELEMENT_DATA_HPP
00017 #define SWEPT_ELEMENT_DATA_HPP
00018 
00019 //
00020 // Class: SweptElementData
00021 //
00022 // Purpose: represent a rectangular element of mesh
00023 //
00024 // A SweptElement represents a rectangular element of mesh, including both vertices and
00025 // elements, and the parametric space used to address that element.  Vertex data,
00026 // i.e. coordinates, may not be stored directly in the element, but the element returns
00027 // information about the vertex handles of vertices in the element.  Vertex and element
00028 // handles associated with the element are each contiguous.
00029 
00030 #include "SequenceData.hpp"
00031 #include "moab/HomXform.hpp"
00032 #include "moab/CN.hpp"
00033 #include "SweptVertexData.hpp"
00034 #include "Internals.hpp"
00035 #include "moab/Range.hpp"
00036 
00037 #include <vector>
00038 #include <algorithm>
00039 
00040 namespace moab {
00041 
00042 class SweptElementData : public SequenceData
00043 {
00044 
00046 class VertexDataRef
00047 {
00048 private:
00049   HomCoord minmax[2];
00050   HomXform xform, invXform;
00051   SweptVertexData *srcSeq;
00052 public:
00053   friend class SweptElementData;
00054   
00055   VertexDataRef(const HomCoord &min, const HomCoord &max,
00056                 const HomXform &tmp_xform, SweptVertexData *this_seq);
00057     
00058   bool contains(const HomCoord &coords) const;
00059 };
00060 
00061 private:
00062 
00064   HomCoord elementParams[3];
00065 
00068   int dIJK[3];
00069   
00072   int dIJKm1[3];
00073 
00075   SweptElementData();
00076 
00078   std::vector<VertexDataRef> vertexSeqRefs;
00079 
00080 public:
00081 
00083   SweptElementData( EntityHandle start_handle,
00084                   const int imin, const int jmin, const int kmin,
00085             const int imax, const int jmax, const int kmax,
00086           const int* Cq );
00087   
00088   virtual ~SweptElementData();
00089   
00091   inline EntityHandle get_vertex(const HomCoord &coords) const;
00092   inline EntityHandle get_vertex(int i, int j, int k) const
00093     { return get_vertex(HomCoord(i,j,k)); }
00094   
00096   EntityHandle get_element(const int i, const int j, const int k) const;
00097   
00099   const HomCoord &min_params() const;
00100 
00102   const HomCoord &max_params() const;
00103   
00105   void param_extents(int &di, int &dj, int &dk) const;
00106 
00108   ErrorCode get_params(const EntityHandle ehandle,
00109                           int &i, int &j, int &k) const;
00110   
00112   int i_min() const {return (elementParams[0].hom_coord())[0];}
00113   int j_min() const {return (elementParams[0].hom_coord())[1];}
00114   int k_min() const {return (elementParams[0].hom_coord())[2];}
00115   int i_max() const {return (elementParams[1].hom_coord())[0];}
00116   int j_max() const {return (elementParams[1].hom_coord())[1];}
00117   int k_max() const {return (elementParams[1].hom_coord())[2];}
00118 
00121   bool boundary_complete() const;
00122 
00124   inline bool contains(const HomCoord &coords) const;
00125 
00127   inline ErrorCode get_params_connectivity(const int i, const int j, const int k,
00128                                        std::vector<EntityHandle>& connectivity) const;
00129   
00135   ErrorCode add_vsequence(SweptVertexData *vseq, 
00136                              const HomCoord &p1, const HomCoord &q1,
00137                              const HomCoord &p2, const HomCoord &q2,
00138                              const HomCoord &p3, const HomCoord &q3,
00139                              bool bb_input = false,
00140                              const HomCoord &bb_min = HomCoord::unitv[0],
00141                              const HomCoord &bb_max = HomCoord::unitv[0]);
00142 
00143 
00144   SequenceData* subset( EntityHandle start, 
00145                         EntityHandle end,
00146                         const int* sequence_data_sizes,
00147                         const int* tag_data_sizes ) const;
00148   
00149   static EntityID calc_num_entities( EntityHandle start_handle,
00150                                        int irange,
00151                                        int jrange,
00152                                        int krange );
00153 
00154   unsigned long get_memory_use() const;
00155 };
00156 
00157 inline EntityHandle SweptElementData::get_element(const int i, const int j, const int k) const
00158 {
00159   return start_handle() + (i-i_min()) + (j-j_min())*dIJKm1[0] + (k-k_min())*dIJKm1[0]*dIJKm1[1];
00160 }
00161 
00162 inline const HomCoord &SweptElementData::min_params() const
00163 {
00164   return elementParams[0];
00165 }
00166 
00167 inline const HomCoord &SweptElementData::max_params() const
00168 {
00169   return elementParams[1];
00170 }
00171 
00173 inline void SweptElementData::param_extents(int &di, int &dj, int &dk) const
00174 {
00175   di = dIJK[0];
00176   dj = dIJK[1];
00177   dk = dIJK[2];
00178 }
00179 
00180 inline ErrorCode SweptElementData::get_params(const EntityHandle ehandle,
00181                                               int &i, int &j, int &k) const
00182 {
00183   if (TYPE_FROM_HANDLE(ehandle) != TYPE_FROM_HANDLE(start_handle())) return MB_FAILURE;
00184 
00185   int hdiff = ehandle - start_handle();
00186 
00187     // use double ?: test below because on some platforms, both sides of the : are
00188     // evaluated, and if dIJKm1[1] is zero, that'll generate a divide-by-zero
00189   k = (dIJKm1[1] > 0 ? hdiff / (dIJKm1[1] > 0 ? dIJKm1[0]*dIJKm1[1] : 1) : 0);
00190   j = (hdiff - (k*dIJKm1[0]*dIJKm1[1])) / dIJKm1[0];
00191   i = hdiff % dIJKm1[0];
00192 
00193   k += elementParams[0].k();
00194   j += elementParams[0].j();
00195   i += elementParams[0].i();
00196 
00197   return (ehandle >= start_handle() &&
00198           ehandle < start_handle()+size() &&
00199           i >= i_min() && i <= i_max() &&
00200           j >= j_min() && j <= j_max() &&
00201           k >= k_min() && k <= k_max()) ? MB_SUCCESS : MB_FAILURE;
00202 }
00203 
00204 inline bool SweptElementData::contains(const HomCoord &temp) const 
00205 {
00206     // upper bound is < instead of <= because element params max is one less
00207     // than vertex params max
00208   return (temp >= elementParams[0] && temp < elementParams[1]);
00209 }
00210   
00211 inline bool SweptElementData::VertexDataRef::contains(const HomCoord &coords) const 
00212 {
00213   return (minmax[0] <= coords && minmax[1] >= coords);
00214 }
00215 
00216 inline SweptElementData::VertexDataRef::VertexDataRef(const HomCoord &this_min, const HomCoord &this_max,
00217                                     const HomXform &tmp_xform, SweptVertexData *this_seq)
00218     : xform(tmp_xform), invXform(tmp_xform.inverse()), srcSeq(this_seq)
00219 {
00220   minmax[0] = HomCoord(this_min);
00221   minmax[1] = HomCoord(this_max); 
00222 }
00223 
00224 inline EntityHandle SweptElementData::get_vertex(const HomCoord &coords) const
00225 {
00226   assert(boundary_complete());
00227    for (std::vector<VertexDataRef>::const_iterator it = vertexSeqRefs.begin();
00228         it != vertexSeqRefs.end(); it++) {
00229      if ((*it).minmax[0] <= coords && (*it).minmax[1] >= coords) {
00230          // first get the vertex block-local parameters
00231        HomCoord local_coords = coords / (*it).xform;
00232     
00233       // now get the vertex handle for those coords
00234        return (*it).srcSeq->get_vertex(local_coords);
00235      }
00236    }
00237    
00238      // got here, it's an error
00239    return 0;
00240 }
00241 
00242 inline ErrorCode SweptElementData::add_vsequence(SweptVertexData *vseq, 
00243                                                  const HomCoord &p1, const HomCoord &q1,
00244                                                  const HomCoord &p2, const HomCoord &q2, 
00245                                                  const HomCoord &p3, const HomCoord &q3,
00246                                                  bool bb_input,
00247                                                  const HomCoord &bb_min,
00248                                                  const HomCoord &bb_max)
00249 {
00250     // compute the transform given the vseq-local parameters and the mapping to
00251     // this element sequence's parameters passed in minmax
00252   HomXform M;
00253   M.three_pt_xform(p1, q1, p2, q2, p3, q3);
00254   
00255     // min and max in element seq's parameter system may not be same as those in 
00256     // vseq's system, so need to take min/max
00257 
00258   HomCoord minmax[2];
00259   if (bb_input) {
00260     minmax[0] = bb_min;
00261     minmax[1] = bb_max;
00262   }
00263   else {
00264     minmax[0] = vseq->min_params() * M;
00265     minmax[1] = vseq->max_params() * M;
00266   }
00267   
00268     // check against other vseq's to make sure they don't overlap
00269   for (std::vector<VertexDataRef>::const_iterator vsit = vertexSeqRefs.begin();
00270        vsit != vertexSeqRefs.end(); vsit++) 
00271     if ((*vsit).contains(minmax[0]) || (*vsit).contains(minmax[1])) 
00272       return MB_FAILURE;
00273     
00274   HomCoord tmp_min(std::min(minmax[0].i(), minmax[1].i()), 
00275                    std::min(minmax[0].j(), minmax[1].j()), 
00276                    std::min(minmax[0].k(), minmax[1].k()));
00277   HomCoord tmp_max(std::max(minmax[0].i(), minmax[1].i()), 
00278                    std::max(minmax[0].j(), minmax[1].j()), 
00279                    std::max(minmax[0].k(), minmax[1].k()));
00280 
00281   
00282     // set up a new vertex sequence reference
00283   VertexDataRef tmp_seq_ref(tmp_min, tmp_max, M, vseq);
00284 
00285     // add to the list
00286   vertexSeqRefs.push_back(tmp_seq_ref);
00287   
00288   return MB_SUCCESS;
00289 }
00290 
00291 inline ErrorCode SweptElementData::get_params_connectivity(const int i, const int j, const int k,
00292                                                            std::vector<EntityHandle>& connectivity) const
00293 {
00294   if (contains(HomCoord(i, j, k)) == false) return MB_FAILURE;
00295   
00296   connectivity.push_back(get_vertex(i, j, k));
00297   connectivity.push_back(get_vertex(i+1, j, k));
00298   if (CN::Dimension(TYPE_FROM_HANDLE(start_handle())) < 2) return MB_SUCCESS;
00299   connectivity.push_back(get_vertex(i+1, j+1, k));
00300   connectivity.push_back(get_vertex(i, j+1, k));
00301   if (CN::Dimension(TYPE_FROM_HANDLE(start_handle())) < 3) return MB_SUCCESS;
00302   connectivity.push_back(get_vertex(i, j, k+1));
00303   connectivity.push_back(get_vertex(i+1, j, k+1));
00304   connectivity.push_back(get_vertex(i+1, j+1, k+1));
00305   connectivity.push_back(get_vertex(i, j+1, k+1));
00306   return MB_SUCCESS;
00307 }
00308 
00309 } // namespace moab
00310 
00311 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines