1 /* 2 3 PETSc mathematics include file. Defines certain basic mathematical 4 constants and functions for working with single and double precision 5 floating point numbers as well as complex and integers. 6 7 This file is included by petscsys.h and should not be used directly. 8 9 */ 10 11 #if !defined(__PETSCMATH_H) 12 #define __PETSCMATH_H 13 #include <math.h> 14 PETSC_EXTERN_CXX_BEGIN 15 16 extern MPI_Datatype MPIU_2SCALAR; 17 extern MPI_Datatype MPIU_2INT; 18 /* 19 20 Defines operations that are different for complex and real numbers; 21 note that one cannot really mix the use of complex and real in the same 22 PETSc program. All PETSc objects in one program are built around the object 23 PetscScalar which is either always a real or a complex. 24 25 */ 26 27 #define PetscExpPassiveScalar(a) PetscExpScalar() 28 29 /* 30 Complex number definitions 31 */ 32 #if defined(PETSC_USE_COMPLEX) 33 #if defined(PETSC_CLANGUAGE_CXX) 34 /* C++ support of complex number */ 35 #include <complex> 36 37 #define PetscRealPart(a) (a).real() 38 #define PetscImaginaryPart(a) (a).imag() 39 #define PetscAbsScalar(a) std::abs(a) 40 #define PetscConj(a) std::conj(a) 41 #define PetscSqrtScalar(a) std::sqrt(a) 42 #define PetscPowScalar(a,b) std::pow(a,b) 43 #define PetscExpScalar(a) std::exp(a) 44 #define PetscLogScalar(a) std::log(a) 45 #define PetscSinScalar(a) std::sin(a) 46 #define PetscCosScalar(a) std::cos(a) 47 48 #if defined(PETSC_USE_SCALAR_SINGLE) 49 typedef std::complex<float> PetscScalar; 50 #elif defined(PETSC_USE_SCALAR_DOUBLE) 51 typedef std::complex<double> PetscScalar; 52 #elif defined(PETSC_USE_SCALAR_LONG_DOUBLE) 53 typedef std::complex<long double> PetscScalar; 54 #endif 55 56 #else 57 /* C support of complex numbers: Requires C99 compliant compiler*/ 58 #include <complex.h> 59 60 #if defined(PETSC_USE_SCALAR_SINGLE) 61 typedef float complex PetscScalar; 62 63 #define PetscRealPart(a) crealf(a) 64 #define PetscImaginaryPart(a) cimagf(a) 65 #define PetscAbsScalar(a) cabsf(a) 66 #define PetscConj(a) conjf(a) 67 #define PetscSqrtScalar(a) csqrtf(a) 68 #define PetscPowScalar(a,b) cpowf(a,b) 69 #define PetscExpScalar(a) cexpf(a) 70 #define PetscLogScalar(a) clogf(a) 71 #define PetscSinScalar(a) csinf(a) 72 #define PetscCosScalar(a) ccosf(a) 73 74 #elif defined(PETSC_USE_SCALAR_DOUBLE) 75 typedef double complex PetscScalar; 76 77 #define PetscRealPart(a) creal(a) 78 #define PetscImaginaryPart(a) cimag(a) 79 #define PetscAbsScalar(a) cabs(a) 80 #define PetscConj(a) conj(a) 81 #define PetscSqrtScalar(a) csqrt(a) 82 #define PetscPowScalar(a,b) cpow(a,b) 83 #define PetscExpScalar(a) cexp(a) 84 #define PetscLogScalar(a) clog(a) 85 #define PetscSinScalar(a) csin(a) 86 #define PetscCosScalar(a) ccos(a) 87 88 #elif defined(PETSC_USE_SCALAR_LONG_DOUBLE) 89 typedef long double complex PetscScalar; 90 91 #define PetscRealPart(a) creall(a) 92 #define PetscImaginaryPart(a) cimagl(a) 93 #define PetscAbsScalar(a) cabsl(a) 94 #define PetscConj(a) conjl(a) 95 #define PetscSqrtScalar(a) csqrtl(a) 96 #define PetscPowScalar(a,b) cpowl(a,b) 97 #define PetscExpScalar(a) cexpl(a) 98 #define PetscLogScalar(a) clogl(a) 99 #define PetscSinScalar(a) csinl(a) 100 #define PetscCosScalar(a) ccosl(a) 101 102 #endif 103 #endif 104 105 #if !defined(PETSC_HAVE_MPI_C_DOUBLE_COMPLEX) 106 extern MPI_Datatype MPI_C_DOUBLE_COMPLEX; 107 extern MPI_Datatype MPI_C_COMPLEX; 108 #endif 109 110 #if defined(PETSC_USE_SCALAR_SINGLE) 111 #define MPIU_SCALAR MPI_C_COMPLEX 112 #elif defined(PETSC_USE_SCALAR_DOUBLE) 113 #define MPIU_SCALAR MPI_C_DOUBLE_COMPLEX 114 #elif defined(PETSC_USE_SCALAR_LONG_DOUBLE) 115 #define MPIU_SCALAR error 116 #endif 117 118 /* 119 real number definitions 120 */ 121 #else 122 #if defined(PETSC_USE_SCALAR_SINGLE) 123 #define MPIU_SCALAR MPI_FLOAT 124 typedef float PetscScalar; 125 #elif defined(PETSC_USE_SCALAR_DOUBLE) 126 #define MPIU_SCALAR MPI_DOUBLE 127 typedef double PetscScalar; 128 #elif defined(PETSC_USE_SCALAR_LONG_DOUBLE) 129 #define MPIU_SCALAR MPI_LONG_DOUBLE 130 typedef long double PetscScalar; 131 #elif defined(PETSC_USE_SCALAR___FLOAT128) 132 extern MPI_Datatype MPIU_SCALAR; 133 typedef __float128 PetscScalar; 134 #endif 135 #define PetscRealPart(a) (a) 136 #define PetscImaginaryPart(a) (0.) 137 #define PetscAbsScalar(a) (((a)<0.0) ? -(a) : (a)) 138 #define PetscConj(a) (a) 139 #if !defined(PETSC_USE_SCALAR___FLOAT128) 140 #define PetscSqrtScalar(a) sqrt(a) 141 #define PetscPowScalar(a,b) pow(a,b) 142 #define PetscExpScalar(a) exp(a) 143 #define PetscLogScalar(a) log(a) 144 #define PetscSinScalar(a) sin(a) 145 #define PetscCosScalar(a) cos(a) 146 #else 147 #include <quadmath.h> 148 #define PetscSqrtScalar(a) sqrtq(a) 149 #define PetscPowScalar(a,b) powq(a,b) 150 #define PetscExpScalar(a) expq(a) 151 #define PetscLogScalar(a) logq(a) 152 #define PetscSinScalar(a) sinq(a) 153 #define PetscCosScalar(a) cosq(a) 154 #endif 155 156 #endif 157 158 #if defined(PETSC_USE_SCALAR_SINGLE) 159 #define MPIU_REAL MPI_FLOAT 160 typedef float PetscReal; 161 #elif defined(PETSC_USE_SCALAR_DOUBLE) 162 #define MPIU_REAL MPI_DOUBLE 163 typedef double PetscReal; 164 #elif defined(PETSC_USE_SCALAR_LONG_DOUBLE) 165 #define MPIU_REAL MPI_LONG_DOUBLE 166 typedef long double PetscReal; 167 #elif defined(PETSC_USE_SCALAR___FLOAT128) 168 extern MPI_Datatype MPIU_REAL; 169 typedef __float128 PetscReal; 170 #endif 171 172 #define PetscSign(a) (((a) >= 0) ? ((a) == 0 ? 0 : 1) : -1) 173 #define PetscAbs(a) (((a) >= 0) ? (a) : -(a)) 174 175 /* --------------------------------------------------------------------------*/ 176 177 /* 178 Certain objects may be created using either single or double precision. 179 This is currently not used. 180 */ 181 typedef enum { PETSC_SCALAR_DOUBLE,PETSC_SCALAR_SINGLE, PETSC_SCALAR_LONG_DOUBLE } PetscScalarPrecision; 182 183 /* PETSC_i is the imaginary number, i */ 184 extern PetscScalar PETSC_i; 185 186 /*MC 187 PetscMin - Returns minimum of two numbers 188 189 Synopsis: 190 type PetscMin(type v1,type v2) 191 192 Not Collective 193 194 Input Parameter: 195 + v1 - first value to find minimum of 196 - v2 - second value to find minimum of 197 198 199 Notes: type can be integer or floating point value 200 201 Level: beginner 202 203 204 .seealso: PetscMin(), PetscAbsInt(), PetscAbsReal(), PetscSqr() 205 206 M*/ 207 #define PetscMin(a,b) (((a)<(b)) ? (a) : (b)) 208 209 /*MC 210 PetscMax - Returns maxium of two numbers 211 212 Synopsis: 213 type max PetscMax(type v1,type v2) 214 215 Not Collective 216 217 Input Parameter: 218 + v1 - first value to find maximum of 219 - v2 - second value to find maximum of 220 221 Notes: type can be integer or floating point value 222 223 Level: beginner 224 225 .seealso: PetscMin(), PetscAbsInt(), PetscAbsReal(), PetscSqr() 226 227 M*/ 228 #define PetscMax(a,b) (((a)<(b)) ? (b) : (a)) 229 230 /*MC 231 PetscAbsInt - Returns the absolute value of an integer 232 233 Synopsis: 234 int abs PetscAbsInt(int v1) 235 236 Not Collective 237 238 Input Parameter: 239 . v1 - the integer 240 241 Level: beginner 242 243 .seealso: PetscMax(), PetscMin(), PetscAbsReal(), PetscSqr() 244 245 M*/ 246 #define PetscAbsInt(a) (((a)<0) ? -(a) : (a)) 247 248 /*MC 249 PetscAbsReal - Returns the absolute value of an real number 250 251 Synopsis: 252 Real abs PetscAbsReal(PetscReal v1) 253 254 Not Collective 255 256 Input Parameter: 257 . v1 - the double 258 259 260 Level: beginner 261 262 .seealso: PetscMax(), PetscMin(), PetscAbsInt(), PetscSqr() 263 264 M*/ 265 #define PetscAbsReal(a) (((a)<0) ? -(a) : (a)) 266 267 /*MC 268 PetscSqr - Returns the square of a number 269 270 Synopsis: 271 type sqr PetscSqr(type v1) 272 273 Not Collective 274 275 Input Parameter: 276 . v1 - the value 277 278 Notes: type can be integer or floating point value 279 280 Level: beginner 281 282 .seealso: PetscMax(), PetscMin(), PetscAbsInt(), PetscAbsReal() 283 284 M*/ 285 #define PetscSqr(a) ((a)*(a)) 286 287 /* ----------------------------------------------------------------------------*/ 288 /* 289 Basic constants - These should be done much better 290 */ 291 #define PETSC_PI 3.14159265358979323846264 292 #define PETSC_DEGREES_TO_RADIANS 0.01745329251994 293 #define PETSC_MAX_INT 2147483647 294 #define PETSC_MIN_INT -2147483647 295 296 #if defined(PETSC_USE_SCALAR_SINGLE) 297 # define PETSC_MAX 1.e30 298 # define PETSC_MIN -1.e30 299 # define PETSC_MACHINE_EPSILON 1.e-7 300 # define PETSC_SQRT_MACHINE_EPSILON 3.e-4 301 # define PETSC_SMALL 1.e-5 302 #else 303 # define PETSC_MAX 1.e300 304 # define PETSC_MIN -1.e300 305 # define PETSC_MACHINE_EPSILON 1.e-14 306 # define PETSC_SQRT_MACHINE_EPSILON 1.e-7 307 # define PETSC_SMALL 1.e-10 308 #endif 309 310 #if defined PETSC_HAVE_ADIC 311 /* Use MPI_Allreduce when ADIC is not available. */ 312 extern PetscErrorCode PetscGlobalMax(MPI_Comm, const PetscReal*,PetscReal*); 313 extern PetscErrorCode PetscGlobalMin(MPI_Comm, const PetscReal*,PetscReal*); 314 extern PetscErrorCode PetscGlobalSum(MPI_Comm, const PetscScalar*,PetscScalar*); 315 #endif 316 317 /*MC 318 PetscIsInfOrNan - Returns 1 if the input double has an infinity for Not-a-number (Nan) value, otherwise 0. 319 320 Input Parameter: 321 . a - the double 322 323 324 Notes: uses the C99 standard isinf() and isnan() on systems where they exist. 325 Otherwises uses ( (a - a) != 0.0), note that some optimizing compiles compile 326 out this form, thus removing the check. 327 328 Level: beginner 329 330 M*/ 331 #if defined(PETSC_HAVE_ISINF) && defined(PETSC_HAVE_ISNAN) 332 PETSC_STATIC_INLINE PetscErrorCode PetscIsInfOrNanScalar(PetscScalar a) { 333 return isinf(PetscAbsScalar(a)) || isnan(PetscAbsScalar(a)); 334 } 335 PETSC_STATIC_INLINE PetscErrorCode PetscIsInfOrNanReal(PetscReal a) { 336 return isinf(a) || isnan(a); 337 } 338 #elif defined(PETSC_HAVE__FINITE) && defined(PETSC_HAVE__ISNAN) 339 #if defined(PETSC_HAVE_FLOAT_H) 340 #include "float.h" /* Microsoft Windows defines _finite() in float.h */ 341 #endif 342 #if defined(PETSC_HAVE_IEEEFP_H) 343 #include "ieeefp.h" /* Solaris prototypes these here */ 344 #endif 345 PETSC_STATIC_INLINE PetscErrorCode PetscIsInfOrNanScalar(PetscScalar a) { 346 return !_finite(PetscAbsScalar(a)) || _isnan(PetscAbsScalar(a)); 347 } 348 PETSC_STATIC_INLINE PetscErrorCode PetscIsInfOrNanReal(PetscReal a) { 349 return !_finite(a) || _isnan(a); 350 } 351 #else 352 PETSC_STATIC_INLINE PetscErrorCode PetscIsInfOrNanScalar(PetscScalar a) { 353 return ((a - a) != 0.0); 354 } 355 PETSC_STATIC_INLINE PetscErrorCode PetscIsInfOrNanReal(PetscReal a) { 356 return ((a - a) != 0.0); 357 } 358 #endif 359 360 361 /* ----------------------------------------------------------------------------*/ 362 /* 363 PetscLogDouble variables are used to contain double precision numbers 364 that are not used in the numerical computations, but rather in logging, 365 timing etc. 366 */ 367 typedef double PetscLogDouble; 368 #define MPIU_PETSCLOGDOUBLE MPI_DOUBLE 369 370 #define PassiveReal PetscReal 371 #define PassiveScalar PetscScalar 372 373 /* 374 These macros are currently hardwired to match the regular data types, so there is no support for a different 375 MatScalar from PetscScalar. We left the MatScalar in the source just in case we use it again. 376 */ 377 #define MPIU_MATSCALAR MPIU_SCALAR 378 typedef PetscScalar MatScalar; 379 typedef PetscReal MatReal; 380 381 382 PETSC_EXTERN_CXX_END 383 #endif 384