Zoltan2
Zoltan2_MeshAdapter.hpp
Go to the documentation of this file.
00001 // @HEADER
00002 //
00003 // ***********************************************************************
00004 //
00005 //   Zoltan2: A package of combinatorial algorithms for scientific computing
00006 //                  Copyright 2012 Sandia Corporation
00007 //
00008 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
00009 // the U.S. Government retains certain rights in this software.
00010 //
00011 // Redistribution and use in source and binary forms, with or without
00012 // modification, are permitted provided that the following conditions are
00013 // met:
00014 //
00015 // 1. Redistributions of source code must retain the above copyright
00016 // notice, this list of conditions and the following disclaimer.
00017 //
00018 // 2. Redistributions in binary form must reproduce the above copyright
00019 // notice, this list of conditions and the following disclaimer in the
00020 // documentation and/or other materials provided with the distribution.
00021 //
00022 // 3. Neither the name of the Corporation nor the names of the
00023 // contributors may be used to endorse or promote products derived from
00024 // this software without specific prior written permission.
00025 //
00026 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
00027 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00028 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
00029 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
00030 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00031 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00032 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00033 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00034 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00035 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00036 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00037 //
00038 // Questions? Contact Karen Devine      (kddevin@sandia.gov)
00039 //                    Erik Boman        (egboman@sandia.gov)
00040 //                    Siva Rajamanickam (srajama@sandia.gov)
00041 //
00042 // ***********************************************************************
00043 //
00044 // @HEADER
00045 
00051 #ifndef _ZOLTAN2_MESHADAPTER_HPP_
00052 #define _ZOLTAN2_MESHADAPTER_HPP_
00053 
00054 #include <Zoltan2_Adapter.hpp>
00055 
00056 namespace Zoltan2 {
00057   
00062 enum MeshEntityType {
00063   MESH_REGION,
00064   MESH_FACE,
00065   MESH_EDGE,
00066   MESH_VERTEX
00067 };
00104   template <typename User>
00105   class MeshAdapter : public BaseAdapter<User> {
00106 private:
00107   enum MeshEntityType primaryEntityType; // Entity type
00108                                          // to be partitioned, ordered,
00109                                          // colored, matched, etc.
00110   enum MeshEntityType adjacencyEntityType; // Entity type defining first-order
00111                                            // adjacencies; adjacencies are of
00112                                            // this type.  
00113   enum MeshEntityType secondAdjacencyEntityType; // Bridge entity type
00114                                                  // defining second-order
00115                                                  // adjacencies.
00116 
00117 public:
00118 
00119 #ifndef DOXYGEN_SHOULD_SKIP_THIS
00120   typedef typename InputTraits<User>::scalar_t    scalar_t;
00121   typedef typename InputTraits<User>::lno_t    lno_t;
00122   typedef typename InputTraits<User>::gno_t    gno_t;
00123   typedef typename InputTraits<User>::zgid_t    zgid_t;
00124   typedef typename InputTraits<User>::part_t   part_t;
00125   typedef typename InputTraits<User>::node_t   node_t;
00126   typedef User user_t;
00127   typedef User userCoord_t;
00128 #endif
00129   
00130   enum BaseAdapterType adapterType() const {return MeshAdapterType;}
00131   
00134   virtual ~MeshAdapter() {};
00135   
00136   // Default MeshEntityType is MESH_REGION with MESH_FACE-based adjacencies and
00137   // second adjacencies and coordinates
00138   MeshAdapter() : primaryEntityType(MESH_REGION),
00139                   adjacencyEntityType(MESH_FACE),
00140       secondAdjacencyEntityType(MESH_FACE) {};
00141   
00143   // Methods to be defined in derived classes.
00144   
00147   virtual size_t getLocalNumOf(MeshEntityType etype) const = 0;
00148   
00149   
00154   virtual void getIDsViewOf(MeshEntityType etype,
00155                             zgid_t const *&Ids) const = 0;
00156 
00157 
00163   virtual int getNumWeightsPerOf(MeshEntityType etype) const { return 0; }
00164   
00178   virtual void getWeightsViewOf(MeshEntityType etype,
00179      const scalar_t *&weights, int &stride, int idx = 0) const
00180   {
00181     weights = NULL;
00182     stride = 0;
00183     Z2_THROW_NOT_IMPLEMENTED_IN_ADAPTER
00184   }
00185 
00186 
00195   virtual int getDimension() const { return 0; }
00196   
00207   virtual void getCoordinatesViewOf(MeshEntityType etype,
00208     const scalar_t *&coords, int &stride, int coordDim) const 
00209   {
00210     coords = NULL;
00211     stride = 0;
00212     Z2_THROW_NOT_IMPLEMENTED_IN_ADAPTER
00213   }
00214 
00215 
00218   virtual bool availAdjs(MeshEntityType source, MeshEntityType target) const {
00219     return false;
00220   }
00221 
00222 
00225   virtual size_t getLocalNumAdjs(MeshEntityType source,
00226                                  MeshEntityType target) const { return 0;}
00227 
00228 
00239   virtual void getAdjsView(MeshEntityType source, MeshEntityType target,
00240      const lno_t *&offsets, const zgid_t *& adjacencyIds) const 
00241   {
00242     offsets = NULL;
00243     adjacencyIds = NULL;
00244     Z2_THROW_NOT_IMPLEMENTED_IN_ADAPTER
00245   }
00246 
00247 
00250   virtual bool avail2ndAdjs(MeshEntityType sourcetarget, 
00251           MeshEntityType through) const { return false;}
00252 
00253 
00259   virtual size_t getLocalNum2ndAdjs(MeshEntityType sourcetarget,
00260                                     MeshEntityType through) const { return 0; }
00261 
00272 // TODO:  Later may allow user to not implement second adjacencies and, if we want them,
00273 // TODO:  we compute A^T A, where A is matrix of first adjacencies.
00274   virtual void get2ndAdjsView(MeshEntityType sourcetarget,
00275                               MeshEntityType through,
00276                               const lno_t *&offsets,
00277                               const zgid_t *&adjacencyIds) const
00278   {
00279     offsets = NULL;
00280     adjacencyIds = NULL;
00281     Z2_THROW_NOT_IMPLEMENTED_IN_ADAPTER
00282   }
00283 
00284 
00287   virtual int getNumWeightsPer2ndAdj(MeshEntityType sourcetarget,
00288                                      MeshEntityType through) const { return 0;}
00289 
00290 
00299   virtual void get2ndAdjWeightsView(MeshEntityType sourcetarget,
00300                                     MeshEntityType through,
00301                                     const scalar_t *&weights,
00302                                     int &stride,
00303                                     int idx) const
00304   {
00305     weights = NULL;
00306     stride = 0;
00307     Z2_THROW_NOT_IMPLEMENTED_IN_ADAPTER
00308   }
00309 
00310 //KDD What if we wanted to provide weights with respect to first adjacencies?
00311 //KDD Should we add functions for that?
00312 //VJL Yes.
00313 
00315   // Implementations of base-class methods
00316 
00319   inline enum MeshEntityType getPrimaryEntityType() const {
00320     return this->primaryEntityType;
00321   }
00322 
00330   inline enum MeshEntityType getAdjacencyEntityType() const {
00331     return this->adjacencyEntityType;
00332   }
00333 
00339   inline enum MeshEntityType getSecondAdjacencyEntityType() const {
00340     return this->secondAdjacencyEntityType;
00341   }
00342   
00351   void setEntityTypes(std::string ptypestr, std::string atypestr,
00352           std::string satypestr) {
00353 
00354     if (ptypestr != atypestr && ptypestr != satypestr) {
00355       if (ptypestr == "region")
00356   this->primaryEntityType = MESH_REGION;
00357       else if (ptypestr == "face")
00358   this->primaryEntityType = MESH_FACE;
00359       else if (ptypestr == "edge")
00360   this->primaryEntityType = MESH_EDGE;
00361       else if (ptypestr == "vertex")
00362   this->primaryEntityType = MESH_VERTEX;
00363       else {
00364   std::ostringstream emsg;
00365   emsg << __FILE__ << "," << __LINE__
00366        << " error:  Invalid MeshEntityType " << ptypestr << std::endl;
00367   emsg << "Valid values: region  face  edge  vertex" << std::endl;
00368   throw std::runtime_error(emsg.str());
00369       }
00370       
00371       if (atypestr == "region")
00372   this->adjacencyEntityType = MESH_REGION;
00373       else if (atypestr == "face")
00374   this->adjacencyEntityType = MESH_FACE;
00375       else if (atypestr == "edge")
00376   this->adjacencyEntityType = MESH_EDGE;
00377       else if (atypestr == "vertex")
00378   this->adjacencyEntityType = MESH_VERTEX;
00379       else {
00380   std::ostringstream emsg;
00381   emsg << __FILE__ << "," << __LINE__
00382        << " error:  Invalid MeshEntityType " << atypestr << std::endl;
00383   emsg << "Valid values: region  face  edge  vertex" << std::endl;
00384   throw std::runtime_error(emsg.str());
00385       }
00386       
00387       if (satypestr == "region")
00388   this->secondAdjacencyEntityType = MESH_REGION;
00389       else if (satypestr == "face")
00390   this->secondAdjacencyEntityType = MESH_FACE;
00391       else if (satypestr == "edge")
00392   this->secondAdjacencyEntityType = MESH_EDGE;
00393       else if (satypestr == "vertex")
00394   this->secondAdjacencyEntityType = MESH_VERTEX;
00395       else {
00396   std::ostringstream emsg;
00397   emsg << __FILE__ << "," << __LINE__
00398        << " error:  Invalid MeshEntityType " << satypestr << std::endl;
00399   emsg << "Valid values: region  face  edge  vertex" << std::endl;
00400   throw std::runtime_error(emsg.str());
00401       }
00402     }
00403     else {
00404       std::ostringstream emsg;
00405       emsg << __FILE__ << "," << __LINE__
00406      << " error:  PrimaryEntityType " << ptypestr
00407      << " matches AdjacencyEntityType " << atypestr
00408      << " or SecondAdjacencyEntityType " << satypestr << std::endl;
00409       throw std::runtime_error(emsg.str());
00410     }
00411   }
00412   
00417   virtual bool useDegreeAsWeightOf(MeshEntityType etype, int idx) const
00418   {
00419     return false;
00420   }
00421 
00423   // Functions from the BaseAdapter interface
00424   size_t getLocalNumIDs() const {
00425     return getLocalNumOf(getPrimaryEntityType());
00426   }
00427   
00428   void getIDsView(const zgid_t *&Ids) const {
00429     getIDsViewOf(getPrimaryEntityType(), Ids);
00430   }
00431   
00432   int getNumWeightsPerID() const {
00433     return getNumWeightsPerOf(getPrimaryEntityType());
00434   }
00435   
00436   void getWeightsView(const scalar_t *&wgt, int &stride, int idx = 0) const {
00437     getWeightsViewOf(getPrimaryEntityType(), wgt, stride, idx);
00438   }
00439 
00440   void getCoordinatesView(const scalar_t *&coords, int &stride, 
00441                           int coordDim) const
00442   {
00443     getCoordinatesViewOf(getPrimaryEntityType(), coords, stride, coordDim);
00444   }
00445 
00446   bool useDegreeAsWeight(int idx) const
00447   {
00448     return useDegreeAsWeightOf(getPrimaryEntityType(), idx);
00449   }
00450 };
00451   
00452 }  //namespace Zoltan2
00453 
00454 #endif