MOAB: Mesh Oriented datABase  (version 5.1.1)
TempestOfflineMap.hpp
Go to the documentation of this file.
00001 ///////////////////////////////////////////////////////////////////////////////
00002 ///
00003 /// \file    OfflineMap.h
00004 /// \author  Paul Ullrich
00005 /// \version August 14, 2014
00006 ///
00007 /// <remarks>
00008 ///     Copyright 2000-2014 Paul Ullrich
00009 ///
00010 ///     This file is distributed as part of the Tempest source code package.
00011 ///     Permission is granted to use, copy, modify and distribute this
00012 ///     source code and its documentation under the terms of the GNU General
00013 ///     Public License.  This software is provided "as is" without express
00014 ///     or implied warranty.
00015 /// </remarks>
00016 
00017 #ifndef _TEMPESTOFFLINEMAP_H_
00018 #define _TEMPESTOFFLINEMAP_H_
00019 
00020 #include "moab/MOABConfig.h"
00021 
00022 #include "SparseMatrix.h"
00023 #include "DataVector.h"
00024 #include "DataMatrix.h"
00025 #include "DataMatrix3D.h"
00026 #include "OfflineMap.h"
00027 #include <string>
00028 #include <vector>
00029 
00030 #ifdef MOAB_HAVE_EIGEN
00031 #include <Eigen/Sparse>
00032 #endif
00033 
00034 #include "moab/Remapping/TempestRemapper.hpp"
00035 
00036 ///////////////////////////////////////////////////////////////////////////////
00037 
00038 #define RECTANGULAR_TRUNCATION
00039 // #define TRIANGULAR_TRUNCATION
00040 
00041 ///////////////////////////////////////////////////////////////////////////////
00042 
00043 // Forward declarations
00044 class Mesh;
00045 
00046 ///////////////////////////////////////////////////////////////////////////////
00047 
00048 namespace moab
00049 {
00050 
00051 /// <summary>
00052 ///     An offline map between two Meshes.
00053 /// </summary>
00054 class TempestOfflineMap : public OfflineMap {
00055 
00056 public:
00057 
00058     /// <summary>
00059     ///     Generate the metadata associated with the offline map.
00060     /// </summary>
00061     TempestOfflineMap(moab::TempestRemapper* remapper);
00062 
00063     /// <summary>
00064     ///     Define a virtual destructor.
00065     /// </summary>
00066     virtual ~TempestOfflineMap();
00067 
00068 public:
00069 
00070     // Input / Output types
00071     enum DiscretizationType
00072     {
00073         DiscretizationType_FV,
00074         DiscretizationType_CGLL,
00075         DiscretizationType_DGLL
00076     };
00077 
00078     /// <summary>
00079     ///     Generate the offline map, given the source and target mesh and discretization details.
00080     ///     This method generates the mapping between the two meshes based on the overlap and stores
00081     ///     the result in the SparseMatrix.
00082     /// </summary>
00083     moab::ErrorCode GenerateOfflineMap( std::string strInputType="fv", std::string strOutputType="fv",
00084                                         const int nPin=1, const int nPout=1,
00085                                         bool fBubble=false, int fMonotoneTypeID=0,
00086                                         bool fVolumetric=false, bool fNoConservation=false, bool fNoCheck=false,
00087                                         const std::string srcDofTagName="GLOBAL_ID", const std::string tgtDofTagName="GLOBAL_ID",
00088                                         const std::string strVariables="",
00089                                         const std::string strInputData="", const std::string strOutputData="",
00090                                         const std::string strNColName="", const bool fOutputDouble=false,
00091                                         const std::string strPreserveVariables="", const bool fPreserveAll=false, const double dFillValueOverride=0.0,
00092                                         const bool fInputConcave = false, const bool fOutputConcave = false );
00093 
00094     /// <summary>
00095     ///     Generate the metadata associated with the offline map.
00096     /// </summary>
00097     // moab::ErrorCode GenerateMetaData();
00098 
00099 public:
00100 
00101     /// <summary>
00102     ///     Read the OfflineMap from a NetCDF file.
00103     /// </summary>
00104     // virtual void Read(
00105     //  const std::string & strSource
00106     // );
00107 
00108     /// <summary>
00109     ///     Write the TempestOfflineMap to a parallel NetCDF file.
00110     /// </summary>
00111     // virtual void Write(
00112     //  const std::string & strTarget
00113     // );
00114 
00115 public:
00116     /// <summary>
00117     ///     Determine if the map is first-order accurate.
00118     /// </summary>
00119     virtual bool IsConsistent(
00120         double dTolerance
00121     );
00122 
00123     /// <summary>
00124     ///     Determine if the map is conservative.
00125     /// </summary>
00126     virtual bool IsConservative(
00127         double dTolerance
00128     );
00129 
00130     /// <summary>
00131     ///     Determine if the map is monotone.
00132     /// </summary>
00133     virtual bool IsMonotone(
00134         double dTolerance
00135     );
00136 
00137     /// <summary>
00138     ///     If we computed the reduction, get the vector representing the source areas for all entities in the mesh
00139     /// </summary>
00140     const DataVector<double>& GetGlobalSourceAreas() const;
00141 
00142     /// <summary>
00143     ///     If we computed the reduction, get the vector representing the target areas for all entities in the mesh
00144     /// </summary>
00145     const DataVector<double>& GetGlobalTargetAreas() const;
00146 
00147 #ifdef MOAB_HAVE_EIGEN
00148     void InitVectors();
00149 #endif
00150 
00151 private:
00152 
00153     /// <summary>
00154     ///     Gather the mapping matrix that was computed in different processors and accumulate the data
00155     ///     on the root so that OfflineMap can be generated in parallel.
00156     /// </summary>
00157     moab::ErrorCode GatherAllToRoot();
00158 
00159     /// <summary>
00160     ///     Compute the remapping weights for a FV field defined on the source to a
00161     ///     FV field defined on the target mesh.
00162     /// </summary>
00163     void LinearRemapFVtoFV_Tempest_MOAB( int nOrder );
00164 
00165     /// <summary>
00166     ///     Generate the OfflineMap for linear conserative element-average
00167     ///     spectral element to element average remapping.
00168     /// </summary>
00169     void LinearRemapSE0_Tempest_MOAB(
00170         const DataMatrix3D<int> & dataGLLNodes,
00171         const DataMatrix3D<double> & dataGLLJacobian);
00172 
00173     /// <summary>
00174     ///     Generate the OfflineMap for cubic conserative element-average
00175     ///     spectral element to element average remapping.
00176     /// </summary>
00177     void LinearRemapSE4_Tempest_MOAB(
00178         const DataMatrix3D<int> & dataGLLNodes,
00179         const DataMatrix3D<double> & dataGLLJacobian,
00180         int nMonotoneType,
00181         bool fContinuousIn,
00182         bool fNoConservation);
00183 
00184     /// <summary>
00185     ///     Generate the OfflineMap for remapping from finite volumes to finite
00186     ///     elements using simple sampling of the FV reconstruction.
00187     /// </summary>
00188     void LinearRemapFVtoGLL_Simple_MOAB(
00189         const DataMatrix3D<int> & dataGLLNodes,
00190         const DataMatrix3D<double> & dataGLLJacobian,
00191         const DataVector<double> & dataGLLNodalArea,
00192         int nOrder,
00193         int nMonotoneType,
00194         bool fContinuous,
00195         bool fNoConservation
00196     );
00197 
00198     /// <summary>
00199     ///     Generate the OfflineMap for remapping from finite volumes to finite
00200     ///     elements using a new experimental method.
00201     /// </summary>
00202     void LinearRemapFVtoGLL_Volumetric_MOAB(
00203         const DataMatrix3D<int> & dataGLLNodes,
00204         const DataMatrix3D<double> & dataGLLJacobian,
00205         const DataVector<double> & dataGLLNodalArea,
00206         int nOrder,
00207         int nMonotoneType,
00208         bool fContinuous,
00209         bool fNoConservation
00210     );
00211 
00212     /// <summary>
00213     ///     Generate the OfflineMap for remapping from finite volumes to finite
00214     ///     elements.
00215     /// </summary>
00216     void LinearRemapFVtoGLL_MOAB(
00217         const DataMatrix3D<int> & dataGLLNodes,
00218         const DataMatrix3D<double> & dataGLLJacobian,
00219         const DataVector<double> & dataGLLNodalArea,
00220         int nOrder,
00221         int nMonotoneType,
00222         bool fContinuous,
00223         bool fNoConservation
00224     );
00225 
00226     /// <summary>
00227     ///     Generate the OfflineMap for remapping from finite elements to finite
00228     ///     elements.
00229     /// </summary>
00230     void LinearRemapGLLtoGLL2_MOAB(
00231         const DataMatrix3D<int> & dataGLLNodesIn,
00232         const DataMatrix3D<double> & dataGLLJacobianIn,
00233         const DataMatrix3D<int> & dataGLLNodesOut,
00234         const DataMatrix3D<double> & dataGLLJacobianOut,
00235         const DataVector<double> & dataNodalAreaOut,
00236         int nPin,
00237         int nPout,
00238         int nMonotoneType,
00239         bool fContinuousIn,
00240         bool fContinuousOut,
00241         bool fNoConservation
00242     );
00243 
00244     /// <summary>
00245     ///     Generate the OfflineMap for remapping from finite elements to finite
00246     ///     elements (pointwise interpolation).
00247     /// </summary>
00248     void LinearRemapGLLtoGLL2_Pointwise_MOAB(
00249         const DataMatrix3D<int> & dataGLLNodesIn,
00250         const DataMatrix3D<double> & dataGLLJacobianIn,
00251         const DataMatrix3D<int> & dataGLLNodesOut,
00252         const DataMatrix3D<double> & dataGLLJacobianOut,
00253         const DataVector<double> & dataNodalAreaOut,
00254         int nPin,
00255         int nPout,
00256         int nMonotoneType,
00257         bool fContinuousIn,
00258         bool fContinuousOut
00259     );
00260 
00261     /// <summary>
00262     ///     Store the tag names associated with global DoF ids for source and target meshes
00263     /// </summary>
00264     moab::ErrorCode SetDofMapTags(const std::string srcDofTagName,
00265                                   const std::string tgtDofTagName);
00266 
00267     /// <summary>
00268     ///     Compute the association between the solution tag global DoF numbering and
00269     ///     the local matrix numbering so that matvec operations can be performed
00270     ///     consistently.
00271     /// </summary>
00272     moab::ErrorCode SetDofMapAssociation(DiscretizationType srcType, bool isSrcContinuous,
00273         DataMatrix3D<int>* srcdataGLLNodes, DataMatrix3D<int>* srcdataGLLNodesSrc,
00274         DiscretizationType destType, bool isDestContinuous,
00275         DataMatrix3D<int>* tgtdataGLLNodes);
00276 
00277 
00278     /// <summary>
00279     ///     Copy the local matrix from Tempest SparseMatrix representation (ELL)
00280     ///     to the parallel CSR Eigen Matrix for scalable application of matvec
00281     ///     needed for projections.
00282     /// </summary>
00283 #ifdef MOAB_HAVE_EIGEN
00284     void CopyTempestSparseMat_Eigen();
00285 #endif
00286 
00287 public:
00288 #ifdef MOAB_HAVE_EIGEN
00289 
00290     typedef Eigen::Matrix< double, 1, Eigen::Dynamic > WeightDRowVector;
00291     typedef Eigen::Matrix< double, Eigen::Dynamic, 1 > WeightDColVector;
00292     typedef Eigen::SparseVector<double> WeightSVector;
00293     typedef Eigen::SparseMatrix<double, Eigen::RowMajor> WeightRMatrix;
00294     typedef Eigen::SparseMatrix<double, Eigen::ColMajor> WeightCMatrix;
00295 
00296     typedef WeightDRowVector WeightRowVector;
00297     typedef WeightDColVector WeightColVector;
00298     typedef WeightRMatrix WeightMatrix;
00299 
00300     /// <summary>
00301     ///     Get the raw reference to the Eigen weight matrix representing the projection from source to destination mesh.
00302     /// </summary>
00303     WeightMatrix& GetWeightMatrix();
00304 
00305     /// <summary>
00306     ///     Get the row vector that is amenable for application of A*x operation.
00307     /// </summary>
00308     WeightRowVector& GetRowVector();
00309 
00310     /// <summary>
00311     ///     Get the column vector that is amenable for application of A^T*x operation.
00312     /// </summary>
00313     WeightColVector& GetColVector();
00314 
00315   ///   <summary>
00316     ///     Get the number of total Degrees-Of-Freedom defined on the source mesh.
00317     /// </summary>
00318     int GetSourceGlobalNDofs();
00319 
00320     /// <summary>
00321     ///     Get the number of total Degrees-Of-Freedom defined on the destination mesh.
00322     /// </summary>
00323     int GetDestinationGlobalNDofs();
00324 
00325     /// <summary>
00326     ///     Get the number of local Degrees-Of-Freedom defined on the source mesh.
00327     /// </summary>
00328     int GetSourceLocalNDofs();
00329 
00330     /// <summary>
00331     ///     Get the number of local Degrees-Of-Freedom defined on the destination mesh.
00332     /// </summary>
00333     int GetDestinationLocalNDofs();
00334 
00335     /// <summary>
00336     ///     Get the number of Degrees-Of-Freedom per element on the source mesh.
00337     /// </summary>
00338     int GetSourceNDofsPerElement();
00339 
00340     /// <summary>
00341     ///     Get the number of Degrees-Of-Freedom per element on the destination mesh.
00342     /// </summary>
00343     int GetDestinationNDofsPerElement();
00344 
00345     /// <summary>
00346     ///     Apply the weight matrix onto the source vector provided as input, and return the column vector (solution projection) after the application
00347     ///     Compute:        \p tgtVals = A * \srcVals, or
00348     ///     if (transpose)  \p tgtVals = A^T * \srcVals
00349     /// </summary>
00350     moab::ErrorCode ApplyWeights (std::vector<double>& srcVals, std::vector<double>& tgtVals, bool transpose=false);
00351 
00352     /// <summary>
00353     ///     Parallel I/O with NetCDF to write out the SCRIP file from multiple processors.
00354     /// </summary>
00355     void WriteParallelWeightsToFile(std::string filename);
00356 
00357 #endif
00358 
00359 public:
00360 
00361     /// <summary>
00362     ///     The fundamental remapping operator object.
00363     /// </summary>
00364     moab::TempestRemapper* m_remapper;
00365 
00366     /// <summary>
00367     ///     The SparseMatrix representing this operator.
00368     /// </summary>
00369     // SparseMatrix<double> m_mapRemapGlobal;
00370     OfflineMap* m_weightMapGlobal;
00371 
00372     /// <summary>
00373     ///     The boolean flag representing whether the root process has the updated global view.
00374     /// </summary>
00375     bool m_globalMapAvailable;
00376 
00377 #ifdef MOAB_HAVE_EIGEN
00378 
00379     WeightMatrix m_weightMatrix;
00380     WeightRowVector m_rowVector;
00381     WeightColVector m_colVector;
00382 
00383 #endif
00384 
00385     /// <summary>
00386     ///     The DataVector that stores the global (GID-based) areas of the source mesh.
00387     /// </summary>
00388     // DataVector<double> m_areasSrcGlobal;
00389     
00390     /// <summary>
00391     ///     The DataVector that stores the global (GID-based) areas of the target mesh.
00392     /// </summary>
00393     // DataVector<double> m_areasTgtGlobal;
00394 
00395     /// <summary>
00396     ///     The reference to the moab::Core object that contains source/target and overlap sets.
00397     /// </summary>
00398     moab::Interface* mbCore;
00399 
00400 #ifdef MOAB_HAVE_MPI
00401     /// <summary>
00402     ///     The reference to the parallel communicator object used by the Core object.
00403     /// </summary>
00404     moab::ParallelComm* pcomm;
00405 #endif
00406 
00407     /// <summary>
00408     ///     The original tag data and local to global DoF mapping to associate matrix values to solution
00409     /// <summary>
00410     moab::Tag m_dofTagSrc, m_dofTagDest;
00411     std::vector<unsigned long> row_dofmap, col_dofmap, srccol_dofmap;
00412     std::vector<unsigned long> row_gdofmap, col_gdofmap, srccol_gdofmap;
00413     std::vector<unsigned long> row_ldofmap, col_ldofmap, srccol_ldofmap;
00414 
00415     DataMatrix3D<int> dataGLLNodesSrc, dataGLLNodesSrcCov, dataGLLNodesDest;
00416     DiscretizationType m_srcDiscType, m_destDiscType;
00417     int m_nTotDofs_Src, m_nTotDofs_SrcCov, m_nTotDofs_Dest;
00418     int m_nDofsPEl_Src, m_nDofsPEl_Dest;
00419 
00420     Mesh* m_meshInput;
00421     Mesh* m_meshInputCov;
00422     Mesh* m_meshOutput;
00423     Mesh* m_meshOverlap;
00424     
00425     bool is_parallel, is_root;
00426     int rank, size;
00427 };
00428 
00429 ///////////////////////////////////////////////////////////////////////////////
00430 
00431 inline
00432 const DataVector<double>& TempestOfflineMap::GetGlobalSourceAreas() const {
00433 #ifdef MOAB_HAVE_MPI
00434   if (pcomm->size() > 1) {
00435         return m_weightMapGlobal->GetSourceAreas();
00436     }
00437     else {
00438         return this->GetSourceAreas();
00439     }
00440 #else
00441   return this->GetSourceAreas();
00442 #endif
00443 }
00444 
00445 inline
00446 const DataVector<double>& TempestOfflineMap::GetGlobalTargetAreas() const {
00447 #ifdef MOAB_HAVE_MPI
00448   if (pcomm->size() > 1) {
00449         return m_weightMapGlobal->GetTargetAreas();
00450     }
00451     else {
00452         return this->GetTargetAreas();
00453     }
00454 #else
00455   return this->GetTargetAreas();
00456 #endif
00457 }
00458 
00459 }
00460 
00461 #endif
00462 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines