The problem

Need complex number support in PETSc. The standard version of FEniCS is compiled with real version of petsc. For the eigenvalue problem we need complex numbers. I have gone to the petsc4py repo and found some useful information.

The resolution

First of all we need to check the installation of petsc.

from petsc4py import PETSc
print(PETSc.ScalarType)

output >> <class 'numpy.float64'>

Now as per Drew Parsons, the structure of the PETSc installation makes it possible to install different versions and different configurations side by side. You can choose which one you want to work with at run time (or build time) using PETSC_DIR, choosing between real and complex number support, for instance.

Also as per the official repo of petsc4py - β€œThe petsc4py project now lives in the main PETSc repository and can be installed by configuring --with-petsc4py or via the Python package.”

For this we first need to install PETSc with different scalar-types and mark those installation with PETSC_ARCH environment variable. Then we can switch between the different installations.

# Real, 32-bit int
    python3 ./configure \
    PETSC_ARCH=linux-gnu-real-32 \
    --with-scalar-type=real && \
    make PETSC_DIR=/usr/local/petsc PETSC_ARCH=linux-gnu-real-32 ${MAKEFLAGS} all && \
# Complex, 32-bit int
    python3 ./configure \
    PETSC_ARCH=linux-gnu-complex-32 \
    --with-scalar-type=complex && \
    make PETSC_DIR=/usr/local/petsc PETSC_ARCH=linux-gnu-complex-32 ${MAKEFLAGS} all && \
# Real, 64-bit int
    python3 ./configure \
    PETSC_ARCH=linux-gnu-real-64 \
    --with-scalar-type=real && \
    make PETSC_DIR=/usr/local/petsc PETSC_ARCH=linux-gnu-real-64 ${MAKEFLAGS} all && \
# Complex, 64-bit int
    python3 ./configure \
    PETSC_ARCH=linux-gnu-complex-64 \
    --with-scalar-type=complex && \
    make PETSC_DIR=/usr/local/petsc PETSC_ARCH=linux-gnu-complex-64 ${MAKEFLAGS} all && \
 

Once PETSc is installed with all of the above ARCH we can install petsc4py and tell it about the different ARCH. The source for petsc4py is now in the PETSc directory

# Install petsc4py
    cd src/binding/petsc4py && \
    PETSC_ARCH=linux-gnu-real-32:linux-gnu-complex-32:linux-gnu-real-64:linux-gnu-complex-64 pip3 install --no-cache-dir .

Now by changing the environment variable we can activate the specific version of petsc and use it. For example to use the complex build we just need to set the environment variable as such

export PETSC_ARCH=linux-gnu-complex-32

This could also be done inside code

import petsc4py
#"linux-gnu-real-32:linux-gnu-complex-32:linux-gnu-real-64:linux-gnu-complex-64"
petsc4py.init(arch="linux-gnu-complex-64")

After this by running Scalartype we will get complex support

from petsc4py import PETSc
print(PETSc.ScalarType)

output >> <class 'numpy.complex128'>

References