# HG changeset patch # User Jed Brown # Date 1347290967 14400 # Node ID fa3c39414903ec37de9896eeacaf2db0f50329a1 # Parent 6a6027ef45156b7709fbcc40b9d1dc0fea6b5611 Refactor complex support to allow portable use of complex in otherwise real builds diff --git a/include/petscmath.h b/include/petscmath.h --- a/include/petscmath.h +++ b/include/petscmath.h @@ -49,8 +49,7 @@ /* Complex number definitions */ -#if defined(PETSC_USE_COMPLEX) -#if defined(PETSC_CLANGUAGE_CXX) +#if defined(PETSC_CLANGUAGE_CXX) && defined(PETSC_HAVE_CXX_COMPLEX) /* C++ support of complex number */ #if defined(PETSC_HAVE_CUSP) #define complexlib cusp @@ -60,76 +59,81 @@ #include #endif -#define PetscRealPart(a) (a).real() -#define PetscImaginaryPart(a) (a).imag() -#define PetscAbsScalar(a) complexlib::abs(a) -#define PetscConj(a) complexlib::conj(a) -#define PetscSqrtScalar(a) complexlib::sqrt(a) -#define PetscPowScalar(a,b) complexlib::pow(a,b) -#define PetscExpScalar(a) complexlib::exp(a) -#define PetscLogScalar(a) complexlib::log(a) -#define PetscSinScalar(a) complexlib::sin(a) -#define PetscCosScalar(a) complexlib::cos(a) +#define PetscRealPartComplex(a) (a).real() +#define PetscImaginaryPartComplex(a) (a).imag() +#define PetscAbsScalarComplex(a) complexlib::abs(a) +#define PetscConjComplex(a) complexlib::conj(a) +#define PetscSqrtScalarComplex(a) complexlib::sqrt(a) +#define PetscPowScalarComplex(a,b) complexlib::pow(a,b) +#define PetscExpScalarComplex(a) complexlib::exp(a) +#define PetscLogScalarComplex(a) complexlib::log(a) +#define PetscSinScalarComplex(a) complexlib::sin(a) +#define PetscCosScalarComplex(a) complexlib::cos(a) #if defined(PETSC_USE_REAL_SINGLE) -typedef complexlib::complex PetscScalar; +typedef complexlib::complex PetscComplex; #elif defined(PETSC_USE_REAL_DOUBLE) -typedef complexlib::complex PetscScalar; +typedef complexlib::complex PetscComplex; #elif defined(PETSC_USE_REAL___FLOAT128) -typedef complexlib::complex<__float128> PetscScalar; +typedef complexlib::complex<__float128> PetscComplex; /* Notstandard and not expected to work, use __complex128 */ #endif /* PETSC_USE_REAL_ */ -#else /* PETSC_CLANGUAGE_CXX */ +#elif defined(PETSC_CLANGUAGE_C) && defined(PETSC_HAVE_C99_COMPLEX) -/* C support of complex numbers: Requires C99 compliant compiler*/ +/* Use C99 _Complex for the type. Do not include complex.h by default to define "complex" because of symbol conflicts in Hypre. */ +/* Compilation units that can safely use complex should define PETSC_DESIRE_COMPLEX before including any headers */ +#if defined(PETSC_USE_COMPLEX) || defined(PETSC_DESIRE_COMPLEX) #include +#endif #if defined(PETSC_USE_REAL_SINGLE) -typedef float complex PetscScalar; +typedef float _Complex PetscComplex; -#define PetscRealPart(a) crealf(a) -#define PetscImaginaryPart(a) cimagf(a) -#define PetscAbsScalar(a) cabsf(a) -#define PetscConj(a) conjf(a) -#define PetscSqrtScalar(a) csqrtf(a) -#define PetscPowScalar(a,b) cpowf(a,b) -#define PetscExpScalar(a) cexpf(a) -#define PetscLogScalar(a) clogf(a) -#define PetscSinScalar(a) csinf(a) -#define PetscCosScalar(a) ccosf(a) +#define PetscRealPartComplex(a) crealf(a) +#define PetscImaginaryPartComplex(a) cimagf(a) +#define PetscAbsScalarComplex(a) cabsf(a) +#define PetscConjComplex(a) conjf(a) +#define PetscSqrtScalarComplex(a) csqrtf(a) +#define PetscPowScalarComplex(a,b) cpowf(a,b) +#define PetscExpScalarComplex(a) cexpf(a) +#define PetscLogScalarComplex(a) clogf(a) +#define PetscSinScalarComplex(a) csinf(a) +#define PetscCosScalarComplex(a) ccosf(a) #elif defined(PETSC_USE_REAL_DOUBLE) -typedef double complex PetscScalar; +typedef double _Complex PetscComplex; -#define PetscRealPart(a) creal(a) -#define PetscImaginaryPart(a) cimag(a) -#define PetscAbsScalar(a) cabs(a) -#define PetscConj(a) conj(a) -#define PetscSqrtScalar(a) csqrt(a) -#define PetscPowScalar(a,b) cpow(a,b) -#define PetscExpScalar(a) cexp(a) -#define PetscLogScalar(a) clog(a) -#define PetscSinScalar(a) csin(a) -#define PetscCosScalar(a) ccos(a) +#define PetscRealPartComplex(a) creal(a) +#define PetscImaginaryPartComplex(a) cimag(a) +#define PetscAbsScalarComplex(a) cabs(a) +#define PetscConjComplex(a) conj(a) +#define PetscSqrtScalarComplex(a) csqrt(a) +#define PetscPowScalarComplex(a,b) cpow(a,b) +#define PetscExpScalarComplex(a) cexp(a) +#define PetscLogScalarComplex(a) clog(a) +#define PetscSinScalarComplex(a) csin(a) +#define PetscCosScalarComplex(a) ccos(a) #elif defined(PETSC_USE_REAL___FLOAT128) -typedef __complex128 PetscScalar; +typedef __complex128 PetscComplex; PETSC_EXTERN MPI_Datatype MPIU___FLOAT128; PETSC_EXTERN MPI_Datatype MPIU___COMPLEX128; #define MPIU_SCALAR MPIU___COMPLEX128 -#define PetscRealPart(a) crealq(a) -#define PetscImaginaryPart(a) cimagq(a) -#define PetscAbsScalar(a) cabsq(a) -#define PetscConj(a) conjq(a) -#define PetscSqrtScalar(a) csqrtq(a) -#define PetscPowScalar(a,b) cpowq(a,b) -#define PetscExpScalar(a) cexpq(a) -#define PetscLogScalar(a) clogq(a) -#define PetscSinScalar(a) csinq(a) -#define PetscCosScalar(a) ccosq(a) +#define PetscRealPartComplex(a) crealq(a) +#define PetscImaginaryPartComplex(a) cimagq(a) +#define PetscAbsScalarComplex(a) cabsq(a) +#define PetscConjComplex(a) conjq(a) +#define PetscSqrtScalarComplex(a) csqrtq(a) +#define PetscPowScalarComplex(a,b) cpowq(a,b) +#define PetscExpScalarComplex(a) cexpq(a) +#define PetscLogScalarComplex(a) clogq(a) +#define PetscSinScalarComplex(a) csinq(a) +#define PetscCosScalarComplex(a) ccosq(a) #endif /* PETSC_USE_REAL_* */ +#elif defined(PETSC_USE_COMPLEX) +#error "PETSc was configured --with-scalar-type=complex, but a language-appropriate complex library is not available" #endif /* PETSC_CLANGUAGE_CXX */ #if defined(PETSC_HAVE_MPI_C_DOUBLE_COMPLEX) @@ -140,6 +144,19 @@ PETSC_EXTERN MPI_Datatype MPIU_C_COMPLEX; #endif /* PETSC_HAVE_MPI_C_DOUBLE_COMPLEX */ +#if defined(PETSC_USE_COMPLEX) +typedef PetscComplex PetscScalar; +#define PetscRealPart(a) PetscRealPartComplex(a) +#define PetscImaginaryPart(a) PetscImaginaryPartComplex(a) +#define PetscAbsScalar(a) PetscAbsScalarComplex(a) +#define PetscConj(a) PetscConjComplex(a) +#define PetscSqrtScalar(a) PetscSqrtScalarComplex(a) +#define PetscPowScalar(a,b) PetscPowScalarComplex(a,b) +#define PetscExpScalar(a) PetscExpScalarComplex(a) +#define PetscLogScalar(a) PetscLogScalarComplex(a) +#define PetscSinScalar(a) PetscSinScalarComplex(a) +#define PetscCosScalar(a) PetscCosScalarComplex(a) + #if defined(PETSC_USE_REAL_SINGLE) #define MPIU_SCALAR MPIU_C_COMPLEX #elif defined(PETSC_USE_REAL_DOUBLE) @@ -194,8 +211,10 @@ */ typedef enum { PETSC_SCALAR_DOUBLE,PETSC_SCALAR_SINGLE, PETSC_SCALAR_LONG_DOUBLE } PetscScalarPrecision; +#if defined(PETSC_HAVE_C99_COMPLEX) || defined(PETSC_HAVE_CXX_COMPLEX) /* PETSC_i is the imaginary number, i */ -PETSC_EXTERN PetscScalar PETSC_i; +PETSC_EXTERN PetscComplex PETSC_i; +#endif /*MC PetscMin - Returns minimum of two numbers diff --git a/src/sys/objects/init.c b/src/sys/objects/init.c --- a/src/sys/objects/init.c +++ b/src/sys/objects/init.c @@ -32,7 +32,7 @@ PetscMPIInt PetscGlobalRank = -1; PetscMPIInt PetscGlobalSize = -1; -#if defined(PETSC_USE_COMPLEX) +#if (defined(PETSC_CLANGUAGE_C) && defined(PETSC_HAVE_C99_COMPLEX)) || (defined(PETSC_CLANGUAGE_CXX) && defined(PETSC_HAVE_CXX_COMPLEX)) #if defined(PETSC_COMPLEX_INSTANTIATE) template <> class std::complex; /* instantiate complex template class */ #endif @@ -40,9 +40,7 @@ MPI_Datatype MPIU_C_DOUBLE_COMPLEX; MPI_Datatype MPIU_C_COMPLEX; #endif -PetscScalar PETSC_i; -#else -PetscScalar PETSC_i = 0.0; +PetscComplex PETSC_i; #endif #if defined(PETSC_USE_REAL___FLOAT128) MPI_Datatype MPIU___FLOAT128 = 0; diff --git a/src/sys/objects/pinit.c b/src/sys/objects/pinit.c --- a/src/sys/objects/pinit.c +++ b/src/sys/objects/pinit.c @@ -2,7 +2,7 @@ /* This file defines the initialization of PETSc, including PetscInitialize() */ - +#define PETSC_DESIRE_COMPLEX #include /*I "petscsys.h" I*/ #if defined(PETSC_HAVE_CUSP) @@ -692,18 +692,17 @@ ierr = MPI_Comm_rank(MPI_COMM_WORLD,&PetscGlobalRank);CHKERRQ(ierr); ierr = MPI_Comm_size(MPI_COMM_WORLD,&PetscGlobalSize);CHKERRQ(ierr); -#if defined(PETSC_USE_COMPLEX) - /* + /* Initialized the global complex variable; this is because with shared libraries the constructors for global variables are not called; at least on IRIX. */ { -#if defined(PETSC_CLANGUAGE_CXX) - PetscScalar ic(0.0,1.0); +#if defined(PETSC_CLANGUAGE_CXX) && defined(PETSC_HAVE_CXX_COMPLEX) + PetscComplex ic(0.0,1.0); PETSC_i = ic; -#else - PETSC_i = I; +#elif defined(PETSC_CLANGUAGE_C) && defined(PETSC_HAVE_C99_COMPLEX) + PETSC_i = _Complex_I; #endif } @@ -712,6 +711,7 @@ ierr = MPI_Type_commit(&MPIU_C_DOUBLE_COMPLEX);CHKERRQ(ierr); ierr = MPI_Type_contiguous(2,MPI_FLOAT,&MPIU_C_COMPLEX);CHKERRQ(ierr); ierr = MPI_Type_commit(&MPIU_C_COMPLEX);CHKERRQ(ierr); +#if defined(PETSC_USE_COMPLEX) ierr = MPI_Op_create(PetscSum_Local,1,&MPIU_SUM);CHKERRQ(ierr); #endif #endif