MOAB: Mesh Oriented datABase
(version 5.1.1)
|
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