$extrastylesheet
petsc_macro.h
Go to the documentation of this file.
00001 // The libMesh Finite Element Library.
00002 // Copyright (C) 2002-2014 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner
00003 
00004 // This library is free software; you can redistribute it and/or
00005 // modify it under the terms of the GNU Lesser General Public
00006 // License as published by the Free Software Foundation; either
00007 // version 2.1 of the License, or (at your option) any later version.
00008 
00009 // This library is distributed in the hope that it will be useful,
00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012 // Lesser General Public License for more details.
00013 
00014 // You should have received a copy of the GNU Lesser General Public
00015 // License along with this library; if not, write to the Free Software
00016 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00017 
00018 #ifndef LIBMESH_PETSC_MACRO_H
00019 #define LIBMESH_PETSC_MACRO_H
00020 
00021 // Local includes
00022 #include "libmesh/libmesh_config.h"
00023 
00024 #ifdef LIBMESH_HAVE_PETSC
00025 
00026 // A convenient macro for comparing PETSc versions.  Returns 1 if the
00027 // current PETSc version is < major.minor.subminor and zero otherwise.
00028 //
00029 // This macro does not require petscversion.h to be included for it to work correctly.
00030 // It instead relies on the PETSc version numbers detected during configure.  Note that if
00031 // LIBMESH_HAVE_PETSC is not defined, none of the LIBMESH_DETECTED_PETSC_VERSION_* variables will
00032 // be defined either.
00033 #define PETSC_VERSION_LESS_THAN(major,minor,subminor)                   \
00034   ((LIBMESH_DETECTED_PETSC_VERSION_MAJOR < (major) ||                   \
00035     (LIBMESH_DETECTED_PETSC_VERSION_MAJOR == (major) && (LIBMESH_DETECTED_PETSC_VERSION_MINOR < (minor) || \
00036                                                          (LIBMESH_DETECTED_PETSC_VERSION_MINOR == (minor) && \
00037                                                           LIBMESH_DETECTED_PETSC_VERSION_SUBMINOR < (subminor))))) ? 1 : 0)
00038 
00039 // The PETSC_VERSION_RELEASE constant was introduced just prior to 2.3.0 (ca. Apr 22 2005),
00040 // so fall back to using PETSC_VERSION_LESS_THAN in case it doesn't exist.
00041 #ifdef LIBMESH_DETECTED_PETSC_VERSION_RELEASE
00042 
00043 #define PETSC_RELEASE_LESS_THAN(major,minor,subminor)                   \
00044   (PETSC_VERSION_LESS_THAN(major,minor,subminor) && LIBMESH_DETECTED_PETSC_VERSION_RELEASE)
00045 
00046 #else
00047 
00048 #define PETSC_RELEASE_LESS_THAN(major,minor,subminor)   \
00049   (PETSC_VERSION_LESS_THAN(major,minor,subminor))
00050 
00051 #endif
00052 
00053 // In case the configure test some day fails, we can fall back on including petscversion.h.
00054 // In order to support PETSc 2.3.1, however, we need to use a few hacks that allow us to
00055 // include petscversion.h without including petsc.h first.  These are explained below...
00056 //
00057 // // We have to jump through some hoops here: in Petsc 2.3.1 you cannot
00058 // // include petscversion.h without including petsc.h beforehand.  This
00059 // // was because petscversion.h relied on the existence of
00060 // // PETSC_EXTERN_CXX_BEGIN/END in 2.3.1.  The problem is, we don't know
00061 // // how to include petsc.h (wrapped or not wrapped in extern "C") until
00062 // // we know the version!
00063 //
00064 // // First figure out if we need to define PETSC_EXTERN_CXX_BEGIN/END to
00065 // // make petscversion.h happy
00066 // #ifndef PETSC_EXTERN_CXX_BEGIN
00067 // #  define PETSC_EXTERN_CXX_BEGIN
00068 // #  define PETSC_EXTERN_CXX_END
00069 // #  define LIBMESH_PETSC_EXTERN_C_WORKAROUND
00070 // #endif
00071 //
00072 // // Now actually include it
00073 // #include <petscversion.h>
00074 //
00075 // // And finally, get rid of our bogus-definitions.  <petsc.h> will set these itself.
00076 // #ifdef LIBMESH_PETSC_EXTERN_C_WORKAROUND
00077 // #  undef PETSC_EXTERN_CXX_BEGIN
00078 // #  undef PETSC_EXTERN_CXX_END
00079 // #endif
00080 
00081 // Make up for missing extern "C" in old PETSc versions
00082 #if !defined(LIBMESH_USE_COMPLEX_NUMBERS) && PETSC_VERSION_LESS_THAN(2,3,0)
00083 #  define EXTERN_C_FOR_PETSC_BEGIN extern "C" {
00084 #  define EXTERN_C_FOR_PETSC_END }
00085 #else
00086 #  define EXTERN_C_FOR_PETSC_BEGIN
00087 #  define EXTERN_C_FOR_PETSC_END
00088 #endif
00089 
00090 
00091 // Petsc include files
00092 EXTERN_C_FOR_PETSC_BEGIN
00093 #include <petsc.h>
00094 EXTERN_C_FOR_PETSC_END
00095 
00096 #if PETSC_RELEASE_LESS_THAN(3,1,1)
00097 typedef PetscTruth PetscBool;
00098 #endif
00099 
00100 #if PETSC_RELEASE_LESS_THAN(3,1,1)
00101 #  define LibMeshVecDestroy(x)         VecDestroy(*(x))
00102 #  define LibMeshVecScatterDestroy(x)  VecScatterDestroy(*(x))
00103 #  define LibMeshMatDestroy(x)         MatDestroy(*(x))
00104 #  define LibMeshISDestroy(x)          ISDestroy(*(x))
00105 #  define LibMeshKSPDestroy(x)         KSPDestroy(*(x))
00106 #  define LibMeshSNESDestroy(x)        SNESDestroy(*(x))
00107 #  define LibMeshPetscViewerDestroy(x) PetscViewerDestroy(*(x))
00108 #  define LibMeshPCDestroy(x)          PCDestroy(*(x))
00109 #else
00110 #  define LibMeshVecDestroy(x)         VecDestroy(x)
00111 #  define LibMeshVecScatterDestroy(x)  VecScatterDestroy(x)
00112 #  define LibMeshMatDestroy(x)         MatDestroy(x)
00113 #  define LibMeshISDestroy(x)          ISDestroy(x)
00114 #  define LibMeshKSPDestroy(x)         KSPDestroy(x)
00115 #  define LibMeshSNESDestroy(x)        SNESDestroy(x)
00116 #  define LibMeshPetscViewerDestroy(x) PetscViewerDestroy(x)
00117 #  define LibMeshPCDestroy(x)          PCDestroy(x)
00118 #endif
00119 
00120 #if PETSC_VERSION_LESS_THAN(2,2,1)
00121 // This version of PETSc always makes a copy. Current occurrences of PETSC_USE_POINTER are safe with the definition below.
00122 typedef enum { PETSC_COPY_VALUES, PETSC_OWN_POINTER, PETSC_USE_POINTER} PetscCopyMode;
00123 #  define ISCreateLibMesh(comm,n,idx,mode,is)                           \
00124   ((mode) == PETSC_OWN_POINTER                                          \
00125    ? (ISCreateGeneral((comm),(n),(idx),(is)) || PetscFree(idx) || (*(idx) = PETSC_NULL)) \
00126    : (ISCreateGeneral((comm),(n),(idx),(is))))
00127 #elif PETSC_RELEASE_LESS_THAN(3,1,1)
00128 typedef enum { PETSC_COPY_VALUES, PETSC_OWN_POINTER, PETSC_USE_POINTER} PetscCopyMode;
00129 #  define ISCreateLibMesh(comm,n,idx,mode,is)           \
00130   ((mode) == PETSC_USE_POINTER                          \
00131    ? ISCreateGeneralWithArray((comm),(n),(idx),(is))    \
00132    : ((mode) == PETSC_OWN_POINTER                       \
00133       ? ISCreateGeneralNC((comm),(n),(idx),(is))        \
00134       : ISCreateGeneral((comm),(n),(idx),(is))))
00135 #else
00136 #  define ISCreateLibMesh(comm,n,idx,mode,is) ISCreateGeneral((comm),(n),(idx),(mode),(is))
00137 #endif
00138 
00139 #define LIBMESH_CHKERRABORT(ierr) CHKERRABORT(this->comm().get(), ierr);
00140 
00141 #else // LIBMESH_HAVE_PETSC
00142 
00143 #define PETSC_VERSION_LESS_THAN(major,minor,subminor) 1
00144 #define PETSC_RELEASE_LESS_THAN(major,minor,subminor) 1
00145 
00146 #endif // LIBMESH_HAVE_PETSC
00147 
00148 #endif // LIBMESH_PETSC_MACRO_H