././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1709010084.4503753 petsc4py-3.20.5/0000755000175000017500000000000014567266244012376 5ustar00balaybalay././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/CHANGES.rst0000644000175000017500000001432014567251135014171 0ustar00balaybalay========================= CHANGES: PETSc for Python ========================= :Author: Lisandro Dalcin :Contact: dalcinl@gmail.com Release 3.20.0 ============== - Update to PETSc 3.20 release. - Update Cython build, require ``Cython >= 3.0.0``. Release 3.19.0 ============== - Update to PETSc 3.19 release. - Expose ``PetscDevice`` and ``PetscDeviceContext`` API as ``PETSc.Device`` and ``PETSc.DeviceContext`` classes respectively. Release 3.18.0 ============== - Update to PETSc 3.18 release. Release 3.17.0 ============== - Update to PETSc 3.17 release. Release 3.16.0 ============== - Update to PETSc 3.16 release. Release 3.15.0 ============== - Update to PETSc 3.15 release. Release 3.14.1 ============== - Fix build issues after changes in recent PETSc patch releases. - Add various missing types and enums definitions. - Update Cython build, require ``Cython >= 0.24``. Release 3.14.0 ============== - Update to PETSc 3.14 release. Release 3.13.0 ============== - Update to PETSc 3.13 release. Release 3.12.0 ============== - Update to PETSc 3.12 release. Release 3.11.0 ============== - Update to PETSc 3.11 release. Release 3.10.1 ============== - Fix for removal of ``SNESTEST``. - Fix ``Mat`` in-place divide. Release 3.10.0 ============== - Update to PETSc 3.10 release. Release 3.9.1 ============= - Add ``Mat.zeroRowsColumnsLocal()``. - Add ``Mat.getISLocalMat()``. - Add ``Mat.convertISToAIJ()``. Release 3.9.0 ============= - Update to PETSc 3.9 release. Release 3.8.0 ============= - Update to PETSc 3.8 release. Release 3.7.0 ============= - Update to PETSc 3.7 release. Release 3.6.0 ============= - Update to PETSc 3.6 release. Release 3.5.1 ============= - Add ``Log.{begin|view|destroy}()``. - Add ``Mat.SOR()`` and ``Mat.SORType``. - Add ``DMPlex.createCoarsePointIS()``. - Add ``LGMap.createSF()``. - Add ``SNES.getVIInactiveSet()``. - Add ``Vec.isaxpy()``. - Add ``PC.setReusePreconditioner()``. - Return correct type in ``DM.getCoordinateDM()``. - Fix SWIG wrappers to handle 64bit ``PetscInt``. - Fix linker flags for Python from Fink. Release 3.5 =========== - Update to PETSc 3.5 release. Release 3.4 =========== - Update to PETSc 3.4 release. - Add support for ``DMComposite`` and ``DMPlex``. - Change ``Mat.getSizes()`` to return ``((m,M),(n,N))``. Release 3.3.1 ============= - Fix ``Options.getAll()`` mishandling values with negative numbers. - Minor backward compatibility fix for PETSc 3.2 . - Minor bugfix for TSPYTHON subtype. Release 3.3 =========== - Update to PETSc 3.3 release. - Change ``Vec.getLocalForm()`` to ``Vec.localForm()`` for use with context manager and add ``Vec.setMPIGhost()``. - Add ``AO.createMemoryScalable()`` and ``LGMap.block()`` / ``LGMap.unblock()`` - Add ``Object.handle`` property (C pointer as a Python integer). Can be used with ``ctypes`` to pass a PETSc handle. - Add ``Comm.tompi4py()`` to get a ``mpi4py`` communicator instance. Release 1.2 =========== - Update to PETSc 3.2 release. - Add new ``DM`` class , make ``DA`` inherit from ``DM``. - Better support for inplace LU/ILU and Cholesky/ICC factorization and factor PC subtypes. - Now the ``Mat``/``PC``/``KSP``/``SNES``/``TS`` Python subtypes are implemented with Cython. - Better interaction between Python garbage collector and PETSc objects. - Support for PEP 3118 and legacy Python's buffer interface. Release 1.1.2 ============= This is a new-features and bug-fix release. - Add support for copying and computing complements in ``IS`` (``IS.copy()`` and ``IS.complement()``). - Add support for coarsening in ``DA`` (``DA.coarsen()``). - Support for shallow copy and deep copy operations (use ``copy.copy`` and ``copy.deepcopy``). Deep copy is only supported for a bunch of types (``IS``, ``Scatter``, ``Vec``, ``Mat``) - Support for ``pip install petsc4py`` to download and install PETSc. Release 1.1.1 ============= This is a new-features and bug-fix release. - Support for setting PETSC_COMM_WORLD before PETSc initialization. - Support for coordinates, refinement and interpolation in DA. Many thanks to Blaise Bourdin. - Workaround build failures when PETSc is built with *mpiuni*. - Workaround GIL-related APIs for non-threaded Python builds. Release 1.1 =========== - Update for API cleanups, changes, and new calls in PETSc 3.1 and some other missing features. - Add support for Jed Brown's THETA an GL timestepper implementations. - Fix the annoying issues related to Open MPI shared libraries dependencies and Python dynamic loading. - Many minor bug-fixes. Many thanks to Ethan Coon, Dmitry Karpeev, Juha Jaykka, and Michele De Stefano. Release 1.0.3 ============= This is a bug-fix release. - Added a quick fix to solve build issues. The macro __SDIR__ is no longer passed to the compiler in the command line. Release 1.0.2 ============= This is a new-features and bug-fix release. - Now ``petsc4py`` works against core PETSc built with complex scalars. - Added support for PETSc logging features like stages, classes and events. Stages and events support the context manager interface (``with`` statement). - Documentation generated with Epydoc and Sphinx is now included in the release tarball. - Removed enumeration-like classes from the ``petsc4py.PETSc`` module namespace. For example, now you have to use ``PETSc.KSP.Type`` instead of ``PETSc.KSPType``. - The ``PETSc.IS`` to ``numpy.ndarray`` conversion now works for stride and block index sets. - Implemented a more robust import machinery for multi-arch ``petsc4py`` installations. Now a wrong value in the ``PETSC_ARCH`` environmental variable emit a warning (instead of failing) at import time. - The unittest-based testsuite now can run under ``nose`` with its default options. - Removed the dependency on ``numpy.distutils``, just use core Python ``distutils``. Release 1.0.1 ============= This is a bug-fix release. Compile Cython-generated C sources with ``-Wwrite-strings`` removed, as this flag (inherited from PETSc) made GCC emit a lot of (harmless but annoying) warnings about conversion of string literals to non-const char pointers. Release 1.0.0 ============= This is the fist release of the all-new, Cython-based, implementation of *PETSc for Python*. ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/DESCRIPTION.rst0000644000175000017500000000242514567251135014707 0ustar00balaybalayPETSc for Python ================ Python bindings for PETSc. Install ------- If you have a working MPI implementation and the ``mpicc`` compiler wrapper is on your search path, it is highly recommended to install ``mpi4py`` first:: $ pip install mpi4py Ensure you have NumPy installed:: $ pip install numpy and finally:: $ pip install petsc petsc4py Citations --------- If PETSc for Python been significant to a project that leads to an academic publication, please acknowledge that fact by citing the project. * L. Dalcin, P. Kler, R. Paz, and A. Cosimo, *Parallel Distributed Computing using Python*, Advances in Water Resources, 34(9):1124-1139, 2011. http://dx.doi.org/10.1016/j.advwatres.2011.04.013 * S. Balay, S. Abhyankar, M. Adams, S. Benson, J. Brown, P. Brune, K. Buschelman, E. Constantinescu, L. Dalcin, A. Dener, V. Eijkhout, J. Faibussowitsch, W. Gropp, V. Hapla, T. Isaac, P. Jolivet, D. Karpeyev, D. Kaushik, M. Knepley, F. Kong, S. Kruger, D. May, L. Curfman McInnes, R. Mills, L. Mitchell, T. Munson, J. Roman, K. Rupp, P. Sanan, J Sarich, B. Smith, S. Zampini, H. Zhang, and H. Zhang, J. Zhang, *PETSc/TAO Users Manual*, ANL-21/39 - Revision 3.20, 2023. http://dx.doi.org/10.2172/2205494, https://petsc.org/release/docs/manual/manual.pdf ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/LICENSE.rst0000644000175000017500000000263114567251135014205 0ustar00balaybalay========================= LICENSE: PETSc for Python ========================= :Author: Lisandro Dalcin :Contact: dalcinl@gmail.com Copyright (c) 2023, Lisandro Dalcin. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/MANIFEST.in0000644000175000017500000000120314567251135014121 0ustar00balaybalayinclude setup*.py *.toml *.cfg *.rst recursive-include demo [M,m]akefile* *.py *.pyx *.i *.[hc] recursive-include demo .f2py_f2cmap *.pyf *.[fF]90 recursive-include conf *.py *.sh *.cfg recursive-include src *.py *.pyx *.px[di] *.h *.c *.i *.cfg recursive-include test *.py recursive-include * [M,m]akefile exclude src/petsc4py/PETSc.c exclude src/petsc4py/PETSc.h exclude src/petsc4py/PETSc_api.h include docs/*.html include docs/*.pdf include docs/*.info include docs/*.[137] include docs/*.rst include docs/*.bib graft docs/html graft docs/source prune docs/source/demo prune docs/source/reference prune docs/source/_build ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1709010084.4503753 petsc4py-3.20.5/PKG-INFO0000644000175000017500000000477714567266244013512 0ustar00balaybalayMetadata-Version: 2.1 Name: petsc4py Version: 3.20.5 Summary: PETSc for Python Home-page: https://gitlab.com/petsc/petsc Download-URL: https://pypi.io/packages/source/p/petsc4py/petsc4py-3.20.5.tar.gz Author: Lisandro Dalcin Author-email: dalcinl@gmail.com Maintainer: PETSc Team Maintainer-email: petsc-maint@mcs.anl.gov License: BSD-2-Clause Keywords: scientific computing,parallel computing,MPI,PETSc Platform: POSIX Platform: Linux Platform: macOS Platform: FreeBSD Classifier: License :: OSI Approved :: BSD License Classifier: Operating System :: POSIX Classifier: Intended Audience :: Developers Classifier: Intended Audience :: Science/Research Classifier: Programming Language :: C Classifier: Programming Language :: C++ Classifier: Programming Language :: Cython Classifier: Programming Language :: Python Classifier: Programming Language :: Python :: 2 Classifier: Programming Language :: Python :: 3 Classifier: Programming Language :: Python :: Implementation :: CPython Classifier: Topic :: Scientific/Engineering Classifier: Topic :: Software Development :: Libraries :: Python Modules Classifier: Development Status :: 5 - Production/Stable Requires: numpy Description-Content-Type: text/x-rst Provides-Extra: doc License-File: LICENSE.rst PETSc for Python ================ Python bindings for PETSc. Install ------- If you have a working MPI implementation and the ``mpicc`` compiler wrapper is on your search path, it is highly recommended to install ``mpi4py`` first:: $ pip install mpi4py Ensure you have NumPy installed:: $ pip install numpy and finally:: $ pip install petsc petsc4py Citations --------- If PETSc for Python been significant to a project that leads to an academic publication, please acknowledge that fact by citing the project. * L. Dalcin, P. Kler, R. Paz, and A. Cosimo, *Parallel Distributed Computing using Python*, Advances in Water Resources, 34(9):1124-1139, 2011. http://dx.doi.org/10.1016/j.advwatres.2011.04.013 * S. Balay, S. Abhyankar, M. Adams, S. Benson, J. Brown, P. Brune, K. Buschelman, E. Constantinescu, L. Dalcin, A. Dener, V. Eijkhout, J. Faibussowitsch, W. Gropp, V. Hapla, T. Isaac, P. Jolivet, D. Karpeyev, D. Kaushik, M. Knepley, F. Kong, S. Kruger, D. May, L. Curfman McInnes, R. Mills, L. Mitchell, T. Munson, J. Roman, K. Rupp, P. Sanan, J Sarich, B. Smith, S. Zampini, H. Zhang, and H. Zhang, J. Zhang, *PETSc/TAO Users Manual*, ANL-21/39 - Revision 3.20, 2023. http://dx.doi.org/10.2172/2205494, https://petsc.org/release/docs/manual/manual.pdf ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/README.rst0000644000175000017500000000120314567251135014052 0ustar00balaybalay================ PETSc for Python ================ Overview -------- Welcome to PETSc for Python. This package provides Python bindings for PETSc_, the *Portable, Extensible Toolkit for Scientific Computation*. Dependencies ------------ * Python_ 2.7, 3.3 or above. * A recent NumPy_ release. * A matching version of PETSc_ built with *shared/dynamic libraries*. * To work with the in-development version, you need Cython_. .. _Python: https://www.python.org .. _NumPy: https://www.numpy.org .. _PETSc: https://petsc.org .. _Cython: https://www.cython.org Documentation ------------- * https://petsc.org/release/petsc4py/petsc4py/ ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1709010084.3713753 petsc4py-3.20.5/conf/0000755000175000017500000000000014567266244013323 5ustar00balaybalay././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/conf/__init__.py0000644000175000017500000000000014567251135015413 0ustar00balaybalay././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/conf/confpetsc.py0000644000175000017500000010475214567251135015663 0ustar00balaybalay# -------------------------------------------------------------------- import re import os import sys import glob import copy import warnings try: from cStringIO import StringIO except ImportError: from io import StringIO try: import setuptools except ImportError: setuptools = None if setuptools: from setuptools import setup as _setup from setuptools import Extension as _Extension from setuptools import Command else: from distutils.core import setup as _setup from distutils.core import Extension as _Extension from distutils.core import Command def import_command(cmd): try: from importlib import import_module except ImportError: def import_module(n): return __import__(n, fromlist=[None]) try: if not setuptools: raise ImportError mod = import_module('setuptools.command.' + cmd) return getattr(mod, cmd) except ImportError: mod = import_module('distutils.command.' + cmd) return getattr(mod, cmd) _config = import_command('config') _build = import_command('build') _build_ext = import_command('build_ext') _install = import_command('install') from distutils import log from distutils import sysconfig from distutils.util import execute from distutils.util import split_quoted from distutils.errors import DistutilsError try: from setuptools import dep_util except ImportError: from distutils import dep_util try: from packaging.version import Version except ImportError: try: from setuptools.extern.packaging.version import Version except ImportError: from distutils.version import StrictVersion as Version # -------------------------------------------------------------------- # Cython CYTHON = '3.0.0' def cython_req(): return CYTHON def cython_chk(VERSION, verbose=True): # def warn(message): if not verbose: return ruler, ws, nl = "*"*80, " " ,"\n" pyexe = sys.executable advise = "$ %s -m pip install --upgrade cython" % pyexe def printer(*s): sys.stderr.write(" ".join(s)+"\n") printer(ruler, nl) printer(ws, message, nl) printer(ws, ws, advise, nl) printer(ruler) # try: import Cython except ImportError: warn("You need Cython to generate C source files.") return False # CYTHON_VERSION = Cython.__version__ m = re.match(r"(\d+\.\d+(?:\.\d+)?).*", CYTHON_VERSION) if not m: warn("Cannot parse Cython version string {0!r}" .format(CYTHON_VERSION)) return False REQUIRED = Version(VERSION) PROVIDED = Version(m.groups()[0]) if PROVIDED < REQUIRED: warn("You need Cython >= {0} (you have version {1})" .format(VERSION, CYTHON_VERSION)) return False # if verbose: log.info("using Cython %s" % CYTHON_VERSION) return True def cython_run( source, target=None, depends=(), includes=(), workdir=None, force=False, VERSION="0.0", ): if target is None: target = os.path.splitext(source)[0]+'.c' cwd = os.getcwd() try: if workdir: os.chdir(workdir) alldeps = [source] for dep in depends: alldeps += glob.glob(dep) if not (force or dep_util.newer_group(alldeps, target)): log.debug("skipping '%s' -> '%s' (up-to-date)", source, target) return finally: os.chdir(cwd) require = 'Cython >= %s' % VERSION if setuptools and not cython_chk(VERSION, verbose=False): if sys.modules.get('Cython'): removed = getattr(sys.modules['Cython'], '__version__', '') log.info("removing Cython %s from sys.modules" % removed) pkgname = re.compile(r'cython(\.|$)', re.IGNORECASE) for modname in list(sys.modules.keys()): if pkgname.match(modname): del sys.modules[modname] try: install_setup_requires = setuptools._install_setup_requires with warnings.catch_warnings(): if hasattr(setuptools, 'SetuptoolsDeprecationWarning'): category = setuptools.SetuptoolsDeprecationWarning warnings.simplefilter('ignore', category) log.info("fetching build requirement '%s'" % require) install_setup_requires(dict(setup_requires=[require])) except Exception: log.info("failed to fetch build requirement '%s'" % require) if not cython_chk(VERSION): raise DistutilsError("unsatisfied build requirement '%s'" % require) # log.info("cythonizing '%s' -> '%s'", source, target) from cythonize import cythonize args = [] if workdir: args += ['--working', workdir] args += [source] if target: args += ['--output-file', target] err = cythonize(args) if err: raise DistutilsError( "Cython failure: '%s' -> '%s'" % (source, target) ) # -------------------------------------------------------------------- def fix_config_vars(names, values): values = list(values) if 'CONDA_BUILD' in os.environ: return values if sys.platform == 'darwin': if 'ARCHFLAGS' in os.environ: ARCHFLAGS = os.environ['ARCHFLAGS'] for i, flag in enumerate(list(values)): flag, count = re.subn(r'-arch\s+\w+', ' ', str(flag)) if count and ARCHFLAGS: flag = flag + ' ' + ARCHFLAGS values[i] = flag if 'SDKROOT' in os.environ: SDKROOT = os.environ['SDKROOT'] for i, flag in enumerate(list(values)): flag, count = re.subn(r'-isysroot [^ \t]*', ' ', str(flag)) if count and SDKROOT: flag = flag + ' ' + '-isysroot ' + SDKROOT values[i] = flag return values def get_config_vars(*names): # Core Python configuration values = sysconfig.get_config_vars(*names) # Do any distutils flags fixup right now values = fix_config_vars(names, values) return values from distutils.unixccompiler import UnixCCompiler rpath_option_orig = UnixCCompiler.runtime_library_dir_option def rpath_option(compiler, dir): option = rpath_option_orig(compiler, dir) if sys.platform[:5] == 'linux': if option.startswith('-R'): option = option.replace('-R', '-Wl,-rpath,', 1) elif option.startswith('-Wl,-R'): option = option.replace('-Wl,-R', '-Wl,-rpath,', 1) return option UnixCCompiler.runtime_library_dir_option = rpath_option # -------------------------------------------------------------------- class PetscConfig: def __init__(self, petsc_dir, petsc_arch, dest_dir=None): if dest_dir is None: dest_dir = os.environ.get('DESTDIR') self.configdict = { } if not petsc_dir: raise DistutilsError("PETSc not found") if not os.path.isdir(petsc_dir): raise DistutilsError("invalid PETSC_DIR: %s" % petsc_dir) self.version = self._get_petsc_version(petsc_dir) self.configdict = self._get_petsc_config(petsc_dir, petsc_arch) self.PETSC_DIR = self['PETSC_DIR'] self.PETSC_ARCH = self['PETSC_ARCH'] self.DESTDIR = dest_dir language_map = {'CONLY':'c', 'CXXONLY':'c++'} self.language = language_map[self['PETSC_LANGUAGE']] def __getitem__(self, item): return self.configdict[item] def get(self, item, default=None): return self.configdict.get(item, default) def configure(self, extension, compiler=None): self.configure_extension(extension) if compiler is not None: self.configure_compiler(compiler) def _get_petsc_version(self, petsc_dir): import re version_re = { 'major' : re.compile(r"#define\s+PETSC_VERSION_MAJOR\s+(\d+)"), 'minor' : re.compile(r"#define\s+PETSC_VERSION_MINOR\s+(\d+)"), 'micro' : re.compile(r"#define\s+PETSC_VERSION_SUBMINOR\s+(\d+)"), 'release': re.compile(r"#define\s+PETSC_VERSION_RELEASE\s+(-*\d+)"), } petscversion_h = os.path.join(petsc_dir, 'include', 'petscversion.h') with open(petscversion_h, 'rt') as f: data = f.read() major = int(version_re['major'].search(data).groups()[0]) minor = int(version_re['minor'].search(data).groups()[0]) micro = int(version_re['micro'].search(data).groups()[0]) release = int(version_re['release'].search(data).groups()[0]) return (major, minor, micro), (release == 1) def _get_petsc_config(self, petsc_dir, petsc_arch): from os.path import join, isdir, exists PETSC_DIR = petsc_dir PETSC_ARCH = petsc_arch # confdir = join('lib', 'petsc', 'conf') if not (PETSC_ARCH and isdir(join(PETSC_DIR, PETSC_ARCH))): petscvars = join(PETSC_DIR, confdir, 'petscvariables') PETSC_ARCH = makefile(open(petscvars, 'rt')).get('PETSC_ARCH') if not (PETSC_ARCH and isdir(join(PETSC_DIR, PETSC_ARCH))): PETSC_ARCH = '' # variables = join(PETSC_DIR, confdir, 'variables') if not exists(variables): variables = join(PETSC_DIR, PETSC_ARCH, confdir, 'variables') petscvariables = join(PETSC_DIR, PETSC_ARCH, confdir, 'petscvariables') # with open(variables) as f: contents = f.read() with open(petscvariables) as f: contents += f.read() # confstr = 'PETSC_DIR = %s\n' % PETSC_DIR confstr += 'PETSC_ARCH = %s\n' % PETSC_ARCH confstr += contents confdict = makefile(StringIO(confstr)) return confdict def _configure_ext(self, ext, dct, append=False): extdict = ext.__dict__ for key, values in dct.items(): if key in extdict: for value in values: if value not in extdict[key]: if not append: extdict[key].insert(0, value) else: extdict[key].append(value) def configure_extension(self, extension): # includes and libraries # paths in PETSc config files point to final installation location, but # we might be building against PETSc in staging location (DESTDIR) when # DESTDIR is set, so append DESTDIR (if nonempty) to those paths petsc_inc = flaglist(prepend_to_flags(self.DESTDIR, self['PETSC_CC_INCLUDES'])) lib_flags = prepend_to_flags(self.DESTDIR, '-L%s %s' % \ (self['PETSC_LIB_DIR'], self['PETSC_LIB_BASIC'])) petsc_lib = flaglist(lib_flags) # runtime_library_dirs is not supported on Windows if sys.platform != 'win32': # if DESTDIR is set, then we're building against PETSc in a staging # directory, but rpath needs to point to final install directory. rpath = strip_prefix(self.DESTDIR, self['PETSC_LIB_DIR']) petsc_lib['runtime_library_dirs'].append(rpath) # Link in extra libraries on static builds if self['BUILDSHAREDLIB'] != 'yes': petsc_ext_lib = split_quoted(self['PETSC_EXTERNAL_LIB_BASIC']) petsc_lib['extra_link_args'].extend(petsc_ext_lib) self._configure_ext(extension, petsc_inc, append=True) self._configure_ext(extension, petsc_lib) def configure_compiler(self, compiler): if compiler.compiler_type != 'unix': return getenv = os.environ.get # distutils C/C++ compiler (cc, cflags, ccshared, cxx) = get_config_vars( 'CC', 'CFLAGS', 'CCSHARED', 'CXX') ccshared = getenv('CCSHARED', ccshared or '') cflags = getenv('CFLAGS', cflags or '') cflags = cflags.replace('-Wstrict-prototypes', '') # distutils linker (ldflags, ldshared, so_ext) = get_config_vars( 'LDFLAGS', 'LDSHARED', 'SO') ld = cc ldshared = getenv('LDSHARED', ldshared) ldflags = getenv('LDFLAGS', cflags + ' ' + (ldflags or '')) ldcmd = split_quoted(ld) + split_quoted(ldflags) ldshared = [flg for flg in split_quoted(ldshared) if flg not in ldcmd and (flg.find('/lib/spack/env')<0)] ldshared = str.join(' ', ldshared) # def get_flags(cmd): if not cmd: return '' cmd = split_quoted(cmd) if os.path.basename(cmd[0]) == 'xcrun': del cmd[0] while True: if cmd[0] == '-sdk': del cmd[0:2] continue if cmd[0] == '-log': del cmd[0] continue break return ' '.join(cmd[1:]) # PETSc C compiler PCC = self['PCC'] PCC_FLAGS = get_flags(cc) + ' ' + self['PCC_FLAGS'] PCC_FLAGS = PCC_FLAGS.replace('-fvisibility=hidden', '') PCC = getenv('PCC', PCC) + ' ' + getenv('PCCFLAGS', PCC_FLAGS) PCC_SHARED = str.join(' ', (PCC, ccshared, cflags)) # PETSc C++ compiler PCXX = PCC if self.language == 'c++' else self.get('CXX', cxx) # PETSc linker PLD = self['PCC_LINKER'] PLD_FLAGS = get_flags(ld) + ' ' + self['PCC_LINKER_FLAGS'] PLD_FLAGS = PLD_FLAGS.replace('-fvisibility=hidden', '') PLD = getenv('PLD', PLD) + ' ' + getenv('PLDFLAGS', PLD_FLAGS) PLD_SHARED = str.join(' ', (PLD, ldshared, ldflags)) # compiler.set_executables( compiler = PCC, compiler_cxx = PCXX, linker_exe = PLD, compiler_so = PCC_SHARED, linker_so = PLD_SHARED, ) compiler.shared_lib_extension = so_ext # if sys.platform == 'darwin': for attr in ('preprocessor', 'compiler', 'compiler_cxx', 'compiler_so', 'linker_so', 'linker_exe'): compiler_cmd = getattr(compiler, attr, []) while '-mno-fused-madd' in compiler_cmd: compiler_cmd.remove('-mno-fused-madd') def log_info(self): PETSC_DIR = self['PETSC_DIR'] PETSC_ARCH = self['PETSC_ARCH'] version = ".".join([str(i) for i in self.version[0]]) release = ("development", "release")[self.version[1]] version_info = version + ' ' + release integer_size = '%s-bit' % self['PETSC_INDEX_SIZE'] scalar_type = self['PETSC_SCALAR'] precision = self['PETSC_PRECISION'] language = self['PETSC_LANGUAGE'] compiler = self['PCC'] linker = self['PCC_LINKER'] log.info('PETSC_DIR: %s' % PETSC_DIR ) log.info('PETSC_ARCH: %s' % PETSC_ARCH ) log.info('version: %s' % version_info) log.info('integer-size: %s' % integer_size) log.info('scalar-type: %s' % scalar_type) log.info('precision: %s' % precision) log.info('language: %s' % language) log.info('compiler: %s' % compiler) log.info('linker: %s' % linker) # -------------------------------------------------------------------- class Extension(_Extension): pass # -------------------------------------------------------------------- cmd_petsc_opts = [ ('petsc-dir=', None, "define PETSC_DIR, overriding environmental variables"), ('petsc-arch=', None, "define PETSC_ARCH, overriding environmental variables"), ] class config(_config): Configure = PetscConfig user_options = _config.user_options + cmd_petsc_opts def initialize_options(self): _config.initialize_options(self) self.petsc_dir = None self.petsc_arch = None def get_config_arch(self, arch): return config.Configure(self.petsc_dir, arch) def run(self): _config.run(self) self.petsc_dir = config.get_petsc_dir(self.petsc_dir) if self.petsc_dir is None: return petsc_arch = config.get_petsc_arch(self.petsc_dir, self.petsc_arch) log.info('-' * 70) log.info('PETSC_DIR: %s' % self.petsc_dir) arch_list = petsc_arch if not arch_list : arch_list = [ None ] for arch in arch_list: conf = self.get_config_arch(arch) archname = conf.PETSC_ARCH or conf['PETSC_ARCH'] scalar_type = conf['PETSC_SCALAR'] precision = conf['PETSC_PRECISION'] language = conf['PETSC_LANGUAGE'] compiler = conf['PCC'] linker = conf['PCC_LINKER'] log.info('-'*70) log.info('PETSC_ARCH: %s' % archname) log.info(' * scalar-type: %s' % scalar_type) log.info(' * precision: %s' % precision) log.info(' * language: %s' % language) log.info(' * compiler: %s' % compiler) log.info(' * linker: %s' % linker) log.info('-' * 70) #@staticmethod def get_petsc_dir(petsc_dir): if not petsc_dir: return None petsc_dir = os.path.expandvars(petsc_dir) if not petsc_dir or '$PETSC_DIR' in petsc_dir: try: import petsc petsc_dir = petsc.get_petsc_dir() except ImportError: log.warn("PETSC_DIR not specified") return None petsc_dir = os.path.expanduser(petsc_dir) petsc_dir = os.path.abspath(petsc_dir) return config.chk_petsc_dir(petsc_dir) get_petsc_dir = staticmethod(get_petsc_dir) #@staticmethod def chk_petsc_dir(petsc_dir): if not os.path.isdir(petsc_dir): log.error('invalid PETSC_DIR: %s (ignored)' % petsc_dir) return None return petsc_dir chk_petsc_dir = staticmethod(chk_petsc_dir) #@staticmethod def get_petsc_arch(petsc_dir, petsc_arch): if not petsc_dir: return None petsc_arch = os.path.expandvars(petsc_arch) if (not petsc_arch or '$PETSC_ARCH' in petsc_arch): petsc_arch = '' petsc_conf = os.path.join(petsc_dir, 'lib', 'petsc', 'conf') if os.path.isdir(petsc_conf): petscvariables = os.path.join(petsc_conf, 'petscvariables') if os.path.exists(petscvariables): conf = makefile(open(petscvariables, 'rt')) petsc_arch = conf.get('PETSC_ARCH', '') petsc_arch = petsc_arch.split(os.pathsep) petsc_arch = unique(petsc_arch) petsc_arch = [arch for arch in petsc_arch if arch] return config.chk_petsc_arch(petsc_dir, petsc_arch) get_petsc_arch = staticmethod(get_petsc_arch) #@staticmethod def chk_petsc_arch(petsc_dir, petsc_arch): valid_archs = [] for arch in petsc_arch: arch_path = os.path.join(petsc_dir, arch) if os.path.isdir(arch_path): valid_archs.append(arch) else: log.warn("invalid PETSC_ARCH: %s (ignored)" % arch) return valid_archs chk_petsc_arch = staticmethod(chk_petsc_arch) class build(_build): user_options = _build.user_options user_options += [( 'inplace', 'i', "ignore build-lib and put compiled extensions into the source " "directory alongside your pure Python modules", )] user_options += cmd_petsc_opts boolean_options = _build.boolean_options boolean_options += ['inplace'] def initialize_options(self): _build.initialize_options(self) self.inplace = None self.petsc_dir = None self.petsc_arch = None def finalize_options(self): _build.finalize_options(self) if self.inplace is None: self.inplace = False self.set_undefined_options('config', ('petsc_dir', 'petsc_dir'), ('petsc_arch', 'petsc_arch')) self.petsc_dir = config.get_petsc_dir(self.petsc_dir) self.petsc_arch = config.get_petsc_arch(self.petsc_dir, self.petsc_arch) sub_commands = \ [('build_src', lambda *args: True)] + \ _build.sub_commands class build_src(Command): description = "build C sources from Cython files" user_options = [ ('force', 'f', "forcibly build everything (ignore file timestamps)"), ] boolean_options = ['force'] def initialize_options(self): self.force = False def finalize_options(self): self.set_undefined_options('build', ('force', 'force'), ) def run(self): sources = getattr(self, 'sources', []) for source in sources: cython_run( force=self.force, VERSION=cython_req(), **source ) class build_ext(_build_ext): user_options = _build_ext.user_options + cmd_petsc_opts def initialize_options(self): _build_ext.initialize_options(self) self.inplace = None self.petsc_dir = None self.petsc_arch = None self._outputs = [] def finalize_options(self): _build_ext.finalize_options(self) self.set_undefined_options('build', ('inplace', 'inplace')) self.set_undefined_options('build', ('petsc_dir', 'petsc_dir'), ('petsc_arch', 'petsc_arch')) if ((sys.platform.startswith('linux') or sys.platform.startswith('gnu') or sys.platform.startswith('sunos')) and sysconfig.get_config_var('Py_ENABLE_SHARED')): py_version = sysconfig.get_python_version() bad_pylib_dir = os.path.join(sys.prefix, "lib", "python" + py_version, "config") try: self.library_dirs.remove(bad_pylib_dir) except ValueError: pass pylib_dir = sysconfig.get_config_var("LIBDIR") if pylib_dir not in self.library_dirs: self.library_dirs.append(pylib_dir) if pylib_dir not in self.rpath: self.rpath.append(pylib_dir) if sys.exec_prefix == '/usr': self.library_dirs.remove(pylib_dir) self.rpath.remove(pylib_dir) def _copy_ext(self, ext): extclass = ext.__class__ fullname = self.get_ext_fullname(ext.name) modpath = str.split(fullname, '.') pkgpath = os.path.join('', *modpath[0:-1]) name = modpath[-1] sources = list(ext.sources) newext = extclass(name, sources) newext.__dict__.update(copy.deepcopy(ext.__dict__)) newext.name = name return pkgpath, newext def _build_ext_arch(self, ext, pkgpath, arch): build_temp = self.build_temp build_lib = self.build_lib try: self.build_temp = os.path.join(build_temp, arch) self.build_lib = os.path.join(build_lib, pkgpath, arch) _build_ext.build_extension(self, ext) finally: self.build_temp = build_temp self.build_lib = build_lib def get_config_arch(self, arch): return config.Configure(self.petsc_dir, arch) def build_extension(self, ext): if not isinstance(ext, Extension): return _build_ext.build_extension(self, ext) petsc_arch = self.petsc_arch if not petsc_arch: petsc_arch = [ None ] for arch in petsc_arch: config = self.get_config_arch(arch) ARCH = arch or config['PETSC_ARCH'] if ARCH not in self.PETSC_ARCH_LIST: self.PETSC_ARCH_LIST.append(ARCH) self.DESTDIR = config.DESTDIR ext.language = config.language config.log_info() pkgpath, newext = self._copy_ext(ext) config.configure(newext, self.compiler) self._build_ext_arch(newext, pkgpath, ARCH) def run(self): self.build_sources() _build_ext.run(self) def build_sources(self): if 'build_src' in self.distribution.cmdclass: self.run_command('build_src') def build_extensions(self, *args, **kargs): self.PETSC_ARCH_LIST = [] _build_ext.build_extensions(self, *args,**kargs) if not self.PETSC_ARCH_LIST: return self.build_configuration(self.PETSC_ARCH_LIST) def build_configuration(self, arch_list): # template, variables = self.get_config_data(arch_list) config_data = template % variables # build_lib = self.build_lib dist_name = self.distribution.get_name() config_file = os.path.join(build_lib, dist_name, 'lib', dist_name.replace('4py', '') + '.cfg') # def write_file(filename, data): with open(filename, 'w') as fh: fh.write(config_data) execute(write_file, (config_file, config_data), msg='writing %s' % config_file, verbose=self.verbose, dry_run=self.dry_run) def get_config_data(self, arch_list): DESTDIR = self.DESTDIR template = "\n".join([ "PETSC_DIR = %(PETSC_DIR)s", "PETSC_ARCH = %(PETSC_ARCH)s", ]) + "\n" variables = { 'PETSC_DIR' : strip_prefix(DESTDIR, self.petsc_dir), 'PETSC_ARCH' : os.path.pathsep.join(arch_list), } return template, variables def copy_extensions_to_source(self): build_py = self.get_finalized_command('build_py') for ext in self.extensions: inp_file, reg_file = self._get_inplace_equivalent(build_py, ext) arch_list = [''] if isinstance(ext, Extension) and self.petsc_arch: arch_list = self.petsc_arch[:] file_pairs = [] inp_head, inp_tail = os.path.split(inp_file) reg_head, reg_tail = os.path.split(reg_file) for arch in arch_list: inp_file = os.path.join(inp_head, arch, inp_tail) reg_file = os.path.join(reg_head, arch, reg_tail) file_pairs.append((inp_file, reg_file)) for inp_file, reg_file in file_pairs: if os.path.exists(reg_file) or not ext.optional: dest_dir, _ = os.path.split(inp_file) self.mkpath(dest_dir) self.copy_file(reg_file, inp_file, level=self.verbose) def get_outputs(self): self.check_extensions_list(self.extensions) outputs = [] for ext in self.extensions: fullname = self.get_ext_fullname(ext.name) filename = self.get_ext_filename(fullname) if isinstance(ext, Extension) and self.petsc_arch: head, tail = os.path.split(filename) for arch in self.petsc_arch: outfile = os.path.join(self.build_lib, head, arch, tail) outputs.append(outfile) else: outfile = os.path.join(self.build_lib, filename) outputs.append(outfile) outputs = list(set(outputs)) return outputs class install(_install): def initialize_options(self): with warnings.catch_warnings(): if setuptools: if hasattr(setuptools, 'SetuptoolsDeprecationWarning'): category = setuptools.SetuptoolsDeprecationWarning warnings.simplefilter('ignore', category) _install.initialize_options(self) self.old_and_unmanageable = True cmdclass_list = [ config, build, build_src, build_ext, install, ] # -------------------------------------------------------------------- def setup(**attrs): cmdclass = attrs.setdefault('cmdclass', {}) for cmd in cmdclass_list: cmdclass.setdefault(cmd.__name__, cmd) build_src.sources = attrs.pop('cython_sources', None) use_setup_requires = False # handle Cython requirement ourselves if setuptools and build_src.sources and use_setup_requires: version = cython_req() if not cython_chk(version, verbose=False): reqs = attrs.setdefault('setup_requires', []) reqs += ['Cython=='+version] return _setup(**attrs) # -------------------------------------------------------------------- if setuptools: try: from setuptools.command import egg_info as mod_egg_info _FileList = mod_egg_info.FileList class FileList(_FileList): def process_template_line(self, line): level = log.set_threshold(log.ERROR) try: _FileList.process_template_line(self, line) finally: log.set_threshold(level) mod_egg_info.FileList = FileList except (ImportError, AttributeError): pass # -------------------------------------------------------------------- def append(seq, item): if item not in seq: seq.append(item) def append_dict(conf, dct): for key, values in dct.items(): if key in conf: for value in values: if value not in conf[key]: conf[key].append(value) def unique(seq): res = [] for item in seq: if item not in res: res.append(item) return res def flaglist(flags): conf = { 'define_macros' : [], 'undef_macros' : [], 'include_dirs' : [], 'libraries' : [], 'library_dirs' : [], 'runtime_library_dirs': [], 'extra_compile_args' : [], 'extra_link_args' : [], } if type(flags) is str: flags = flags.split() switch = '-Wl,' newflags = [] linkopts = [] for f in flags: if f.startswith(switch): if len(f) > 4: append(linkopts, f[4:]) else: append(newflags, f) if linkopts: newflags.append(switch + ','.join(linkopts)) flags = newflags append_next_word = None for word in flags: if append_next_word is not None: append(append_next_word, word) append_next_word = None continue switch, value = word[0:2], word[2:] if switch == "-I": append(conf['include_dirs'], value) elif switch == "-D": try: idx = value.index("=") macro = (value[:idx], value[idx+1:]) except ValueError: macro = (value, None) append(conf['define_macros'], macro) elif switch == "-U": append(conf['undef_macros'], value) elif switch == "-l": append(conf['libraries'], value) elif switch == "-L": append(conf['library_dirs'], value) elif switch == "-R": append(conf['runtime_library_dirs'], value) elif word.startswith("-Wl"): linkopts = word.split(',') append_dict(conf, flaglist(linkopts[1:])) elif word == "-rpath": append_next_word = conf['runtime_library_dirs'] elif word == "-Xlinker": append_next_word = conf['extra_link_args'] else: #log.warn("unrecognized flag '%s'" % word) pass return conf def prepend_to_flags(path, flags): """Prepend a path to compiler flags with absolute paths""" if not path: return flags def append_path(m): switch = m.group(1) open_quote = m.group(4) old_path = m.group(5) close_quote = m.group(6) if os.path.isabs(old_path): moded_path = os.path.normpath(path + os.path.sep + old_path) return switch + open_quote + moded_path + close_quote return m.group(0) return re.sub(r'((^|\s+)(-I|-L))(\s*["\']?)(\S+)(["\']?)', append_path, flags) def strip_prefix(prefix, string): if not prefix: return string return re.sub(r'^' + prefix, '', string) # -------------------------------------------------------------------- from distutils.text_file import TextFile # Regexes needed for parsing Makefile-like syntaxes import re as _re _variable_rx = _re.compile(r"([a-zA-Z][a-zA-Z0-9_]+)\s*=\s*(.*)") _findvar1_rx = _re.compile(r"\$\(([A-Za-z][A-Za-z0-9_]*)\)") _findvar2_rx = _re.compile(r"\${([A-Za-z][A-Za-z0-9_]*)}") def makefile(fileobj, dct=None): """Parse a Makefile-style file. A dictionary containing name/value pairs is returned. If an optional dictionary is passed in as the second argument, it is used instead of a new dictionary. """ fp = TextFile(file=fileobj, strip_comments=1, skip_blanks=1, join_lines=1) if dct is None: dct = {} done = {} notdone = {} while 1: line = fp.readline() if line is None: # eof break m = _variable_rx.match(line) if m: n, v = m.group(1, 2) v = str.strip(v) if "$" in v: notdone[n] = v else: try: v = int(v) except ValueError: pass done[n] = v try: del notdone[n] except KeyError: pass fp.close() # do variable interpolation here while notdone: for name in list(notdone.keys()): value = notdone[name] m = _findvar1_rx.search(value) or _findvar2_rx.search(value) if m: n = m.group(1) found = True if n in done: item = str(done[n]) elif n in notdone: # get it on a subsequent round found = False else: done[n] = item = "" if found: after = value[m.end():] value = value[:m.start()] + item + after if "$" in after: notdone[name] = value else: try: value = int(value) except ValueError: done[name] = str.strip(value) else: done[name] = value del notdone[name] else: # bogus variable reference; # just drop it since we can't deal del notdone[name] # save the results in the global dictionary dct.update(done) return dct # -------------------------------------------------------------------- ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/conf/cyautodoc.py0000644000175000017500000002512214567251135015662 0ustar00balaybalay# ruff: noqa: UP008,UP031 from Cython.Compiler import Options from Cython.Compiler import PyrexTypes from Cython.Compiler.ExprNodes import TupleNode from Cython.Compiler.Visitor import CythonTransform from Cython.Compiler.StringEncoding import EncodedString from Cython.Compiler.AutoDocTransforms import ( ExpressionWriter as BaseExpressionWriter, AnnotationWriter as BaseAnnotationWriter, ) class ExpressionWriter(BaseExpressionWriter): def visit_IndexNode(self, node): self.visit(node.base) self.put(u"[") if isinstance(node.index, TupleNode): if node.index.subexpr_nodes(): self.emit_sequence(node.index) else: self.put(u"()") else: self.visit(node.index) self.put(u"]") def visit_UnicodeNode(self, node): self.emit_string(node, "") class AnnotationWriter(ExpressionWriter, BaseAnnotationWriter): pass class EmbedSignature(CythonTransform): def __init__(self, context): super(EmbedSignature, self).__init__(context) self.class_name = None self.class_node = None def _select_format(self, embed, clinic): return embed def _fmt_expr(self, node): writer = ExpressionWriter() result = writer.write(node) # print(type(node).__name__, '-->', result) return result def _fmt_annotation(self, node): writer = AnnotationWriter() result = writer.write(node) # print(type(node).__name__, '-->', result) return result def _fmt_arg(self, arg): annotation = None if arg.is_self_arg: doc = self._select_format(arg.name, '$self') elif arg.is_type_arg: doc = self._select_format(arg.name, '$type') else: doc = arg.name if arg.type is PyrexTypes.py_object_type: annotation = None else: annotation = arg.type.declaration_code('', for_display=1) if arg.default and arg.default.is_none: annotation += ' | None' if arg.annotation: annotation = self._fmt_annotation(arg.annotation) annotation = self._select_format(annotation, None) if annotation: doc = doc + (': %s' % annotation) if arg.default: default = self._fmt_expr(arg.default) doc = doc + (' = %s' % default) elif arg.default: default = self._fmt_expr(arg.default) doc = doc + ('=%s' % default) return doc def _fmt_star_arg(self, arg): arg_doc = arg.name if arg.annotation: annotation = self._fmt_annotation(arg.annotation) arg_doc = arg_doc + (': %s' % annotation) return arg_doc def _fmt_arglist(self, args, npoargs=0, npargs=0, pargs=None, nkargs=0, kargs=None, hide_self=False): arglist = [] for arg in args: if not hide_self or not arg.entry.is_self_arg: arg_doc = self._fmt_arg(arg) arglist.append(arg_doc) if pargs: arg_doc = self._fmt_star_arg(pargs) arglist.insert(npargs + npoargs, '*%s' % arg_doc) elif nkargs: arglist.insert(npargs + npoargs, '*') if npoargs: arglist.insert(npoargs, '/') if kargs: arg_doc = self._fmt_star_arg(kargs) arglist.append('**%s' % arg_doc) return arglist def _fmt_ret_type(self, ret): if ret is PyrexTypes.py_object_type: return None else: return ret.declaration_code("", for_display=1) def _fmt_signature(self, cls_name, func_name, args, npoargs=0, npargs=0, pargs=None, nkargs=0, kargs=None, return_expr=None, return_type=None, hide_self=False): arglist = self._fmt_arglist(args, npoargs, npargs, pargs, nkargs, kargs, hide_self=hide_self) arglist_doc = ', '.join(arglist) func_doc = '%s(%s)' % (func_name, arglist_doc) if cls_name: namespace = self._select_format('%s.' % cls_name, '') func_doc = '%s%s' % (namespace, func_doc) ret_doc = None if return_expr: ret_doc = self._fmt_annotation(return_expr) elif return_type: ret_doc = self._fmt_ret_type(return_type) if ret_doc: docfmt = self._select_format('%s -> %s', '%s -> (%s)') func_doc = docfmt % (func_doc, ret_doc) return func_doc def _fmt_relative_position(self, pos): return 'Source code at ' + ':'.join((str(pos[0].get_filenametable_entry()), str(pos[1]))) def _embed_signature(self, signature, pos, node_doc): pos = self._fmt_relative_position(pos) if node_doc: docfmt = self._select_format("%s\n%s\n%s", "%s\n--\n\n%s") return docfmt % (signature, node_doc, pos) else: docfmt = self._select_format("%s\n%s", "%s\n--\n\n%s") return docfmt % (signature, pos) def __call__(self, node): if not Options.docstrings: return node else: return super(EmbedSignature, self).__call__(node) def visit_ClassDefNode(self, node): oldname = self.class_name oldclass = self.class_node self.class_node = node try: # PyClassDefNode self.class_name = node.name except AttributeError: # CClassDefNode self.class_name = node.class_name self.visitchildren(node) self.class_name = oldname self.class_node = oldclass return node def visit_LambdaNode(self, node): # lambda expressions so not have signature or inner functions return node def visit_DefNode(self, node): if not self.current_directives['embedsignature']: return node is_constructor = False hide_self = False if node.entry.is_special: is_constructor = self.class_node and node.name == '__init__' if not is_constructor: return node class_name, func_name = None, self.class_name hide_self = True else: class_name, func_name = self.class_name, node.name npoargs = getattr(node, 'num_posonly_args', 0) nkargs = getattr(node, 'num_kwonly_args', 0) npargs = len(node.args) - nkargs - npoargs signature = self._fmt_signature( class_name, func_name, node.args, npoargs, npargs, node.star_arg, nkargs, node.starstar_arg, return_expr=node.return_type_annotation, return_type=None, hide_self=hide_self) if signature: if is_constructor: doc_holder = self.class_node.entry.type.scope else: doc_holder = node.entry if doc_holder.doc is not None: old_doc = doc_holder.doc elif not is_constructor and getattr(node, 'py_func', None) is not None: old_doc = node.py_func.entry.doc else: old_doc = None new_doc = self._embed_signature(signature, node.pos, old_doc) doc_holder.doc = EncodedString(new_doc) if not is_constructor and getattr(node, 'py_func', None) is not None: node.py_func.entry.doc = EncodedString(new_doc) return node def visit_CFuncDefNode(self, node): if not self.current_directives['embedsignature']: return node if not node.overridable: # not cpdef FOO(...): return node signature = self._fmt_signature( self.class_name, node.declarator.base.name, node.declarator.args, return_type=node.return_type) if signature: if node.entry.doc is not None: old_doc = node.entry.doc elif getattr(node, 'py_func', None) is not None: old_doc = node.py_func.entry.doc else: old_doc = None new_doc = self._embed_signature(signature, node.pos, old_doc) node.entry.doc = EncodedString(new_doc) py_func = getattr(node, 'py_func', None) if py_func is not None: py_func.entry.doc = EncodedString(new_doc) return node def visit_PropertyNode(self, node): if not self.current_directives['embedsignature']: return node entry = node.entry body = node.body prop_name = entry.name type_name = None if entry.visibility == 'public': # property synthesised from a cdef public attribute type_name = entry.type.declaration_code("", for_display=1) if not entry.type.is_pyobject: type_name = "'%s'" % type_name elif entry.type.is_extension_type: type_name = entry.type.module_name + '.' + type_name if type_name is None: for stat in body.stats: if stat.name != '__get__': continue cls_name = self.class_name if cls_name: namespace = self._select_format('%s.' % cls_name, '') prop_name = '%s%s' % (namespace, prop_name) ret_annotation = stat.return_type_annotation if ret_annotation: type_name = self._fmt_annotation(ret_annotation) if type_name is not None: signature = '%s: %s' % (prop_name, type_name) new_doc = self._embed_signature(signature, node.pos, entry.doc) entry.doc = EncodedString(new_doc) return node # Monkeypatch AutoDocTransforms.EmbedSignature try: from Cython.Compiler import AutoDocTransforms AutoDocTransforms.EmbedSignature = EmbedSignature except Exception as exc: import logging logging.Logger(__name__).exception(exc) # Monkeypatch Nodes.raise_utility_code try: from Cython.Compiler.Nodes import raise_utility_code code = raise_utility_code.impl try: ipos = code.index("if (tb) {\n#if CYTHON_COMPILING_IN_PYPY\n") except ValueError: ipos = None else: raise_utility_code.impl = code[:ipos] + code[ipos:].replace( 'CYTHON_COMPILING_IN_PYPY', '!CYTHON_FAST_THREAD_STATE', 1) del raise_utility_code, code, ipos except Exception as exc: import logging logging.Logger(__name__).exception(exc) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/conf/cythonize.py0000755000175000017500000000244314567251135015710 0ustar00balaybalay#!/usr/bin/env python """Run Cython with custom options.""" import os import sys appdir = os.path.dirname(os.path.abspath(__file__)) sys.path.insert(0, appdir) import cyautodoc # noqa: F401,E402 from Cython.Compiler.Main import main as cython_main # noqa: E402 def cythonize(args=None): """Run `cython --3str --cleanup 3 ...`.""" if args is None: argv = sys.argv[:] else: argv = [os.path.abspath(__file__)] + list(args) if '--cleanup' not in argv: argv[1:1] = ['--cleanup', '3'] if '--3str' not in argv: argv[1:1] = ['--3str'] cwd = os.getcwd() sys_argv = sys.argv[:] try: sys.argv[:] = argv cython_main(command_line=1) return 0 except SystemExit as exc: return exc.code finally: os.chdir(cwd) sys.argv[:] = sys_argv def main(): """Entry-point to run Cython with custom options.""" args = sys.argv[1:] if not args: topdir = os.path.dirname(appdir) srcdir = os.path.join(topdir, 'src') source = os.path.join('petsc4py', 'PETSc.pyx') target = os.path.join('petsc4py', 'PETSc.c') args += ['--working', srcdir] args += [source, '--output-file', target] sys.exit(cythonize(args)) if __name__ == "__main__": main() ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/conf/cythonize.sh0000755000175000017500000000022314567251135015664 0ustar00balaybalay#!/bin/sh topdir=$(cd $(dirname "$0")/.. && pwd) python$py "$topdir/conf/cythonize.py" \ --working "$topdir/src" $@ \ "petsc4py/PETSc.pyx" ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/conf/epydoc.cfg0000644000175000017500000001055314567251135015264 0ustar00balaybalay[epydoc] # Epydoc section marker (required by ConfigParser) # The list of objects to document. Objects can be named using # dotted names, module filenames, or package directory names. # Alases for this option include "objects" and "values". modules: petsc4py # The type of output that should be generated. Should be one # of: html, text, latex, dvi, ps, pdf. #output: html # The path to the output directory. May be relative or absolute. #target: docs/html/ # An integer indicating how verbose epydoc should be. The default # value is 0; negative values will suppress warnings and errors; # positive values will give more verbose output. verbosity: 0 # A boolean value indicating that Epydoc should show a tracaback # in case of unexpected error. By default don't show tracebacks #debug: 0 # If True, don't try to use colors or cursor control when doing # textual output. The default False assumes a rich text prompt #simple-term: 0 ### Generation options # The default markup language for docstrings, for modules that do # not define __docformat__. Defaults to epytext. docformat: reStructuredText # Whether or not parsing should be used to examine objects. parse: yes # Whether or not introspection should be used to examine objects. introspect: yes # Don't examine in any way the modules whose dotted name match this # regular expression pattern. exclude: petsc4py.__main__ # Don't perform introspection on the modules whose dotted name match this # regular expression pattern. #exclude-introspect # Don't perform parsing on the modules whose dotted name match this # regular expression pattern. #exclude-parse: # The format for showing inheritance objects. # It should be one of: 'grouped', 'listed', 'included'. inheritance: listed # Whether or not to include private variables. (Even if included, # private variables will be hidden by default.) private: yes # Whether or not to list each module's imports. imports: no # Whether or not to include syntax highlighted source code in # the output (HTML only). sourcecode: no # Whether or not to include a a page with Epydoc log, containing # effective option at the time of generation and the reported logs. include-log: no ### Output options # The documented project's name. name: PETSc for Python # The documented project's URL. url: https://gitlab.com/petsc/petsc # The CSS stylesheet for HTML output. Can be the name of a builtin # stylesheet, or the name of a file. css: white # HTML code for the project link in the navigation bar. If left # unspecified, the project link will be generated based on the # project's name and URL. #link: My Cool Project # The "top" page for the documentation. Can be a URL, the name # of a module or class, or one of the special names "trees.html", # "indices.html", or "help.html" #top: os.path # An alternative help file. The named file should contain the # body of an HTML file; navigation bars will be added to it. #help: my_helpfile.html # Whether or not to include a frames-based table of contents. frames: yes # Whether each class should be listed in its own section when # generating LaTeX or PDF output. separate-classes: no ### API linking options # Define a new API document. A new interpreted text role # will be created #external-api: epydoc # Use the records in this file to resolve objects in the API named NAME. #external-api-file: epydoc:api-objects.txt # Use this URL prefix to configure the string returned for external API. #external-api-root: epydoc:http://epydoc.sourceforge.net/api ### Graph options # The list of graph types that should be automatically included # in the output. Graphs are generated using the Graphviz "dot" # executable. Graph types include: "classtree", "callgraph", # "umlclasstree". Use "all" to include all graph types graph: classtree # The path to the Graphviz "dot" executable, used to generate # graphs. #dotpath: /usr/local/bin/dot # The name of one or more pstat files (generated by the profile # or hotshot module). These are used to generate call graphs. #pstat: profile.out # Specify the font used to generate Graphviz graphs. # (e.g., helvetica or times). graph-font: Helvetica # Specify the font size used to generate Graphviz graphs. graph-font-size: 10 ### Return value options # The condition upon which Epydoc should exit with a non-zero # exit status. Possible values are error, warning, docstring_warning #fail-on: error ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/conf/epydocify.py0000755000175000017500000000550514567251135015671 0ustar00balaybalay#!/usr/bin/env python # -------------------------------------------------------------------- from petsc4py import PETSc # -------------------------------------------------------------------- try: from docutils.nodes import NodeVisitor NodeVisitor.unknown_visit = lambda self, node: None NodeVisitor.unknown_departure = lambda self, node: None except ImportError: pass try: # epydoc 3.0.1 + docutils 0.6 from docutils.nodes import Text from UserString import UserString if not isinstance(Text, UserString): def Text_get_data(s): try: return s._data except AttributeError: return s.astext() def Text_set_data(s, d): s.astext = lambda: d s._data = d Text.data = property(Text_get_data, Text_set_data) except ImportError: pass # -------------------------------------------------------------------- from epydoc.docwriter import dotgraph import re dotgraph._DOT_VERSION_RE = \ re.compile(r'dot (?:- Graphviz )version ([\d\.]+)') try: dotgraph.DotGraph.DEFAULT_HTML_IMAGE_FORMAT dotgraph.DotGraph.DEFAULT_HTML_IMAGE_FORMAT = 'png' except AttributeError: DotGraph_to_html = dotgraph.DotGraph.to_html DotGraph_run_dot = dotgraph.DotGraph._run_dot def to_html(self, image_file, image_url, center=True): if image_file[-4:] == '.gif': image_file = image_file[:-4] + '.png' if image_url[-4:] == '.gif': image_url = image_url[:-4] + '.png' return DotGraph_to_html(self, image_file, image_url) def _run_dot(self, *options): if '-Tgif' in options: opts = list(options) for i, o in enumerate(opts): if o == '-Tgif': opts[i] = '-Tpng' options = type(options)(opts) return DotGraph_run_dot(self, *options) dotgraph.DotGraph.to_html = to_html dotgraph.DotGraph._run_dot = _run_dot # -------------------------------------------------------------------- import re _SIGNATURE_RE = re.compile( # Class name (for builtin methods) r'^\s*((?P\w+)\.)?' + # The function name r'(?P\w+)' + # The parameters r'\(((?P(?:self|cls|mcs)),?)?(?P.*)\)' + # The return value (optional) r'(\s*(->)\s*(?P\S.*?))?'+ # The end marker r'\s*(\n|\s+(--|<=+>)\s+|$|\.\s+|\.\n)') from epydoc import docstringparser as dsp dsp._SIGNATURE_RE = _SIGNATURE_RE # -------------------------------------------------------------------- import sys, os import epydoc.cli def epydocify(): dirname = os.path.dirname(__file__) config = os.path.join(dirname, 'epydoc.cfg') sys.argv.append('--config=' + config) epydoc.cli.cli() if __name__ == '__main__': epydocify() # -------------------------------------------------------------------- ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/conf/stubgen.py0000644000175000017500000002467114567251135015347 0ustar00balaybalayimport os import inspect import textwrap def is_cyfunction(obj): return type(obj).__name__ == 'cython_function_or_method' def is_function(obj): return ( inspect.isbuiltin(obj) or is_cyfunction(obj) or type(obj) is type(ord) ) def is_method(obj): return ( inspect.ismethoddescriptor(obj) or inspect.ismethod(obj) or is_cyfunction(obj) or type(obj) in ( type(str.index), type(str.__add__), type(str.__new__), ) ) def is_classmethod(obj): return ( inspect.isbuiltin(obj) or type(obj).__name__ in ( 'classmethod', 'classmethod_descriptor', ) ) def is_staticmethod(obj): return ( type(obj).__name__ in ( 'staticmethod', ) ) def is_constant(obj): return isinstance(obj, (int, float, str)) def is_datadescr(obj): return inspect.isdatadescriptor(obj) and not hasattr(obj, 'fget') def is_property(obj): return inspect.isdatadescriptor(obj) and hasattr(obj, 'fget') def is_class(obj): return inspect.isclass(obj) or type(obj) is type(int) class Lines(list): INDENT = " " * 4 level = 0 @property def add(self): return self @add.setter def add(self, lines): if lines is None: return if isinstance(lines, str): lines = textwrap.dedent(lines).strip().split("\n") indent = self.INDENT * self.level for line in lines: self.append(indent + line) def signature(obj): doc = obj.__doc__ doc = doc or f"{obj.__name__}: Any" # FIXME remove line sig = doc.split('\n', 1)[0].split('.', 1)[-1] return sig or None def visit_constant(constant): name, value = constant return f"{name}: Final[{type(value).__name__}] = ..." def visit_function(function): sig = signature(function) return f"def {sig}: ..." def visit_method(method): sig = signature(method) return f"def {sig}: ..." def visit_datadescr(datadescr): sig = signature(datadescr) return f"{sig}" def visit_property(prop, name=None): sig = signature(prop.fget) pname = name or prop.fget.__name__ ptype = sig.rsplit('->', 1)[-1].strip() return f"{pname}: {ptype}" def visit_constructor(cls, name='__init__', args=None): init = (name == '__init__') argname = cls.__name__.lower() argtype = cls.__name__ initarg = args or f"{argname}: Optional[{argtype}] = None" selfarg = 'self' if init else 'cls' rettype = 'None' if init else argtype arglist = f"{selfarg}, {initarg}" sig = f"{name}({arglist}) -> {rettype}" return f"def {sig}: ..." def visit_class(cls, outer=None, done=None): skip = { '__doc__', '__dict__', '__module__', '__weakref__', '__pyx_vtable__', '__enum2str', # FIXME refactor implementation '_traceback_', # FIXME maybe refactor? '__lt__', '__le__', '__ge__', '__gt__', } special = { '__len__': "__len__(self) -> int", '__bool__': "__bool__(self) -> bool", '__hash__': "__hash__(self) -> int", '__int__': "__int__(self) -> int", '__index__': "__int__(self) -> int", '__str__': "__str__(self) -> str", '__repr__': "__repr__(self) -> str", '__eq__': "__eq__(self, other: object) -> bool", '__ne__': "__ne__(self, other: object) -> bool", } constructor = ( '__new__', '__init__', ) qualname = cls.__name__ cls_name = cls.__name__ if outer is not None and cls_name.startswith(outer): cls_name = cls_name[len(outer):] qualname = f"{outer}.{cls_name}" override = OVERRIDE.get(qualname, {}) done = set() if done is None else done lines = Lines() try: class sub(cls): pass final = False except TypeError: final = True if final: lines.add = "@final" base = cls.__base__ if base is object: lines.add = f"class {cls_name}:" else: lines.add = f"class {cls_name}({base.__name__}):" lines.level += 1 start = len(lines) for name in constructor: if name in cls.__dict__: done.add(name) if '__hash__' in cls.__dict__: if cls.__hash__ is None: done.add('__hash__') dct = cls.__dict__ keys = list(dct.keys()) def dunder(name): return name.startswith('__') and name.endswith('__') def members(seq): for name in seq: if name in skip: continue if name in done: continue if dunder(name): if name not in special and name not in override: done.add(name) continue yield name for name in members(keys): attr = getattr(cls, name) if is_class(attr): done.add(name) lines.add = visit_class(attr, outer=cls_name) continue for name in members(keys): if name in override: done.add(name) lines.add = override[name] continue if name in special: done.add(name) sig = special[name] lines.add = f"def {sig}: ..." continue attr = getattr(cls, name) if is_method(attr): done.add(name) if name == attr.__name__: obj = dct[name] if is_classmethod(obj): lines.add = "@classmethod" elif is_staticmethod(obj): lines.add = "@staticmethod" lines.add = visit_method(attr) elif True: lines.add = f"{name} = {attr.__name__}" continue if is_datadescr(attr): done.add(name) lines.add = visit_datadescr(attr) continue if is_property(attr): done.add(name) lines.add = visit_property(attr, name) continue if is_constant(attr): done.add(name) lines.add = visit_constant((name, attr)) continue leftovers = [name for name in keys if name not in done and name not in skip] if leftovers: raise RuntimeError(f"leftovers: {leftovers}") if len(lines) == start: lines.add = "pass" lines.level -= 1 return lines def visit_module(module, done=None): skip = { '__doc__', '__name__', '__loader__', '__spec__', '__file__', '__package__', '__builtins__', '__pyx_unpickle_Enum', # FIXME review } done = set() if done is None else done lines = Lines() keys = list(module.__dict__.keys()) keys.sort(key=lambda name: name.startswith("_")) constants = [ (name, getattr(module, name)) for name in keys if all(( name not in done and name not in skip, isinstance(getattr(module, name), int), )) ] for name, value in constants: done.add(name) if name in OVERRIDE: lines.add = OVERRIDE[name] else: lines.add = visit_constant((name, value)) if constants: lines.add = "" for name in keys: if name in done or name in skip: continue value = getattr(module, name) if is_class(value): done.add(name) if value.__module__ != module.__name__: continue lines.add = visit_class(value) lines.add = "" instances = [ (k, getattr(module, k)) for k in keys if all(( k not in done and k not in skip, type(getattr(module, k)) is value, )) ] for attrname, attrvalue in instances: done.add(attrname) lines.add = visit_constant((attrname, attrvalue)) if instances: lines.add = "" continue if is_function(value): done.add(name) if name == value.__name__: lines.add = visit_function(value) else: lines.add = f"{name} = {value.__name__}" continue lines.add = "" for name in keys: if name in done or name in skip: continue value = getattr(module, name) done.add(name) if name in OVERRIDE: lines.add = OVERRIDE[name] else: lines.add = visit_constant((name, value)) leftovers = [name for name in keys if name not in done and name not in skip] if leftovers: raise RuntimeError(f"leftovers: {leftovers}") return lines IMPORTS = """ from __future__ import annotations import sys from threading import Lock from typing import ( Any, Union, Optional, NoReturn, overload, ) if sys.version_info >= (3, 8): from typing import ( final, Final, Literal, ) else: from typing_extensions import ( final, Final, Literal, ) if sys.version_info >= (3, 9): from collections.abc import ( Callable, Hashable, Iterable, Iterator, Sequence, Mapping, ) else: from typing import ( Callable, Hashable, Iterable, Iterator, Sequence, Mapping, ) if sys.version_info >= (3, 11): from typing import Self else: from typing_extensions import Self from os import PathLike import numpy IntType: numpy.dtype = ... RealType: numpy.dtype = ... ComplexType: numpy.dtype = ... ScalarType: numpy.dtype = ... """ OVERRIDE = { 'Error': { }, '__pyx_capi__': "__pyx_capi__: Final[Dict[str, Any]] = ...", '__type_registry__': "__type_registry__: Final[Dict[int, type[Object]]] = ...", } TYPING = """ """ def visit_petsc4py_PETSc(done=None): from petsc4py import PETSc as module lines = Lines() lines.add = IMPORTS lines.add = "" lines.add = visit_module(module) lines.add = TYPING return lines def generate(filename): dirname = os.path.dirname(filename) os.makedirs(dirname, exist_ok=True) with open(filename, 'w') as f: for line in visit_petsc4py_PETSc(): print(line, file=f) OUTDIR = os.path.join('src', 'petsc4py') if __name__ == '__main__': generate(os.path.join(OUTDIR, 'PETSc.pyi')) ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1709010084.3653753 petsc4py-3.20.5/demo/0000755000175000017500000000000014567266244013322 5ustar00balaybalay././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1709010084.3713753 petsc4py-3.20.5/demo/legacy/0000755000175000017500000000000014567266244014566 5ustar00balaybalay././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1709010084.3723752 petsc4py-3.20.5/demo/legacy/binary-io/0000755000175000017500000000000014567266244016457 5ustar00balaybalay././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/demo/legacy/binary-io/makefile0000644000175000017500000000045514567251135020154 0ustar00balaybalay# -*- makefile -*- MPIEXEC= PYTHON=python -include ../../../../../petscdir.mk -include ${PETSC_DIR}/lib/petsc/conf/variables .PHONY:test test: run clean .PHONY:run run: ${MPIEXEC} ${PYTHON} matvecio.py .PHONY:clean clean: ${RM} matrix-*.dat* vector-*.dat* ${RM} *.py[co] ${RM} -r __pycache__ ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/demo/legacy/binary-io/matvecio.py0000644000175000017500000000211214567251135020625 0ustar00balaybalaytry: range = xrange except NameError: pass import sys, petsc4py petsc4py.init(sys.argv) from petsc4py import PETSc m, n = 16, 32 A = PETSc.Mat().create(PETSc.COMM_WORLD) A.setSizes([m*n, m*n]) A.setFromOptions() A.setUp() Istart, Iend = A.getOwnershipRange() for I in range(Istart, Iend): A[I,I] = 4 i = I//n if i>0 : J = I-n; A[I,J] = -1 if i0 : J = I-1; A[I,J] = -1 if j x(2:m-1, 2:n-1) ! center uN => x(2:m-1, 1:n-2) ! north uS => x(2:m-1, 3:n ) ! south uW => x(1:m-2, 2:n-1) ! west uE => x(3:m, 2:n-1) ! east ! compute nonlinear function hx = 1.0/(m-1) ! x grid spacing hy = 1.0/(n-1) ! y grid spacing f(:,:) = x f(2:m-1, 2:n-1) = & (2*u - uE - uW) * (hy/hx) & + (2*u - uN - uS) * (hx/hy) & - alpha * exp(u) * (hx*hy) end subroutine bratu2d ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/demo/legacy/bratu2d/bratu2dnpy.py0000644000175000017500000000105714567251135020571 0ustar00balaybalay# file: bratu2dnpy.py def bratu2d(alpha, x, f): # get 'exp' from numpy from numpy import exp # setup 5-points stencil u = x[1:-1, 1:-1] # center uN = x[1:-1, :-2] # north uS = x[1:-1, 2: ] # south uW = x[ :-2, 1:-1] # west uE = x[2:, 1:-1] # east # compute nonlinear function nx, ny = x.shape hx = 1.0/(nx-1) # x grid spacing hy = 1.0/(ny-1) # y grid spacing f[:,:] = x f[1:-1, 1:-1] = \ (2*u - uE - uW) * (hy/hx) \ + (2*u - uN - uS) * (hx/hy) \ - alpha * exp(u) * (hx*hy) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/demo/legacy/bratu2d/makefile0000644000175000017500000000131614567251135017623 0ustar00balaybalay# -*- makefile -*- MPIEXEC= PYTHON=python F2PY = f2py --quiet F2PY_FLAGS = F2PY_FLAGS = -DF2PY_REPORT_ATEXIT -DF2PY_REPORT_ON_ARRAY_COPY=0 F2PY_FLAGS =--noarch --f90flags='' F2PY_FLAGS +=-DF2PY_REPORT_ON_ARRAY_COPY=1 -include ../../../../../petscdir.mk -include ${PETSC_DIR}/lib/petsc/conf/variables .PHONY:test test: run clean .PHONY:run run: run_py run_f90 .PHONY:run_py run_py: ${MPIEXEC} ${PYTHON} bratu2d.py -impl python MODULE=bratu2df90 .PHONY:${MODULE} ${MODULE}: ${MODULE}.so ${MODULE}.so: ${MODULE}.f90 ${F2PY} ${F2PY_FLAGS} -c $< -m ${MODULE} .PHONY:run_f90 run_f90: ${MODULE} ${MPIEXEC} ${PYTHON} bratu2d.py -impl fortran .PHONY:clean clean: ${RM} *.py[co] ${MODULE}*.so ${RM} -r __pycache__ ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1709010084.3733752 petsc4py-3.20.5/demo/legacy/bratu3d/0000755000175000017500000000000014567266244016132 5ustar00balaybalay././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/demo/legacy/bratu3d/bratu3d.py0000644000175000017500000001533214567251135020045 0ustar00balaybalay# ------------------------------------------------------------------------ # # Solid Fuel Ignition (SFI) problem. This problem is modeled by the # partial differential equation # # -Laplacian(u) - lambda * exp(u) = 0, 0 < x,y,z < 1, # # with boundary conditions # # u = 0 for x = 0, x = 1, y = 0, y = 1, z = 0, z = 1 # # A finite difference approximation with the usual 7-point stencil # is used to discretize the boundary value problem to obtain a # nonlinear system of equations. The problem is solved in a 3D # rectangular domain, using distributed arrays (DAs) to partition # the parallel grid. # # ------------------------------------------------------------------------ try: range = xrange except: pass import sys, petsc4py petsc4py.init(sys.argv) from numpy import exp, sqrt from petsc4py import PETSc class Bratu3D(object): def __init__(self, da, lambda_): assert da.getDim() == 3 self.da = da self.lambda_ = lambda_ self.localX = da.createLocalVec() def formInitGuess(self, snes, X): # x = self.da.getVecArray(X) # mx, my, mz = self.da.getSizes() hx, hy, hz = [1.0/(m-1) for m in [mx, my, mz]] lambda_ = self.lambda_ scale = lambda_/(lambda_ + 1.0) # (xs, xe), (ys, ye), (zs, ze) = self.da.getRanges() for k in range(zs, ze): min_k = min(k,mz-k-1)*hz for j in range(ys, ye): min_j = min(j,my-j-1)*hy for i in range(xs, xe): min_i = min(i,mx-i-1)*hx if (i==0 or j==0 or k==0 or i==mx-1 or j==my-1 or k==mz-1): # boundary points x[i, j, k] = 0.0 else: # interior points min_kij = min(min_i,min_j,min_k) x[i, j, k] = scale*sqrt(min_kij) def formFunction(self, snes, X, F): # self.da.globalToLocal(X, self.localX) x = self.da.getVecArray(self.localX) f = self.da.getVecArray(F) # mx, my, mz = self.da.getSizes() hx, hy, hz = [1.0/m for m in [mx, my, mz]] hxhyhz = hx*hy*hz hxhzdhy = hx*hz/hy; hyhzdhx = hy*hz/hx; hxhydhz = hx*hy/hz; lambda_ = self.lambda_ # (xs, xe), (ys, ye), (zs, ze) = self.da.getRanges() for k in range(zs, ze): for j in range(ys, ye): for i in range(xs, xe): if (i==0 or j==0 or k==0 or i==mx-1 or j==my-1 or k==mz-1): f[i, j, k] = x[i, j, k] - 0 else: u = x[ i , j , k ] # center u_e = x[i+1 , j , k ] # east u_w = x[i-1 , j , k ] # west u_n = x[ i , j+1 , k ] # north u_s = x[ i , j-1 , k ] # south u_u = x[ i , j , k+1] # up u_d = x[ i , j , k-1] # down u_xx = (-u_e + 2*u - u_w)*hyhzdhx u_yy = (-u_n + 2*u - u_s)*hxhzdhy u_zz = (-u_u + 2*u - u_d)*hxhydhz f[i, j, k] = u_xx + u_yy + u_zz \ - lambda_*exp(u)*hxhyhz def formJacobian(self, snes, X, J, P): # self.da.globalToLocal(X, self.localX) x = self.da.getVecArray(self.localX) # mx, my, mz = self.da.getSizes() hx, hy, hz = [1.0/m for m in [mx, my, mz]] hxhyhz = hx*hy*hz hxhzdhy = hx*hz/hy; hyhzdhx = hy*hz/hx; hxhydhz = hx*hy/hz; lambda_ = self.lambda_ # P.zeroEntries() row = PETSc.Mat.Stencil() col = PETSc.Mat.Stencil() # (xs, xe), (ys, ye), (zs, ze) = self.da.getRanges() for k in range(zs, ze): for j in range(ys, ye): for i in range(xs, xe): row.index = (i,j,k) row.field = 0 if (i==0 or j==0 or k==0 or i==mx-1 or j==my-1 or k==mz-1): P.setValueStencil(row, row, 1.0) else: u = x[i,j,k] diag = (2*(hyhzdhx+hxhzdhy+hxhydhz) - lambda_*exp(u)*hxhyhz) for index, value in [ ((i,j,k-1), -hxhydhz), ((i,j-1,k), -hxhzdhy), ((i-1,j,k), -hyhzdhx), ((i, j, k), diag), ((i+1,j,k), -hyhzdhx), ((i,j+1,k), -hxhzdhy), ((i,j,k+1), -hxhydhz), ]: col.index = index col.field = 0 P.setValueStencil(row, col, value) P.assemble() if J != P: J.assemble() # matrix-free operator return PETSc.Mat.Structure.SAME_NONZERO_PATTERN OptDB = PETSc.Options() n = OptDB.getInt('n', 16) nx = OptDB.getInt('nx', n) ny = OptDB.getInt('ny', n) nz = OptDB.getInt('nz', n) lambda_ = OptDB.getReal('lambda', 6.0) da = PETSc.DMDA().create([nx, ny, nz], stencil_width=1) pde = Bratu3D(da, lambda_) snes = PETSc.SNES().create() F = da.createGlobalVec() snes.setFunction(pde.formFunction, F) fd = OptDB.getBool('fd', False) mf = OptDB.getBool('mf', False) if mf: J = None snes.setUseMF() else: J = da.createMat() snes.setJacobian(pde.formJacobian, J) if fd: snes.setUseFD() snes.getKSP().setType('cg') snes.setFromOptions() X = da.createGlobalVec() pde.formInitGuess(snes, X) snes.solve(None, X) U = da.createNaturalVec() da.globalToNatural(X, U) if OptDB.getBool('plot_mpl', False): def plot_mpl(da, U): comm = da.getComm() rank = comm.getRank() scatter, U0 = PETSc.Scatter.toZero(U) scatter.scatter(U, U0, False, PETSc.Scatter.Mode.FORWARD) if rank == 0: try: from matplotlib import pylab except ImportError: PETSc.Sys.Print("matplotlib not available") else: from numpy import mgrid nx, ny, nz = da.sizes solution = U0[...].reshape(da.sizes, order='f') xx, yy = mgrid[0:1:1j*nx,0:1:1j*ny] pylab.contourf(xx, yy, solution[:, :, nz//2]) pylab.axis('equal') pylab.xlabel('X') pylab.ylabel('Y') pylab.title('Z/2') pylab.show() comm.barrier() plot_mpl(da, U) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/demo/legacy/bratu3d/makefile0000644000175000017500000000062214567251135017623 0ustar00balaybalay# -*- makefile -*- MPIEXEC= PYTHON=python -include ../../../../../petscdir.mk -include ${PETSC_DIR}/lib/petsc/conf/variables .PHONY:test test: run clean .PHONY:run run: run_fd run_mf .PHONY:run_fd run_fd: ${MPIEXEC} ${PYTHON} bratu3d.py -fd -nx 7 -ny 8 -nz 9 .PHONY:run_mf run_mf: ${MPIEXEC} ${PYTHON} bratu3d.py -mf -nx 9 -ny 8 -nz 7 .PHONY:clean clean: ${RM} *.py[co] ${RM} -r __pycache__ ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1709010084.3743753 petsc4py-3.20.5/demo/legacy/dmplex/0000755000175000017500000000000014567266244016057 5ustar00balaybalay././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/demo/legacy/dmplex/anisotropic_adaptation.py0000644000175000017500000000624214567251135023164 0ustar00balaybalayimport sys,petsc4py petsc4py.init(sys.argv) from petsc4py import PETSc import numpy as np def sensor(x, y): """ Classic hyperbolic sensor function for testing multi-scale anisotropic mesh adaptation: f:[-1, 1]² → R, f(x, y) = sin(50xy)/100 if |xy| > 2π/50 else sin(50xy) (mapped to have domain [0,1]² in this case). """ xy = (2*x - 1)*(2*y - 1) ret = np.sin(50*xy) if np.abs(xy) > 2*np.pi/50: ret *= 0.01 return ret # Set metric parameters h_min = 1.0e-10 # Minimum tolerated metric magnitude ~ cell size h_max = 1.0e-01 # Maximum tolerated metric magnitude ~ cell size a_max = 1.0e+05 # Maximum tolerated anisotropy targetComplexity = 10000.0 # Analogous to number of vertices in adapted mesh p = 1.0 # Lᵖ normalization order # Create a uniform mesh OptDB = PETSc.Options() dim = OptDB.getInt('dim', 2) numEdges = 10 simplex = True plex = PETSc.DMPlex().createBoxMesh([numEdges]*dim, simplex=simplex) plex.distribute() plex.view() viewer = PETSc.Viewer().createVTK("anisotropic_mesh_0.vtk", "w") viewer(plex) # Do four mesh adaptation iterations for i in range(1, 5): vStart, vEnd = plex.getDepthStratum(0) # Create a P1 sensor function comm = plex.getComm() fe = PETSc.FE().createLagrange(dim, 1, simplex, 1, -1, comm=comm) plex.setField(0, fe) plex.createDS() f = plex.createLocalVector() csec = plex.getCoordinateSection() coords = plex.getCoordinatesLocal() pf = f.getArray() pcoords = coords.getArray() for v in range(vStart, vEnd): off = csec.getOffset(v) x = pcoords[off] y = pcoords[off+1] pf[off//dim] = sensor(x, y) f.setName("Sensor") viewer = PETSc.Viewer().createVTK(f"sensor_{i}.vtk", "w") viewer(f) # Recover the gradient of the sensor function dmGrad = plex.clone() fe = PETSc.FE().createLagrange(dim, dim, simplex, 1, -1, comm=comm) dmGrad.setField(0, fe) dmGrad.createDS() g = dmGrad.createLocalVector() plex.computeGradientClementInterpolant(f, g) g.setName("Gradient") viewer = PETSc.Viewer().createVTK(f"gradient_{i}.vtk", "w") viewer(g) # Recover the Hessian of the sensor function dmHess = plex.clone() H = dmHess.metricCreate() dmGrad.computeGradientClementInterpolant(g, H) H.setName("Hessian") viewer = PETSc.Viewer().createVTK(f"hessian_{i}.vtk", "w") viewer(H) # Obtain a metric by Lᵖ normalization dmHess.metricSetMinimumMagnitude(h_min) dmHess.metricSetMaximumMagnitude(h_max) dmHess.metricSetMaximumAnisotropy(a_max) dmHess.metricSetNormalizationOrder(p) dmHess.metricSetTargetComplexity(targetComplexity) metric = dmHess.metricCreate() det = dmHess.metricDeterminantCreate() dmHess.metricNormalize(H, metric, det) metric.setName("Metric") viewer = PETSc.Viewer().createVTK(f"metric_{i}.vtk", "w") viewer(metric) # Call adapt routine - boundary label None by default plex = plex.adaptMetric(metric) plex.distribute() plex.view() # Write to VTK file viewer = PETSc.Viewer().createVTK(f"anisotropic_mesh_{i}.vtk", "w") viewer(plex) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/demo/legacy/dmplex/distribute_field.py0000644000175000017500000000343414567251135021747 0ustar00balaybalay# -*- coding: utf-8 -*- """ Created on Fri Dec 25 17:03:18 2015 @author: ale """ import sys,petsc4py petsc4py.init(sys.argv) from petsc4py import PETSc import numpy as np dim = 2 if not PETSc.COMM_WORLD.rank: coords = np.asarray([[0.0, 0.0], [0.5, 0.0], [1.0, 0.0], [0.0, 0.5], [0.5, 0.5], [1.0, 0.5], [0.0, 1.0], [0.5, 1.0], [1.0, 1.0]], dtype=PETSc.RealType) cells = np.asarray([[0,1,4,3], [1,2,5,4], [3,4,7,6], [4,5,8,7]], dtype=PETSc.IntType) else: coords = np.zeros((0, 2), dtype=PETSc.RealType) cells = np.zeros((0, 4), dtype=PETSc.IntType) plex = PETSc.DMPlex().createFromCellList(dim, cells, coords, comm=PETSc.COMM_WORLD) pStart, pEnd = plex.getChart() plex.view() print("pStart, pEnd: ", pStart, pEnd) # Create section with 1 field with 1 DoF per vertex, edge and cell numComp = 1 # Start with an empty vector numDof = [0] * 3 # Field defined on vertices numDof[0] = 1 # Field defined on edges numDof[1] = 1 # Field defined on cells numDof[2] = 1 plex.setNumFields(1) origSect = plex.createSection(numComp, numDof) origSect.setFieldName(0, 'TestField') origSect.setUp() origSect.view() plex.setSection(origSect) origVec = plex.createGlobalVec() origVec.view() origVec.setValues(list(range(pStart, pEnd)),list(range(pStart,pEnd))) origVec.assemblyBegin() origVec.assemblyEnd() origVec.view() if PETSc.COMM_WORLD.size > 1: sf = plex.distribute() sf.view() newSect, newVec = plex.distributeField(sf, origSect, origVec) else: newSect = origSect newVec = origVec newSect.view() newVec.view() ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/demo/legacy/dmplex/isotropic_adaptation.py0000644000175000017500000000165714567251135022652 0ustar00balaybalayimport sys,petsc4py petsc4py.init(sys.argv) from petsc4py import PETSc import numpy as np OptDB = PETSc.Options() dim = OptDB.getInt('dim', 2) plex = PETSc.DMPlex().createBoxMesh([4]*dim, simplex=True) plex.distribute() plex.view() # Create two metric tensor fields corresponding to uniform mesh sizes of 0.1 and 0.2 metric1 = plex.metricCreateUniform(100.0) metric2 = plex.metricCreateUniform(25.0) # The metrics can be combined using intersection, the result of which corresponds to # the maximum ellipsoid at each point metric = plex.metricCreate() plex.metricIntersection2(metric1, metric2, metric) metric1.axpy(-1, metric) assert np.isclose(metric1.norm(), 0.0) # Call adapt routine - boundary label None by default newplex = plex.adaptMetric(metric) newplex.view() # Write to VTK file viewer = PETSc.Viewer().createVTK('base_mesh.vtk', 'w') viewer(plex) viewer = PETSc.Viewer().createVTK('isotropic_mesh.vtk', 'w') viewer(newplex) ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1709010084.3763752 petsc4py-3.20.5/demo/legacy/kspsolve/0000755000175000017500000000000014567266244016434 5ustar00balaybalay././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/demo/legacy/kspsolve/makefile0000644000175000017500000000062014567251135020123 0ustar00balaybalay# -*- makefile -*- MPIEXEC= PYTHON=python -include ../../../../../petscdir.mk -include ${PETSC_DIR}/lib/petsc/conf/variables .PHONY:test test: run clean .PHONY:run run: run_1 run_2 SCRIPT1=test_mat_cg .PHONY:run_1 run_1: ${MPIEXEC} ${PYTHON} ${SCRIPT1}.py SCRIPT2= test_mat_ksp .PHONY:run_2 run_2: ${MPIEXEC} ${PYTHON} ${SCRIPT2}.py .PHONY:clean clean: ${RM} *.py[co] ${RM} -r __pycache__ ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/demo/legacy/kspsolve/petsc-cg.py0000644000175000017500000000133614567251135020507 0ustar00balaybalaydef cg(A, b, x, imax=50, eps=1e-6): """ A, b, x : matrix, rhs, solution imax : maximum allowed iterations eps : tolerance for convergence """ # allocate work vectors r = b.duplicate() d = b.duplicate() q = b.duplicate() # initialization i = 0 A.mult(x, r) r.aypx(-1, b) r.copy(d) delta_0 = r.dot(r) delta = delta_0 # enter iteration loop while i < imax and \ delta > delta_0 * eps**2: A.mult(d, q) alpha = delta / d.dot(q) x.axpy(+alpha, d) r.axpy(-alpha, q) delta_old = delta delta = r.dot(r) beta = delta / delta_old d.aypx(beta, r) i = i + 1 return i, delta**0.5 ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/demo/legacy/kspsolve/petsc-ksp.py0000644000175000017500000000046414567251135020714 0ustar00balaybalay# create linear solver ksp = PETSc.KSP() ksp.create(PETSc.COMM_WORLD) # use conjugate gradients ksp.setType('cg') # and incomplete Cholesky ksp.getPC().setType('icc') # obtain sol & rhs vectors x, b = A.createVecs() x.set(0) b.set(1) # and next solve ksp.setOperators(A) ksp.setFromOptions() ksp.solve(b, x) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/demo/legacy/kspsolve/petsc-mat.py0000644000175000017500000000166014567251135020677 0ustar00balaybalaytry: range = xrange except: pass from petsc4py import PETSc # grid size and spacing m, n = 32, 32 hx = 1.0/(m-1) hy = 1.0/(n-1) # create sparse matrix A = PETSc.Mat() A.create(PETSc.COMM_WORLD) A.setSizes([m*n, m*n]) A.setType('aij') # sparse A.setPreallocationNNZ(5) # precompute values for setting # diagonal and non-diagonal entries diagv = 2.0/hx**2 + 2.0/hy**2 offdx = -1.0/hx**2 offdy = -1.0/hy**2 # loop over owned block of rows on this # processor and insert entry values Istart, Iend = A.getOwnershipRange() for I in range(Istart, Iend) : A[I,I] = diagv i = I//n # map row number to j = I - i*n # grid coordinates if i> 0 : J = I-n; A[I,J] = offdx if i< m-1: J = I+n; A[I,J] = offdx if j> 0 : J = I-1; A[I,J] = offdy if j< n-1: J = I+1; A[I,J] = offdy # communicate off-processor values # and setup internal data structures # for performing parallel operations A.assemblyBegin() A.assemblyEnd() ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/demo/legacy/kspsolve/test_mat_cg.py0000644000175000017500000000252314567251135021272 0ustar00balaybalaytry: execfile except NameError: def execfile(file, globals=globals(), locals=locals()): fh = open(file, "r") try: exec(fh.read()+"\n", globals, locals) finally: fh.close() import petsc4py, sys petsc4py.init(sys.argv) from petsc4py import PETSc execfile('petsc-mat.py') execfile('petsc-cg.py') x, b = A.createVecs() ksp = PETSc.KSP().create() ksp.setType('cg') ksp.getPC().setType('none') ksp.setOperators(A) ksp.setFromOptions() ksp.max_it = 100 ksp.rtol = 1e-5 ksp.atol = 0 x.set(0) b.set(1) ksp.solve(b,x) print("iterations: %d residual norm: %g" % (ksp.its, ksp.norm)) x.set(0) b.set(1) its, norm = cg(A,b,x,100,1e-5) print("iterations: %d residual norm: %g" % (its, norm)) OptDB = PETSc.Options() if OptDB.getBool('plot', True): da = PETSc.DMDA().create([m,n]) u = da.createGlobalVec() x.copy(u) draw = PETSc.Viewer.DRAW() OptDB['draw_pause'] = 1 draw(u) if OptDB.getBool('plot_mpl', False): try: from matplotlib import pylab except ImportError: print("matplotlib not available") else: from numpy import mgrid X, Y = mgrid[0:1:1j*m,0:1:1j*n] Z = x[...].reshape(m,n) pylab.figure() pylab.contourf(X,Y,Z) pylab.plot(X.ravel(),Y.ravel(),'.k') pylab.axis('equal') pylab.colorbar() pylab.show() ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/demo/legacy/kspsolve/test_mat_ksp.py0000644000175000017500000000171614567251135021501 0ustar00balaybalaytry: execfile except NameError: def execfile(file, globals=globals(), locals=locals()): fh = open(file, "r") try: exec(fh.read()+"\n", globals, locals) finally: fh.close() import petsc4py, sys petsc4py.init(sys.argv) from petsc4py import PETSc execfile('petsc-mat.py') execfile('petsc-ksp.py') OptDB = PETSc.Options() if OptDB.getBool('plot', True): da = PETSc.DMDA().create([m,n]) u = da.createGlobalVec() x.copy(u) draw = PETSc.Viewer.DRAW() OptDB['draw_pause'] = 1 draw(u) if OptDB.getBool('plot_mpl', False): try: from matplotlib import pylab except ImportError: print("matplotlib not available") else: from numpy import mgrid X, Y = mgrid[0:1:1j*m,0:1:1j*n] Z = x[...].reshape(m,n) pylab.figure() pylab.contourf(X,Y,Z) pylab.plot(X.ravel(),Y.ravel(),'.k') pylab.axis('equal') pylab.colorbar() pylab.show() ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/demo/legacy/makefile0000644000175000017500000000176514567251135016270 0ustar00balaybalay.PHONY:all -include ../../../../petscdir.mk -include ${PETSC_DIR}/lib/petsc/conf/variables all: petsc -@PYTHONPATH=${PYTHONPATH:+$PYTHONPATH:}${PETSC_MPI4PY_PYTHONPATH} ${MAKE} -C binary-io -@PYTHONPATH=${PYTHONPATH:+$PYTHONPATH:}${PETSC_MPI4PY_PYTHONPATH} ${MAKE} -C kspsolve -@PYTHONPATH=${PYTHONPATH:+$PYTHONPATH:}${PETSC_MPI4PY_PYTHONPATH} ${MAKE} -C bratu2d -@PYTHONPATH=${PYTHONPATH:+$PYTHONPATH:}${PETSC_MPI4PY_PYTHONPATH} ${MAKE} -C bratu3d -@PYTHONPATH=${PYTHONPATH:+$PYTHONPATH:}${PETSC_MPI4PY_PYTHONPATH} ${MAKE} -C poisson2d -@PYTHONPATH=${PYTHONPATH:+$PYTHONPATH:}${PETSC_MPI4PY_PYTHONPATH} ${MAKE} -C poisson3d -@PYTHONPATH=${PYTHONPATH:+$PYTHONPATH:}${PETSC_MPI4PY_PYTHONPATH} ${MAKE} -C perftest -@PYTHONPATH=${PYTHONPATH:+$PYTHONPATH:}${PETSC_MPI4PY_PYTHONPATH} ${MAKE} -C wrap-swig -@PYTHONPATH=${PYTHONPATH:+$PYTHONPATH:}${PETSC_MPI4PY_PYTHONPATH} ${MAKE} -C wrap-f2py .PHONY:petsc petsc: -@PYTHONPATH=${PYTHONPATH:+$PYTHONPATH:}${PETSC_MPI4PY_PYTHONPATH} ${MAKE} -C petsc-examples ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1709010084.3793752 petsc4py-3.20.5/demo/legacy/ode/0000755000175000017500000000000014567266244015335 5ustar00balaybalay././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/demo/legacy/ode/bouncing_ball.py0000644000175000017500000000322514567251135020500 0ustar00balaybalayimport sys, petsc4py petsc4py.init(sys.argv) from petsc4py import PETSc class BouncingBall(object): n = 2 comm = PETSc.COMM_SELF def __init__(self): pass def initialCondition(self, u): u[0] = 0.0 u[1] = 20.0 u.assemble() def evalRHSFunction(self, ts, t, u, f): f[0] = u[1] f[1] = -9.8 f.assemble() def evalRHSJacobian(self, ts, t, u, A, B): J = A J[0,0] = 0.0 J[1,0] = 0.0 J[0,1] = 1.0 J[1,1] = 0.0 J.assemble() if A != B: B.assemble() return True # same nonzero pattern class Monitor(object): def __init__(self): pass def __call__(self, ts, k, t, x): PETSc.Sys.Print(f"Position at time {t}: {x[0]}") ode = BouncingBall() J = PETSc.Mat().create() J.setSizes([ode.n,ode.n]) J.setType('aij') J.setUp() J.assemble() u = PETSc.Vec().createSeq(ode.n, comm=ode.comm) f = u.duplicate() ts = PETSc.TS().create(comm=ode.comm) ts.setProblemType(ts.ProblemType.NONLINEAR) ts.setType(ts.Type.BEULER) ts.setRHSFunction(ode.evalRHSFunction, f) ts.setRHSJacobian(ode.evalRHSJacobian, J) #ts.setSaveTrajectory() ts.setTime(0.0) ts.setTimeStep(0.01) ts.setMaxTime(15.0) #ts.setMaxSteps(1000) ts.setExactFinalTime(PETSc.TS.ExactFinalTime.MATCHSTEP) #ts.setMonitor(Monitor()) direction = [-1] terminate = [False] def event(ts, t, X, fvalue): fvalue[0] = X[0] def postevent(ts, events, t, X, forward): X[0] = 0.0 X[1] = -0.9*X[1] X.assemble() ts.setEventHandler(direction, terminate, event, postevent) ts.setEventTolerances(1e-6, vtol=[1e-9]) ts.setFromOptions() ode.initialCondition(u) ts.solve(u) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/demo/legacy/ode/ce.py0000644000175000017500000000346514567251135016277 0ustar00balaybalay# Stiff scalar valued ODE problem with an exact solution import sys, petsc4py petsc4py.init(sys.argv) from petsc4py import PETSc from math import sin, cos, exp class CE(object): n = 1 comm = PETSc.COMM_SELF def __init__(self, lambda_=1.0): self.lambda_ = lambda_ def evalSolution(self, t, x): l = self.lambda_ x[0] = l/(l*l+1)*(l*cos(t)+sin(t)) - l*l/(l*l+1)*exp(-l*t) x.assemble() def evalFunction(self, ts, t, x, xdot, f): l = self.lambda_ f[0] = xdot[0] + l*(x[0] - cos(t)) f.assemble() def evalJacobian(self, ts, t, x, xdot, a, A, B): J = B l = self.lambda_ J[0,0] = a + l J.assemble() if A != B: A.assemble() return True # same nonzero pattern OptDB = PETSc.Options() lambda_ = OptDB.getScalar('lambda', 10.0) ode = CE(lambda_) J = PETSc.Mat().createDense([ode.n,ode.n], comm=ode.comm) J.setUp() x = PETSc.Vec().createSeq(ode.n, comm=ode.comm) f = x.duplicate() ts = PETSc.TS().create(comm=ode.comm) ts.setProblemType(ts.ProblemType.NONLINEAR) ts.setType(ts.Type.GLLE) ts.setIFunction(ode.evalFunction, f) ts.setIJacobian(ode.evalJacobian, J) ts.setTime(0.0) ts.setTimeStep(0.001) ts.setMaxTime(10) ts.setMaxSteps(10000) ts.setExactFinalTime(PETSc.TS.ExactFinalTime.INTERPOLATE) class Monitor(object): def __init__(self, ode): self.ode = ode self.x = PETSc.Vec().createSeq(ode.n, comm=ode.comm) def __call__(self, ts, k, t, x): ode.evalSolution(t, self.x) self.x.axpy(-1, x) e = self.x.norm() h = ts.getTimeStep() PETSc.Sys.Print("step %3d t=%8.2e h=%8.2e error=%8.2e" % (k, t, h, e), comm=self.ode.comm) ts.setMonitor(Monitor(ode)) ts.setFromOptions() ode.evalSolution(0.0, x) ts.solve(x) del ode, J, x, f, ts ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/demo/legacy/ode/heat.py0000644000175000017500000001327014567251135016624 0ustar00balaybalay# Solves Heat equation on a periodic domain, using raw VecScatter from __future__ import division import sys, petsc4py petsc4py.init(sys.argv) from petsc4py import PETSc from mpi4py import MPI import numpy class Heat(object): def __init__(self,comm,N): self.comm = comm self.N = N # global problem size self.h = 1/N # grid spacing on unit interval self.n = N // comm.size + int(comm.rank < (N % comm.size)) # owned part of global problem self.start = comm.exscan(self.n) if comm.rank == 0: self.start = 0 gindices = numpy.arange(self.start-1, self.start+self.n+1, dtype=PETSc.IntType) % N # periodic self.mat = PETSc.Mat().create(comm=comm) size = (self.n, self.N) # local and global sizes self.mat.setSizes((size,size)) self.mat.setFromOptions() self.mat.setPreallocationNNZ((3,1)) # Conservative preallocation for 3 "local" columns and one non-local # Allow matrix insertion using local indices [0:n+2] lgmap = PETSc.LGMap().create(list(gindices), comm=comm) self.mat.setLGMap(lgmap, lgmap) # Global and local vectors self.gvec = self.mat.createVecRight() self.lvec = PETSc.Vec().create(comm=PETSc.COMM_SELF) self.lvec.setSizes(self.n+2) self.lvec.setUp() # Configure scatter from global to local isg = PETSc.IS().createGeneral(list(gindices), comm=comm) self.g2l = PETSc.Scatter().create(self.gvec, isg, self.lvec, None) self.tozero, self.zvec = PETSc.Scatter.toZero(self.gvec) self.history = [] if False: # Print some diagnostics print('[%d] local size %d, global size %d, starting offset %d' % (comm.rank, self.n, self.N, self.start)) self.gvec.setArray(numpy.arange(self.start,self.start+self.n)) self.gvec.view() self.g2l.scatter(self.gvec, self.lvec, PETSc.InsertMode.INSERT) for rank in range(comm.size): if rank == comm.rank: print('Contents of local Vec on rank %d' % rank) self.lvec.view() comm.barrier() def evalSolution(self, t, x): assert t == 0.0, "only for t=0.0" coord = numpy.arange(self.start, self.start+self.n) / self.N x.setArray((numpy.abs(coord-0.5) < 0.1) * 1.0) def evalFunction(self, ts, t, x, xdot, f): self.g2l.scatter(x, self.lvec, PETSc.InsertMode.INSERT) # lvec is a work vector h = self.h with self.lvec as u, xdot as udot: f.setArray(udot*h + 2*u[1:-1]/h - u[:-2]/h - u[2:]/h) # Scale equation by volume element def evalJacobian(self, ts, t, x, xdot, a, A, B): h = self.h for i in range(self.n): lidx = i + 1 gidx = self.start + i B.setValuesLocal([lidx], [lidx-1,lidx,lidx+1], [-1/h, a*h+2/h, -1/h]) B.assemble() if A != B: A.assemble() # If operator is different from preconditioning matrix return True # same nonzero pattern def monitor(self, ts, i, t, x): if self.history: lasti, lastt, lastx = self.history[-1] if i < lasti + 4 or t < lastt + 1e-4: return self.tozero.scatter(x, self.zvec, PETSc.InsertMode.INSERT) xx = self.zvec[:].tolist() self.history.append((i, t, xx)) def plotHistory(self): try: from matplotlib import pylab, rcParams except ImportError: print("matplotlib not available") raise SystemExit rcParams.update({'text.usetex':True, 'figure.figsize':(10,6)}) #rc('figure', figsize=(600,400)) pylab.title('Heat: TS \\texttt{%s}' % ts.getType()) x = numpy.arange(self.N) / self.N for i,t,u in self.history: pylab.plot(x, u, label='step=%d t=%8.2g'%(i,t)) pylab.xlabel('$x$') pylab.ylabel('$u$') pylab.legend(loc='upper right') pylab.savefig('heat-history.png') #pylab.show() OptDB = PETSc.Options() ode = Heat(MPI.COMM_WORLD, OptDB.getInt('n',100)) x = ode.gvec.duplicate() f = ode.gvec.duplicate() ts = PETSc.TS().create(comm=ode.comm) ts.setType(ts.Type.ROSW) # Rosenbrock-W. ARKIMEX is a nonlinearly implicit alternative. ts.setIFunction(ode.evalFunction, ode.gvec) ts.setIJacobian(ode.evalJacobian, ode.mat) ts.setMonitor(ode.monitor) ts.setTime(0.0) ts.setTimeStep(ode.h**2) ts.setMaxTime(1) ts.setMaxSteps(100) ts.setExactFinalTime(PETSc.TS.ExactFinalTime.INTERPOLATE) ts.setMaxSNESFailures(-1) # allow an unlimited number of failures (step will be rejected and retried) snes = ts.getSNES() # Nonlinear solver snes.setTolerances(max_it=10) # Stop nonlinear solve after 10 iterations (TS will retry with shorter step) ksp = snes.getKSP() # Linear solver ksp.setType(ksp.Type.CG) # Conjugate gradients pc = ksp.getPC() # Preconditioner if False: # Configure algebraic multigrid, could use run-time options instead pc.setType(pc.Type.GAMG) # PETSc's native AMG implementation, mostly based on smoothed aggregation OptDB['mg_coarse_pc_type'] = 'svd' # more specific multigrid options OptDB['mg_levels_pc_type'] = 'sor' ts.setFromOptions() # Apply run-time options, e.g. -ts_adapt_monitor -ts_type arkimex -snes_converged_reason ode.evalSolution(0.0, x) ts.solve(x) if ode.comm.rank == 0: print('steps %d (%d rejected, %d SNES fails), nonlinear its %d, linear its %d' % (ts.getStepNumber(), ts.getStepRejections(), ts.getSNESFailures(), ts.getSNESIterations(), ts.getKSPIterations())) if OptDB.getBool('plot_history', True) and ode.comm.rank == 0: ode.plotHistory() ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/demo/legacy/ode/orego.py0000644000175000017500000000727114567251135017022 0ustar00balaybalay# Oregonator: stiff 3-variable oscillatory ODE system from chemical reactions, # problem OREGO in Hairer&Wanner volume 2 # See also http://www.scholarpedia.org/article/Oregonator import sys, petsc4py petsc4py.init(sys.argv) from petsc4py import PETSc class Orego(object): n = 3 comm = PETSc.COMM_SELF def evalSolution(self, t, x): assert t == 0.0, "only for t=0.0" x.setArray([1, 2, 3]) def evalFunction(self, ts, t, x, xdot, f): f.setArray([xdot[0] - 77.27*(x[1] + x[0]*(1 - 8.375e-6*x[0] - x[1])), xdot[1] - 1/77.27*(x[2] - (1 + x[0])*x[1]), xdot[2] - 0.161*(x[0] - x[2])]) def evalJacobian(self, ts, t, x, xdot, a, A, B): B[:,:] = [[a - 77.27*((1 - 8.375e-6*x[0] - x[1]) - 8.375e-6*x[0]), -77.27*(1 - x[0]), 0], [1/77.27*x[1], a + 1/77.27*(1 + x[0]), -1/77.27], [-0.161, 0, a + 0.161]] B.assemble() if A != B: A.assemble() return True # same nonzero pattern OptDB = PETSc.Options() ode = Orego() J = PETSc.Mat().createDense([ode.n, ode.n], comm=ode.comm) J.setUp() x = PETSc.Vec().createSeq(ode.n, comm=ode.comm) f = x.duplicate() ts = PETSc.TS().create(comm=ode.comm) ts.setType(ts.Type.ROSW) # Rosenbrock-W. ARKIMEX is a nonlinearly implicit alternative. ts.setIFunction(ode.evalFunction, f) ts.setIJacobian(ode.evalJacobian, J) history = [] def monitor(ts, i, t, x): xx = x[:].tolist() history.append((i, t, xx)) ts.setMonitor(monitor) ts.setTime(0.0) ts.setTimeStep(0.1) ts.setMaxTime(360) ts.setMaxSteps(2000) ts.setExactFinalTime(PETSc.TS.ExactFinalTime.INTERPOLATE) ts.setMaxSNESFailures(-1) # allow an unlimited number of failures (step will be rejected and retried) # Set a different tolerance on each variable. Can use a scalar or a vector for either or both atol and rtol. vatol = x.duplicate(array=[1e-2, 1e-1, 1e-4]) ts.setTolerances(atol=vatol,rtol=1e-3) # adaptive controller attempts to match this tolerance snes = ts.getSNES() # Nonlinear solver snes.setTolerances(max_it=10) # Stop nonlinear solve after 10 iterations (TS will retry with shorter step) ksp = snes.getKSP() # Linear solver ksp.setType(ksp.Type.PREONLY) # Just use the preconditioner without a Krylov method pc = ksp.getPC() # Preconditioner pc.setType(pc.Type.LU) # Use a direct solve ts.setFromOptions() # Apply run-time options, e.g. -ts_adapt_monitor -ts_type arkimex -snes_converged_reason ode.evalSolution(0.0, x) ts.solve(x) print('steps %d (%d rejected, %d SNES fails), nonlinear its %d, linear its %d' % (ts.getStepNumber(), ts.getStepRejections(), ts.getSNESFailures(), ts.getSNESIterations(), ts.getKSPIterations())) if OptDB.getBool('plot_history', True): try: from matplotlib import pylab from matplotlib import rc except ImportError: print("matplotlib not available") raise SystemExit import numpy as np ii = np.asarray([v[0] for v in history]) tt = np.asarray([v[1] for v in history]) xx = np.asarray([v[2] for v in history]) rc('text', usetex=True) pylab.suptitle('Oregonator: TS \\texttt{%s}' % ts.getType()) pylab.subplot(2,2,1) pylab.subplots_adjust(wspace=0.3) pylab.semilogy(ii[:-1], np.diff(tt), ) pylab.xlabel('step number') pylab.ylabel('timestep') for i in range(0,3): pylab.subplot(2,2,i+2) pylab.semilogy(tt, xx[:,i], "rgb"[i]) pylab.xlabel('time') pylab.ylabel('$x_%d$' % i) # pylab.savefig('orego-history.png') pylab.show() ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/demo/legacy/ode/rober.py0000644000175000017500000000430414567251135017012 0ustar00balaybalay# Stiff 3-variable ODE system from chemical reactions, # due to Robertson (1966), # problem ROBER in Hairer&Wanner, ODE 2, 1996 import sys, petsc4py petsc4py.init(sys.argv) from petsc4py import PETSc class Rober(object): n = 3 comm = PETSc.COMM_SELF def evalSolution(self, t, x): assert t == 0.0, "only for t=0.0" x[:] = [1, 0, 0] x.assemble() def evalFunction(self, ts, t, x, xdot, f): f[:] = [xdot[0] + 0.04*x[0] - 1e4*x[1]*x[2], xdot[1] - 0.04*x[0] + 1e4*x[1]*x[2] + 3e7*x[1]**2, xdot[2] - 3e7*x[1]**2] f.assemble() def evalJacobian(self, ts, t, x, xdot, a, A, B): J = B J[:,:] = [[a + 0.04, -1e4*x[2], -1e4*x[1]], [-0.04, a + 1e4*x[2] + 3e7*2*x[1], 1e4*x[1]], [0, -3e7*2*x[1], a]] J.assemble() if A != B: A.assemble() return True # same nonzero pattern OptDB = PETSc.Options() ode = Rober() J = PETSc.Mat().createDense([ode.n, ode.n], comm=ode.comm) J.setUp() x = PETSc.Vec().createSeq(ode.n, comm=ode.comm) f = x.duplicate() ts = PETSc.TS().create(comm=ode.comm) ts.setProblemType(ts.ProblemType.NONLINEAR) ts.setType(ts.Type.THETA) ts.setIFunction(ode.evalFunction, f) ts.setIJacobian(ode.evalJacobian, J) history = [] def monitor(ts, i, t, x): xx = x[:].tolist() history.append((i, t, xx)) ts.setMonitor(monitor) ts.setTime(0.0) ts.setTimeStep(.001) ts.setMaxTime(1e30) ts.setMaxSteps(100) ts.setExactFinalTime(PETSc.TS.ExactFinalTime.INTERPOLATE) ts.setFromOptions() ode.evalSolution(0.0, x) ts.solve(x) del ode, J, x, ts try: from matplotlib import pylab except ImportError: print("matplotlib not available") raise SystemExit import numpy as np ii = np.asarray([v[0] for v in history]) tt = np.asarray([v[1] for v in history]) xx = np.asarray([v[2] for v in history]) pylab.suptitle('Rober') pylab.subplot(2,2,1) pylab.subplots_adjust(wspace=0.3) pylab.semilogy(ii[:-1], np.diff(tt), ) pylab.xlabel('step number') pylab.ylabel('timestep') for i in range(0,3): pylab.subplot(2,2,i+2) pylab.semilogx(tt, xx[:,i], "rgb"[i]) pylab.xlabel('t') pylab.ylabel('x%d' % i) pylab.show() ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/demo/legacy/ode/vanderpol.py0000644000175000017500000001574514567251135017706 0ustar00balaybalay# Testing TSAdjoint and matrix-free Jacobian # Basic usage: # python vanderpol.py # Test implicit methods using implicit form: # python -implicitform # Test explicit methods: # python -implicitform 0 # Test IMEX methods: # python -imexform # Matrix-free implementations can be enabled with an additional option -mf import sys, petsc4py petsc4py.init(sys.argv) from petsc4py import PETSc class VDP(object): n = 2 comm = PETSc.COMM_SELF def __init__(self, mu_=1.0e3, mf_=False, imex_=False): self.mu_ = mu_ self.mf_ = mf_ self.imex_ = imex_ if self.mf_: self.Jim_ = PETSc.Mat().createDense([self.n,self.n], comm=self.comm) self.Jim_.setUp() self.JimP_ = PETSc.Mat().createDense([self.n,1], comm=self.comm) self.JimP_.setUp() self.Jex_ = PETSc.Mat().createDense([self.n,self.n], comm=self.comm) self.Jex_.setUp() self.JexP_ = PETSc.Mat().createDense([self.n,1], comm=self.comm) self.JexP_.setUp() def initialCondition(self, u): mu = self.mu_ u[0] = 2.0 u[1] = -2.0/3.0 + 10.0/(81.0*mu) - 292.0/(2187.0*mu*mu) u.assemble() def evalFunction(self, ts, t, u, f): mu = self.mu_ f[0] = u[1] if self.imex_: f[1] = 0.0 else: f[1] = mu*((1.-u[0]*u[0])*u[1]-u[0]) f.assemble() def evalJacobian(self, ts, t, u, A, B): if not self.mf_: J = A else : J = self.Jex_ mu = self.mu_ J[0,0] = 0 J[0,1] = 1.0 if self.imex_: J[1,0] = 0 J[1,1] = 0 else: J[1,0] = -mu*(2.0*u[1]*u[0]+1.) J[1,1] = mu*(1.0-u[0]*u[0]) J.assemble() if A != B: B.assemble() return True # same nonzero pattern def evalJacobianP(self, ts, t, u, C): if not self.mf_: Jp = C else: Jp = self.JexP_ if not self.imex_: Jp[0,0] = 0 Jp[1,0] = (1.-u[0]*u[0])*u[1]-u[0] Jp.assemble() return True def evalIFunction(self, ts, t, u, udot, f): mu = self.mu_ if self.imex_: f[0] = udot[0] else: f[0] = udot[0]-u[1] f[1] = udot[1]-mu*((1.-u[0]*u[0])*u[1]-u[0]) f.assemble() def evalIJacobian(self, ts, t, u, udot, shift, A, B): if not self.mf_: J = A else : J = self.Jim_ mu = self.mu_ if self.imex_: J[0,0] = shift J[0,1] = 0.0 else: J[0,0] = shift J[0,1] = -1.0 J[1,0] = mu*(2.0*u[1]*u[0]+1.) J[1,1] = shift-mu*(1.0-u[0]*u[0]) J.assemble() if A != B: B.assemble() return True # same nonzero pattern def evalIJacobianP(self, ts, t, u, udot, shift, C): if not self.mf_: Jp = C else: Jp = self.JimP_ Jp[0,0] = 0 Jp[1,0] = u[0]-(1.-u[0]*u[0])*u[1] Jp.assemble() return True class JacShell: def __init__(self, ode): self.ode_ = ode def mult(self, A, x, y): "y <- A * x" self.ode_.Jex_.mult(x,y) def multTranspose(self, A, x, y): "y <- A' * x" self.ode_.Jex_.multTranspose(x, y) class JacPShell: def __init__(self, ode): self.ode_ = ode def multTranspose(self, A, x, y): "y <- A' * x" self.ode_.JexP_.multTranspose(x, y) class IJacShell: def __init__(self, ode): self.ode_ = ode def mult(self, A, x, y): "y <- A * x" self.ode_.Jim_.mult(x,y) def multTranspose(self, A, x, y): "y <- A' * x" self.ode_.Jim_.multTranspose(x, y) class IJacPShell: def __init__(self, ode): self.ode_ = ode def multTranspose(self, A, x, y): "y <- A' * x" self.ode_.JimP_.multTranspose(x, y) OptDB = PETSc.Options() mu_ = OptDB.getScalar('mu', 1.0e3) mf_ = OptDB.getBool('mf', False) implicitform_ = OptDB.getBool('implicitform', False) imexform_ = OptDB.getBool('imexform', False) ode = VDP(mu_,mf_,imexform_) if not mf_: Jim = PETSc.Mat().createDense([ode.n,ode.n], comm=ode.comm) Jim.setUp() JimP = PETSc.Mat().createDense([ode.n,1], comm=ode.comm) JimP.setUp() Jex = PETSc.Mat().createDense([ode.n,ode.n], comm=ode.comm) Jex.setUp() JexP = PETSc.Mat().createDense([ode.n,1], comm=ode.comm) JexP.setUp() else: Jim = PETSc.Mat().create() Jim.setSizes([ode.n,ode.n]) Jim.setType('python') shell = IJacShell(ode) Jim.setPythonContext(shell) Jim.setUp() Jim.assemble() JimP = PETSc.Mat().create() JimP.setSizes([ode.n,1]) JimP.setType('python') shell = IJacPShell(ode) JimP.setPythonContext(shell) JimP.setUp() JimP.assemble() Jex = PETSc.Mat().create() Jex.setSizes([ode.n,ode.n]) Jex.setType('python') shell = JacShell(ode) Jex.setPythonContext(shell) Jex.setUp() Jex.assemble() JexP = PETSc.Mat().create() JexP.setSizes([ode.n,1]) JexP.setType('python') shell = JacPShell(ode) JexP.setPythonContext(shell) JexP.setUp() JexP.zeroEntries() JexP.assemble() u = PETSc.Vec().createSeq(ode.n, comm=ode.comm) f = u.duplicate() adj_u = [] adj_u.append(PETSc.Vec().createSeq(ode.n, comm=ode.comm)) adj_u.append(PETSc.Vec().createSeq(ode.n, comm=ode.comm)) adj_p = [] adj_p.append(PETSc.Vec().createSeq(1, comm=ode.comm)) adj_p.append(PETSc.Vec().createSeq(1, comm=ode.comm)) ts = PETSc.TS().create(comm=ode.comm) ts.setProblemType(ts.ProblemType.NONLINEAR) if imexform_: ts.setType(ts.Type.ARKIMEX) ts.setIFunction(ode.evalIFunction, f) ts.setIJacobian(ode.evalIJacobian, Jim) ts.setIJacobianP(ode.evalIJacobianP, JimP) ts.setRHSFunction(ode.evalFunction, f) ts.setRHSJacobian(ode.evalJacobian, Jex) ts.setRHSJacobianP(ode.evalJacobianP, JexP) else: if implicitform_: ts.setType(ts.Type.CN) ts.setIFunction(ode.evalIFunction, f) ts.setIJacobian(ode.evalIJacobian, Jim) ts.setIJacobianP(ode.evalIJacobianP, JimP) else: ts.setType(ts.Type.RK) ts.setRHSFunction(ode.evalFunction, f) ts.setRHSJacobian(ode.evalJacobian, Jex) ts.setRHSJacobianP(ode.evalJacobianP, JexP) ts.setSaveTrajectory() ts.setTime(0.0) ts.setTimeStep(0.001) ts.setMaxTime(0.5) ts.setMaxSteps(1000) ts.setExactFinalTime(PETSc.TS.ExactFinalTime.MATCHSTEP) ts.setFromOptions() ode.initialCondition(u) ts.solve(u) adj_u[0][0] = 1 adj_u[0][1] = 0 adj_u[0].assemble() adj_u[1][0] = 0 adj_u[1][1] = 1 adj_u[1].assemble() adj_p[0][0] = 0 adj_p[0].assemble() adj_p[1][0] = 0 adj_p[1].assemble() ts.setCostGradients(adj_u,adj_p) ts.adjointSolve() adj_u[0].view() adj_u[1].view() adj_p[0].view() adj_p[1].view() def compute_derp(du,dp): print(du[1]*(-10.0/(81.0*mu_*mu_)+2.0*292.0/(2187.0*mu_*mu_*mu_))+dp[0]) compute_derp(adj_u[0],adj_p[0]) compute_derp(adj_u[1],adj_p[1]) del ode, Jim, JimP, Jex, JexP, u, f, ts, adj_u, adj_p ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1709010084.3813753 petsc4py-3.20.5/demo/legacy/perftest/0000755000175000017500000000000014567266244016422 5ustar00balaybalay././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/demo/legacy/perftest/App.f900000644000175000017500000000573114567251135017461 0ustar00balaybalaysubroutine formFunction_C(nx, ny, nz, h, t, x, xdot, f) & bind(C, name="formFunction") use ISO_C_BINDING, only: C_INT, C_DOUBLE implicit none integer(kind=C_INT), intent(in) :: nx, ny, nz real(kind=C_DOUBLE), intent(in) :: h(3), t real(kind=C_DOUBLE), intent(in) :: x(nx,ny,nz), xdot(nx,ny,nz) real(kind=C_DOUBLE), intent(inout) :: f(nx,ny,nz) call formfunction_f(nx, ny, nz, h, t, x, xdot, f) end subroutine formFunction_C subroutine formInitial_C(nx, ny, nz, h, t, x) & bind(C, name="formInitial") use ISO_C_BINDING, only: C_INT, C_DOUBLE implicit none integer(kind=C_INT), intent(in) :: nx, ny, nz real(kind=C_DOUBLE), intent(in) :: h(3), t real(kind=C_DOUBLE), intent(inout) :: x(nx,ny,nz) call forminitial_f(nx, ny, nz, h, t, x) end subroutine formInitial_C subroutine evalK (P, K) real(kind=8), intent(in) :: P real(kind=8), intent(out) :: K if (P >= 0.0) then K = 1.0 else K = 1.0/(1+P**2) end if end subroutine evalK subroutine fillK (P, K) real(kind=8), intent(in) :: P(-1:1) real(kind=8), intent(out) :: K(-1:1) real(kind=8) Ka, Kb call evalK((P(-1)+P( 0))/2.0, Ka) call evalK((P( 0)+P( 1))/2.0, Kb) K(-1) = -Ka K( 0) = Ka + Kb K(+1) = -Kb end subroutine fillK subroutine forminitial_f(nx, ny, nz, h, t, x) implicit none integer, intent(in) :: nx, ny, nz real(kind=8), intent(in) :: h(3), t real(kind=8), intent(inout) :: x(nx,ny,nz) ! x(:,:,:) = 0.0 end subroutine forminitial_f subroutine formfunction_f(nx, ny, nz, h, t, x, xdot, f) implicit none integer, intent(in) :: nx, ny, nz real(kind=8), intent(in) :: h(3), t real(kind=8), intent(in) :: x(nx,ny,nz), xdot(nx,ny,nz) real(kind=8), intent(inout) :: f(nx,ny,nz) ! integer :: i,j,k,ii(-1:1),jj(-1:1),kk(-1:1) real(kind=8) :: K1(-1:1), K2(-1:1), K3(-1:1) real(kind=8) :: P1(-1:1), P2(-1:1), P3(-1:1) ! do k=1,nz do j=1,ny do i=1,nx ! ii = (/i-1, i, i+1/) if (i == 1) then ii(-1) = i else if (i == nx) then ii(+1) = i endif ! jj = (/j-1, j, j+1/) if (j == 1) then jj(-1) = j else if (j == ny) then jj(+1) = j end if ! kk = (/k-1, k, k+1/) if (k == 1) then kk(-1) = k else if (k == nz) then kk(+1) = k end if ! P1 = x(ii,j,k) P2 = x(i,jj,k) P3 = x(i,j,kk) call fillK(P1,K1) call fillK(P2,K2) call fillK(P3,K3) f(i,j,k) = & xdot(i,j,k) + & sum(K1*P1)/h(1)**2 + & sum(K2*P2)/h(2)**2 + & sum(K3*P3)/h(3)**2 ! end do !i end do !j end do !k ! i = nx/4+1 j = ny/4+1 k = nz/2+1 f(i,j,k:nz) = f(i,j,k:nz) + 300.0 ! end subroutine formfunction_f ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/demo/legacy/perftest/App.pyf0000644000175000017500000000156514567251135017662 0ustar00balaybalay! -*- f90 -*- python module App interface subroutine formFunction(nx, ny, nz, h, t, x, xdot, f) intent(c) formFunction integer, intent(in), intent(hide) :: nx = shape(x,0) integer, intent(in), intent(hide) :: ny = shape(x,1) integer, intent(in), intent(hide) :: nz = shape(x,2) real(kind=8), intent(in) :: h(3), t real(kind=8), intent(in) :: x(nx,ny,nz), xdot(nx,ny,nz) real(kind=8), intent(inout) :: f(nx,ny,nz) end subroutine formFunction subroutine formInitial(nx, ny, nz, h, t, x) intent(c) formInitial integer, intent(in), intent(hide) :: nx = shape(x,0) integer, intent(in), intent(hide) :: ny = shape(x,1) integer, intent(in), intent(hide) :: nz = shape(x,2) real(kind=8), intent(in) :: h(3), t real(kind=8), intent(inout) :: x(nx,ny,nz) end subroutine formFunction end python module App ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/demo/legacy/perftest/driver.c0000644000175000017500000000703514567251135020057 0ustar00balaybalay#include EXTERN_C_BEGIN extern void formInitial(int*,int*,int*,double*, double*,double*); extern void formFunction(const int*,const int*,const int*,const double*, const double*,const double[],const double[],double[]); EXTERN_C_END typedef struct AppCtx { PetscInt nx,ny,nz; PetscScalar h[3]; } AppCtx; PetscErrorCode FormInitial(PetscReal t, Vec X, void *ctx) { PetscScalar *x; AppCtx *app = (AppCtx*) ctx; PetscFunctionBegin; PetscCall(VecGetArray(X,&x)); /**/ formInitial(&app->nx,&app->ny,&app->nz,app->h,&t,x); /**/ PetscCall(VecRestoreArray(X,&x)); PetscFunctionReturn(PETSC_SUCCESS); } PetscErrorCode FormFunction(TS ts, PetscReal t, Vec X, Vec Xdot,Vec F, void *ctx) { const PetscScalar *x; const PetscScalar *xdot; PetscScalar *f; AppCtx *app = (AppCtx*) ctx; PetscFunctionBegin; PetscCall(VecGetArrayRead(X,&x)); PetscCall(VecGetArrayRead(Xdot,&xdot)); PetscCall(VecGetArray(F,&f)); /**/ formFunction(&app->nx,&app->ny,&app->nz,app->h,&t,x,xdot,f); /**/ PetscCall(VecRestoreArrayRead(X,&x)); PetscCall(VecRestoreArrayRead(Xdot,&xdot)); PetscCall(VecRestoreArray(F,&f)); PetscFunctionReturn(PETSC_SUCCESS); } PetscErrorCode RunTest(int nx, int ny, int nz, int loops, double *wt) { Vec x,f; TS ts; AppCtx _app,*app=&_app; double t1,t2; PetscFunctionBegin; app->nx = nx; app->h[0] = 1./(nx-1); app->ny = ny; app->h[1] = 1./(ny-1); app->nz = nz; app->h[2] = 1./(nz-1); PetscCall(VecCreate(PETSC_COMM_SELF,&x)); PetscCall(VecSetSizes(x,nx*ny*nz,nx*ny*nz)); PetscCall(VecSetUp(x)); PetscCall(VecDuplicate(x,&f)); PetscCall(TSCreate(PETSC_COMM_SELF,&ts)); PetscCall(TSSetProblemType(ts,TS_NONLINEAR)); PetscCall(TSSetType(ts,TSTHETA)); PetscCall(TSThetaSetTheta(ts,1.0)); PetscCall(TSSetTimeStep(ts,0.01)); PetscCall(TSSetTime(ts,0.0)); PetscCall(TSSetMaxTime(ts,1.0)); PetscCall(TSSetMaxSteps(ts,10)); PetscCall(TSSetExactFinalTime(ts,TS_EXACTFINALTIME_STEPOVER)); PetscCall(TSSetSolution(ts,x)); PetscCall(TSSetIFunction(ts,f,FormFunction,app)); PetscCall(PetscOptionsSetValue(NULL,"-snes_mf","1")); { SNES snes; KSP ksp; PetscCall(TSGetSNES(ts,&snes)); PetscCall(SNESGetKSP(snes,&ksp)); PetscCall(KSPSetType(ksp,KSPCG)); } PetscCall(TSSetFromOptions(ts)); PetscCall(TSSetUp(ts)); *wt = 1e300; while (loops-- > 0) { PetscCall(FormInitial(0.0,x,app)); PetscCall(PetscTime(&t1)); PetscCall(TSSolve(ts,x)); PetscCall(PetscTime(&t2)); *wt = PetscMin(*wt,t2-t1); } PetscCall(VecDestroy(&x)); PetscCall(VecDestroy(&f)); PetscCall(TSDestroy(&ts)); PetscFunctionReturn(PETSC_SUCCESS); } PetscErrorCode GetInt(const char* name, PetscInt *v, PetscInt defv) { PetscFunctionBegin; *v = defv; PetscCall(PetscOptionsGetInt(NULL,NULL,name,v,NULL)); PetscFunctionReturn(PETSC_SUCCESS); } int main(int argc, char *argv[]) { double wt; PetscInt n,start,step,stop,samples; PetscCall(PetscInitialize(&argc,&argv,NULL,NULL)); PetscCall(GetInt("-start", &start, 12)); PetscCall(GetInt("-step", &step, 4)); PetscCall(GetInt("-stop", &stop, start)); PetscCall(GetInt("-samples", &samples, 1)); for (n=start; n<=stop; n+=step) { int nx=n+1, ny=n+1, nz=n+1; PetscCall(RunTest(nx,ny,nz,samples,&wt)); PetscCall(PetscPrintf(PETSC_COMM_SELF,"Grid %3d x %3d x %3d -> %f seconds (%2d samples)\n",nx,ny,nz,wt,samples)); } PetscCall(PetscFinalize()); return 0; } ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/demo/legacy/perftest/driver.py0000644000175000017500000000672014567251135020265 0ustar00balaybalay#!/usr/bin/env python import sys, petsc4py petsc4py.init(sys.argv) from petsc4py import PETSc import numpy as np try: from matplotlib import pylab except ImportError: pylab = None # this user class is an application # context for the nonlinear problem # at hand; it contains some parameters # and knows how to compute residuals class AppCtx: def __init__(self, nx, ny, nz): self.n = np.array([nx, ny, nz], dtype='i') self.h = np.array([1.0/(n-1) for n in self.n], dtype='d') from App import formFunction from App import formInitial self._formFunction = formFunction self._formInitial = formInitial def formInitial(self, t, X): xx = X.getArray(readonly=0).reshape(self.n, order='f') self._formInitial(self.h, t, xx) def formFunction(self, ts, t, X, Xdot, F): n = self.n h = self.h x = X.getArray(readonly=1).reshape(n, order='f') xdot = Xdot.getArray(readonly=1).reshape(n, order='f') f = F[...].reshape(n, order='f') self._formFunction(h, t, x, xdot, f) def plot(self, t, x): nx, ny, nz = self.n from numpy import mgrid # U = x.getArray(readonly=1).reshape(nx,ny,nz, order='f') # X, Y = mgrid[0:1:1j*nx,0:1:1j*ny] Z = U[:,:,nz//2] pylab.figure(0) pylab.contourf(X,Y,Z) pylab.colorbar() pylab.plot(X.ravel(),Y.ravel(),'.k') pylab.title('z=0.50') pylab.xlabel('x') pylab.ylabel('y') pylab.axis('equal') # X, Y = mgrid[0:1:1j*nx,0:1:1j*nz] Z = U[:,ny//4,:] pylab.figure(1) pylab.contourf(X,Y,Z) pylab.colorbar() pylab.plot(X.ravel(),Y.ravel(),'.k') pylab.title('y=0.25') pylab.xlabel('x') pylab.ylabel('z') pylab.axis('equal') # X, Y = mgrid[0:1:1j*ny,0:1:1j*nz] Z = U[nx//2,:,:] pylab.figure(2) pylab.contourf(X,Y,Z) pylab.colorbar() pylab.plot(X.ravel(),Y.ravel(),'.k') pylab.title('x=0.50') pylab.xlabel('y') pylab.ylabel('z') pylab.axis('equal') def run_test(nx,ny,nz,samples,plot=False): ts = PETSc.TS().create() ts.setType('theta') ts.setTheta(1.0) ts.setTimeStep(0.01) ts.setTime(0.0) ts.setMaxTime(1.0) ts.setMaxSteps(10) eft = PETSc.TS.ExactFinalTime.STEPOVER ts.setExactFinalTime(eft) x = PETSc.Vec().createSeq(nx*ny*nz) ts.setSolution(x) app = AppCtx(nx, ny, nz) f = PETSc.Vec().createSeq(nx*ny*nz) ts.setIFunction(app.formFunction, f) ts.snes.setUseMF(1) ts.snes.ksp.setType('cg') ts.setFromOptions() ts.setUp() wt = 1e300 for i in range(samples): app.formInitial(0, x) t1 = PETSc.Log.getTime() ts.solve(x) t2 = PETSc.Log.getTime() wt = min(wt,t2-t1) if plot and pylab: app.plot(ts.time, x) return wt OptDB = PETSc.Options() start = OptDB.getInt('start', 12) step = OptDB.getInt('step', 4) stop = OptDB.getInt('stop', start) samples = OptDB.getInt('samples', 1) plot = OptDB.getBool('plot', False) if plot and not pylab: PETSc.Sys.Print("matplotlib not available") for n in range(start, stop+step, step): nx = ny = nz = n+1 wt = run_test(nx,ny,nz,samples,plot) PETSc.Sys.Print("Grid %3d x %3d x %3d -> %f seconds (%2d samples)" % (nx,ny,nz,wt,samples)) if plot and pylab: pylab.show() ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/demo/legacy/perftest/makefile0000644000175000017500000000114214567251135020111 0ustar00balaybalay# -*- makefile -*- MPIEXEC= PYTHON=python -include ../../../../../petscdir.mk -include ${PETSC_DIR}/lib/petsc/conf/variables .PHONY:test test: run clean .PHONY:run run: run_py run_cc SCRIPT=driver MODULE=App .PHONY:run_py run_py: ${MODULE}.so ${MPIEXEC} ${PYTHON} ${SCRIPT}.py EXECUTABLE=driver .PHONY:run_cc run_cc: ${EXECUTABLE}.exe ${MPIEXEC} ./${EXECUTABLE}.exe ${MODULE}.so: ${MAKE} -f makefile.f2py ${EXECUTABLE}.exe: ${MAKE} -f makefile.petsc \ PETSC_DIR=${PETSC_DIR} PETSC_ARCH=${PETSC_ARCH} .PHONY:clean clean: ${RM} -r __pycache__ *.py[co] ${RM} ${MODULE}.so ${EXECUTABLE}.exe ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/demo/legacy/perftest/makefile.f2py0000644000175000017500000000047414567251135020777 0ustar00balaybalay-include ../../../../../petscdir.mk.f2py # -*- makefile -*- MODULE=App .PHONY:all all: ${MODULE}.so F2PY = f2py F2PY_FLAGS = --quiet F2PY_FLAGS += --noarch --f90flags='' F2PY_FLAGS += -DF2PY_REPORT_ON_ARRAY_COPY=1 ${MODULE}.so: ${MODULE}.pyf ${MODULE}.f90 ${F2PY} ${F2PY_FLAGS} -m ${MODULE} -c $< ${MODULE}.f90 ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/demo/legacy/perftest/makefile.petsc0000644000175000017500000000116314567251135021231 0ustar00balaybalay# -*- makefile -*- EXECUTABLE=driver -include ../../../../../petscdir.mk -include ${PETSC_DIR}/lib/petsc/conf/variables .PHONY:all all: ${EXECUTABLE}.exe SOURCEC=${EXECUTABLE}.c SOURCEF=App.f90 OBJSC=${SOURCEC:.c=.o} OBJSF=${SOURCEF:.f90=.o} ${EXECUTABLE}.exe: ${SOURCEC} ${SOURCEF} ${FC} -o ${OBJSF} ${SOURCEF} -c ${FC_FLAGS} ${FFLAGS} ${CC} -o ${OBJSC} ${SOURCEC} -c ${CC_FLAGS} ${CFLAGS} ${CCPPFLAGS} ${CLINKER} -o $@ ${OBJSC} ${OBJSF} ${PETSC_TS_LIB} ${RM} ${OBJSC} ${OBJSF} include ${PETSC_DIR}/lib/petsc/conf/variables include ${PETSC_DIR}/lib/petsc/conf/rules OBJSC=${SOURCEC:.c=.o} OBJSF=${SOURCEF:.f90=.o} ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1709010084.3823752 petsc4py-3.20.5/demo/legacy/petsc-examples/0000755000175000017500000000000014567266244017520 5ustar00balaybalay././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1709010084.3823752 petsc4py-3.20.5/demo/legacy/petsc-examples/ksp/0000755000175000017500000000000014567266244020315 5ustar00balaybalay././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/demo/legacy/petsc-examples/ksp/ex2.py0000644000175000017500000001465314567251135021367 0ustar00balaybalay ''' Ex2 from PETSc example files implemented for PETSc4py. https://petsc.org/release/src/ksp/ksp/tutorials/ex2.c.html By: Miguel Arriaga Solves a linear system in parallel with KSP. Input parameters include: -view_exact_sol : write exact solution vector to stdout -m : number of mesh points in x-direction -n : number of mesh points in y-direction Vec x,b,u; # approx solution, RHS, exact solution Mat A; # linear system matrix KSP ksp; # linear solver context PetscReal norm; # norm of solution error ''' import sys import petsc4py petsc4py.init(sys.argv) from petsc4py import PETSc import numpy as np comm = PETSc.COMM_WORLD size = comm.getSize() rank = comm.getRank() OptDB = PETSc.Options() m = OptDB.getInt('m', 8) n = OptDB.getInt('n', 7) ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Compute the matrix and right-hand-side vector that define the linear system, Ax = b. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ''' ''' Create parallel matrix, specifying only its global dimensions. When using MatCreate(), the matrix format can be specified at runtime. Also, the parallel partitioning of the matrix is determined by PETSc at runtime. Performance tuning note: For problems of substantial size, preallocation of matrix memory is crucial for attaining good performance. See the matrix chapter of the users manual for details. ''' A = PETSc.Mat().create(comm=comm) A.setSizes((m*n,m*n)) A.setFromOptions() A.setPreallocationNNZ((5,5)) ''' Currently, all PETSc parallel matrix formats are partitioned by contiguous chunks of rows across the processors. Determine which rows of the matrix are locally owned. ''' Istart,Iend = A.getOwnershipRange() ''' Set matrix elements for the 2-D, five-point stencil in parallel. - Each processor needs to insert only elements that it owns locally (but any non-local elements will be sent to the appropriate processor during matrix assembly). - Always specify global rows and columns of matrix entries. Note: this uses the less common natural ordering that orders first all the unknowns for x = h then for x = 2h etc; Hence you see J = Ii +- n instead of J = I +- m as you might expect. The more standard ordering would first do all variables for y = h, then y = 2h etc. ''' for Ii in range(Istart,Iend): v = -1.0 i = int(Ii/n) j = int(Ii - i*n) if (i>0): J = Ii - n A.setValues(Ii,J,v,addv=True) if (i0): J = Ii - 1 A.setValues(Ii,J,v,addv=True) if (j -pc_type -ksp_monitor -ksp_rtol These options will override those specified above as long as KSPSetFromOptions() is called _after_ any other customization routines. ''' ksp.setFromOptions() ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Solve the linear system - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ''' ksp.solve(b,x) ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Check the solution and clean up - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ''' x = x - u # x.axpy(-1.0,u) norm = x.norm(PETSc.NormType.NORM_2) its = ksp.getIterationNumber() ''' Print convergence information. PetscPrintf() produces a single print statement from all processes that share a communicator. An alternative is PetscFPrintf(), which prints to a file. ''' if norm > rtol*10: PETSc.Sys.Print("Norm of error {}, Iterations {}".format(norm,its),comm=comm) else: if size==1: PETSc.Sys.Print("- Serial OK",comm=comm) else: PETSc.Sys.Print("- Parallel OK",comm=comm) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/demo/legacy/petsc-examples/ksp/ex23.py0000644000175000017500000001174714567251135021453 0ustar00balaybalay ''' Ex23 from PETSc example files implemented for PETSc4py. https://petsc.org/release/src/ksp/ksp/tutorials/ex23.c.html By: Miguel Arriaga Solves a tridiagonal linear system. Vec x, b, u; approx solution, RHS, exact solution Mat A; linear system matrix KSP ksp; linear solver context PC pc; preconditioner context PetscReal norm; norm of solution error ''' import sys import petsc4py petsc4py.init(sys.argv) from petsc4py import PETSc import numpy as np comm = PETSc.COMM_WORLD size = comm.getSize() rank = comm.getRank() n = 12 # Size of problem tol = 1E-11 # Tolerance of Result. tol=1000.*PETSC_MACHINE_EPSILON; ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Compute the matrix and right-hand-side vector that define the linear system, Ax = b. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Create vectors. Note that we form 1 vector from scratch and then duplicate as needed. For this simple case let PETSc decide how many elements of the vector are stored on each processor. The second argument to VecSetSizes() below causes PETSc to decide. ''' x = PETSc.Vec().create(comm=comm) x.setSizes(n) x.setFromOptions() b = x.duplicate() u = x.duplicate() ''' Identify the starting and ending mesh points on each processor for the interior part of the mesh. We let PETSc decide above. ''' rstart,rend = x.getOwnershipRange() nlocal = x.getLocalSize() ''' Create matrix. When using MatCreate(), the matrix format can be specified at runtime. Performance tuning note: For problems of substantial size, preallocation of matrix memory is crucial for attaining good performance. See the matrix chapter of the users manual for details. We pass in nlocal as the "local" size of the matrix to force it to have the same parallel layout as the vector created above. ''' A = PETSc.Mat().create(comm=comm) A.setSizes(n,nlocal) A.setFromOptions() A.setUp() ''' Assemble matrix. The linear system is distributed across the processors by chunks of contiguous rows, which correspond to contiguous sections of the mesh on which the problem is discretized. For matrix assembly, each processor contributes entries for the part that it owns locally. ''' col = np.zeros(3,dtype=PETSc.IntType) value = np.zeros(3,dtype=PETSc.ScalarType) if not rstart: rstart = 1 i = 0; col[0] = 0; col[1] = 1; value[0] = 2.0; value[1] = -1.0 A.setValues(i,col[0:2],value[0:2]) if rend == n: rend = n-1 i = n-1; col[0] = n-2; col[1] = n-1; value[0] = -1.0; value[1] = 2.0 A.setValues(i,col[0:2],value[0:2]) ''' Set entries corresponding to the mesh interior ''' value[0] = -1.0; value[1] = 2.0; value[2] = -1.0 for i in range(rstart,rend): col[0] = i-1; col[1] = i; col[2] = i+1 A.setValues(i,col,value) ''' Assemble the matrix ''' A.assemblyBegin(A.AssemblyType.FINAL) A.assemblyEnd(A.AssemblyType.FINAL) ''' Set exact solution; then compute right-hand-side vector. ''' u.set(1.0) b = A(u) ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Create the linear solver and set various options - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ''' ''' Create linear solver context ''' ksp = PETSc.KSP().create() ''' Set operators. Here the matrix that defines the linear system also serves as the preconditioning matrix. ''' ksp.setOperators(A,A) ''' Set linear solver defaults for this problem (optional). - By extracting the KSP and PC contexts from the KSP context, we can then directly call any KSP and PC routines to set various options. - The following four statements are optional; all of these parameters could alternatively be specified at runtime via KSPSetFromOptions(); ''' pc = ksp.getPC() pc.setType('jacobi') ksp.setTolerances(rtol=1.e-7) ''' Set runtime options, e.g., -ksp_type -pc_type -ksp_monitor -ksp_rtol These options will override those specified above as long as KSPSetFromOptions() is called _after_ any other customization routines. ''' ksp.setFromOptions() ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Solve the linear system - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ''' ''' Solve linear system ''' ksp.solve(b,x) ''' View solver info; we could instead use the option -ksp_view to print this info to the screen at the conclusion of KSPSolve(). ''' # ksp.view() ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Check solution and clean up - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ''' ''' Check the error ''' x = x - u # x.axpy(-1.0,u) norm = x.norm(PETSc.NormType.NORM_2) its = ksp.getIterationNumber() if norm > tol: PETSc.Sys.Print("Norm of error {}, Iterations {}\n".format(norm,its),comm=comm) else: if size==1: PETSc.Sys.Print("- Serial OK",comm=comm) else: PETSc.Sys.Print("- Parallel OK",comm=comm) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/demo/legacy/petsc-examples/ksp/makefile0000644000175000017500000000035614567251135022012 0ustar00balaybalay# -*- makefile -*- MPIEXEC=mpiexec -n 2 PYTHON=python3 -include ../../../../../../petscdir.mk -include ${PETSC_DIR}/lib/petsc/conf/variables scripts = ex2 ex23 all: $(scripts) $(scripts): ${PYTHON} $@.py ${MPIEXEC} ${PYTHON} $@.py ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/demo/legacy/petsc-examples/makefile0000644000175000017500000000010414567251135021204 0ustar00balaybalay-include ../../../../../petscdir.mk .PHONY:all all: ${MAKE} -C ksp ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1709010084.3833752 petsc4py-3.20.5/demo/legacy/poisson2d/0000755000175000017500000000000014567266244016506 5ustar00balaybalay././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/demo/legacy/poisson2d/makefile0000644000175000017500000000043114567251135020175 0ustar00balaybalay# -*- makefile -*- MPIEXEC= PYTHON=python -include ../../../../../petscdir.mk -include ${PETSC_DIR}/lib/petsc/conf/variables .PHONY:test test: run clean .PHONY:run run: ${MPIEXEC} ${PYTHON} poisson2d.py -nx 15 -ny 16 .PHONY:clean clean: ${RM} *.py[co] ${RM} -r __pycache__ ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/demo/legacy/poisson2d/poisson2d.py0000644000175000017500000000520314567251135020771 0ustar00balaybalay# ------------------------------------------------------------------------ # # Poisson problem. This problem is modeled by the partial # differential equation # # -Laplacian(u) = 1, 0 < x,y < 1, # # with boundary conditions # # u = 0 for x = 0, x = 1, y = 0, y = 1 # # A finite difference approximation with the usual 7-point stencil # is used to discretize the boundary value problem to obtain a # nonlinear system of equations. The problem is solved in a 2D # rectangular domain, using distributed arrays (DAs) to partition # the parallel grid. # # ------------------------------------------------------------------------ try: range = xrange except: pass import sys, petsc4py petsc4py.init(sys.argv) from petsc4py import PETSc class Poisson2D(object): def __init__(self, da): assert da.getDim() == 2 self.da = da self.localX = da.createLocalVec() def formRHS(self, B): b = self.da.getVecArray(B) mx, my = self.da.getSizes() hx, hy = [1.0/m for m in [mx, my]] (xs, xe), (ys, ye) = self.da.getRanges() for j in range(ys, ye): for i in range(xs, xe): b[i, j] = 1*hx*hy def mult(self, mat, X, Y): # self.da.globalToLocal(X, self.localX) x = self.da.getVecArray(self.localX) y = self.da.getVecArray(Y) # mx, my = self.da.getSizes() hx, hy = [1.0/m for m in [mx, my]] (xs, xe), (ys, ye) = self.da.getRanges() for j in range(ys, ye): for i in range(xs, xe): u = x[i, j] # center u_e = u_w = u_n = u_s = 0 if i > 0: u_w = x[i-1, j] # west if i < mx-1: u_e = x[i+1, j] # east if j > 0: u_s = x[i, j-1] # south if j < ny-1: u_n = x[i, j+1] # north u_xx = (-u_e + 2*u - u_w)*hy/hx u_yy = (-u_n + 2*u - u_s)*hx/hy y[i, j] = u_xx + u_yy OptDB = PETSc.Options() n = OptDB.getInt('n', 16) nx = OptDB.getInt('nx', n) ny = OptDB.getInt('ny', n) da = PETSc.DMDA().create([nx, ny], stencil_width=1) pde = Poisson2D(da) x = da.createGlobalVec() b = da.createGlobalVec() # A = da.createMat('python') A = PETSc.Mat().createPython( [x.getSizes(), b.getSizes()], comm=da.comm) A.setPythonContext(pde) A.setUp() ksp = PETSc.KSP().create() ksp.setOperators(A) ksp.setType('cg') pc = ksp.getPC() pc.setType('none') ksp.setFromOptions() pde.formRHS(b) ksp.solve(b, x) u = da.createNaturalVec() da.globalToNatural(x, u) if OptDB.getBool('plot', True): draw = PETSc.Viewer.DRAW(x.comm) OptDB['draw_pause'] = 1 draw(x) ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1709010084.3843753 petsc4py-3.20.5/demo/legacy/poisson3d/0000755000175000017500000000000014567266244016507 5ustar00balaybalay././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/demo/legacy/poisson3d/del2lib.f900000644000175000017500000000120214567251135020330 0ustar00balaybalay! file: del2lib.f90 ! to build a Python module, use this: ! $$ f2py -m del2lib -c del2lib.f90 subroutine del2apply (n, F, x, y) !f2py intent(hide) :: n=shape(F,0)-2 integer , intent(in) :: n real(kind=8) , intent(inout) :: F(0:n+1,0:n+1,0:n+1) real(kind=8) , intent(in) :: x(n,n,n) real(kind=8) , intent(inout) :: y(n,n,n) F(1:n,1:n,1:n) = x y(:,:,:) = 6.0 * F(1:n,1:n,1:n) & - F(0:n-1,1:n,1:n) & - F(2:n+1,1:n,1:n) & - F(1:n,0:n-1,1:n) & - F(1:n,2:n+1,1:n) & - F(1:n,1:n,0:n-1) & - F(1:n,1:n,2:n+1) end subroutine del2apply ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/demo/legacy/poisson3d/del2mat.h0000644000175000017500000000211214567251135020175 0ustar00balaybalay/* file: del2mat.h */ #ifndef DEL2MAT_H #define DEL2MAT_H #include #include #include /* external Fortran 90 subroutine */ #define Del2Apply del2apply_ EXTERN_C_BEGIN extern void Del2Apply(int*,double*,const double*,double*); EXTERN_C_END /* user data structure and routines * defining the matrix-free operator */ typedef struct { PetscInt N; PetscScalar *F; } Del2Mat; /* y <- A * x */ PetscErrorCode Del2Mat_mult(Mat A, Vec x, Vec y) { Del2Mat *ctx; const PetscScalar *xx; PetscScalar *yy; PetscFunctionBegin; PetscCall(MatShellGetContext(A,&ctx)); /* get raw vector arrays */ PetscCall(VecGetArrayRead(x,&xx)); PetscCall(VecGetArray(y,&yy)); /* call external Fortran subroutine */ Del2Apply(&ctx->N,ctx->F,xx,yy); /* restore raw vector arrays */ PetscCall(VecRestoreArrayRead(x,&xx)); PetscCall(VecRestoreArray(y,&yy)); PetscFunctionReturn(PETSC_SUCCESS); } /*D_i <- A_ii */ PetscErrorCode Del2Mat_diag(Mat A, Vec D) { PetscFunctionBegin; PetscCall(VecSet(D,6.0)); PetscFunctionReturn(PETSC_SUCCESS); } #endif ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/demo/legacy/poisson3d/del2mat.py0000644000175000017500000000150714567251135020405 0ustar00balaybalay# file: del2mat.py from numpy import zeros from del2lib import del2apply class Del2Mat: def __init__(self, n=1): self.N = (n, n, n) self.F = zeros([n+2]*3, order='f') def create(self, A): N = self.N mat_size = A.getSize() grid_eqs = N[0]*N[1]*N[2] assert mat_size[0] == grid_eqs assert mat_size[1] == grid_eqs def mult(self, A, x, y): "y <- A * x" N, F = self.N, self.F # get 3D arrays from vectos xx = x.getArray(readonly=1).reshape(N, order='f') yy = y.getArray(readonly=0).reshape(N, order='f') # call Fortran subroutine del2apply(F, xx, yy) def multTranspose(self, A, x, y): "y <- A' * x" self.mult(x, y) def getDiagonal(self, A, D): "D[i] <- A[i,i]" D[...] = 6.0 ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/demo/legacy/poisson3d/makefile0000644000175000017500000000137714567251135020210 0ustar00balaybalay# -*- makefile -*- MPIEXEC= PYTHON=python F2PY = f2py F2PY_FLAGS = --quiet F2PY_FLAGS += --noarch --f90flags='' F2PY_FLAGS += -DF2PY_REPORT_ON_ARRAY_COPY=1 -include ../../../../../petscdir.mk -include ${PETSC_DIR}/lib/petsc/conf/variables .PHONY:test test: run clean .PHONY:run run: run_py run_cc SCRIPT=poisson3d MODULE=del2lib .PHONY:run_py run_py: ${MODULE}.so ${MPIEXEC} ${PYTHON} ${SCRIPT}.py ${MODULE}.so: ${MODULE}.f90 ${F2PY} ${F2PY_FLAGS} -c $< -m ${MODULE} EXECUTABLE=poisson3d .PHONY:run_cc run_cc: ${EXECUTABLE}.exe ${MPIEXEC} ./${EXECUTABLE}.exe ${EXECUTABLE}.exe: ${MAKE} -f makefile.petsc \ PETSC_DIR=${PETSC_DIR} PETSC_ARCH=${PETSC_ARCH} .PHONY:clean clean: ${RM} *.py[co] ${MODULE}*.so ${EXECUTABLE}.exe ${RM} -r __pycache__ ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/demo/legacy/poisson3d/makefile.petsc0000644000175000017500000000110114567251135021306 0ustar00balaybalay# -*- makefile -*- EXECUTABLE=poisson3d -include ../../../../../petscdir.mk -include ${PETSC_DIR}/lib/petsc/conf/variables .PHONY:all all: ${EXECUTABLE}.exe SOURCEC=${EXECUTABLE}.c SOURCEF=del2lib.f90 SOURCEH=del2mat.h OBJSC=${SOURCEC:.c=.o} OBJSF=${SOURCEF:.f90=.o} ${EXECUTABLE}.exe: ${SOURCEC} ${SOURCEF} ${SOURCEH} ${PETSC_FCOMPILE} ${PETSC_COMPILE} ${CLINKER} -o $@ ${OBJSC} ${OBJSF} ${PETSC_TS_LIB} ${RM} ${OBJSC} ${OBJSF} include ${PETSC_DIR}/lib/petsc/conf/variables include ${PETSC_DIR}/lib/petsc/conf/rules OBJSC=${SOURCEC:.c=.o} OBJSF=${SOURCEF:.f90=.o} ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/demo/legacy/poisson3d/poisson3d.c0000644000175000017500000000364514567251135020575 0ustar00balaybalay#include #include #include #include #include "del2mat.h" #define DEL2MAT_MULT ((void(*)(void))Del2Mat_mult) #define DEL2MAT_DIAG ((void(*)(void))Del2Mat_diag) int main(int argc,char **argv) { PetscInt n; PetscScalar h; Del2Mat shell; Mat A; Vec x,b; KSP ksp; PC pc; PetscMPIInt size; /* PETSc initialization */ PetscInitialize(&argc, &argv, NULL, NULL); MPI_Comm_size(PETSC_COMM_WORLD,&size); if (size != 1) { PetscPrintf(PETSC_COMM_WORLD, "This a sequential example\n"); PetscFinalize(); return 1; } /* number of nodes in each direction * excluding those at the boundary */ n = 32; h = 1.0/(n+1); /* grid spacing */ /* setup linear system (shell) matrix */ MatCreate(PETSC_COMM_SELF, &A); MatSetSizes(A, n*n*n, n*n*n, n*n*n, n*n*n); MatSetType(A, MATSHELL); shell.N = n; PetscMalloc((n+2)*(n+2)*(n+2)*sizeof(PetscScalar),&shell.F); PetscMemzero(shell.F, (n+2)*(n+2)*(n+2)*sizeof(PetscScalar)); MatShellSetContext(A, &shell); MatShellSetOperation(A, MATOP_MULT, DEL2MAT_MULT); MatShellSetOperation(A, MATOP_MULT_TRANSPOSE, DEL2MAT_MULT); MatShellSetOperation(A, MATOP_GET_DIAGONAL, DEL2MAT_DIAG); MatSetUp(A); /* setup linear system vectors */ MatCreateVecs(A, &x, &b); VecSet(x, 0); VecSet(b, 1); /* setup Krylov linear solver */ KSPCreate(PETSC_COMM_SELF, &ksp); KSPGetPC(ksp, &pc); KSPSetType(ksp, KSPCG); /* use conjugate gradients */ PCSetType(pc, PCNONE); /* with no preconditioning */ KSPSetFromOptions(ksp); /* iteratively solve linear system of equations A*x=b */ KSPSetOperators(ksp,A,A); KSPSolve(ksp, b, x); /* scale solution vector to account for grid spacing */ VecScale(x, h*h); /* free memory and destroy objects */ PetscFree(shell.F); VecDestroy(&x); VecDestroy(&b); MatDestroy(&A); KSPDestroy(&ksp); /* finalize PETSc */ PetscFinalize(); return 0; } ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/demo/legacy/poisson3d/poisson3d.py0000644000175000017500000000231214567251135020771 0ustar00balaybalayimport sys, petsc4py petsc4py.init(sys.argv) from petsc4py import PETSc from del2mat import Del2Mat # this a sequential example assert PETSc.COMM_WORLD.getSize() == 1 # number of nodes in each direction # excluding those at the boundary n = 32 h = 1.0/(n+1) # grid spacing # setup linear system matrix A = PETSc.Mat().create() A.setSizes([n**3, n**3]) A.setType('python') shell = Del2Mat(n) # shell context A.setPythonContext(shell) A.setUp() # setup linear system vectors x, b = A.createVecs() x.set(0.0) b.set(1.0) # setup Krylov solver ksp = PETSc.KSP().create() pc = ksp.getPC() ksp.setType('cg') pc.setType('none') # iteratively solve linear # system of equations A*x=b ksp.setOperators(A) ksp.setFromOptions() ksp.solve(b, x) # scale solution vector to # account for grid spacing x.scale(h**2) OptDB = PETSc.Options() if OptDB.getBool('plot_mpl', False): try: from matplotlib import pylab except ImportError: PETSc.Sys.Print("matplotlib not available") else: from numpy import mgrid X, Y = mgrid[0:1:1j*n,0:1:1j*n] Z = x[...].reshape(n,n,n)[:,:,n/2-2] pylab.contourf(X, Y, Z) pylab.axis('equal') pylab.colorbar() pylab.show() ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1709010084.3853753 petsc4py-3.20.5/demo/legacy/taosolve/0000755000175000017500000000000014567266244016422 5ustar00balaybalay././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/demo/legacy/taosolve/chwirut.py0000644000175000017500000000346114567251135020456 0ustar00balaybalayimport sys, petsc4py petsc4py.init(sys.argv) import numpy as np from petsc4py import PETSc class Chwirut(object): """ Finds the nonlinear least-squares solution to the model y = exp(-b1*x)/(b2+b3*x) + e """ def __init__(self): BETA = [0.2, 0.12, 0.08] NOBSERVATIONS = 100 NPARAMETERS = 3 np.random.seed(456) x = np.random.rand(NOBSERVATIONS) e = np.random.rand(NOBSERVATIONS) y = np.exp(-BETA[0]*x)/(BETA[1] + BETA[2]*x) + e self.NOBSERVATIONS = NOBSERVATIONS self.NPARAMETERS = NPARAMETERS self.x = x self.y = y def createVecs(self): X = PETSc.Vec().create(PETSc.COMM_SELF) X.setSizes(self.NPARAMETERS) F = PETSc.Vec().create(PETSc.COMM_SELF) F.setSizes(self.NOBSERVATIONS) return X, F def formInitialGuess(self, X): X[0] = 0.15 X[1] = 0.08 X[2] = 0.05 def formResidual(self, tao, X, F): x, y = self.x, self.y b1, b2, b3 = X.array F.array = y - np.exp(-b1*x)/(b2 + b3*x) def plotSolution(self, X): try: from matplotlib import pylab except ImportError: return b1, b2, b3 = X.array x, y = self.x, self.y u = np.linspace(x.min(), x.max(), 100) v = np.exp(-b1*u)/(b2+b3*u) pylab.plot(x, y, 'ro') pylab.plot(u, v, 'b-') pylab.show() OptDB = PETSc.Options() user = Chwirut() x, f = user.createVecs() x.setFromOptions() f.setFromOptions() tao = PETSc.TAO().create(PETSc.COMM_SELF) tao.setType(PETSc.TAO.Type.POUNDERS) tao.setResidual(user.formResidual, f) tao.setFromOptions() user.formInitialGuess(x) tao.solve(x) plot = OptDB.getBool('plot', False) if plot: user.plotSolution(x) x.destroy() f.destroy() tao.destroy() ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/demo/legacy/taosolve/rosenbrock.py0000644000175000017500000000705714567251135021145 0ustar00balaybalay""" This example demonstrates the use of TAO for Python to solve an unconstrained minimization problem on a single processor. We minimize the extended Rosenbrock function:: sum_{i=0}^{n/2-1} ( alpha*(x_{2i+1}-x_{2i}^2)^2 + (1-x_{2i})^2 ) """ try: range = xrange except NameError: pass # the two lines below are only # needed to build options database # from command line arguments import sys, petsc4py petsc4py.init(sys.argv) from petsc4py import PETSc class AppCtx(object): """ Extended Rosenbrock function. """ def __init__(self, n=2, alpha=99.0): self.size = int(n) self.alpha = float(alpha) def formObjective(self, tao, x): #print 'AppCtx.formObjective()' alpha = self.alpha nn = self.size // 2 ff = 0.0 for i in range(nn): t1 = x[2*i+1] - x[2*i] * x[2*i] t2 = 1 - x[2*i]; ff += alpha*t1*t1 + t2*t2; return ff def formGradient(self, tao, x, G): #print 'AppCtx.formGradient()' alpha = self.alpha nn = self.size // 2 G.zeroEntries() for i in range(nn): t1 = x[2*i+1] - x[2*i] * x[2*i] t2 = 1 - x[2*i]; G[2*i] = -4*alpha*t1*x[2*i] - 2*t2; G[2*i+1] = 2*alpha*t1; def formObjGrad(self, tao, x, G): #print 'AppCtx.formObjGrad()' alpha = self.alpha nn = self.size // 2 ff = 0.0 G.zeroEntries() for i in range(nn): t1 = x[2*i+1] - x[2*i] * x[2*i] t2 = 1 - x[2*i]; ff += alpha*t1*t1 + t2*t2; G[2*i] = -4*alpha*t1*x[2*i] - 2*t2; G[2*i+1] = 2*alpha*t1; return ff def formHessian(self, tao, x, H, HP): #print 'AppCtx.formHessian()' alpha = self.alpha nn = self.size // 2 idx = [0, 0] v = [[0.0, 0.0], [0.0, 0.0]] H.zeroEntries() for i in range(nn): v[1][1] = 2*alpha v[0][0] = -4*alpha*(x[2*i+1]-3*x[2*i]*x[2*i]) + 2 v[1][0] = v[0][1] = -4.0*alpha*x[2*i]; idx[0] = 2*i idx[1] = 2*i+1 H[idx,idx] = v H.assemble() # access PETSc options database OptDB = PETSc.Options() # create user application context # and configure user parameters user = AppCtx() user.size = OptDB.getInt ( 'n', user.size) user.alpha = OptDB.getReal('alpha', user.alpha) # create solution vector x = PETSc.Vec().create(PETSc.COMM_SELF) x.setSizes(user.size) x.setFromOptions() # create Hessian matrix H = PETSc.Mat().create(PETSc.COMM_SELF) H.setSizes([user.size, user.size]) H.setFromOptions() H.setOption(PETSc.Mat.Option.SYMMETRIC, True) H.setUp() # pass the following to command line: # $ ... -methods nm,lmvm,nls,ntr,cg,blmvm,tron # to try many methods methods = OptDB.getString('methods', '') methods = methods.split(',') for meth in methods: # create TAO Solver tao = PETSc.TAO().create(PETSc.COMM_SELF) if meth: tao.setType(meth) tao.setFromOptions() # solve the problem tao.setObjectiveGradient(user.formObjGrad) tao.setObjective(user.formObjective) tao.setGradient(user.formGradient) tao.setHessian(user.formHessian, H) #app.getKSP().getPC().setFromOptions() x.set(0) # zero initial guess tao.setSolution(x) tao.solve() tao.destroy() ## # this is just for testing ## x = app.getSolution() ## G = app.getGradient() ## H, HP = app.getHessian() ## f = tao.computeObjective(x) ## tao.computeGradient(x, G) ## f = tao.computeObjectiveGradient(x, G) ## tao.computeHessian(x, H, HP) ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1709010084.3863752 petsc4py-3.20.5/demo/legacy/wrap-cython/0000755000175000017500000000000014567266244017041 5ustar00balaybalay././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/demo/legacy/wrap-cython/Bratu3D.pyx0000644000175000017500000000227014567251135021041 0ustar00balaybalayfrom petsc4py.PETSc cimport Vec, PetscVec from petsc4py.PETSc cimport Mat, PetscMat from petsc4py.PETSc cimport DM, PetscDM from petsc4py.PETSc cimport SNES, PetscSNES from petsc4py.PETSc import Error cdef extern from "Bratu3Dimpl.h": ctypedef struct Params: double lambda_ int FormInitGuess(PetscDM da, PetscVec x, Params *p) int FormFunction (PetscDM da, PetscVec x, PetscVec F, Params *p) int FormJacobian (PetscDM da, PetscVec x, PetscMat J, Params *p) def formInitGuess(Vec x, DM da, double lambda_): cdef int ierr cdef Params p = {"lambda_" : lambda_} ierr = FormInitGuess(da.dm, x.vec, &p) if ierr != 0: raise Error(ierr) def formFunction(SNES snes, Vec x, Vec f, DM da, double lambda_): cdef int ierr cdef Params p = {"lambda_" : lambda_} ierr = FormFunction(da.dm, x.vec, f.vec, &p) if ierr != 0: raise Error(ierr) def formJacobian(SNES snes, Vec x, Mat J, Mat P, DM da, double lambda_): cdef int ierr cdef Params p = {"lambda_" : lambda_} ierr = FormJacobian(da.dm, x.vec, P.mat, &p) if ierr != 0: raise Error(ierr) if J != P: J.assemble() # for matrix-free operator return Mat.Structure.SAME_NONZERO_PATTERN ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/demo/legacy/wrap-cython/Bratu3Dimpl.c0000644000175000017500000002042014567251135021322 0ustar00balaybalay/* ------------------------------------------------------------------------ Solid Fuel Ignition (SFI) problem. This problem is modeled by the partial differential equation -Laplacian(u) - lambda * exp(u) = 0, 0 < x,y,z < 1, with boundary conditions u = 0 for x = 0, x = 1, y = 0, y = 1, z = 0, z = 1 A finite difference approximation with the usual 7-point stencil is used to discretize the boundary value problem to obtain a nonlinear system of equations. The problem is solved in a 3D rectangular domain, using distributed arrays (DAs) to partition the parallel grid. ------------------------------------------------------------------------- */ #include "Bratu3Dimpl.h" PetscErrorCode FormInitGuess(DM da, Vec X, Params *p) { PetscInt i,j,k,Mx,My,Mz,xs,ys,zs,xm,ym,zm; PetscReal lambda,temp1,hx,hy,hz,tempk,tempj; PetscScalar ***x; PetscFunctionBegin; PetscCall(DMDAGetInfo(da,PETSC_IGNORE,&Mx,&My,&Mz,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE)); lambda = p->lambda_; hx = 1.0/(PetscReal)(Mx-1); hy = 1.0/(PetscReal)(My-1); hz = 1.0/(PetscReal)(Mz-1); temp1 = lambda/(lambda + 1.0); /* Get a pointer to vector data. - For default PETSc vectors, VecGetArray() returns a pointer to the data array. Otherwise, the routine is implementation dependent. - You MUST call VecRestoreArray() when you no longer need access to the array. */ PetscCall(DMDAVecGetArray(da,X,&x)); /* Get local grid boundaries (for 3-dimensional DMDA): - xs, ys, zs: starting grid indices (no ghost points) - xm, ym, zm: widths of local grid (no ghost points) */ PetscCall(DMDAGetCorners(da,&xs,&ys,&zs,&xm,&ym,&zm)); /* Compute initial guess over the locally owned part of the grid */ for (k=zs; klambda_; hx = 1.0/(PetscReal)(Mx-1); hy = 1.0/(PetscReal)(My-1); hz = 1.0/(PetscReal)(Mz-1); sc = hx*hy*hz*lambda; hxhzdhy = hx*hz/hy; hyhzdhx = hy*hz/hx; hxhydhz = hx*hy/hz; /* */ PetscCall(DMGetLocalVector(da,&localX)); /* Scatter ghost points to local vector,using the 2-step process DMGlobalToLocalBegin(),DMGlobalToLocalEnd(). By placing code between these two statements, computations can be done while messages are in transition. */ PetscCall(DMGlobalToLocalBegin(da,X,INSERT_VALUES,localX)); PetscCall(DMGlobalToLocalEnd(da,X,INSERT_VALUES,localX)); /* Get pointers to vector data. */ PetscCall(DMDAVecGetArray(da,localX,&x)); PetscCall(DMDAVecGetArray(da,F,&f)); /* Get local grid boundaries. */ PetscCall(DMDAGetCorners(da,&xs,&ys,&zs,&xm,&ym,&zm)); /* Compute function over the locally owned part of the grid. */ for (k=zs; klambda_; hx = 1.0/(PetscReal)(Mx-1); hy = 1.0/(PetscReal)(My-1); hz = 1.0/(PetscReal)(Mz-1); sc = hx*hy*hz*lambda; hxhzdhy = hx*hz/hy; hyhzdhx = hy*hz/hx; hxhydhz = hx*hy/hz; /* */ PetscCall(DMGetLocalVector(da,&localX)); /* Scatter ghost points to local vector, using the 2-step process DMGlobalToLocalBegin(), DMGlobalToLocalEnd(). By placing code between these two statements, computations can be done while messages are in transition. */ PetscCall(DMGlobalToLocalBegin(da,X,INSERT_VALUES,localX)); PetscCall(DMGlobalToLocalEnd(da,X,INSERT_VALUES,localX)); /* Get pointer to vector data. */ PetscCall(DMDAVecGetArray(da,localX,&x)); /* Get local grid boundaries. */ PetscCall(DMDAGetCorners(da,&xs,&ys,&zs,&xm,&ym,&zm)); /* Compute entries for the locally owned part of the Jacobian. - Currently, all PETSc parallel matrix formats are partitioned by contiguous chunks of rows across the processors. - Each processor needs to insert only elements that it owns locally (but any non-local elements will be sent to the appropriate processor during matrix assembly). - Here, we set all entries for a particular row at once. - We can set matrix entries either using either MatSetValuesLocal() or MatSetValues(), as discussed above. */ for (k=zs; k typedef struct Params { double lambda_; } Params; PetscErrorCode FormInitGuess(DM da, Vec x, Params *p); PetscErrorCode FormFunction(DM da, Vec x, Vec F, Params *p); PetscErrorCode FormJacobian(DM da, Vec x, Mat J, Params *p); #endif /* !BRATU3D_H */ ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/demo/legacy/wrap-cython/makefile0000644000175000017500000000116114567251135020531 0ustar00balaybalay# -*- makefile -*- MPIEXEC= PYTHON=python -include ../../../../../petscdir.mk -include ${PETSC_DIR}/lib/petsc/conf/variables .PHONY:test test: run clean SCRIPT=run_demo MODULE=Bratu3D .PHONY:build build: ${MODULE}.so .PHONY:run run: build ${MPIEXEC} ${PYTHON} ${SCRIPT}.py ${MODULE}.so: ${MODULE}.pyx ${MODULE}impl.h ${MODULE}impl.c CC=${CC} F90=${FC} \ ${PYTHON} setup.py -q build_ext --inplace ${RM} -r build ${MODULE}.c .PHONY:clean clean:: ${RM} ${MODULE}.c ${MODULE}*.so ${RM} *.py[co] ${RM} -r __pycache__ include ${PETSC_DIR}/lib/petsc/conf/variables include ${PETSC_DIR}/lib/petsc/conf/rules MPIEXEC= ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/demo/legacy/wrap-cython/run_demo.py0000644000175000017500000000243714567251135021222 0ustar00balaybalayimport sys, petsc4py petsc4py.init(sys.argv) from petsc4py import PETSc import Bratu3D as Bratu3D OptDB = PETSc.Options() N = OptDB.getInt('N', 16) lambda_ = OptDB.getReal('lambda', 6.0) do_plot = OptDB.getBool('plot', False) da = PETSc.DMDA().create([N, N, N], stencil_width=1) #app = App(da, lambda_) snes = PETSc.SNES().create() F = da.createGlobalVec() snes.setFunction(Bratu3D.formFunction, F, args=(da, lambda_)) J = da.createMat() snes.setJacobian(Bratu3D.formJacobian, J, args=(da, lambda_)) snes.setFromOptions() X = da.createGlobalVec() Bratu3D.formInitGuess(X, da, lambda_) snes.solve(None, X) U = da.createNaturalVec() da.globalToNatural(X, U) def plot(da, U): scatter, U0 = PETSc.Scatter.toZero(U) scatter.scatter(U, U0, False, PETSc.Scatter.Mode.FORWARD) rank = PETSc.COMM_WORLD.getRank() if rank == 0: solution = U0[...].reshape(da.sizes, order='f').copy() try: from matplotlib import pyplot pyplot.contourf(solution[:, :, N//2]) pyplot.axis('equal') pyplot.show() except: pass PETSc.COMM_WORLD.barrier() scatter.destroy() U0.destroy() if do_plot: plot(da, U) U.destroy() X.destroy() F.destroy() J.destroy() da.destroy() snes.destroy() ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/demo/legacy/wrap-cython/setup.py0000644000175000017500000000272214567251135020547 0ustar00balaybalay#!/usr/bin/env python #$ python setup.py build_ext --inplace from distutils.core import setup from distutils.extension import Extension from Cython.Build import cythonize import numpy import petsc4py def configure(): INCLUDE_DIRS = [] LIBRARY_DIRS = [] LIBRARIES = [] # PETSc import os PETSC_DIR = os.environ['PETSC_DIR'] PETSC_ARCH = os.environ.get('PETSC_ARCH', '') from os.path import join, isdir if PETSC_ARCH and isdir(join(PETSC_DIR, PETSC_ARCH)): INCLUDE_DIRS += [join(PETSC_DIR, PETSC_ARCH, 'include'), join(PETSC_DIR, 'include')] LIBRARY_DIRS += [join(PETSC_DIR, PETSC_ARCH, 'lib')] else: if PETSC_ARCH: pass # XXX should warn ... INCLUDE_DIRS += [join(PETSC_DIR, 'include')] LIBRARY_DIRS += [join(PETSC_DIR, 'lib')] LIBRARIES += ['petsc'] # PETSc for Python INCLUDE_DIRS += [petsc4py.get_include()] # NumPy INCLUDE_DIRS += [numpy.get_include()] return dict( include_dirs=INCLUDE_DIRS + [os.curdir], libraries=LIBRARIES, library_dirs=LIBRARY_DIRS, runtime_library_dirs=LIBRARY_DIRS, ) extensions = [ Extension('Bratu3D', sources = ['Bratu3D.pyx', 'Bratu3Dimpl.c'], depends = ['Bratu3Dimpl.h'], **configure()), ] setup(name = "Bratu3D", ext_modules = cythonize( extensions, include_path=[petsc4py.get_include()]), ) ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1709010084.3883753 petsc4py-3.20.5/demo/legacy/wrap-f2py/0000755000175000017500000000000014567266244016415 5ustar00balaybalay././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/demo/legacy/wrap-f2py/.f2py_f2cmap0000644000175000017500000000004314567251135020514 0ustar00balaybalay{'integer':{'HANDLE_KIND':'long'}} ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/demo/legacy/wrap-f2py/Bratu2D.F900000644000175000017500000001610414567251135020133 0ustar00balaybalay! --------------------------------------------------------------------- ! ! Solid Fuel Ignition (SFI) problem. This problem is modeled by ! the partial differential equation ! ! -Laplacian(u) - lambda * exp(u) = 0, 0 < x,y < 1, ! ! with boundary conditions ! ! u = 0 for x = 0, x = 1, y = 0, y = 1, ! ! A finite difference approximation with the usual 5-point stencil ! is used to discretize the boundary value problem to obtain a ! nonlinear system of equations. The problem is solved in a 2D ! rectangular domain, using distributed arrays (DAs) to partition ! the parallel grid. ! ! -------------------------------------------------------------------- #include module Bratu2D use petsc implicit none type gridinfo PetscInt mx,xs,xe,xm,gxs,gxe,gxm PetscInt my,ys,ye,ym,gys,gye,gym end type gridinfo contains subroutine GetGridInfo(da, grd, ierr) implicit none DM da type(gridinfo) grd PetscErrorCode ierr ! PetscCall(DMDAGetInfo(da, PETSC_NULL_INTEGER,grd%mx, grd%my, PETSC_NULL_INTEGER,PETSC_NULL_INTEGER,PETSC_NULL_INTEGER,PETSC_NULL_INTEGER,PETSC_NULL_INTEGER,PETSC_NULL_INTEGER,PETSC_NULL_INTEGER,PETSC_NULL_INTEGER,PETSC_NULL_INTEGER,PETSC_NULL_INTEGER,ierr)) PetscCall(DMDAGetCorners(da,grd%xs,grd%ys,PETSC_NULL_INTEGER,grd%xm,grd%ym,PETSC_NULL_INTEGER,ierr)) PetscCall(DMDAGetGhostCorners(da,grd%gxs,grd%gys,PETSC_NULL_INTEGER,grd%gxm,grd%gym,PETSC_NULL_INTEGER,ierr)) grd%xs = grd%xs+1 grd%ys = grd%ys+1 grd%gxs = grd%gxs+1 grd%gys = grd%gys+1 grd%ye = grd%ys+grd%ym-1 grd%xe = grd%xs+grd%xm-1 grd%gye = grd%gys+grd%gym-1 grd%gxe = grd%gxs+grd%gxm-1 end subroutine GetGridInfo subroutine InitGuessLocal(grd, x, lambda, ierr) implicit none type(gridinfo) grd PetscScalar x(grd%xs:grd%xe,grd%ys:grd%ye) PetscReal lambda PetscErrorCode ierr ! PetscInt i, j PetscReal hx,hy,temp,temp1,one one = 1.0 hx = one/(dble(grd%mx-1)) hy = one/(dble(grd%my-1)) temp1 = lambda/(lambda+one) do j=grd%ys,grd%ye temp = dble(min(j-1,grd%my-j))*hy do i=grd%xs,grd%xe if (i==1 .or. j==1 .or. i==grd%mx .or. j==grd%my) then ! boundary points x(i,j) = 0.0 else ! interior grid points x(i,j) = temp1*sqrt(min(dble(min(i-1,grd%mx-i)*hx),dble(temp))) end if end do end do ierr = 0 end subroutine InitGuessLocal subroutine FunctionLocal(grd, x, f, lambda, ierr) implicit none type(gridinfo) grd PetscScalar x(grd%gxs:grd%gxe,grd%gys:grd%gye) PetscScalar f(grd%xs:grd%xe,grd%ys:grd%ye) PetscReal lambda PetscErrorCode ierr ! PetscInt i,j PetscReal hx,hy,hxdhy,hydhx,sc,one,two PetscScalar u,uxx,uyy one = 1.0 two = 2.0 hx = one/dble(grd%mx-1) hy = one/dble(grd%my-1) sc = hx*hy hxdhy = hx/hy hydhx = hy/hx do j=grd%ys,grd%ye do i=grd%xs,grd%xe if (i==1 .or. j==1 .or. i==grd%mx .or. j==grd%my) then ! boundary points f(i,j) = x(i,j) - 0.0 else ! interior grid points u = x(i,j) uxx = (two*u - x(i-1,j) - x(i+1,j)) * hydhx uyy = (two*u - x(i,j-1) - x(i,j+1)) * hxdhy f(i,j) = uxx + uyy - lambda*exp(u)*sc end if end do end do ierr = 0 end subroutine FunctionLocal subroutine JacobianLocal(grd, x, Jac, lambda, ierr) implicit none type(gridinfo) grd PetscScalar x(grd%gxs:grd%gxe,grd%gys:grd%gye) Mat Jac PetscReal lambda PetscErrorCode ierr ! PetscInt i,j,row(1),col(5) PetscInt ione,ifive PetscReal hx,hy,hxdhy,hydhx,sc,v(5),one,two ione = 1 ifive = 5 one = 1.0 two = 2.0 hx = one/dble(grd%mx-1) hy = one/dble(grd%my-1) sc = hx*hy hxdhy = hx/hy hydhx = hy/hx do j=grd%ys,grd%ye row = (j - grd%gys)*grd%gxm + grd%xs - grd%gxs - 1 do i=grd%xs,grd%xe row = row + 1 if (i==1 .or. j==1 .or. i==grd%mx .or. j==grd%my) then ! boundary points col(1) = row(1) v(1) = one PetscCall(MatSetValuesLocal(Jac,ione,row,ione,col,v,INSERT_VALUES,ierr)) else ! interior grid points v(1) = -hxdhy v(2) = -hydhx v(3) = two*(hydhx + hxdhy) - lambda*exp(x(i,j))*sc v(4) = -hydhx v(5) = -hxdhy col(1) = row(1) - grd%gxm col(2) = row(1) - 1 col(3) = row(1) col(4) = row(1) + 1 col(5) = row(1) + grd%gxm PetscCall(MatSetValuesLocal(Jac,ione,row,ifive,col,v,INSERT_VALUES,ierr)) end if end do end do end subroutine JacobianLocal end module Bratu2D ! -------------------------------------------------------------------- subroutine FormInitGuess(da, X, lambda, ierr) use Bratu2D implicit none DM da Vec X PetscReal lambda PetscErrorCode ierr ! type(gridinfo) :: grd PetscScalar,pointer :: xx(:) PetscCall(VecGetArrayF90(X,xx,ierr)) PetscCall(GetGridInfo(da,grd,ierr)) PetscCall(InitGuessLocal(grd,xx,lambda,ierr)) PetscCall(VecRestoreArrayF90(X,xx,ierr)) end subroutine FormInitGuess subroutine FormFunction(da, X, F, lambda, ierr) use Bratu2D implicit none DM da Vec X Vec F PetscReal lambda PetscErrorCode ierr ! type(gridinfo) :: grd Vec :: localX PetscScalar,pointer :: xx(:) PetscScalar,pointer :: ff(:) PetscCall(DMGetLocalVector(da,localX,ierr)) PetscCall(DMGlobalToLocalBegin(da,X,INSERT_VALUES,localX,ierr)) PetscCall(DMGlobalToLocalEnd(da,X,INSERT_VALUES,localX,ierr)) PetscCall(VecGetArrayF90(localX,xx,ierr)) PetscCall(VecGetArrayF90(F,ff,ierr)) PetscCall(GetGridInfo(da,grd,ierr)) PetscCall(FunctionLocal(grd,xx,ff,lambda,ierr)) PetscCall(VecRestoreArrayF90(F,ff,ierr)) PetscCall(VecRestoreArrayF90(localX,xx,ierr)) PetscCall(DMRestoreLocalVector(da,localX,ierr)) end subroutine FormFunction subroutine FormJacobian(da, X, J, lambda, ierr) use Bratu2D implicit none DM da Vec X Mat J PetscReal lambda PetscErrorCode ierr ! type(gridinfo) :: grd Vec :: localX PetscScalar,pointer :: xx(:) PetscCall(DMGetLocalVector(da,localX,ierr)) PetscCall(DMGlobalToLocalBegin(da,X,INSERT_VALUES,localX,ierr)) PetscCall(DMGlobalToLocalEnd(da,X,INSERT_VALUES,localX,ierr)) PetscCall(VecGetArrayF90(localX,xx,ierr)) PetscCall(GetGridInfo(da,grd,ierr)) PetscCall(JacobianLocal(grd,xx,J,lambda,ierr)) PetscCall(VecRestoreArrayF90(localX,xx,ierr)) PetscCall(DMRestoreLocalVector(da,localX,ierr)) PetscCall(MatAssemblyBegin(J,MAT_FINAL_ASSEMBLY,ierr)) PetscCall(MatAssemblyEnd (J,MAT_FINAL_ASSEMBLY,ierr)) end subroutine FormJacobian ! -------------------------------------------------------------------- ! Local Variables: ! mode: f90 ! End: ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/demo/legacy/wrap-f2py/Bratu2D.pyf0000644000175000017500000000204314567251135020370 0ustar00balaybalay! -*- f90 -*- python module Bratu2D usercode ''' #include "Bratu2Dmodule.h" ''' interface subroutine FormInitGuess(dm, x, param, ierr) !integer, parameter :: HANDLE_KIND=4 integer(kind=HANDLE_KIND) dm ! DM integer(kind=HANDLE_KIND) x ! Vec real(kind=8) param integer, intent(out) :: ierr end subroutine FormInitGuess subroutine FormFunction(dm, x, f, param, ierr) !integer, parameter :: HANDLE_KIND=4 integer(kind=HANDLE_KIND) dm ! DM integer(kind=HANDLE_KIND) x ! Vec integer(kind=HANDLE_KIND) f ! Vec real(kind=8) param integer, intent(out) :: ierr end subroutine FormFunction subroutine FormJacobian(dm, x, J, param, ierr) !integer, parameter :: HANDLE_KIND=4 integer(kind=HANDLE_KIND) dm ! DM integer(kind=HANDLE_KIND) x ! Vec integer(kind=HANDLE_KIND) J ! Vec real(kind=8) param integer, intent(out) :: ierr end subroutine FormJacobian end interface end python module Bratu2D ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/demo/legacy/wrap-f2py/Bratu2Dmodule.h0000644000175000017500000000072514567251135021234 0ustar00balaybalay#define FormInitGuess forminitguess #define FormFunction formfunction #define FormJacobian formjacobian #define FormInitGuess_ forminitguess_ #define FormFunction_ formfunction_ #define FormJacobian_ formjacobian_ #define _FormInitGuess _forminitguess #define _FormFunction _formfunction #define _FormJacobian _formjacobian #define _FormInitGuess_ _forminitguess_ #define _FormFunction_ _formfunction_ #define _FormJacobian_ _formjacobian_ ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/demo/legacy/wrap-f2py/makefile0000644000175000017500000000127314567251135020111 0ustar00balaybalay# -*- makefile -*- MPIEXEC= PYTHON=python -include ../../../../../petscdir.mk -include ${PETSC_DIR}/lib/petsc/conf/variables .PHONY:test test: run clean SCRIPT=run_demo MODULE=Bratu2D .PHONY:build build: ${MODULE}.so .PHONY:run run: build ${PYTHON} ${SCRIPT}.py ${MODULE}.so: ${MODULE}.pyf ${MODULE}.F90 env \ F77="${FC}" F77FLAGS="${FC_FLAGS}" \ F90="${FC}" F90FLAGS="${FC_FLAGS}" \ LDSHARED="${FC_LINKER}" \ ${PYTHON} setup.py -q build_ext --inplace ${RM} -r build ${MODULE}module.c .PHONY:clean clean:: ${RM} ${MODULE}*.so ${RM} *.py[co] ${RM} -r __pycache__ include ${PETSC_DIR}/lib/petsc/conf/variables include ${PETSC_DIR}/lib/petsc/conf/rules MPIEXEC= ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/demo/legacy/wrap-f2py/run_demo.py0000644000175000017500000000432314567251135020572 0ustar00balaybalayimport sys, petsc4py petsc4py.init(sys.argv) from petsc4py import PETSc import Bratu2D as Bratu2D class App(object): def __init__(self, da, lambda_): assert da.getDim() == 2 self.da = da self.lambda_ = lambda_ def formInitGuess(self, snes, X): X.zeroEntries() # just in case da = self.da.fortran vec_X = X.fortran ierr = Bratu2D.FormInitGuess(da, vec_X, self.lambda_) if ierr: raise PETSc.Error(ierr) def formFunction(self, snes, X, F): F.zeroEntries() # just in case da = self.da.fortran vec_X = X.fortran vec_F = F.fortran ierr = Bratu2D.FormFunction(da, vec_X, vec_F, self.lambda_) if ierr: raise PETSc.Error(ierr) def formJacobian(self, snes, X, J, P): P.zeroEntries() # just in case da = self.da.fortran vec_X = X.fortran mat_P = P.fortran ierr = Bratu2D.FormJacobian(da, vec_X, mat_P, self.lambda_) if ierr: raise PETSc.Error(ierr) if J != P: J.assemble() # matrix-free operator return PETSc.Mat.Structure.SAME_NONZERO_PATTERN OptDB = PETSc.Options() N = OptDB.getInt('N', 16) lambda_ = OptDB.getReal('lambda', 6.0) do_plot = OptDB.getBool('plot', False) da = PETSc.DA().create([N, N], stencil_width=1) app = App(da, lambda_) snes = PETSc.SNES().create() F = da.createGlobalVec() snes.setFunction(app.formFunction, F) J = da.createMat() snes.setJacobian(app.formJacobian, J) snes.setFromOptions() X = da.createGlobalVec() app.formInitGuess(snes, X) snes.solve(None, X) U = da.createNaturalVec() da.globalToNatural(X, U) def plot(da, U): comm = da.getComm() scatter, U0 = PETSc.Scatter.toZero(U) scatter.scatter(U, U0, False, PETSc.Scatter.Mode.FORWARD) rank = comm.getRank() if rank == 0: solution = U0[...] solution = solution.reshape(da.sizes, order='f').copy() try: from matplotlib import pyplot pyplot.contourf(solution) pyplot.axis('equal') pyplot.show() except: pass comm.barrier() scatter.destroy() U0.destroy() if do_plot: plot(da, U) U.destroy() X.destroy() F.destroy() J.destroy() da.destroy() snes.destroy() ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/demo/legacy/wrap-f2py/setup.py0000644000175000017500000000404214567251135020120 0ustar00balaybalay#!/usr/bin/env python #$ python setup.py build_ext --inplace # a bit of monkeypatching ... try: from numpy.distutils.fcompiler import FCompiler def runtime_library_dir_option(self, dir): return self.c_compiler.runtime_library_dir_option(dir) FCompiler.runtime_library_dir_option = \ runtime_library_dir_option except Exception: pass def configuration(parent_package='',top_path=None): INCLUDE_DIRS = [] LIBRARY_DIRS = [] LIBRARIES = [] # PETSc import os PETSC_DIR = os.environ['PETSC_DIR'] PETSC_ARCH = os.environ.get('PETSC_ARCH', '') from os.path import join, isdir if PETSC_ARCH and isdir(join(PETSC_DIR, PETSC_ARCH)): INCLUDE_DIRS += [join(PETSC_DIR, PETSC_ARCH, 'include'), join(PETSC_DIR, 'include')] LIBRARY_DIRS += [join(PETSC_DIR, PETSC_ARCH, 'lib')] else: if PETSC_ARCH: pass # XXX should warn ... INCLUDE_DIRS += [join(PETSC_DIR, 'include')] LIBRARY_DIRS += [join(PETSC_DIR, 'lib')] LIBRARIES += [#'petscts', 'petscsnes', 'petscksp', #'petscdm', 'petscmat', 'petscvec', 'petsc'] # PETSc for Python import petsc4py INCLUDE_DIRS += [petsc4py.get_include()] # Configuration from numpy.distutils.misc_util import Configuration config = Configuration('', parent_package, top_path) config.add_extension('Bratu2D', sources = ['Bratu2D.pyf', 'Bratu2D.F90'], depends = ['Bratu2Dmodule.h'], f2py_options=['--quiet'], define_macros=[('F2PY_REPORT_ON_ARRAY_COPY',1)], include_dirs=INCLUDE_DIRS + [os.curdir], libraries=LIBRARIES, library_dirs=LIBRARY_DIRS, runtime_library_dirs=LIBRARY_DIRS) return config if __name__ == "__main__": from numpy.distutils.core import setup setup(**configuration(top_path='').todict()) ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1709010084.3893752 petsc4py-3.20.5/demo/legacy/wrap-swig/0000755000175000017500000000000014567266244016506 5ustar00balaybalay././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/demo/legacy/wrap-swig/Bratu3D.c0000644000175000017500000002036314567251135020113 0ustar00balaybalay/* ------------------------------------------------------------------------ Solid Fuel Ignition (SFI) problem. This problem is modeled by the partial differential equation -Laplacian(u) - lambda * exp(u) = 0, 0 < x,y,z < 1, with boundary conditions u = 0 for x = 0, x = 1, y = 0, y = 1, z = 0, z = 1 A finite difference approximation with the usual 7-point stencil is used to discretize the boundary value problem to obtain a nonlinear system of equations. The problem is solved in a 3D rectangular domain, using distributed arrays (DAs) to partition the parallel grid. ------------------------------------------------------------------------- */ #include "Bratu3D.h" PetscErrorCode FormInitGuess(DM da, Vec X, Params *p) { PetscInt i,j,k,Mx,My,Mz,xs,ys,zs,xm,ym,zm; PetscReal lambda,temp1,hx,hy,hz,tempk,tempj; PetscScalar ***x; PetscFunctionBegin; PetscCall(DMDAGetInfo(da,PETSC_IGNORE,&Mx,&My,&Mz,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE)); lambda = p->lambda_; hx = 1.0/(PetscReal)(Mx-1); hy = 1.0/(PetscReal)(My-1); hz = 1.0/(PetscReal)(Mz-1); temp1 = lambda/(lambda + 1.0); /* Get a pointer to vector data. - For default PETSc vectors, VecGetArray() returns a pointer to the data array. Otherwise, the routine is implementation dependent. - You MUST call VecRestoreArray() when you no longer need access to the array. */ PetscCall(DMDAVecGetArray(da,X,&x)); /* Get local grid boundaries (for 3-dimensional DMDA): - xs, ys, zs: starting grid indices (no ghost points) - xm, ym, zm: widths of local grid (no ghost points) */ PetscCall(DMDAGetCorners(da,&xs,&ys,&zs,&xm,&ym,&zm)); /* Compute initial guess over the locally owned part of the grid */ for (k=zs; klambda_; hx = 1.0/(PetscReal)(Mx-1); hy = 1.0/(PetscReal)(My-1); hz = 1.0/(PetscReal)(Mz-1); sc = hx*hy*hz*lambda; hxhzdhy = hx*hz/hy; hyhzdhx = hy*hz/hx; hxhydhz = hx*hy/hz; PetscCall(DMGetLocalVector(da,&localX)); /* Scatter ghost points to local vector,using the 2-step process DMGlobalToLocalBegin(),DMGlobalToLocalEnd(). By placing code between these two statements, computations can be done while messages are in transition. */ PetscCall(DMGlobalToLocalBegin(da,X,INSERT_VALUES,localX)); PetscCall(DMGlobalToLocalEnd(da,X,INSERT_VALUES,localX)); /* Get pointers to vector data. */ PetscCall(DMDAVecGetArray(da,localX,&x)); PetscCall(DMDAVecGetArray(da,F,&f)); /* Get local grid boundaries. */ PetscCall(DMDAGetCorners(da,&xs,&ys,&zs,&xm,&ym,&zm)); /* Compute function over the locally owned part of the grid. */ for (k=zs; klambda_; hx = 1.0/(PetscReal)(Mx-1); hy = 1.0/(PetscReal)(My-1); hz = 1.0/(PetscReal)(Mz-1); sc = hx*hy*hz*lambda; hxhzdhy = hx*hz/hy; hyhzdhx = hy*hz/hx; hxhydhz = hx*hy/hz; PetscCall(DMGetLocalVector(da,&localX)); /* Scatter ghost points to local vector, using the 2-step process DMGlobalToLocalBegin(), DMGlobalToLocalEnd(). By placing code between these two statements, computations can be done while messages are in transition. */ PetscCall(DMGlobalToLocalBegin(da,X,INSERT_VALUES,localX)); PetscCall(DMGlobalToLocalEnd(da,X,INSERT_VALUES,localX)); /* Get pointer to vector data. */ PetscCall(DMDAVecGetArray(da,localX,&x)); /* Get local grid boundaries. */ PetscCall(DMDAGetCorners(da,&xs,&ys,&zs,&xm,&ym,&zm)); /* Compute entries for the locally owned part of the Jacobian. - Currently, all PETSc parallel matrix formats are partitioned by contiguous chunks of rows across the processors. - Each processor needs to insert only elements that it owns locally (but any non-local elements will be sent to the appropriate processor during matrix assembly). - Here, we set all entries for a particular row at once. - We can set matrix entries either using either MatSetValuesLocal() or MatSetValues(), as discussed above. */ for (k=zs; k typedef struct Params { double lambda_; } Params; PetscErrorCode FormInitGuess(DM da, Vec x, Params *p); PetscErrorCode FormFunction(DM da, Vec x, Vec F, Params *p); PetscErrorCode FormJacobian(DM da, Vec x, Mat J, Params *p); #endif/*BRATU3D_H*/ ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/demo/legacy/wrap-swig/Bratu3D.i0000644000175000017500000000021414567251135020112 0ustar00balaybalay%module Bratu3D %include petsc4py/petsc4py.i %{ #include "Bratu3D.h" %} %include Bratu3D.h /* * Local Variables: * mode: C * End: */ ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/demo/legacy/wrap-swig/makefile0000644000175000017500000000125014567251135020175 0ustar00balaybalay# -*- makefile -*- MPIEXEC= PYTHON=python -include ../../../../../petscdir.mk -include ${PETSC_DIR}/lib/petsc/conf/variables .PHONY:test test: run clean SCRIPT=run_demo MODULE=Bratu3D .PHONY:build build: ${MODULE}.py _${MODULE}.so .PHONY:run run: build ${MPIEXEC} ${PYTHON} ${SCRIPT}.py ${MODULE}.py _${MODULE}.so: ${MODULE}.i ${MODULE}.c ${MODULE}.h CC=${CC} F90=${FC} LDSHARED='${CLINKER} -shared' \ ${PYTHON} setup.py -q build_ext --inplace ${RM} -r build ${MODULE}_wrap.c .PHONY:clean clean:: ${RM} ${MODULE}.py _${MODULE}*.so ${RM} *.py[co] ${RM} -r __pycache__ include ${PETSC_DIR}/lib/petsc/conf/variables include ${PETSC_DIR}/lib/petsc/conf/rules MPIEXEC= ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/demo/legacy/wrap-swig/run_demo.py0000644000175000017500000000357314567251135020671 0ustar00balaybalayimport sys, petsc4py petsc4py.init(sys.argv) from petsc4py import PETSc import Bratu3D as Bratu3D class App(object): def __init__(self, da, lambda_): assert da.getDim() == 3 self.da = da self.params = Bratu3D.Params() self.params.lambda_ = lambda_ def formInitGuess(self, X): X.zeroEntries() # just in case Bratu3D.FormInitGuess(self.da, X, self.params) def formFunction(self, snes, X, F): F.zeroEntries() # just in case Bratu3D.FormFunction(self.da, X, F, self.params) def formJacobian(self, snes, X, J, P): P.zeroEntries() # just in case Bratu3D.FormJacobian(self.da, X, P, self.params) if J != P: J.assemble() # matrix-free operator return PETSc.Mat.Structure.SAME_NONZERO_PATTERN OptDB = PETSc.Options() N = OptDB.getInt('N', 16) lambda_ = OptDB.getReal('lambda', 6.0) do_plot = OptDB.getBool('plot', False) da = PETSc.DMDA().create([N, N, N], stencil_width=1) app = App(da, lambda_) snes = PETSc.SNES().create() F = da.createGlobalVec() snes.setFunction(app.formFunction, F) J = da.createMat() snes.setJacobian(app.formJacobian, J) snes.setFromOptions() X = da.createGlobalVec() app.formInitGuess(X) snes.solve(None, X) U = da.createNaturalVec() da.globalToNatural(X, U) def plot(da, U): scatter, U0 = PETSc.Scatter.toZero(U) scatter.scatter(U, U0, False, PETSc.Scatter.Mode.FORWARD) rank = PETSc.COMM_WORLD.getRank() if rank == 0: solution = U0[...].reshape(da.sizes, order='f').copy() try: from matplotlib import pyplot pyplot.contourf(solution[:, :, N//2]) pyplot.axis('equal') pyplot.show() except: pass PETSc.COMM_WORLD.barrier() scatter.destroy() U0.destroy() if do_plot: plot(da, U) U.destroy() X.destroy() F.destroy() J.destroy() da.destroy() snes.destroy() ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/demo/legacy/wrap-swig/setup.py0000644000175000017500000000400014567251135020203 0ustar00balaybalay#!/usr/bin/env python #$ python setup.py build_ext --inplace # a bit of monkeypatching ... try: from numpy.distutils.fcompiler import FCompiler from numpy.distutils.unixccompiler import UnixCCompiler try: # Python 2 meth = UnixCCompiler.runtime_library_dir_option.im_func except AttributeError: # Python 3 meth = UnixCCompiler.runtime_library_dir_option FCompiler.runtime_library_dir_option = meth except Exception: pass def configuration(parent_package='',top_path=None): INCLUDE_DIRS = [] LIBRARY_DIRS = [] LIBRARIES = [] # PETSc import os PETSC_DIR = os.environ['PETSC_DIR'] PETSC_ARCH = os.environ.get('PETSC_ARCH', '') from os.path import join, isdir if PETSC_ARCH and isdir(join(PETSC_DIR, PETSC_ARCH)): INCLUDE_DIRS += [join(PETSC_DIR, PETSC_ARCH, 'include'), join(PETSC_DIR, 'include')] LIBRARY_DIRS += [join(PETSC_DIR, PETSC_ARCH, 'lib')] else: if PETSC_ARCH: pass # XXX should warn ... INCLUDE_DIRS += [join(PETSC_DIR, 'include')] LIBRARY_DIRS += [join(PETSC_DIR, 'lib')] LIBRARIES += [#'petscts', 'petscsnes', 'petscksp', #'petscdm', 'petscmat', 'petscvec', 'petsc'] # PETSc for Python import petsc4py INCLUDE_DIRS += [petsc4py.get_include()] # Configuration from numpy.distutils.misc_util import Configuration config = Configuration('', parent_package, top_path) config.add_extension('_Bratu3D', sources = ['Bratu3D.i', 'Bratu3D.c'], depends = ['Bratu3D.h'], include_dirs=INCLUDE_DIRS + [os.curdir], libraries=LIBRARIES, library_dirs=LIBRARY_DIRS, runtime_library_dirs=LIBRARY_DIRS) return config if __name__ == "__main__": from numpy.distutils.core import setup setup(**configuration(top_path='').todict()) ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1709010084.3893752 petsc4py-3.20.5/demo/poisson2d/0000755000175000017500000000000014567266244015242 5ustar00balaybalay././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/demo/poisson2d/poisson2d.py0000644000175000017500000001171114567251135017526 0ustar00balaybalay# Poisson in 2D # ============= # # Solve a constant coefficient Poisson problem on a regular grid. The source # code for this demo can be `downloaded here <../../_static/poisson2d.py>`__ # # .. math:: # # - u_{xx} - u_{yy} = 1 \quad\textsf{in}\quad [0,1]^2\\ # u = 0 \quad\textsf{on the boundary.} # This is a naïve, parallel implementation, using :math:`n` interior grid # points per dimension and a lexicographic ordering of the nodes. # This code is kept as simple as possible. However, simplicity comes at a # price. Here we use a naive decomposition that does not lead to an optimal # communication complexity for the matrix-vector product. An optimal complexity # decomposition of a structured grid could be achieved using `PETSc.DMDA`. # # This demo is structured as a script to be executed using: # # .. code-block:: console # # $ python poisson2d.py # # potentially with additional options passed at the end of the command. # # At the start of your script, call `petsc4py.init` passing `sys.argv` so that # command-line arguments to the script are passed through to PETSc. import sys import petsc4py petsc4py.init(sys.argv) # The full PETSc4py API is to be found in the `petsc4py.PETSc` module. from petsc4py import PETSc # PETSc is extensively programmable using the `PETSc.Options` database. For # more information see `working with PETSc Options `. OptDB = PETSc.Options() # Grid size and spacing using a default value of ``5``. The user can specify a # different number of points in each direction by passing the ``-n`` option to # the script. n = OptDB.getInt('n', 5) h = 1.0 / (n + 1) # Sparse matrices are represented by `PETSc.Mat` objects. # # You can omit the ``comm`` argument if your objects live on # `PETSc.COMM_WORLD` but it is a dangerous choice to rely on default values # for such important arguments. A = PETSc.Mat() A.create(comm=PETSc.COMM_WORLD) # Specify global matrix shape with a tuple. A.setSizes((n * n, n * n)) # The call above implicitly assumes that we leave the parallel decomposition of # the matrix rows to PETSc by using `PETSc.DECIDE` for local sizes. # It is equivalent to: # # .. code-block:: python # # A.setSizes(((PETSc.DECIDE, n * n), (PETSc.DECIDE, n * n))) # Various `sparse matrix formats ` can be selected: A.setType(PETSc.Mat.Type.AIJ) # Finally we allow the user to set any options they want to on the matrix from # the command line: A.setFromOptions() # Insertion into some matrix types is vastly more efficient if we preallocate # space rather than allow this to happen dynamically. Here we hint the number # of nonzeros to be expected on each row. A.setPreallocationNNZ(5) # We can now write out our finite difference matrix assembly using conventional # Python syntax. `Mat.getOwnershipRange` is used to retrieve the range of rows # local to this processor. def index_to_grid(r): """Convert a row number into a grid point.""" return (r // n, r % n) rstart, rend = A.getOwnershipRange() for row in range(rstart, rend): i, j = index_to_grid(row) A[row, row] = 4.0 / h**2 if i > 0: column = row - n A[row, column] = -1.0 / h**2 if i < n - 1: column = row + n A[row, column] = -1.0 / h**2 if j > 0: column = row - 1 A[row, column] = -1.0 / h**2 if j < n - 1: column = row + 1 A[row, column] = -1.0 / h**2 # At this stage, any parallel synchronization required in the matrix assembly # process has not occurred. We achieve this by calling `Mat.assemblyBegin` and # then `Mat.assemblyEnd`. A.assemblyBegin() A.assemblyEnd() # We set up an additional option so that the user can print the matrix by # passing ``-view_mat`` to the script. A.viewFromOptions('-view_mat') # PETSc represents all linear solvers as preconditioned Krylov subspace methods # of type `PETSc.KSP`. Here we create a KSP object for a conjugate gradient # solver preconditioned with an algebraic multigrid method. ksp = PETSc.KSP() ksp.create(comm=A.getComm()) ksp.setType(PETSc.KSP.Type.CG) ksp.getPC().setType(PETSc.PC.Type.GAMG) # We set the matrix in our linear solver and allow the user to program the # solver with options. ksp.setOperators(A) ksp.setFromOptions() # Since the matrix knows its size and parallel distribution, we can retrieve # appropriately-scaled vectors using `Mat.createVecs`. PETSc vectors are # objects of type `PETSc.Vec`. Here we set the right hand side of our system to # a vector of ones, and then solve. x, b = A.createVecs() b.set(1.0) ksp.solve(b, x) # Finally, allow the user to print the solution by passing ``-view_sol`` to the # script. x.viewFromOptions('-view_sol') # Things to try # ------------- # # - Show the solution with ``-view_sol``. # - Show the matrix with ``-view_mat``. # - Change the resolution with ``-n``. # - Use a direct solver by passing ``-ksp_type preonly -pc_type lu``. # - Run in parallel on two processors using: # # .. code-block:: console # # mpiexec -n 2 python poisson2d.py ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1709010084.3903754 petsc4py-3.20.5/demo/python_types/0000755000175000017500000000000014567266244016067 5ustar00balaybalay././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/demo/python_types/ksppython_protocol.py0000644000175000017500000000231414567251135022412 0ustar00balaybalayfrom petsc4py.PETSc import KSP from petsc4py.PETSc import Mat from petsc4py.PETSc import Vec from petsc4py.PETSc import Viewer # A template class with the Python methods supported by KSPPYTHON class KSPPythonProtocol: def solve(self, ksp: KSP, b: Vec, x: Vec) -> None: """Solve the linear system with right-hand side b. Return solution in x.""" ... def solveTranspose(self, ksp: KSP, b: Vec, x: Vec) -> None: """Solve the transposed linear system with right-hand side b. Return solution in x.""" ... def view(self, ksp: KSP, viewer: Viewer) -> None: """View the Krylov solver.""" ... def setFromOptions(self, ksp: KSP) -> None: """Process command line for customization.""" ... def setUp(self, ksp: KSP) -> None: """Perform the required setup.""" ... def buildSolution(self, ksp: KSP, x: Vec) -> None: """Compute the solution vector.""" ... def buildResidual(self, ksp: KSP, t: Vec, r: Vec) -> None: """Compute the residual vector, return it in r. t is a scratch working vector.""" ... def reset(self, ksp: KSP) -> None: """Reset the Krylov solver.""" ... ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/demo/python_types/mat.py0000644000175000017500000001137614567251135017223 0ustar00balaybalay# ------------------------------------------------------------------------ # # Poisson problem. This problem is modeled by the partial # differential equation # # -Laplacian(u) = 1, 0 < x,y < 1, # # with boundary conditions # # u = 0 for x = 0, x = 1, y = 0, y = 1 # # A finite difference approximation with the usual 7-point stencil # is used to discretize the boundary value problem to obtain a # nonlinear system of equations. The problem is solved in a 2D # rectangular domain, using distributed arrays (DAs) to partition # the parallel grid. # # ------------------------------------------------------------------------ # We first import petsc4py and sys to initialize PETSc import sys, petsc4py petsc4py.init(sys.argv) # Import the PETSc module from petsc4py import PETSc # Here we define a class representing the discretized operator # This allows us to apply the operator "matrix-free" class Poisson2D: def __init__(self, da): assert da.getDim() == 2 self.da = da self.localX = da.createLocalVec() # This is the method that PETSc will look for when applying # the operator. `X` is the PETSc input vector, `Y` the output vector, # while `mat` is the PETSc matrix holding the PETSc datastructures. def mult(self, mat, X, Y): # Grid sizes mx, my = self.da.getSizes() hx, hy = [1.0/m for m in [mx, my]] # Bounds for the local part of the grid this process owns (xs, xe), (ys, ye) = self.da.getRanges() # Map global vector to local vectors self.da.globalToLocal(X, self.localX) # We can access the vector data as NumPy arrays x = self.da.getVecArray(self.localX) y = self.da.getVecArray(Y) # Loop on the local grid and compute the local action of the operator for j in range(ys, ye): for i in range(xs, xe): u = x[i, j] # center u_e = u_w = u_n = u_s = 0 if i > 0: u_w = x[i-1, j] # west if i < mx-1: u_e = x[i+1, j] # east if j > 0: u_s = x[i, j-1] # south if j < ny-1: u_n = x[i, j+1] # north u_xx = (-u_e + 2*u - u_w)*hy/hx u_yy = (-u_n + 2*u - u_s)*hx/hy y[i, j] = u_xx + u_yy # This is the method that PETSc will look for when the diagonal of the matrix is needed. def getDiagonal(self, mat, D): mx, my = self.da.getSizes() hx, hy = [1.0/m for m in [mx, my]] (xs, xe), (ys, ye) = self.da.getRanges() d = self.da.getVecArray(D) # Loop on the local grid and compute the diagonal for j in range(ys, ye): for i in range(xs, xe): d[i, j] = 2*hy/hx + 2*hx/hy # The class can contain other methods that PETSc won't use def formRHS(self, B): b = self.da.getVecArray(B) mx, my = self.da.getSizes() hx, hy = [1.0/m for m in [mx, my]] (xs, xe), (ys, ye) = self.da.getRanges() for j in range(ys, ye): for i in range(xs, xe): b[i, j] = 1*hx*hy # Access the option database and read options from the command line OptDB = PETSc.Options() n = OptDB.getInt('n', 16) # Read `-n `, defaults to 16 nx = OptDB.getInt('nx', n) ny = OptDB.getInt('ny', n) # Create the distributed memory implementation for structured grid da = PETSc.DMDA().create([nx, ny], stencil_width=1) # Create vectors to hold the solution and the right-hand side x = da.createGlobalVec() b = da.createGlobalVec() # Instantiate an object of our Poisson2D class pde = Poisson2D(da) # Create a PETSc matrix of type Python using `pde` as context A = PETSc.Mat().create(comm=da.comm) A.setSizes([x.getSizes(), b.getSizes()]) A.setType(PETSc.Mat.Type.PYTHON) A.setPythonContext(pde) A.setUp() # Create a Conjugate Gradient Krylov solver ksp = PETSc.KSP().create() ksp.setType(PETSc.KSP.Type.CG) # Use diagonal preconditioning ksp.getPC().setType(PETSc.PC.Type.JACOBI) # Allow command-line customization ksp.setFromOptions() # Assemble right-hand side and solve the linear system pde.formRHS(b) ksp.setOperators(A) ksp.solve(b, x) # Here we programmatically visualize the solution if OptDB.getBool('plot', True): # Modify the option database: keep the X window open for 1 second OptDB['draw_pause'] = 1 # Obtain a viewer of type DRAW draw = PETSc.Viewer.DRAW(x.comm) # View the vector in the X window draw(x) # We can also visualize the solution by command line options # For example, we can dump a VTK file with: # # $ python poisson2d.py -plot 0 -view_solution vtk:sol.vts: # # or obtain the same visualization as programmatically done above as: # # $ python poisson2d.py -plot 0 -view_solution draw -draw_pause 1 # x.viewFromOptions('-view_solution') ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/demo/python_types/matpython_protocol.py0000644000175000017500000001216714567251135022405 0ustar00balaybalayfrom petsc4py.typing import Scalar from petsc4py.PETSc import Mat from petsc4py.PETSc import Vec from petsc4py.PETSc import IS from petsc4py.PETSc import InsertMode from petsc4py.PETSc import NormType from petsc4py.PETSc import Viewer # A template class with the Python methods supported by MATPYTHON class MatPythonProtocol: def mult(self, A: Mat, x: Vec, y: Vec) -> None: """Matrix vector multiplication: y = A @ x.""" ... def multAdd(self, A: Mat, x: Vec, y: Vec, z: Vec) -> None: """Matrix vector multiplication: z = A @ x + y.""" ... def multTranspose(self, A: Mat, x: Vec, y: Vec) -> None: """Transposed matrix vector multiplication: y = A^T @ x.""" ... def multTransposeAdd(self, A: Mat, x: Vec, y: Vec, z: Vec) -> None: """Transposed matrix vector multiplication: z = A^T @ x + y.""" ... def multHermitian(self, A: Mat, x: Vec, y: Vec) -> None: """Hermitian matrix vector multiplication: y = A^H @ x.""" ... def multHermitianAdd(self, A: Mat, x: Vec, y: Vec, z: Vec) -> None: """Hermitian matrix vector multiplication: z = A^H @ x + y.""" ... def view(self, A: Mat, viewer: Viewer) -> None: """View the matrix.""" ... def setFromOptions(self, A: Mat) -> None: """Process command line for customization.""" ... def multDiagonalBlock(self, A: Mat, x: Vec, y: Vec) -> None: """Perform the on-process matrix vector multiplication.""" ... def createVecs(self, A: Mat) -> tuple[Vec, Vec]: """Return tuple of vectors (x,y) suitable for A @ x = y.""" ... def scale(self, A: Mat, s: Scalar) -> None: """Scale the matrix by a scalar.""" ... def shift(self, A: Mat, s: Scalar) -> None: """Shift the matrix by a scalar.""" ... def createSubMatrix(self, A: Mat, r: IS, c: IS, out: Mat) -> Mat: """Return the submatrix corresponding to r rows and c columns. Matrix out must be reused if not None. """ ... def zeroRowsColumns(self, A: Mat, r: IS, diag: Scalar, x: Vec, b: Vec) -> None: """Zero rows and columns of the matrix corresponding to the index set r. Insert diag on the diagonal and modify vectors x and b accordingly if not None. """ ... def getDiagonal(self, A: Mat, d: Vec) -> None: """Compute the diagonal of the matrix: d = diag(A).""" ... def setDiagonal(self, A: Mat, d: Vec, im: InsertMode) -> None: """Set the diagonal of the matrix.""" ... def missingDiagonal(self, A: Mat, d: Vec, im: InsertMode) -> tuple[bool, int]: """Return a flag indicating if the matrix is missing a diagonal entry and the location.""" ... def diagonalScale(self, A: Mat, L: Vec, R: Vec) -> None: """Perform left and right diagonal scaling if vectors are not None. A = diag(L)@A@diag(R). """ ... def getDiagonalBlock(self, A: Mat) -> Mat: """Return the on-process matrix.""" ... def setUp(self, A: Mat) -> None: """Perform the required setup.""" ... def duplicate(self, A: Mat, op: Mat.DuplicateOption) -> Mat: """Duplicate the matrix.""" ... def copy(self, A: Mat, B: Mat, op: Mat.Structure) -> None: """Copy the matrix: B = A.""" ... def productSetFromOptions(self, A: Mat, prodtype: str, X: Mat, Y: Mat, Z: Mat) -> bool: """The boolean flag indicating if the matrix supports prodtype.""" ... def productSymbolic(self, A: Mat, product: Mat, producttype: str, X: Mat, Y: Mat, Z: Mat) -> None: """Perform the symbolic stage of the requested matrix product.""" ... def productNumeric(self, A: Mat, product: Mat, producttype: str, X: Mat, Y: Mat, Z: Mat) -> None: """Perform the numeric stage of the requested matrix product.""" ... def zeroEntries(self, A: Mat) -> None: """Set the matrix to zero.""" ... def norm(self, A: Mat, normtype: NormType) -> float: """Compute the norm of the matrix.""" ... def solve(self, A: Mat, y: Vec, x: Vec) -> None: """Solve the equation: x = inv(A) y.""" ... def solveAdd(self, A: Mat, y: Vec, z: Vec, x: Vec) -> None: """Solve the equation: x = inv(A) y + z.""" ... def solveTranspose(self, A: Mat, y: Vec, x: Vec) -> None: """Solve the equation: x = inv(A)^T y.""" ... def solveTransposeAdd(self, A: Mat, y: Vec, z: Vec, x: Vec) -> None: """Solve the equation: x = inv(A)^T y + z.""" ... def SOR(self, A: Mat, b: Vec, omega: float, sortype: Mat.SORType, shift: float, its: int, lits: int, x: Vec) -> None: """Perform SOR iterations.""" ... def conjugate(self, A: Mat) -> None: """Perform the conjugation of the matrix: A = conj(A).""" ... def imagPart(self, A: Mat) -> None: """Set real part to zero. A = imag(A).""" ... def realPart(self, A: sMat) -> None: """Set imaginary part to zero. A = real(A).""" ... ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/demo/python_types/pc.py0000644000175000017500000000053414567251135017036 0ustar00balaybalay# The user-defined Python class implementing the Jacobi method. class myJacobi: # Setup the internal data. In this case, we access the matrix diagonal. def setUp(self, pc): _, P = pc.getOperators() self.D = P.getDiagonal() # Apply the preconditioner def apply(self, pc, x, y): y.pointwiseDivide(x, self.D) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/demo/python_types/pcpython_protocol.py0000644000175000017500000000355114567251135022223 0ustar00balaybalayfrom petsc4py.PETSc import KSP from petsc4py.PETSc import PC from petsc4py.PETSc import Mat from petsc4py.PETSc import Vec from petsc4py.PETSc import Viewer # A template class with the Python methods supported by PCPYTHON class PCPythonProtocol: def apply(self, pc: PC, b: Vec, x: Vec) -> None: """Apply the preconditioner on vector b, return in x.""" ... def applySymmetricLeft(self, pc: PC, b: Vec, x: Vec) -> None: """Apply the symmetric left part of the preconditioner on vector b, return in x.""" ... def applySymmetricRight(self, pc: PC, b: Vec, x: Vec) -> None: """Apply the symmetric right part of the preconditioner on vector b, return in x.""" ... def applyTranspose(self, pc: PC, b: Vec, x: Vec) -> None: """Apply the transposed preconditioner on vector b, return in x.""" ... def applyMat(self, pc: PC, B: Mat, X: Mat) -> None: """Apply the preconditioner on a block of right-hand sides B, return in X.""" ... def preSolve(self, pc: PC, ksp: KSP, b: Vec, x: Vec) -> None: """Callback called at the beginning of a Krylov method. This method is allowed to modify the right-hand side b and the initial guess x. """ ... def postSolve(self, pc: PC, ksp: KSP, b: Vec, x: Vec) -> None: """Callback called at the end of a Krylov method. This method is allowed to modify the right-hand side b and the solution x. """ def view(self, pc: PC, viewer: Viewer) -> None: """View the preconditioner.""" ... def setFromOptions(self, pc: PC) -> None: """Process command line for customization.""" ... def setUp(self, pc: PC) -> None: """Perform the required setup.""" ... def reset(self, pc: PC) -> None: """Reset the preconditioner.""" ... ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1709010084.3903754 petsc4py-3.20.5/docs/0000755000175000017500000000000014567266244013326 5ustar00balaybalay././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/docs/index.rst0000644000175000017500000000360514567251135015164 0ustar00balaybalay================ PETSc for Python ================ :Author: Lisandro Dalcin :Contact: dalcinl@gmail.com Online Documentation -------------------- + `User Manual (HTML)`_ (generated with Sphinx_). + `User Manual (PDF)`_ (generated with Sphinx_). + `API Reference`_ (generated with Sphinx_). .. _User Manual (HTML): html/index.html .. _User Manual (PDF): petsc4py.pdf .. _API Reference: html/reference/index.html .. _Sphinx: https://www.sphinx-doc.org/ .. _Epydoc: https://epydoc.sourceforge.net/ Discussion and Support ---------------------- + Mailing Lists: petsc-users@mcs.anl.gov, petsc-dev@mcs.anl.gov Downloads and Development ------------------------- + Issue Tracker: https://gitlab.com/petsc/petsc/-/issues + Git Repository: https://gitlab.com/petsc/petsc.git + The source code is in ``src/binding/petsc4py`` + Previous source releases: https://pypi.org/project/petsc4py/ Citations --------- If PETSc for Python been significant to a project that leads to an academic publication, please acknowledge that fact by citing the project. * L. Dalcin, P. Kler, R. Paz, and A. Cosimo, *Parallel Distributed Computing using Python*, Advances in Water Resources, 34(9):1124-1139, 2011. http://dx.doi.org/10.1016/j.advwatres.2011.04.013 * S. Balay, S. Abhyankar, M. Adams, J. Brown, P. Brune, K. Buschelman, L. Dalcin, A. Dener, V. Eijkhout, W. Gropp, D. Karpeyev, D. Kaushik, M. Knepley, D. May, L. Curfman McInnes, R. Mills, T. Munson, K. Rupp, P. Sanan, B. Smith, S. Zampini, H. Zhang, and H. Zhang, *PETSc Users Manual*, ANL-95/11 - Revision 3.17, 2022. https://petsc.org/release/docs/manual Acknowledgments --------------- This project was partially supported by the Extreme Computing Research Center (ECRC), Division of Computer, Electrical, and Mathematical Sciences & Engineering (CEMSE), King Abdullah University of Science and Technology (KAUST). ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1709010084.3933752 petsc4py-3.20.5/docs/source/0000755000175000017500000000000014567266244014626 5ustar00balaybalay././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/docs/source/.gitignore0000644000175000017500000000005314567251135016605 0ustar00balaybalay_build/ reference/ petsc_objects.inv demo/ ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/docs/source/Makefile0000644000175000017500000000117214567251135016260 0ustar00balaybalay# Minimal makefile for Sphinx documentation # # You can set these variables from the command line, and also # from the environment for the first two. SPHINXOPTS ?= SPHINXBUILD ?= sphinx-build SOURCEDIR = . BUILDDIR = _build # Put it first so that "make" without argument is like "make help". help: @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) .PHONY: help Makefile # Catch-all target: route all unknown targets to Sphinx using the new # "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). %: Makefile @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1709010084.3943753 petsc4py-3.20.5/docs/source/_templates/0000755000175000017500000000000014567266244016763 5ustar00balaybalay././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1709010084.3943753 petsc4py-3.20.5/docs/source/_templates/autosummary/0000755000175000017500000000000014567266244021351 5ustar00balaybalay././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/docs/source/_templates/autosummary/class.rst0000644000175000017500000000415714567251135023210 0ustar00balaybalay{{ fullname | escape | underline}} {%- if autotype is defined %} {%- set objtype = autotype.get(name) or objtype %} {%- endif %} .. auto{{ objtype }}:: {{ module}}.{{ objname }} :show-inheritance: {%- for item in ['__new__', '__init__'] %} {%- if item in members and item not in inherited_members %} {%- endif %} {%- endfor %} {%- for item in ['__new__', '__init__'] %} {%- if item in methods %} {%- set dummy = methods.remove(item) %} {%- endif %} {%- endfor %} {%- for item in inherited_members %} {%- if item in methods %} {%- set dummy = methods.remove(item) %} {%- endif %} {%- if item in attributes %} {%- set dummy = attributes.remove(item) %} {%- endif %} {%- endfor %} {%- set enumerations = [] %} {%- for item in members %} {%- if item not in inherited_members and item not in all_methods and item not in all_attributes %} {%- set dummy = enumerations.append(item) %} {%- endif %} {%- endfor %} {% block enumerations_documentation %} {%- if enumerations %} .. rubric:: Enumerations .. autosummary:: :toctree: {%+ for item in enumerations %} ~{{ fullname }}.{{ item }} {%- endfor %} {%- endif %} {%- endblock %} {% block methods_summary %} {%- if methods %} .. rubric:: Methods Summary .. autosummary:: {%+ for item in methods %} ~{{ fullname }}.{{ item }} {%- endfor %} {%- endif %} {%- endblock %} {% block attributes_summary %} {%- if attributes %} .. rubric:: Attributes Summary .. autosummary:: {%+ for item in attributes %} ~{{ fullname }}.{{ item }} {%- endfor %} {%- endif %} {%- endblock %} {% block methods_documentation %} {%- if methods %} .. rubric:: Methods Documentation {%+ for item in methods %} .. automethod:: {{ item }} {%- endfor %} {%- endif %} {%- endblock %} {% block attributes_documentation %} {%- if attributes %} .. rubric:: Attributes Documentation {%+ for item in attributes %} .. autoattribute:: {{ item }} {%- endfor %} {%- endif %} {%- endblock %} {# #} ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/docs/source/_templates/autosummary/module.rst0000644000175000017500000000233514567251135023364 0ustar00balaybalay{{ fullname | escape | underline}} .. automodule:: {{ fullname }} {%- if synopsis is defined %} :synopsis: {{ synopsis.get(fullname, '') }} {%- endif %} {% block classes %} {%- if classes %} .. rubric:: {{ _('Classes') }} .. autosummary:: :toctree: {% for item in classes %} {{ item }} {%- endfor %} {%- endif %} {%- endblock %} {% block exceptions %} {%- if exceptions %} .. rubric:: {{ _('Exceptions') }} .. autosummary:: :toctree: {% for item in exceptions %} {{ item }} {%- endfor %} {%- endif %} {%- endblock %} {% block functions %} {%- if functions %} .. rubric:: {{ _('Functions') }} .. autosummary:: :toctree: {% for item in functions %} {{ item }} {%- endfor %} {%- endif %} {%- endblock %} {% block attributes %} {%- if attributes %} .. rubric:: {{ _('Attributes') }} .. autosummary:: :toctree: {% for item in attributes %} {{ item }} {%- endfor %} {%- endif %} {%- endblock %} {% block modules %} {%- if modules %} .. rubric:: {{ _('Modules') }} .. autosummary:: :toctree: :recursive: {% for item in modules %} {{ item }} {%- endfor %} {%- endif %} {%- endblock %} ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/docs/source/_templates/layout.html0000644000175000017500000000057314567251135021164 0ustar00balaybalay{% extends "!layout.html" %} {% macro menu_genindex() -%} {%- endmacro %} {% block menu %} {{ super() }} {%- if builder == 'html' %} {{ menu_genindex() }} {%- endif %} {%- if builder == 'dirhtml' %} {{ menu_genindex() }} {%- endif %} {% endblock %} ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/docs/source/apidoc.py0000644000175000017500000003546714567251135016447 0ustar00balaybalayimport os import sys import inspect import textwrap from sphinx.util import logging logger = logging.getLogger(__name__) def is_cyfunction(obj): return type(obj).__name__ == 'cython_function_or_method' def is_function(obj): return ( inspect.isbuiltin(obj) or is_cyfunction(obj) or type(obj) is type(ord) ) def is_method(obj): return ( inspect.ismethoddescriptor(obj) or inspect.ismethod(obj) or is_cyfunction(obj) or type(obj) in ( type(str.index), type(str.__add__), type(str.__new__), ) ) def is_classmethod(obj): return ( inspect.isbuiltin(obj) or type(obj).__name__ in ( 'classmethod', 'classmethod_descriptor', ) ) def is_staticmethod(obj): return ( type(obj).__name__ in ( 'staticmethod', ) ) def is_constant(obj): return isinstance(obj, (int, float, str, dict)) def is_datadescr(obj): return inspect.isdatadescriptor(obj) and not hasattr(obj, 'fget') def is_property(obj): return inspect.isdatadescriptor(obj) and hasattr(obj, 'fget') def is_class(obj): return inspect.isclass(obj) or type(obj) is type(int) class Lines(list): INDENT = " " * 4 level = 0 @property def add(self): return self @add.setter def add(self, lines): if lines is None: return if isinstance(lines, str): lines = textwrap.dedent(lines).strip().split('\n') indent = self.INDENT * self.level for line in lines: self.append(indent + line) def signature(obj): doc = obj.__doc__ doc = doc or f"{obj.__name__}: Any" # FIXME remove line sig = doc.partition('\n')[0].split('.', 1)[-1] return sig or None def docstring(obj): doc = obj.__doc__ doc = doc or '' # FIXME link = None sig = None cl = is_class(obj) if cl: doc = doc.strip() else: sig, _, doc = doc.partition('\n') doc, _, link = doc.rpartition('\n') summary, _, docbody = doc.partition('\n') summary = summary.strip() docbody = textwrap.dedent(docbody).strip() if docbody and sig: if not summary.endswith('.'): logger.warning(f'Summary for {sig} does not end with period.') if len(summary) > 79: logger.warning(f'Summary for {sig} too long.') # FIXME lines = docbody.split('\n') for i,l in enumerate(lines): if len(l) > 79: logger.warning(f'Line {i} for {sig} too long.') #init = ("Collective.", "Not collective.", "Logically collective.", "Neighborwise collective.") #if lines[0] not in init: # logger.warning(f'Unexpected collectiveness specification for {sig}\nFound {lines[0]}') if link: linktxt, _, link = link.rpartition(' ') linkloc = link.replace(':','#L') # FIXME do we want to use a special section? # section = f'References\n----------`' section = '\n' linkbody = f':sources:`{linktxt} {link} <{linkloc}>`' linkbody = f'{section}\n{linkbody}' if docbody: docbody = f'{docbody}\n\n{linkbody}' else: docbody = linkbody if docbody: doc = f'"""{summary}\n\n{docbody}\n\n"""' else: doc = f'"""{summary}"""' doc = textwrap.indent(doc, Lines.INDENT) return doc def visit_data(constant): name, value = constant typename = type(value).__name__ kind = "Constant" if isinstance(value, int) else "Object" init = f"_def({typename}, '{name}')" doc = f"#: {kind} ``{name}`` of type :class:`{typename}`" return f"{name}: {typename} = {init} {doc}\n" def visit_function(function): sig = signature(function) doc = docstring(function) body = Lines.INDENT + "..." return f"def {sig}:\n{doc}\n{body}\n" def visit_method(method): sig = signature(method) doc = docstring(method) body = Lines.INDENT + "..." return f"def {sig}:\n{doc}\n{body}\n" def visit_datadescr(datadescr, name=None): sig = signature(datadescr) doc = docstring(datadescr) name = sig.partition(':')[0].strip() or datadescr.__name__ type = sig.partition(':')[2].strip() or 'Any' sig = f"{name}(self) -> {type}" body = Lines.INDENT + "..." return f"@property\ndef {sig}:\n{doc}\n{body}\n" def visit_property(prop, name=None): sig = signature(prop.fget) name = name or prop.fget.__name__ type = sig.rsplit('->', 1)[-1].strip() sig = f"{name}(self) -> {type}" doc = f'"""{prop.__doc__}"""' doc = textwrap.indent(doc, Lines.INDENT) body = Lines.INDENT + "..." return f"@property\ndef {sig}:\n{doc}\n{body}\n" def visit_constructor(cls, name='__init__', args=None): init = (name == '__init__') argname = cls.__mro__[-2].__name__.lower() argtype = cls.__name__ initarg = args or f"{argname}: Optional[{argtype}] = None" selfarg = 'self' if init else 'cls' rettype = 'None' if init else argtype arglist = f"{selfarg}, {initarg}" sig = f"{name}({arglist}) -> {rettype}" ret = '...' if init else 'return super().__new__(cls)' body = Lines.INDENT + ret return f"def {sig}:\n{body}" def visit_class(cls, outer=None, done=None): skip = { '__doc__', '__dict__', '__module__', '__weakref__', '__pyx_vtable__', '__lt__', '__le__', '__ge__', '__gt__', '__enum2str', # FIXME refactor implementation '_traceback_', # FIXME maybe refactor? } special = { '__len__': "__len__(self) -> int", '__bool__': "__bool__(self) -> bool", '__hash__': "__hash__(self) -> int", '__int__': "__int__(self) -> int", '__index__': "__int__(self) -> int", '__str__': "__str__(self) -> str", '__repr__': "__repr__(self) -> str", '__eq__': "__eq__(self, other: object) -> bool", '__ne__': "__ne__(self, other: object) -> bool", } constructor = ( '__new__', '__init__', ) qualname = cls.__name__ cls_name = cls.__name__ if outer is not None and cls_name.startswith(outer): cls_name = cls_name[len(outer):] qualname = f"{outer}.{cls_name}" override = OVERRIDE.get(qualname, {}) done = set() if done is None else done lines = Lines() base = cls.__base__ if base is object: lines.add = f"class {cls_name}:" else: lines.add = f"class {cls_name}({base.__name__}):" lines.level += 1 lines.add = docstring(cls) for name in ('__new__', '__init__', '__hash__'): if name in cls.__dict__: done.add(name) dct = cls.__dict__ keys = list(dct.keys()) def dunder(name): return name.startswith('__') and name.endswith('__') def members(seq): for name in seq: if name in skip: continue if name in done: continue if dunder(name): if name not in special and name not in override: done.add(name) continue yield name for name in members(keys): attr = getattr(cls, name) if is_class(attr): done.add(name) lines.add = visit_class(attr, outer=cls_name) continue for name in members(keys): if name in override: done.add(name) lines.add = override[name] continue if name in special: done.add(name) sig = special[name] lines.add = f"def {sig}: ..." continue attr = getattr(cls, name) if is_method(attr): done.add(name) if name == attr.__name__: obj = dct[name] if is_classmethod(obj): lines.add = "@classmethod" elif is_staticmethod(obj): lines.add = "@staticmethod" lines.add = visit_method(attr) elif False: lines.add = f"{name} = {attr.__name__}" continue if is_datadescr(attr): done.add(name) lines.add = visit_datadescr(attr) continue if is_property(attr): done.add(name) lines.add = visit_property(attr, name) continue if is_constant(attr): done.add(name) lines.add = visit_data((name, attr)) continue leftovers = [name for name in keys if name not in done and name not in skip] if leftovers: raise RuntimeError(f"leftovers: {leftovers}") lines.level -= 1 return lines def visit_module(module, done=None): skip = { '__doc__', '__name__', '__loader__', '__spec__', '__file__', '__package__', '__builtins__', '__pyx_capi__', '__pyx_unpickle_Enum', # FIXME review } done = set() if done is None else done lines = Lines() keys = list(module.__dict__.keys()) keys.sort(key=lambda name: name.startswith("_")) constants = [ (name, getattr(module, name)) for name in keys if all(( name not in done and name not in skip, is_constant(getattr(module, name)), )) ] for _, value in constants: cls = type(value) name = cls.__name__ if name in done or name in skip: continue if cls.__module__ == module.__name__: done.add(name) lines.add = visit_class(cls) lines.add = "" for attr in constants: name, value = attr done.add(name) if name in OVERRIDE: lines.add = OVERRIDE[name] else: lines.add = visit_data((name, value)) if constants: lines.add = "" for name in keys: if name in done or name in skip: continue value = getattr(module, name) if is_class(value): done.add(name) if value.__name__ != name: continue if value.__module__ != module.__name__: continue lines.add = visit_class(value) lines.add = "" instances = [ (k, getattr(module, k)) for k in keys if all(( k not in done and k not in skip, type(getattr(module, k)) is value, )) ] for attrname, attrvalue in instances: done.add(attrname) lines.add = visit_data((attrname, attrvalue)) if instances: lines.add = "" continue if is_function(value): done.add(name) if name == value.__name__: lines.add = visit_function(value) else: lines.add = f"{name} = {value.__name__}" continue lines.add = "" for name in keys: if name in done or name in skip: continue value = getattr(module, name) done.add(name) if name in OVERRIDE: lines.add = OVERRIDE[name] else: lines.add = visit_data((name, value)) leftovers = [name for name in keys if name not in done and name not in skip] if leftovers: raise RuntimeError(f"leftovers: {leftovers}") return lines IMPORTS = """ from __future__ import annotations import sys from typing import ( Any, Union, Literal, Optional, NoReturn, Final, ) from typing import ( Callable, Hashable, Iterable, Iterator, Sequence, Mapping, ) if sys.version_info >= (3, 11): from typing import Self else: from typing_extensions import Self import numpy from numpy import dtype, ndarray from mpi4py.MPI import ( Intracomm, Datatype, Op, ) class _dtype: def __init__(self, name): self.name = name def __repr__(self): return self.name IntType: dtype = _dtype('IntType') RealType: dtype = _dtype('RealType') ComplexType: dtype = _dtype('ComplexType') ScalarType: dtype = _dtype('ScalarType') """ HELPERS = """ class _Int(int): pass class _Str(str): pass class _Float(float): pass class _Dict(dict): pass def _repr(obj): try: return obj._name except AttributeError: return super(obj).__repr__() def _def(cls, name): if cls is int: cls = _Int if cls is str: cls = _Str if cls is float: cls = _Float if cls is dict: cls = _Dict obj = cls() obj._name = name if '__repr__' not in cls.__dict__: cls.__repr__ = _repr return obj """ OVERRIDE = { } TYPING = """ from .typing import * """ def visit_petsc4py_PETSc(done=None): from petsc4py import PETSc lines = Lines() lines.add = f'"""{PETSc.__doc__}"""' lines.add = IMPORTS lines.add = "" lines.add = HELPERS lines.add = "" lines.add = visit_module(PETSc) lines.add = "" lines.add = TYPING return lines def generate(filename): dirname = os.path.dirname(filename) os.makedirs(dirname, exist_ok=True) with open(filename, 'w') as f: for line in visit_petsc4py_PETSc(): print(line, file=f) def load_module(filename, name=None): if name is None: name, _ = os.path.splitext( os.path.basename(filename)) module = type(sys)(name) module.__file__ = filename module.__package__ = name.rsplit('.', 1)[0] old = replace_module(module) with open(filename) as f: exec(f.read(), module.__dict__) # noqa: S102 restore_module(old) return module _sys_modules = {} def replace_module(module): name = module.__name__ assert name not in _sys_modules _sys_modules[name] = sys.modules[name] sys.modules[name] = module return _sys_modules[name] def restore_module(module): name = module.__name__ assert name in _sys_modules sys.modules[name] = _sys_modules[name] del _sys_modules[name] def annotate(dest, source): try: dest.__annotations__ = source.__annotations__ except AttributeError: pass if isinstance(dest, type): for name in dest.__dict__.keys(): if hasattr(source, name): obj = getattr(dest, name) annotate(obj, getattr(source, name)) if isinstance(dest, type(sys)): for name in dir(dest): if hasattr(source, name): obj = getattr(dest, name) mod = getattr(obj, '__module__', None) if dest.__name__ == mod: annotate(obj, getattr(source, name)) for name in dir(source): if not hasattr(dest, name): setattr(dest, name, getattr(source, name)) OUTDIR = 'reference' if __name__ == '__main__': generate(os.path.join(OUTDIR, 'petsc4py.PETSc.py')) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/docs/source/citing.rst0000644000175000017500000000164714567251135016636 0ustar00balaybalayCitations ========= If PETSc for Python been significant to a project that leads to an academic publication, please acknowledge that fact by citing the project. * L. Dalcin, P. Kler, R. Paz, and A. Cosimo, *Parallel Distributed Computing using Python*, Advances in Water Resources, 34(9):1124-1139, 2011. http://dx.doi.org/10.1016/j.advwatres.2011.04.013 * S. Balay, S. Abhyankar, M. Adams, S. Benson, J. Brown, P. Brune, K. Buschelman, E. Constantinescu, L. Dalcin, A. Dener, V. Eijkhout, J. Faibussowitsch, W. Gropp, V. Hapla, T. Isaac, P. Jolivet, D. Karpeyev, D. Kaushik, M. Knepley, F. Kong, S. Kruger, D. May, L. Curfman McInnes, R. Mills, L. Mitchell, T. Munson, J. Roman, K. Rupp, P. Sanan, J Sarich, B. Smith, S. Zampini, H. Zhang, and H. Zhang, J. Zhang, *PETSc/TAO Users Manual*, ANL-21/39 - Revision 3.20, 2023. http://dx.doi.org/10.2172/2205494, https://petsc.org/release/docs/manual/manual.pdf ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/docs/source/conf.py0000644000175000017500000003261114567251135016121 0ustar00balaybalay# Configuration file for the Sphinx documentation builder. # # For the full list of built-in configuration values, see the documentation: # https://www.sphinx-doc.org/en/master/usage/configuration.html # -- Path setup -------------------------------------------------------------- # If extensions (or modules to document with autodoc) are in another directory, # add these directories to sys.path here. If the directory is relative to the # documentation root, use os.path.abspath to make it absolute, like shown here. import re import os import shutil import sys import typing import datetime import importlib import sphobjinv import functools import pylit from sphinx.ext.napoleon.docstring import NumpyDocstring sys.path.insert(0, os.path.abspath('.')) _today = datetime.datetime.now() # -- Project information ----------------------------------------------------- # https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information package = 'petsc4py' docdir = os.path.abspath(os.path.dirname(__file__)) topdir = os.path.abspath(os.path.join(docdir, *[os.path.pardir]*2)) def pkg_version(): with open(os.path.join(topdir, 'src', package, '__init__.py')) as f: m = re.search(r"__version__\s*=\s*'(.*)'", f.read()) return m.groups()[0] def get_doc_branch(): release = 1 if topdir.endswith(os.path.join(os.path.sep, 'src', 'binding', package)): rootdir = os.path.abspath(os.path.join(topdir, *[os.path.pardir]*3)) rootname = package.replace('4py', '') version_h = os.path.join(rootdir, 'include', f'{rootname}version.h') if os.path.exists(version_h) and os.path.isfile(version_h): release_macro = f'{rootname.upper()}_VERSION_RELEASE' version_re = re.compile(rf"#define\s+{release_macro}\s+([-]*\d+)") with open(version_h, 'r') as f: release = int(version_re.search(f.read()).groups()[0]) return 'release' if release else 'main' project = 'PETSc for Python' author = 'Lisandro Dalcin' copyright = f'{_today.year}, {author}' release = pkg_version() version = release.rsplit('.', 1)[0] # -- General configuration --------------------------------------------------- # https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration extensions = [ 'sphinx.ext.autodoc', 'sphinx.ext.autosummary', 'sphinx.ext.intersphinx', 'sphinx.ext.napoleon', 'sphinx.ext.extlinks', ] templates_path = ['_templates'] exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store'] needs_sphinx = '5.0.0' default_role = 'any' pygments_style = 'tango' nitpicky = True nitpick_ignore = [ ('envvar', 'NUMPY_INCLUDE'), ('py:class', 'ndarray'), # FIXME ('py:class', 'typing_extensions.Self'), ] nitpick_ignore_regex = [ (r'c:.*', r'MPI_.*'), (r'c:.*', r'Petsc.*'), (r'envvar', r'(LD_LIBRARY_)?PATH'), (r'envvar', r'(MPICH|OMPI|MPIEXEC)_.*'), ] toc_object_entries = False toc_object_entries_show_parents = 'hide' # python_use_unqualified_type_names = True autodoc_class_signature = 'separated' autodoc_typehints = 'description' autodoc_typehints_format = 'short' autodoc_mock_imports = [] autodoc_type_aliases = {} autosummary_context = { 'synopsis': {}, 'autotype': {}, } # Links depends on the actual branch -> release or main www = f'https://gitlab.com/petsc/petsc/-/tree/{get_doc_branch()}' extlinks = {'sources': (f'{www}/src/binding/petsc4py/src/%s','')} napoleon_preprocess_types = True try: import sphinx_rtd_theme if 'sphinx_rtd_theme' not in extensions: extensions.append('sphinx_rtd_theme') except ImportError: sphinx_rtd_theme = None intersphinx_mapping = { 'python': ('https://docs.python.org/3/', None), 'numpy': ('https://numpy.org/doc/stable/', None), 'numpydoc': ('https://numpydoc.readthedocs.io/en/latest/', None), 'mpi4py': ('https://mpi4py.readthedocs.io/en/stable/', None), 'pyopencl': ('https://documen.tician.de/pyopencl/', None), 'dlpack': ('https://dmlc.github.io/dlpack/latest/', None), 'petsc': ('https://petsc.org/release/', None), } def _mangle_petsc_intersphinx(): """Preprocess the keys in PETSc's intersphinx inventory. PETSc have intersphinx keys of the form: manualpages/Vec/VecShift instead of: petsc.VecShift This function downloads their object inventory and strips the leading path elements so that references to PETSc names actually resolve.""" website = intersphinx_mapping['petsc'][0].partition('/release/')[0] branch = get_doc_branch() doc_url = f"{website}/{branch}/" if 'LOC' in os.environ and os.path.isfile(os.path.join(os.environ['LOC'],'objects.inv')): inventory_url=f"file://" + os.path.join(os.environ['LOC'],'objects.inv') else: inventory_url=f"{doc_url}objects.inv" print("Using PETSC inventory from "+inventory_url) inventory = sphobjinv.Inventory(url=inventory_url) print(inventory) for obj in inventory.objects: if obj.name.startswith("manualpages"): obj.name = "petsc." + "/".join(obj.name.split("/")[2:]) obj.role = "class" obj.domain = "py" new_inventory_filename = "petsc_objects.inv" sphobjinv.writebytes( new_inventory_filename, sphobjinv.compress(inventory.data_file(contract=True)) ) intersphinx_mapping['petsc'] = (doc_url, new_inventory_filename) _mangle_petsc_intersphinx() def _setup_mpi4py_typing(): pkg = type(sys)('mpi4py') mod = type(sys)('mpi4py.MPI') mod.__package__ = pkg.__name__ sys.modules[pkg.__name__] = pkg sys.modules[mod.__name__] = mod for clsname in ( 'Intracomm', 'Datatype', 'Op', ): cls = type(clsname, (), {}) cls.__module__ = mod.__name__ setattr(mod, clsname, cls) def _patch_domain_python(): from sphinx.domains.python import PythonDomain PythonDomain.object_types['data'].roles += ('class',) def _setup_autodoc(app): from sphinx.ext import autodoc from sphinx.util import inspect from sphinx.util import typing # def stringify_annotation(annotation, mode='fully-qualified-except-typing'): qualname = getattr(annotation, '__qualname__', '') module = getattr(annotation, '__module__', '') args = getattr(annotation, '__args__', None) if module == 'builtins' and qualname and args is not None: args = ', '.join(stringify_annotation(a, mode) for a in args) return f'{qualname}[{args}]' return stringify_annotation_orig(annotation, mode) try: stringify_annotation_orig = typing.stringify_annotation inspect.stringify_annotation = stringify_annotation typing.stringify_annotation = stringify_annotation autodoc.stringify_annotation = stringify_annotation autodoc.typehints.stringify_annotation = stringify_annotation except AttributeError: stringify_annotation_orig = typing.stringify inspect.stringify_annotation = stringify_annotation typing.stringify = stringify_annotation autodoc.stringify_typehint = stringify_annotation # class ClassDocumenterMixin: def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) if self.config.autodoc_class_signature == 'separated': members = self.options.members special_members = self.options.special_members if special_members is not None: for name in ('__new__', '__init__'): if name in members: members.remove(name) if name in special_members: special_members.remove(name) class ClassDocumenter( ClassDocumenterMixin, autodoc.ClassDocumenter, ): pass class ExceptionDocumenter( ClassDocumenterMixin, autodoc.ExceptionDocumenter, ): pass app.add_autodocumenter(ClassDocumenter, override=True) app.add_autodocumenter(ExceptionDocumenter, override=True) def _monkey_patch_returns(): """Rewrite the role of names in "Returns" sections. This is needed because Napoleon uses ``:class:`` for the return types and this does not work with type aliases like ``ArrayScalar``. To resolve this we swap ``:class:`` for ``:any:``. """ _parse_returns_section = \ NumpyDocstring._parse_returns_section @functools.wraps(NumpyDocstring._parse_returns_section) def wrapper(*args, **kwargs): out = _parse_returns_section(*args, **kwargs) return [line.replace(":class:", ":any:") for line in out] NumpyDocstring._parse_returns_section = wrapper def _monkey_patch_see_also(): """Rewrite the role of names in "see also" sections. Napoleon uses :obj: for all names found in "see also" sections but we need :all: so that references to labels work.""" _parse_numpydoc_see_also_section = \ NumpyDocstring._parse_numpydoc_see_also_section @functools.wraps(NumpyDocstring._parse_numpydoc_see_also_section) def wrapper(*args, **kwargs): out = _parse_numpydoc_see_also_section(*args, **kwargs) return [line.replace(":obj:", ":any:") for line in out] NumpyDocstring._parse_numpydoc_see_also_section = wrapper def _apply_monkey_patches(): """Modify Napoleon types after parsing to make references work.""" _monkey_patch_returns() _monkey_patch_see_also() _apply_monkey_patches() def _process_demos(*demos): # Convert demo .py files to rst. Also copy the .py file so it can be # linked from the demo rst file. try: os.mkdir("demo") except FileExistsError: pass for demo in demos: demo_dir = os.path.join("demo", os.path.dirname(demo)) demo_src = os.path.join(os.pardir, os.pardir, "demo", demo) try: os.mkdir(demo_dir) except FileExistsError: pass with open(demo_src, "r") as infile: with open(os.path.join( os.path.join("demo", os.path.splitext(demo)[0] + ".rst")), "w" ) as outfile: converter = pylit.Code2Text(infile) outfile.write(str(converter)) demo_copy_name = os.path.join(demo_dir, os.path.basename(demo)) shutil.copyfile(demo_src, demo_copy_name) html_static_path.append(demo_copy_name) with open(os.path.join("demo", "demo.rst"), "w") as demofile: demofile.write(""" petsc4py demos ============== .. toctree:: """) for demo in demos: demofile.write(" " + os.path.splitext(demo)[0] + "\n") demofile.write("\n") html_static_path=[] _process_demos( "poisson2d/poisson2d.py" ) def setup(app): _setup_mpi4py_typing() _patch_domain_python() _monkey_patch_returns() _monkey_patch_see_also() _setup_autodoc(app) try: from petsc4py import PETSc except ImportError: autodoc_mock_imports.append('PETSc') return del PETSc.DA # FIXME sys_dwb = sys.dont_write_bytecode sys.dont_write_bytecode = True import apidoc sys.dont_write_bytecode = sys_dwb name = PETSc.__name__ here = os.path.abspath(os.path.dirname(__file__)) outdir = os.path.join(here, apidoc.OUTDIR) source = os.path.join(outdir, f'{name}.py') getmtime = os.path.getmtime generate = ( not os.path.exists(source) or getmtime(source) < getmtime(PETSc.__file__) or getmtime(source) < getmtime(apidoc.__file__) ) if generate: apidoc.generate(source) module = apidoc.load_module(source) apidoc.replace_module(module) modules = [ 'petsc4py', ] typing_overload = typing.overload typing.overload = lambda arg: arg for name in modules: mod = importlib.import_module(name) ann = apidoc.load_module(f'{mod.__file__}i', name) apidoc.annotate(mod, ann) typing.overload = typing_overload from petsc4py import typing as tp for attr in tp.__all__: autodoc_type_aliases[attr] = f'~petsc4py.typing.{attr}' # -- Options for HTML output ------------------------------------------------- # https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. html_theme = 'pydata_sphinx_theme' html_theme_options = { "navigation_with_keys":True } # -- Options for HTMLHelp output ------------------------------------------ # Output file base name for HTML help builder. htmlhelp_basename = f'{package}-man' # -- Options for LaTeX output --------------------------------------------- # (source start file, target name, title, # author, documentclass [howto, manual, or own class]). latex_documents = [ ('index', f'{package}.tex', project, author, 'howto'), ] latex_elements = { 'papersize': 'a4', } # -- Options for manual page output --------------------------------------- # (source start file, name, description, authors, manual section). man_pages = [ ('index', package, project, [author], 3) ] # -- Options for Texinfo output ------------------------------------------- # (source start file, target name, title, author, # dir menu entry, description, category) texinfo_documents = [ ('index', package, project, author, package, f'{project}.', 'Miscellaneous'), ] # -- Options for Epub output ---------------------------------------------- # Output file base name for ePub builder. epub_basename = package ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/docs/source/documentation_standards.rst0000644000175000017500000001012014567251135022257 0ustar00balaybalayDocumentation standards for PETSc4py ==================================== Subject to exceptions given below, new contributions to PETSc4py **must** include `type annotations ` for function parameters and results, and docstrings on every class, function and method. The documentation should be consistent with the corresponding C API documentation, including copying text where this is appropriate. More in-depth documentation from the C API (such as extended discussions of algorithmic or performance factors) should not be copied. Docstring standards ------------------- Docstrings are to be written in `numpydoc:format` format. The first line of a function or method docstring must be a short description of the method in imperative mood ("Return the norm of the matrix.") "Return" is to be preferred over "Get" in this sentence. A blank line must follow this description. Use one-liner descriptions for properties. If the corresponding C API documentation lists a function as being collective, then this information must be repeated on the next line of the docstring. Valid strings are: "Not collective.", "Logically collective.", "Collective.", or "Neighborwise collective.". The initial description section can contain more information if this is useful. In particular, if there is a PETSc manual chapter about a class, then this should be referred to from here. Use double backticks around literals (like strings and numbers). E.g. \`\`2\`\`, \`\`"foo"\`\`. Reference PETSc functions simply using backticks. eg: `petsc.KSP`. refers to the PETSc C documentation for KSP. Do **not** use URLs in docstrings. Always use Intersphinx references. The following sections describe the use of numpydoc sections. Other sections allowed by numpydoc may be included if they are useful. Parameters .......... This is required unless there are no parameters, or it will be completely obvious to even a novice user what the parameters do. Types should only be specified in this section if for some reason the types provided by typing prove to be inadequate. If no type is being specified, do not include a colon (``:``) to the right of the parameter name. Use `Sys.getDefaultComm` when specifying the default communicator. Returns ....... This should only be specified if the return value is not obvious from the initial description and typing. If a "Returns" section is required, the type of the returned items *must* be specified, even if this duplicates typing information. See Also ........ If any of the following apply, then this section is required. The order of entries is as follows. Other links are permitted in this section if they add information useful to users. Every ``setFromOptions`` must include the link \`petsc_options\`. Any closely related part of the PETSc4py API not already linked in the docstring should appear (e.g. setters and getters should cross-refer). If there is a corresponding C API documentation page, this must be linked from the "See also" section. E.g. \`petsc.MatSetValues\`. End docstring with an empty line - "closing three quotation marks must be on a line by itself, preferably preceded by a blank line" .. warning:: The docstrings must not cause Sphinx warnings. Type hint standards ------------------- If returning ``self``, use ``-> Self`` in function signature. Type hints are not required when the static type signature includes a PETSc type (e.g. ``Vec x``). These will be automatically generated. This will also work for ``= None``. When using type hints, use spacing around the equals in any ``= None``. Communicators in type signatures must use Python typing instead of c-typing (i.e. ``comm: Comm`` not ``Comm comm``). This is because communicators can come from ``mpi4py`` and not just the ``petsc4py.PETSc.Comm`` class. For petsc4py native types that are can be strings, the type is ``argument: KSP.Type | str`` (not eg: ``KSPType argument``). If the type is strictly an enum the ``| str`` can be omitted. Full signature example:: def setType(self, ksp_type: KSP.Type | str) -> None: If a NumPy is returned, use ``ArrayInt``/``ArrayReal``/``ArrayScalar`` as the return type. ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/docs/source/index.rst0000644000175000017500000000244214567251135016462 0ustar00balaybalay================ PETSc for Python ================ .. only:: html or man :Author: Lisandro Dalcin :Contact: dalcinl@gmail.com :Web Site: https://gitlab.com/petsc/petsc :Date: |today| .. topic:: Abstract This document describes petsc4py_, a Python_ wrapper to the PETSc_ libraries. PETSc_ (the Portable, Extensible Toolkit for Scientific Computation) is a suite of data structures and routines for the scalable (parallel) solution of scientific applications modeled by partial differential equations. It employs the MPI_ standard for all message-passing communication. This package provides an important subset of PETSc functionalities and uses NumPy_ to efficiently manage input and output of array data. A *good friend* of petsc4py is: * mpi4py_: Python bindings for MPI_, the *Message Passing Interface*. Other projects depends on petsc4py: * slepc4py_: Python bindings for SLEPc_, the *Scalable Library for Eigenvalue Problem Computations*. .. include:: links.txt .. toctree:: :caption: Contents :maxdepth: 2 overview install citing .. toctree:: :caption: Python specifics :maxdepth: 2 reference petsc_python_types petsc_options demo/demo documentation_standards ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/docs/source/install.rst0000644000175000017500000000317214567251135017022 0ustar00balaybalayInstallation ============ .. _petsc4py_install: Install from PyPI using **pip** ------------------------------- You can use :program:`pip` to install :mod:`petsc4py` and its dependencies (:mod:`mpi4py` is optional but highly recommended):: $ python -m pip install mpi4py petsc petsc4py Install from the PETSc source tree ---------------------------------- First `build PETSc `. Next :file:`cd` to the top of the PETSc source tree and set the `PETSC_DIR ` and `PETSC_ARCH ` environment variables. Run:: $ python -m pip install src/binding/petsc4py The installation of :mod:`petsc4py` supports multiple `PETSC_ARCH ` in the the form of colon separated list:: $ PETSC_ARCH='arch-0:...:arch-N' python -m pip install src/binding/petsc4py If you are cross-compiling, and the :mod:`numpy` module cannot be loaded on your build host, then before invoking :file:`pip`, set the :envvar:`NUMPY_INCLUDE` environment variable to the path that would be returned by :samp:`import numpy; numpy.get_include()`:: $ export NUMPY_INCLUDE=/usr/lib/pythonX/site-packages/numpy/core/include Building the documentation -------------------------- Install the documentation dependencies using the ``[doc]`` extra:: $ python -m pip install "src/binding/petsc4py[doc]" Then:: $ cd src/binding/petsc4py/docs/source $ make html The resulting HTML files will be in :file:`_build/html`. .. note:: Building the documentation requires Python 3.11 or later. .. note:: All new code must include documentation in accordance with the `documentation standard ` ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/docs/source/links.txt0000644000175000017500000000066714567251135016511 0ustar00balaybalay.. _MPI: http://www.mpi-forum.org .. _MPICH: http://www.mpich.org/ .. _Open MPI: http://www.open-mpi.org .. _PETSc: https://petsc.org .. _SLEPc: http://slepc.upv.es .. _Python: http://www.python.org .. _NumPy: http://www.numpy.org .. _mpi4py: http://github.com/mpi4py/mpi4py .. _petsc4py: http://gitlab.com/petsc/petsc4py .. _slepc4py: http://gitlab.com/slepc/slepc4py ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/docs/source/overview.rst0000644000175000017500000001030714567251135017220 0ustar00balaybalayOverview ======== PETSc_ is a suite of data structures and routines for the scalable (parallel) solution of scientific applications modeled by partial differential equations. It employs the MPI_ standard for all message-passing communication. PETSc is intended for use in large-scale application projects [petsc-efficient]_, and several ongoing computational science projects are built around the PETSc libraries. With strict attention to component interoperability, PETSc facilitates the integration of independently developed application modules, which often most naturally employ different coding styles and data structures. PETSc is easy to use for beginners [petsc-user-ref]_. Moreover, its careful design allows advanced users to have detailed control over the solution process. PETSc includes an expanding suite of parallel linear and nonlinear equation solvers that are easily used in application codes written in C, C++, and Fortran. PETSc provides many of the mechanisms needed within parallel application codes, such as simple parallel matrix and vector assembly routines that allow the overlap of communication and computation. .. [petsc-user-ref] S. Balay, S. Abhyankar, M. Adams, S. Benson, J. Brown, P. Brune, K. Buschelman, E. Constantinescu, L. Dalcin, A. Dener, V. Eijkhout, J. Faibussowitsch, W. Gropp, V. Hapla, T. Isaac, P. Jolivet, D. Karpeyev, D. Kaushik, M. Knepley, F. Kong, S. Kruger, D. May, L. Curfman McInnes, R. Mills, L. Mitchell, T. Munson, J. Roman, K. Rupp, P. Sanan, J Sarich, B. Smith, S. Zampini, H. Zhang, and H. Zhang, J. Zhang, *PETSc/TAO Users Manual*, ANL-21/39 - Revision 3.20, 2023. http://dx.doi.org/10.2172/2205494, https://petsc.org/release/docs/manual/manual.pdf .. [petsc-efficient] Satish Balay, Victor Eijkhout, William D. Gropp, Lois Curfman McInnes and Barry F. Smith. Efficient Management of Parallelism in Object Oriented Numerical Software Libraries. Modern Software Tools in Scientific Computing. E. Arge, A. M. Bruaset and H. P. Langtangen, editors. 163--202. Birkhauser Press. 1997. .. include:: links.txt Components ---------- PETSc is designed with an object-oriented style. Almost all user-visible types are abstract interfaces with implementations that may be chosen at runtime. Those objects are managed through handles to opaque data structures which are created, accessed and destroyed by calling appropriate library routines. PETSc consists of a variety of components. Each component manipulates a particular family of objects and the operations one would like to perform on these objects. These components provide the functionality required for many parallel solutions of PDEs. :Vec: Provides the vector operations required for setting up and solving large-scale linear and nonlinear problems. Includes easy-to-use parallel scatter and gather operations, as well as special-purpose code for handling ghost points for regular data structures. :Mat: A large suite of data structures and code for the manipulation of parallel sparse matrices. Includes four different parallel matrix data structures, each appropriate for a different class of problems. :PC: A collection of sequential and parallel preconditioners, including (sequential) ILU(k), LU, and (both sequential and parallel) block Jacobi, overlapping additive Schwarz methods and (through BlockSolve95) ILU(0) and ICC(0). :KSP: Parallel implementations of many popular Krylov subspace iterative methods, including GMRES, CG, CGS, Bi-CG-Stab, two variants of TFQMR, CR, and LSQR. All are coded so that they are immediately usable with any preconditioners and any matrix data structures, including matrix-free methods. :SNES: Data-structure-neutral implementations of Newton-like methods for nonlinear systems. Includes both line search and trust region techniques with a single interface. Employs by default the above data structures and linear solvers. Users can set custom monitoring routines, convergence criteria, etc. :TS: Code for the time evolution of solutions of PDEs. In addition, provides pseudo-transient continuation techniques for computing steady-state solutions. ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/docs/source/petsc_options.rst0000644000175000017500000000013114567251135020235 0ustar00balaybalay.. _petsc_options: Working with PETSc options (TODO) ================================= ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/docs/source/petsc_python_types.rst0000644000175000017500000000577114567251135021326 0ustar00balaybalay.. _petsc_python_types: PETSc Python types ================== Here we discuss details about Python-aware PETSc types that can be used within the library. In particular, we discuss matrices, preconditioners, Krylov solvers, nonlinear solvers and ODE integrators. The low-level, Cython implementation exposing the Python methods is contained in :file:`${PETSC_DIR}/src/binding/petsc4py/src/petsc4py/PETSc/libpetsc4py.pyx` The scripts can be found in :file:`${PETSC_DIR}/src/binding/petsc4py/demo/python_types`. .. _petsc_python_mat: PETSc Python matrix type ------------------------ PETSc provides a convenient way to compute the action of linear operators coded in Python through the `petsc4py.PETSc.Mat.Type.PYTHON` type. In addition to the matrix action, the implementation can expose additional methods for use within the library. A template class for the supported methods is given below. .. literalinclude:: ../../demo/python_types/matpython_protocol.py In the example below, we create an operator that applies the Laplacian operator on a two-dimensional grid, and use it to solve the associated linear system. The default preconditioner in the script is `petsc4py.PETSc.PC.Type.JACOBI` which needs to access the diagonal of the matrix. .. literalinclude:: ../../demo/python_types/mat.py .. _petsc_python_pc: PETSc Python preconditioner type -------------------------------- The protocol for the `petsc4py.PETSc.PC.Type.PYTHON` preconditioner is: .. literalinclude:: ../../demo/python_types/pcpython_protocol.py In the example below, we create a Jacobi preconditioner, which needs to access the diagonal of the matrix. The action of the preconditioner consists of the pointwise multiplication of the inverse diagonal with the input vector. .. literalinclude:: ../../demo/python_types/pc.py We can run the script used to test our matrix class and use command line arguments to specify that our preconditioner should be used: .. code-block:: console $ python mat.py -pc_type python -pc_python_type pc.myJacobi -ksp_view KSP Object: 1 MPI process type: cg maximum iterations=10000, initial guess is zero tolerances: relative=1e-05, absolute=1e-50, divergence=10000. left preconditioning using PRECONDITIONED norm type for convergence test PC Object: 1 MPI process type: python Python: pc.myJacobi linear system matrix = precond matrix: Mat Object: 1 MPI process type: python rows=256, cols=256 Python: __main__.Poisson2D .. _petsc_python_ksp: PETSc Python linear solver type ------------------------------- The protocol for the `petsc4py.PETSc.KSP.Type.PYTHON` Krylov solver is: .. literalinclude:: ../../demo/python_types/ksppython_protocol.py .. _petsc_python_snes: PETSc Python nonlinear solver type (TODO) ----------------------------------------- .. _petsc_python_ts: PETSc Python ode-integrator type (TODO) --------------------------------------- .. _petsc_python_tao: PETSc Python optimization solver type (TODO) -------------------------------------------- ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/docs/source/reference.rst0000644000175000017500000000020014567251135017277 0ustar00balaybalay.. _reference: Reference ========= .. autosummary:: :toctree: reference/ petsc4py petsc4py.typing petsc4py.PETSc ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1709010084.4503753 petsc4py-3.20.5/setup.cfg0000644000175000017500000000046114567266244014220 0ustar00balaybalay[config] petsc_dir = $PETSC_DIR petsc_arch = $PETSC_ARCH [build] debug = 0 [sdist] force_manifest = 1 [nosetests] where = test [options.extras_require] doc = pydata-sphinx-theme==0.15.1 sphinx>=7.0.0 sphobjinv typing_extensions;python_version<'3.11' pylit [egg_info] tag_build = tag_date = 0 ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/setup.py0000755000175000017500000001777514567251135014125 0ustar00balaybalay#!/usr/bin/env python # Author: Lisandro Dalcin # Contact: dalcinl@gmail.com import re import os import sys try: import setuptools except ImportError: setuptools = None topdir = os.path.abspath(os.path.dirname(__file__)) sys.path.insert(0, os.path.join(topdir, 'conf')) pyver = sys.version_info[:2] if pyver < (2, 6) or (3, 0) <= pyver < (3, 2): raise RuntimeError("Python version 2.6, 2.7 or >= 3.2 required") if pyver == (2, 6) or pyver == (3, 2): sys.stderr.write( "WARNING: Python %d.%d is not supported.\n" % pyver) PNAME = 'PETSc' EMAIL = 'petsc-maint@mcs.anl.gov' PLIST = [PNAME] # -------------------------------------------------------------------- # Metadata # -------------------------------------------------------------------- def F(string): return string.format( Name=PNAME, name=PNAME.lower(), pyname=PNAME.lower()+'4py', ) def get_name(): return F('{pyname}') def get_version(): try: return get_version.result except AttributeError: pass pkg_init_py = os.path.join(F('{pyname}'), '__init__.py') with open(os.path.join(topdir, 'src', pkg_init_py)) as f: m = re.search(r"__version__\s*=\s*'(.*)'", f.read()) version = m.groups()[0] get_version.result = version return version def description(): return F('{Name} for Python') def long_description(): with open(os.path.join(topdir, 'DESCRIPTION.rst')) as f: return f.read() url = F('https://gitlab.com/{name}/{name}') pypiroot = F('https://pypi.io/packages/source') pypislug = F('{pyname}')[0] + F('/{pyname}') tarball = F('{pyname}-%s.tar.gz' % get_version()) download = '/'.join([pypiroot, pypislug, tarball]) classifiers = """ License :: OSI Approved :: BSD License Operating System :: POSIX Intended Audience :: Developers Intended Audience :: Science/Research Programming Language :: C Programming Language :: C++ Programming Language :: Cython Programming Language :: Python Programming Language :: Python :: 2 Programming Language :: Python :: 3 Programming Language :: Python :: Implementation :: CPython Topic :: Scientific/Engineering Topic :: Software Development :: Libraries :: Python Modules Development Status :: 5 - Production/Stable """.strip().split('\n') keywords = """ scientific computing parallel computing MPI """.strip().split('\n') platforms = """ POSIX Linux macOS FreeBSD """.strip().split('\n') metadata = { 'name' : get_name(), 'version' : get_version(), 'description' : description(), 'long_description' : long_description(), 'url' : url, 'download_url' : download, 'classifiers' : classifiers, 'keywords' : keywords + PLIST, 'license' : 'BSD-2-Clause', 'platforms' : platforms, 'author' : 'Lisandro Dalcin', 'author_email' : 'dalcinl@gmail.com', 'maintainer' : F('{Name} Team'), 'maintainer_email' : EMAIL, } metadata.update({ 'requires': ['numpy'], }) metadata_extra = { 'long_description_content_type': 'text/x-rst', } # -------------------------------------------------------------------- # Extension modules # -------------------------------------------------------------------- def sources(): src = dict( source=F('{pyname}/{Name}.pyx'), depends=[ F('{pyname}/*.pyx'), F('{pyname}/*.pxd'), F('{pyname}/{Name}/*.pyx'), F('{pyname}/{Name}/*.pxd'), F('{pyname}/{Name}/*.pxi'), ], workdir='src', ) return [src] def extensions(): from os import walk from glob import glob from os.path import join # depends = [] glob_join = lambda *args: glob(join(*args)) for pth, dirs, files in walk('src'): depends += glob_join(pth, '*.h') depends += glob_join(pth, '*.c') for pkg in map(str.lower, reversed(PLIST)): if (pkg.upper()+'_DIR') in os.environ: pd = os.environ[pkg.upper()+'_DIR'] pa = os.environ.get('PETSC_ARCH', '') depends += glob_join(pd, 'include', '*.h') depends += glob_join(pd, 'include', pkg, 'private', '*.h') depends += glob_join(pd, pa, 'include', '%sconf.h' % pkg) # include_dirs = [] numpy_include = os.environ.get('NUMPY_INCLUDE') if numpy_include is not None: numpy_includes = [numpy_include] else: try: import numpy numpy_includes = [numpy.get_include()] except ImportError: numpy_includes = [] include_dirs.extend(numpy_includes) if F('{pyname}') != 'petsc4py': try: import petsc4py petsc4py_includes = [petsc4py.get_include()] except ImportError: petsc4py_includes = [] include_dirs.extend(petsc4py_includes) # ext = dict( name=F('{pyname}.lib.{Name}'), sources=[F('src/{pyname}/{Name}.c')], depends=depends, include_dirs=[ 'src', F('src/{pyname}/include'), ] + include_dirs, define_macros=[ ('MPICH_SKIP_MPICXX', 1), ('OMPI_SKIP_MPICXX', 1), ('NPY_NO_DEPRECATED_API', 'NPY_1_7_API_VERSION'), ], ) return [ext] # -------------------------------------------------------------------- # Setup # -------------------------------------------------------------------- def get_release(): suffix = os.path.join('src', 'binding', F('{pyname}')) if not topdir.endswith(os.path.join(os.path.sep, suffix)): return True release = 1 rootdir = os.path.abspath(os.path.join(topdir, *[os.path.pardir]*3)) version_h = os.path.join(rootdir, 'include', F('{name}version.h')) release_macro = '%s_VERSION_RELEASE' % F('{name}').upper() version_re = re.compile(r"#define\s+%s\s+([-]*\d+)" % release_macro) if os.path.exists(version_h) and os.path.isfile(version_h): with open(version_h, 'r') as f: release = int(version_re.search(f.read()).groups()[0]) return bool(release) def requires(pkgname, major, minor, release=True): minor = minor + int(not release) devel = '' if release else '.dev0' vmin = "%s.%s%s" % (major, minor, devel) vmax = "%s.%s" % (major, minor + 1) return "%s>=%s,<%s" % (pkgname, vmin, vmax) def run_setup(): setup_args = metadata.copy() vstr = setup_args['version'].split('.')[:2] x, y = tuple(map(int, vstr)) release = get_release() if not release: setup_args['version'] = "%d.%d.0.dev0" %(x, y+1) if setuptools: setup_args['zip_safe'] = False setup_args['install_requires'] = ['numpy'] for pkg in map(str.lower, PLIST): PKG_DIR = os.environ.get(pkg.upper() + '_DIR') if not (PKG_DIR and os.path.isdir(PKG_DIR)): package = requires(pkg, x, y, release) setup_args['install_requires'] += [package] if F('{pyname}') != 'petsc4py': package = requires('petsc4py', x, y, release) setup_args['install_requires'] += [package] setup_args.update(metadata_extra) # conf = __import__(F('conf{name}')) conf.setup( packages=[ F('{pyname}'), F('{pyname}.lib'), ], package_dir={'' : 'src'}, package_data={ F('{pyname}'): [ F('{Name}.pxd'), F('{Name}*.h'), F('include/{pyname}/*.h'), F('include/{pyname}/*.i'), 'py.typed', '*.pyi', '*/*.pyi', ], F('{pyname}.lib'): [ F('{name}.cfg'), ], }, cython_sources=[ src for src in sources() ], ext_modules=[ conf.Extension(**ext) for ext in extensions() ], **setup_args ) # -------------------------------------------------------------------- def main(): run_setup() if __name__ == '__main__': main() # -------------------------------------------------------------------- ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1709010084.3943753 petsc4py-3.20.5/src/0000755000175000017500000000000014567266244013165 5ustar00balaybalay././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/src/cython.h0000644000175000017500000000332314567251135014634 0ustar00balaybalaystatic void *Cython_ImportFunction(PyObject *module, const char *funcname, const char *signature) { PyObject *capi = NULL, *capsule = NULL; void *p = NULL; capi = PyObject_GetAttrString(module, (char *)"__pyx_capi__"); if (!capi) goto bad; capsule = PyDict_GetItemString(capi, (char *)funcname); if (!capsule) { PyErr_Format(PyExc_ImportError, "%s does not export expected C function %s", PyModule_GetName(module), funcname); goto bad; } #if PY_VERSION_HEX < 0x03020000 if (PyCObject_Check(capsule)) { const char *desc, *s1, *s2; desc = (const char *)PyCObject_GetDesc(capsule); if (!desc) goto bad; s1 = desc; s2 = signature; while (*s1 != '\0' && *s1 == *s2) { s1++; s2++; } if (*s1 != *s2) { PyErr_Format(PyExc_TypeError, "C function %s.%s has wrong signature " "(expected %s, got %s)", PyModule_GetName(module), funcname, signature, desc); goto bad; } p = PyCObject_AsVoidPtr(capsule); } #endif #if PY_VERSION_HEX >= 0x02070000 if (PyCapsule_CheckExact(capsule)) { if (!PyCapsule_IsValid(capsule, signature)) { const char *desc = PyCapsule_GetName(capsule); PyErr_Format(PyExc_TypeError, "C function %s.%s has wrong signature " "(expected %s, got %s)", PyModule_GetName(module), funcname, signature, desc); goto bad; } p = PyCapsule_GetPointer(capsule, signature); } #endif Py_DECREF(capi); return p; bad: Py_XDECREF(capi); return NULL; } /* Local variables: c-basic-offset: 2 indent-tabs-mode: nil End: */ ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1709010084.3953753 petsc4py-3.20.5/src/lib-petsc/0000755000175000017500000000000014567266244015047 5ustar00balaybalay././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1709010084.3973753 petsc4py-3.20.5/src/lib-petsc/compat/0000755000175000017500000000000014567266244016332 5ustar00balaybalay././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/src/lib-petsc/compat/cuda.h0000644000175000017500000000242414567251135017412 0ustar00balaybalay#ifndef PETSC4PY_COMPAT_CUDA_H #define PETSC4PY_COMPAT_CUDA_H #if !defined(PETSC_HAVE_CUDA) #define PetscCUDAError do { \ PetscFunctionBegin; \ SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"%s() requires CUDA",PETSC_FUNCTION_NAME); \ PetscFunctionReturn(PETSC_ERR_SUP);} while (0) PetscErrorCode MatDenseCUDAGetArrayRead(PETSC_UNUSED Mat A, PETSC_UNUSED const PetscScalar **gpuarray) {PetscCUDAError;} PetscErrorCode MatDenseCUDARestoreArrayRead(PETSC_UNUSED Mat A, PETSC_UNUSED const PetscScalar **gpuarray) {PetscCUDAError;} PetscErrorCode MatDenseCUDAGetArrayWrite(PETSC_UNUSED Mat A, PETSC_UNUSED PetscScalar **gpuarray) {PetscCUDAError;} PetscErrorCode MatDenseCUDARestoreArrayWrite(PETSC_UNUSED Mat A, PETSC_UNUSED PetscScalar **gpuarray) {PetscCUDAError;} PetscErrorCode MatDenseCUDAGetArray(PETSC_UNUSED Mat A, PETSC_UNUSED PetscScalar **gpuarray) {PetscCUDAError;} PetscErrorCode MatDenseCUDARestoreArray(PETSC_UNUSED Mat A, PETSC_UNUSED PetscScalar **gpuarray) {PetscCUDAError;} PetscErrorCode MatCreateDenseCUDA(PETSC_UNUSED MPI_Comm comm, PETSC_UNUSED PetscInt m, PETSC_UNUSED PetscInt n, PETSC_UNUSED PetscInt M, PETSC_UNUSED PetscInt N, PETSC_UNUSED PetscScalar gpuarray[], PETSC_UNUSED Mat *A) {PetscCUDAError;} #undef PetscCUDAError #endif #endif/*PETSC4PY_COMPAT_CUDA_H*/ ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/src/lib-petsc/compat/h2opus.h0000644000175000017500000000175714567251135017726 0ustar00balaybalay#ifndef PETSC4PY_COMPAT_H2OPUS_H #define PETSC4PY_COMPAT_H2OPUS_H #if !defined(PETSC_HAVE_H2OPUS) #define PetscMatH2OPUSError do { \ PetscFunctionBegin; \ SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"%s() requires H2OPUS",PETSC_FUNCTION_NAME); \ PetscFunctionReturn(PETSC_ERR_SUP);} while (0) PetscErrorCode MatCreateH2OpusFromMat(PETSC_UNUSED Mat a,PETSC_UNUSED PetscInt b,PETSC_UNUSED const PetscReal c[],PETSC_UNUSED PetscBool d,PETSC_UNUSED PetscReal e,PETSC_UNUSED PetscInt f,PETSC_UNUSED PetscInt g,PETSC_UNUSED PetscInt h,PETSC_UNUSED PetscReal i,PETSC_UNUSED Mat* l) {PetscMatH2OPUSError;} PetscErrorCode MatH2OpusOrthogonalize(PETSC_UNUSED Mat a) {PetscMatH2OPUSError;} PetscErrorCode MatH2OpusCompress(PETSC_UNUSED Mat a,PETSC_UNUSED PetscReal b) {PetscMatH2OPUSError;} PetscErrorCode MatH2OpusLowRankUpdate(PETSC_UNUSED Mat a,PETSC_UNUSED Mat b,PETSC_UNUSED Mat c,PETSC_UNUSED PetscScalar d) {PetscMatH2OPUSError;} #undef PetscMatH2OPUSError #endif #endif/*PETSC4PY_COMPAT_H2OPUS_H*/ ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/src/lib-petsc/compat/hdf5.h0000644000175000017500000000242314567251135017323 0ustar00balaybalay#ifndef PETSC4PY_COMPAT_HDF5_H #define PETSC4PY_COMPAT_HDF5_H #include #if !defined(PETSC_HAVE_HDF5) #define PetscViewerHDF5Error do { \ PetscFunctionBegin; \ SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"%s() requires HDF5",PETSC_FUNCTION_NAME); \ PetscFunctionReturn(PETSC_ERR_SUP);} while (0) PetscErrorCode PetscViewerHDF5PushGroup(PETSC_UNUSED PetscViewer vw,PETSC_UNUSED const char g[]){PetscViewerHDF5Error;} PetscErrorCode PetscViewerHDF5PopGroup(PETSC_UNUSED PetscViewer vw){PetscViewerHDF5Error;} PetscErrorCode PetscViewerHDF5GetGroup(PETSC_UNUSED PetscViewer vw, PETSC_UNUSED const char p[], PETSC_UNUSED char *g[]){PetscViewerHDF5Error;} PetscErrorCode PetscViewerHDF5PushTimestepping(PETSC_UNUSED PetscViewer vw){PetscViewerHDF5Error;} PetscErrorCode PetscViewerHDF5PopTimestepping(PETSC_UNUSED PetscViewer vw){PetscViewerHDF5Error;} PetscErrorCode PetscViewerHDF5SetTimestep(PETSC_UNUSED PetscViewer vw, PETSC_UNUSED PetscInt n){PetscViewerHDF5Error;} PetscErrorCode PetscViewerHDF5GetTimestep(PETSC_UNUSED PetscViewer vw, PETSC_UNUSED PetscInt*n){PetscViewerHDF5Error;} PetscErrorCode PetscViewerHDF5IncrementTimestep(PETSC_UNUSED PetscViewer vw){PetscViewerHDF5Error;} #undef PetscViewerHDF5Error #endif #endif/*PETSC4PY_COMPAT_HDF5_H*/ ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/src/lib-petsc/compat/hip.h0000644000175000017500000000053214567251135017254 0ustar00balaybalay#ifndef PETSC4PY_COMPAT_HIP_H #define PETSC4PY_COMPAT_HIP_H #if !defined(PETSC_HAVE_HIP) #define PetscHIPError do { \ PetscFunctionBegin; \ SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"%s() requires HIP",PETSC_FUNCTION_NAME); \ PetscFunctionReturn(PETSC_ERR_SUP);} while (0) #undef PetscHIPError #endif #endif/*PETSC4PY_COMPAT_HIP_H*/ ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/src/lib-petsc/compat/hpddm.h0000644000175000017500000000266114567251135017575 0ustar00balaybalay#ifndef PETSC4PY_COMPAT_HPDDM_H #define PETSC4PY_COMPAT_HPDDM_H #if !defined(PETSC_HAVE_HPDDM) #define PetscHPDDMError do { \ PetscFunctionBegin; \ SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"%s() requires HPDDM",PETSC_FUNCTION_NAME); \ PetscFunctionReturn(PETSC_ERR_SUP);} while (0) PetscErrorCode KSPHPDDMSetType(PETSC_UNUSED KSP ksp,PETSC_UNUSED KSPHPDDMType type){PetscHPDDMError;} PetscErrorCode KSPHPDDMGetType(PETSC_UNUSED KSP ksp,PETSC_UNUSED KSPHPDDMType *type){PetscHPDDMError;} PetscErrorCode PCHPDDMSetAuxiliaryMat(PETSC_UNUSED PC pc,PETSC_UNUSED IS is,PETSC_UNUSED Mat aux,PETSC_UNUSED PetscErrorCode (*setup)(Mat,PetscReal,Vec,Vec,PetscReal,IS,void*),PETSC_UNUSED void* ctx){PetscHPDDMError;} PetscErrorCode PCHPDDMSetRHSMat(PETSC_UNUSED PC pc,PETSC_UNUSED Mat B){PetscHPDDMError;} PetscErrorCode PCHPDDMHasNeumannMat(PETSC_UNUSED PC pc,PETSC_UNUSED PetscBool has){PetscHPDDMError;} PetscErrorCode PCHPDDMSetCoarseCorrectionType(PETSC_UNUSED PC pc,PETSC_UNUSED PCHPDDMCoarseCorrectionType type){PetscHPDDMError;} PetscErrorCode PCHPDDMGetCoarseCorrectionType(PETSC_UNUSED PC pc,PETSC_UNUSED PCHPDDMCoarseCorrectionType *type){PetscHPDDMError;} PetscErrorCode PCHPDDMGetSTShareSubKSP(PETSC_UNUSED PC pc,PETSC_UNUSED PetscBool *share){PetscHPDDMError;} PetscErrorCode PCHPDDMSetDeflationMat(PETSC_UNUSED PC pc,PETSC_UNUSED IS is,PETSC_UNUSED Mat U){PetscHPDDMError;} #undef PetscHPDDMError #endif #endif/*PETSC4PY_COMPAT_HPDDM_H*/ ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/src/lib-petsc/compat/hypre.h0000644000175000017500000000263714567251135017633 0ustar00balaybalay#ifndef PETSC4PY_COMPAT_HYPRE_H #define PETSC4PY_COMPAT_HYPRE_H #if !defined(PETSC_HAVE_HYPRE) #define PetscPCHYPREError do { \ PetscFunctionBegin; \ SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"%s() requires HYPRE",PETSC_FUNCTION_NAME); \ PetscFunctionReturn(PETSC_ERR_SUP);} while (0) PetscErrorCode PCHYPREGetType(PETSC_UNUSED PC pc,PETSC_UNUSED const char *name[]){PetscPCHYPREError;} PetscErrorCode PCHYPRESetType(PETSC_UNUSED PC pc,PETSC_UNUSED const char name[]){PetscPCHYPREError;} PetscErrorCode PCHYPRESetDiscreteCurl(PETSC_UNUSED PC pc,PETSC_UNUSED Mat C){PetscPCHYPREError;} PetscErrorCode PCHYPRESetDiscreteGradient(PETSC_UNUSED PC pc,PETSC_UNUSED Mat G){PetscPCHYPREError;} PetscErrorCode PCHYPRESetAlphaPoissonMatrix(PETSC_UNUSED PC pc,PETSC_UNUSED Mat A){PetscPCHYPREError;} PetscErrorCode PCHYPRESetBetaPoissonMatrix(PETSC_UNUSED PC pc,PETSC_UNUSED Mat B){PetscPCHYPREError;} PetscErrorCode PCHYPRESetInterpolations(PETSC_UNUSED PC pc,PETSC_UNUSED PetscInt dim,PETSC_UNUSED Mat RT_Pi_Full,PETSC_UNUSED Mat RT_Pi[],PETSC_UNUSED Mat ND_Pi_Full,PETSC_UNUSED Mat ND_Pi[]){PetscPCHYPREError;} PetscErrorCode PCHYPRESetEdgeConstantVectors(PETSC_UNUSED PC pc,PETSC_UNUSED Vec ozz,PETSC_UNUSED Vec zoz,PETSC_UNUSED Vec zzo){PetscPCHYPREError;} PetscErrorCode PCHYPREAMSSetInteriorNodes(PETSC_UNUSED PC pc,PETSC_UNUSED Vec interior){PetscPCHYPREError;} #undef PetscPCHYPREError #endif #endif/*PETSC4PY_COMPAT_HYPRE_H*/ ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/src/lib-petsc/compat/mpi.h0000644000175000017500000001113614567251135017263 0ustar00balaybalay#ifndef PETSC4PY_COMPAT_MPI_H #define PETSC4PY_COMPAT_MPI_H #if defined(OPEN_MPI) /* * The hackery below redefines the actual calls to 'MPI_Init()' and * 'MPI_Init_thread()' in order to preload the main MPI dynamic * library with appropriate flags to 'dlopen()' ensuring global * availability of library symbols. */ #if !defined(OPENMPI_DLOPEN_LIBMPI) && defined(OMPI_MAJOR_VERSION) #if OMPI_MAJOR_VERSION >= 3 && OMPI_MAJOR_VERSION < 10 #define OPENMPI_DLOPEN_LIBMPI 0 #endif #endif #ifndef OPENMPI_DLOPEN_LIBMPI #define OPENMPI_DLOPEN_LIBMPI 1 #endif #if OPENMPI_DLOPEN_LIBMPI #if HAVE_DLOPEN #if HAVE_DLFCN_H #include #else #if defined(__linux__) #define RTLD_LAZY 0x00001 #define RTLD_NOW 0x00002 #define RTLD_LOCAL 0x00000 #define RTLD_GLOBAL 0x00100 #define RTLD_NOLOAD 0x00004 #define RTLD_NODELETE 0x01000 #define RTLD_DEEPBIND 0x00008 #elif defined(__APPLE__) #define RTLD_LAZY 0x1 #define RTLD_NOW 0x2 #define RTLD_LOCAL 0x4 #define RTLD_GLOBAL 0x8 #define RTLD_NOLOAD 0x10 #define RTLD_NODELETE 0x80 #define RTLD_FIRST 0x100 #elif defined(__CYGWIN__) #define RTLD_LAZY 1 #define RTLD_NOW 2 #define RTLD_LOCAL 0 #define RTLD_GLOBAL 4 #endif #if defined(__cplusplus) || defined(c_plusplus) extern "C" { #endif extern void *dlopen(const char *, int); extern void *dlsym(void *, const char *); extern int dlclose(void *); extern char *dlerror(void); #if defined(__cplusplus) || defined(c_plusplus) } #endif #endif #ifndef RTLD_LAZY #define RTLD_LAZY 1 #endif #ifndef RTLD_NOW #define RTLD_NOW RTLD_LAZY #endif #ifndef RTLD_LOCAL #define RTLD_LOCAL 0 #endif #ifndef RTLD_GLOBAL #define RTLD_GLOBAL RTLD_LOCAL #endif /* static void * my_dlopen(const char *name, int mode) { void *handle; static int called = 0; if (!called) { called = 1; #if HAVE_DLFCN_H printf("HAVE_DLFCN_H: yes\n"); #else printf("HAVE_DLFCN_H: no\n"); #endif printf("\n"); printf("RTLD_LAZY: 0x%X\n", RTLD_LAZY); printf("RTLD_NOW: 0x%X\n", RTLD_NOW); printf("RTLD_LOCAL: 0x%X\n", RTLD_LOCAL); printf("RTLD_GLOBAL: 0x%X\n", RTLD_GLOBAL); #ifdef RTLD_NOLOAD printf("RTLD_NOLOAD: 0x%X\n", RTLD_NOLOAD); #endif printf("\n"); } handle = dlopen(name, mode); printf("dlopen(\"%s\",0x%X) -> %p\n", name, mode, handle); printf("dlerror() -> %s\n\n", dlerror()); return handle; } #define dlopen my_dlopen */ static void OPENMPI_dlopen_libmpi(void) { void *handle = 0; int mode = RTLD_NOW | RTLD_GLOBAL; #if defined(__APPLE__) /* macOS */ #ifdef RTLD_NOLOAD mode |= RTLD_NOLOAD; #endif #if defined(OMPI_MAJOR_VERSION) #if OMPI_MAJOR_VERSION == 3 if (!handle) handle = dlopen("libmpi.40.dylib", mode); #elif OMPI_MAJOR_VERSION == 2 if (!handle) handle = dlopen("libmpi.20.dylib", mode); #elif OMPI_MAJOR_VERSION == 1 && OMPI_MINOR_VERSION >= 10 if (!handle) handle = dlopen("libmpi.12.dylib", mode); #elif OMPI_MAJOR_VERSION == 1 && OMPI_MINOR_VERSION >= 6 if (!handle) handle = dlopen("libmpi.1.dylib", mode); #elif OMPI_MAJOR_VERSION == 1 if (!handle) handle = dlopen("libmpi.0.dylib", mode); #endif #endif if (!handle) handle = dlopen("libmpi.dylib", mode); #else /* GNU/Linux and others */ #ifdef RTLD_NOLOAD mode |= RTLD_NOLOAD; #endif #if defined(OMPI_MAJOR_VERSION) #if OMPI_MAJOR_VERSION >= 10 /* IBM Spectrum MPI */ if (!handle) handle = dlopen("libmpi_ibm.so.2", mode); if (!handle) handle = dlopen("libmpi_ibm.so.1", mode); if (!handle) handle = dlopen("libmpi_ibm.so", mode); #elif OMPI_MAJOR_VERSION == 3 if (!handle) handle = dlopen("libmpi.so.40", mode); #elif OMPI_MAJOR_VERSION == 2 if (!handle) handle = dlopen("libmpi.so.20", mode); #elif OMPI_MAJOR_VERSION == 1 && OMPI_MINOR_VERSION >= 10 if (!handle) handle = dlopen("libmpi.so.12", mode); #elif OMPI_MAJOR_VERSION == 1 && OMPI_MINOR_VERSION >= 6 if (!handle) handle = dlopen("libmpi.so.1", mode); #elif OMPI_MAJOR_VERSION == 1 if (!handle) handle = dlopen("libmpi.so.0", mode); #endif #endif if (!handle) handle = dlopen("libmpi.so", mode); #endif } static PetscErrorCode PetscInitialize_OpenMPI(int *argc,char ***args, const char file[], const char help[]) { OPENMPI_dlopen_libmpi(); return PetscInitialize(argc,args,file,help); } #undef PetscInitialize #define PetscInitialize PetscInitialize_OpenMPI #endif /* HAVE_DLOPEN */ #endif /* OPENMPI_DLOPEN_LIBMPI */ #endif /* OPEN_MPI */ #endif/*PETSC4PY_COMPAT_MPI_H*/ ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/src/lib-petsc/compat/mumps.h0000644000175000017500000000257614567251135017647 0ustar00balaybalay#ifndef PETSC4PY_COMPAT_MUMPS_H #define PETSC4PY_COMPAT_MUMPS_H #include #if !defined(PETSC_HAVE_MUMPS) #define PetscMUMPSError do { \ PetscFunctionBegin; \ SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"%s() requires MUMPS",PETSC_FUNCTION_NAME); \ PetscFunctionReturn(PETSC_ERR_SUP);} while (0) PetscErrorCode MatMumpsSetIcntl(PETSC_UNUSED Mat F,PETSC_UNUSED PetscInt icntl,PETSC_UNUSED PetscInt ival){PetscMUMPSError;} PetscErrorCode MatMumpsGetIcntl(PETSC_UNUSED Mat F,PETSC_UNUSED PetscInt icntl,PETSC_UNUSED PetscInt *ival){PetscMUMPSError;} PetscErrorCode MatMumpsSetCntl(PETSC_UNUSED Mat F,PETSC_UNUSED PetscInt icntl,PETSC_UNUSED PetscReal val){PetscMUMPSError;} PetscErrorCode MatMumpsGetCntl(PETSC_UNUSED Mat F,PETSC_UNUSED PetscInt icntl,PETSC_UNUSED PetscReal *val){PetscMUMPSError;} PetscErrorCode MatMumpsGetInfo(PETSC_UNUSED Mat F,PETSC_UNUSED PetscInt icntl,PETSC_UNUSED PetscInt *ival){PetscMUMPSError;} PetscErrorCode MatMumpsGetInfog(PETSC_UNUSED Mat F,PETSC_UNUSED PetscInt icntl,PETSC_UNUSED PetscInt *ival){PetscMUMPSError;} PetscErrorCode MatMumpsGetRinfo(PETSC_UNUSED Mat F,PETSC_UNUSED PetscInt icntl,PETSC_UNUSED PetscReal *val){PetscMUMPSError;} PetscErrorCode MatMumpsGetRinfog(PETSC_UNUSED Mat F,PETSC_UNUSED PetscInt icntl,PETSC_UNUSED PetscReal *val){PetscMUMPSError;} #undef PetscMUMPSError #endif #endif/*PETSC4PY_COMPAT_MUMPS_H*/ ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/src/lib-petsc/compat/spai.h0000644000175000017500000000210514567251135017426 0ustar00balaybalay#ifndef PETSC4PY_COMPAT_SPAI_H #define PETSC4PY_COMPAT_SPAI_H #if !defined(PETSC_HAVE_SPAI) #define PetscSPAIError do { \ PetscFunctionBegin; \ SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"%s() requires SPAI",PETSC_FUNCTION_NAME); \ PetscFunctionReturn(PETSC_ERR_SUP);} while (0) PetscErrorCode PCSPAISetEpsilon(PETSC_UNUSED PC a,PETSC_UNUSED PetscReal b) {PetscSPAIError;} PetscErrorCode PCSPAISetNBSteps(PETSC_UNUSED PC a,PETSC_UNUSED PetscInt b) {PetscSPAIError;} PetscErrorCode PCSPAISetMax(PETSC_UNUSED PC a,PETSC_UNUSED PetscInt b) {PetscSPAIError;} PetscErrorCode PCSPAISetMaxNew(PETSC_UNUSED PC a,PETSC_UNUSED PetscInt b) {PetscSPAIError;} PetscErrorCode PCSPAISetBlockSize(PETSC_UNUSED PC a,PETSC_UNUSED PetscInt b) {PetscSPAIError;} PetscErrorCode PCSPAISetCacheSize(PETSC_UNUSED PC a,PETSC_UNUSED PetscInt b) {PetscSPAIError;} PetscErrorCode PCSPAISetVerbose(PETSC_UNUSED PC a,PETSC_UNUSED PetscInt b) {PetscSPAIError;} PetscErrorCode PCSPAISetSp(PETSC_UNUSED PC a,PETSC_UNUSED PetscInt b) {PetscSPAIError;} #undef PetscSPAIError #endif #endif/*PETSC4PY_COMPAT_SPAI_H*/ ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/src/lib-petsc/compat/tao.h0000644000175000017500000000334314567251135017262 0ustar00balaybalay#ifndef PETSC4PY_COMPAT_TAO_H #define PETSC4PY_COMPAT_TAO_H #if defined(PETSC_USE_COMPLEX) #define PetscTaoError do { \ PetscFunctionBegin; \ SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"%s() not supported with complex scalars",PETSC_FUNCTION_NAME); \ PetscFunctionReturn(PETSC_ERR_SUP);} while (0) PetscErrorCode TaoLMVMSetH0(PETSC_UNUSED Tao tao,PETSC_UNUSED Mat mat) {PetscTaoError;} PetscErrorCode TaoLMVMGetH0(PETSC_UNUSED Tao tao,PETSC_UNUSED Mat *mat) {PetscTaoError;} PetscErrorCode TaoLMVMGetH0KSP(PETSC_UNUSED Tao tao,PETSC_UNUSED KSP *ksp) {PetscTaoError;} PetscErrorCode TaoBRGNGetSubsolver(PETSC_UNUSED Tao tao,PETSC_UNUSED Tao *subsolver) {PetscTaoError;} PetscErrorCode TaoBRGNSetRegularizerObjectiveAndGradientRoutine(PETSC_UNUSED Tao tao,PETSC_UNUSED PetscErrorCode (*func)(Tao,Vec,PetscReal*,Vec,void*),PETSC_UNUSED void *ctx) {PetscTaoError;} PetscErrorCode TaoBRGNSetRegularizerHessianRoutine(PETSC_UNUSED Tao tao,PETSC_UNUSED Mat H,PETSC_UNUSED PetscErrorCode (*func)(Tao,Vec,Mat,void*),PETSC_UNUSED void *ctx) {PetscTaoError;} PetscErrorCode TaoBRGNSetRegularizerWeight(PETSC_UNUSED Tao tao,PETSC_UNUSED PetscReal weight) {PetscTaoError;} PetscErrorCode TaoBRGNSetL1SmoothEpsilon(PETSC_UNUSED Tao tao,PETSC_UNUSED PetscReal epsilon) {PetscTaoError;} PetscErrorCode TaoBRGNSetDictionaryMatrix(PETSC_UNUSED Tao tao,PETSC_UNUSED Mat D) {PetscTaoError;} PetscErrorCode TaoBRGNGetDampingVector(PETSC_UNUSED Tao tao,PETSC_UNUSED Vec *d) {PetscTaoError;} PetscErrorCode TaoBNCGSetType(PETSC_UNUSED Tao tao, PETSC_UNUSED TaoBNCGType type) {PetscTaoError;} PetscErrorCode TaoBNCGGetType(PETSC_UNUSED Tao tao, PETSC_UNUSED TaoBNCGType *type) {PetscTaoError;} #undef PetscTaoError #endif/*PETSC_USE_COMPLEX*/ #endif/*PETSC4PY_COMPAT_TAO_H*/ ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/src/lib-petsc/compat/viennacl.h0000644000175000017500000000213714567251135020276 0ustar00balaybalay#ifndef PETSC4PY_COMPAT_VIENNACL_H #define PETSC4PY_COMPAT_VIENNACL_H #if !defined(PETSC_HAVE_VIENNACL) #define PetscViennaCLError do { \ PetscFunctionBegin; \ SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"%s() requires ViennaCL",PETSC_FUNCTION_NAME); \ PetscFunctionReturn(PETSC_ERR_SUP);} while (0) PetscErrorCode VecCreateSeqViennaCLWithArrays(PETSC_UNUSED MPI_Comm comm,PETSC_UNUSED PetscInt bs,PETSC_UNUSED PetscInt n,PETSC_UNUSED PetscScalar cpuarray[],PETSC_UNUSED PetscScalar* viennaclvec,PETSC_UNUSED Vec *V) {PetscViennaCLError;} PetscErrorCode VecCreateMPIViennaCLWithArrays(PETSC_UNUSED MPI_Comm comm,PETSC_UNUSED PetscInt bs,PETSC_UNUSED PetscInt n,PETSC_UNUSED PetscInt N,PETSC_UNUSED PetscScalar cpuarray[],PETSC_UNUSED PetscScalar *viennaclvec,PETSC_UNUSED Vec *vv) {PetscViennaCLError;} #undef PetscViennaCLError # else PetscErrorCode VecCreateSeqViennaCLWithArrays(MPI_Comm,PetscInt,PetscInt,PetscScalar[],PetscScalar[],Vec*); PetscErrorCode VecCreateMPIViennaCLWithArrays(MPI_Comm,PetscInt,PetscInt,PetscInt,PetscScalar[],PetscScalar[],Vec*); #endif #endif/*PETSC4PY_COMPAT_VIENNACL_H*/ ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/src/lib-petsc/compat.h0000644000175000017500000000057614567251135016504 0ustar00balaybalay#ifndef PETSC4PY_COMPAT_H #define PETSC4PY_COMPAT_H #include #include "compat/mpi.h" #include "compat/hdf5.h" #include "compat/mumps.h" #include "compat/hypre.h" #include "compat/hpddm.h" #include "compat/viennacl.h" #include "compat/cuda.h" #include "compat/hip.h" #include "compat/tao.h" #include "compat/h2opus.h" #include "compat/spai.h" #endif/*PETSC4PY_COMPAT_H*/ ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/src/lib-petsc/custom.h0000644000175000017500000005155214567251135016533 0ustar00balaybalay#ifndef PETSC4PY_CUSTOM_H #define PETSC4PY_CUSTOM_H #include #include #include #include #include #include #include #include #include /* ---------------------------------------------------------------- */ #ifndef PETSC_ERR_PYTHON #define PETSC_ERR_PYTHON ((PetscErrorCode)(-1)) #endif #define PetscERROR(comm,FUNCT,n,t,msg,arg) \ PetscError(comm,__LINE__,FUNCT,__FILE__,n,t,msg,arg) /* ---------------------------------------------------------------- */ typedef PetscErrorCode (*PetscErrorHandlerFunction) (MPI_Comm,int,const char*,const char*, PetscErrorCode,PetscErrorType,const char*,void*); #define PetscTBEH PetscTraceBackErrorHandler /* ---------------------------------------------------------------- */ PETSC_EXTERN PetscErrorCode (*PetscPythonMonitorSet_C)(PetscObject,const char*); /* ---------------------------------------------------------------- */ static PetscErrorCode PetscLogStageFindId(const char name[], PetscLogStage *stageid) { PetscLogState log_state = NULL; PetscFunctionBegin; PetscAssertPointer(name,1); PetscAssertPointer(stageid,2); *stageid = -1; if (!(log_state = petsc_log_state)) PetscFunctionReturn(PETSC_SUCCESS); /* logging is off ? */ PetscCall(PetscLogStageGetId(name, stageid)); PetscFunctionReturn(PETSC_SUCCESS); } static PetscErrorCode PetscLogClassFindId(const char name[], PetscClassId *classid) { PetscLogState log_state = NULL; PetscFunctionBegin; PetscAssertPointer(name,1); PetscAssertPointer(classid,2); *classid = -1; if (!(log_state = petsc_log_state)) PetscFunctionReturn(PETSC_SUCCESS); /* logging is off ? */ PetscCall(PetscLogClassGetClassId(name, classid)); PetscFunctionReturn(PETSC_SUCCESS); } static PetscErrorCode PetscLogEventFindId(const char name[], PetscLogEvent *eventid) { PetscLogState log_state = NULL; PetscFunctionBegin; PetscAssertPointer(name,1); PetscAssertPointer(eventid,2); *eventid = -1; if (!(log_state = petsc_log_state)) PetscFunctionReturn(PETSC_SUCCESS); /* logging is off ? */ PetscCall(PetscLogEventGetId(name, eventid)); PetscFunctionReturn(PETSC_SUCCESS); } static PetscErrorCode PetscLogStageFindName(PetscLogStage stageid, const char *name[]) { PetscLogState log_state = NULL; PetscFunctionBegin; PetscAssertPointer(name,3); *name = NULL; if (!(log_state = petsc_log_state)) PetscFunctionReturn(PETSC_SUCCESS); /* logging is off ? */ PetscCall(PetscLogStageGetName(stageid, name)); PetscFunctionReturn(PETSC_SUCCESS); } static PetscErrorCode PetscLogClassFindName(PetscClassId classid, const char *name[]) { PetscLogState log_state = NULL; PetscFunctionBegin; PetscAssertPointer(name,3); *name = 0; if (!(log_state = petsc_log_state)) PetscFunctionReturn(PETSC_SUCCESS); /* logging is off ? */ PetscCall(PetscLogClassIdGetName(classid, name)); PetscFunctionReturn(PETSC_SUCCESS); } static PetscErrorCode PetscLogEventFindName(PetscLogEvent eventid, const char *name[]) { PetscLogState log_state = NULL; PetscFunctionBegin; PetscAssertPointer(name,3); *name = 0; if (!(log_state = petsc_log_state)) PetscFunctionReturn(PETSC_SUCCESS); /* logging is off ? */ PetscCall(PetscLogEventGetName(eventid, name)); PetscFunctionReturn(PETSC_SUCCESS); } /* ---------------------------------------------------------------- */ static PetscErrorCode PetscObjectComposedDataGetIntPy(PetscObject o, PetscInt id, PetscInt *v, PetscBool *exist) { PetscFunctionBegin; PetscCall(PetscObjectComposedDataGetInt(o,id,*v,*exist)); PetscFunctionReturn(PETSC_SUCCESS); } static PetscErrorCode PetscObjectComposedDataSetIntPy(PetscObject o, PetscInt id, PetscInt v) { PetscFunctionBegin; PetscCall(PetscObjectComposedDataSetInt(o,id,v)); PetscFunctionReturn(PETSC_SUCCESS); } static PetscErrorCode PetscObjectComposedDataRegisterPy(PetscInt *id) { PetscFunctionBegin; PetscCall(PetscObjectComposedDataRegister(id)); PetscFunctionReturn(PETSC_SUCCESS); } /* ---------------------------------------------------------------- */ /* The object is not used so far. I expect PETSc will sooner or later support a different device context for each object */ static PetscErrorCode PetscObjectGetDeviceId(PetscObject o, PetscInt *id) { #if defined(PETSC_HAVE_DEVICE) PetscDeviceContext dctx; PetscDevice device; #endif PetscFunctionBegin; PetscValidHeader(o,1); #if defined(PETSC_HAVE_DEVICE) PetscCall(PetscDeviceContextGetCurrentContext(&dctx)); PetscCall(PetscDeviceContextGetDevice(dctx,&device)); PetscCall(PetscDeviceGetDeviceId(device,id)); #else *id = 0; #endif PetscFunctionReturn(PETSC_SUCCESS); } /* ---------------------------------------------------------------- */ static PetscErrorCode VecGetCurrentMemType(Vec v, PetscMemType *m) { PetscBool bound; PetscFunctionBegin; PetscValidHeaderSpecific(v,VEC_CLASSID,1); PetscAssertPointer(m,2); *m = PETSC_MEMTYPE_HOST; PetscCall(VecBoundToCPU(v,&bound)); if (!bound) { VecType rtype; char *iscuda = NULL, *iship = NULL, *iskok = NULL; PetscCall(VecGetRootType_Private(v,&rtype)); PetscCall(PetscStrstr(rtype,"cuda",&iscuda)); PetscCall(PetscStrstr(rtype,"hip",&iship)); PetscCall(PetscStrstr(rtype,"kokkos",&iskok)); if (iscuda) *m = PETSC_MEMTYPE_CUDA; else if (iship) *m = PETSC_MEMTYPE_HIP; else if (iskok) *m = PETSC_MEMTYPE_KOKKOS; } PetscFunctionReturn(PETSC_SUCCESS); } /* ---------------------------------------------------------------- */ static PetscErrorCode MatIsPreallocated(Mat A,PetscBool *flag) { PetscFunctionBegin; PetscValidHeaderSpecific(A,MAT_CLASSID,1); PetscAssertPointer(flag,2); *flag = A->preallocated; PetscFunctionReturn(PETSC_SUCCESS); } static PetscErrorCode MatHasPreallocationAIJ(Mat A,PetscBool *aij,PetscBool *baij,PetscBool *sbaij,PetscBool *is) { void (*f)(void) = 0; PetscFunctionBegin; PetscValidHeaderSpecific(A,MAT_CLASSID,1); PetscValidType(A,1); PetscAssertPointer(aij,2); PetscAssertPointer(baij,3); PetscAssertPointer(sbaij,4); PetscAssertPointer(is,5); *aij = *baij = *sbaij = *is = PETSC_FALSE; if (!f) PetscCall(PetscObjectQueryFunction((PetscObject)A,"MatMPIAIJSetPreallocation_C",&f)); if (!f) PetscCall(PetscObjectQueryFunction((PetscObject)A,"MatSeqAIJSetPreallocation_C",&f)); if (f) {*aij = PETSC_TRUE; goto done;} if (!f) PetscCall(PetscObjectQueryFunction((PetscObject)A,"MatMPIBAIJSetPreallocation_C",&f)); if (!f) PetscCall(PetscObjectQueryFunction((PetscObject)A,"MatSeqBAIJSetPreallocation_C",&f)); if (f) {*baij = PETSC_TRUE; goto done;} if (!f) PetscCall(PetscObjectQueryFunction((PetscObject)A,"MatMPISBAIJSetPreallocation_C",&f)); if (!f) PetscCall(PetscObjectQueryFunction((PetscObject)A,"MatSeqSBAIJSetPreallocation_C",&f)); if (f) {*sbaij = PETSC_TRUE; goto done;} if (!f) PetscCall(PetscObjectQueryFunction((PetscObject)A,"MatISSetPreallocation_C",&f)); if (f) {*is = PETSC_TRUE; goto done;} done: PetscFunctionReturn(PETSC_SUCCESS); } static PetscErrorCode MatGetCurrentMemType(Mat A, PetscMemType *m) { PetscBool bound; PetscFunctionBegin; PetscValidHeaderSpecific(A,MAT_CLASSID,1); PetscAssertPointer(m,2); *m = PETSC_MEMTYPE_HOST; PetscCall(MatBoundToCPU(A,&bound)); if (!bound) { VecType rtype; char *iscuda = NULL, *iship = NULL, *iskok = NULL; PetscCall(MatGetRootType_Private(A,&rtype)); PetscCall(PetscStrstr(rtype,"cuda",&iscuda)); PetscCall(PetscStrstr(rtype,"hip",&iship)); PetscCall(PetscStrstr(rtype,"kokkos",&iskok)); if (iscuda) *m = PETSC_MEMTYPE_CUDA; else if (iship) *m = PETSC_MEMTYPE_HIP; else if (iskok) *m = PETSC_MEMTYPE_KOKKOS; } PetscFunctionReturn(PETSC_SUCCESS); } #ifndef MatNullSpaceFunction typedef PetscErrorCode MatNullSpaceFunction(MatNullSpace,Vec,void*); #endif /* ---------------------------------------------------------------- */ static PetscErrorCode MatFactorInfoDefaults(PetscBool incomplete,PetscBool cholesky,MatFactorInfo *info) { PetscFunctionBegin; PetscAssertPointer(info,2); PetscCall(MatFactorInfoInitialize(info)); if (incomplete) { info->levels = (PetscReal)0; info->diagonal_fill = (PetscReal)0; info->fill = (PetscReal)1.0; info->usedt = (PetscReal)0; info->dt = (PetscReal)PETSC_DEFAULT; info->dtcount = (PetscReal)PETSC_DEFAULT; info->dtcol = (PetscReal)PETSC_DEFAULT; info->zeropivot = (PetscReal)100.0*PETSC_MACHINE_EPSILON; info->pivotinblocks = (PetscReal)1; } else { info->fill = (PetscReal)5.0; info->dtcol = (PetscReal)1.e-6; info->zeropivot = (PetscReal)100.0*PETSC_MACHINE_EPSILON; info->pivotinblocks = (PetscReal)1; } if (incomplete) { if (cholesky) info->shifttype = (PetscReal)MAT_SHIFT_POSITIVE_DEFINITE; else info->shifttype = (PetscReal)MAT_SHIFT_NONZERO; info->shiftamount = (PetscReal)100.0*PETSC_MACHINE_EPSILON; } else { info->shifttype = (PetscReal)MAT_SHIFT_NONE; info->shiftamount = (PetscReal)0.0; } PetscFunctionReturn(PETSC_SUCCESS); } /* ---------------------------------------------------------------- */ static PetscErrorCode KSPSetIterationNumber(KSP ksp, PetscInt its) { PetscFunctionBegin; PetscValidHeaderSpecific(ksp,KSP_CLASSID,1); PetscCheck(its >= 0,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"iteration number must be nonnegative"); ksp->its = its; PetscFunctionReturn(PETSC_SUCCESS); } static PetscErrorCode KSPSetResidualNorm(KSP ksp, PetscReal rnorm) { PetscFunctionBegin; PetscValidHeaderSpecific(ksp,KSP_CLASSID,1); PetscCheck(rnorm >= 0,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"residual norm must be nonnegative"); ksp->rnorm = rnorm; PetscFunctionReturn(PETSC_SUCCESS); } static PetscErrorCode KSPConvergenceTestCall(KSP ksp, PetscInt its, PetscReal rnorm, KSPConvergedReason *reason) { PetscFunctionBegin; PetscValidHeaderSpecific(ksp,KSP_CLASSID,1); PetscAssertPointer(reason,4); PetscCheck(its >= 0,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"iteration number must be nonnegative"); PetscCheck(rnorm >= 0,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"residual norm must be nonnegative"); PetscCall((*ksp->converged)(ksp,its,rnorm,reason,ksp->cnvP)); PetscFunctionReturn(PETSC_SUCCESS); } static PetscErrorCode KSPSetConvergedReason(KSP ksp, KSPConvergedReason reason) { PetscFunctionBegin; PetscValidHeaderSpecific(ksp,KSP_CLASSID,1); ksp->reason = reason; PetscFunctionReturn(PETSC_SUCCESS); } static PetscErrorCode KSPConverged(KSP ksp,PetscInt iter,PetscReal rnorm,KSPConvergedReason *reason) { PetscFunctionBegin; PetscValidHeaderSpecific(ksp,KSP_CLASSID,1); if (reason) PetscAssertPointer(reason,2); if (!iter) ksp->rnorm0 = rnorm; if (!iter) { ksp->reason = KSP_CONVERGED_ITERATING; ksp->ttol = PetscMax(rnorm*ksp->rtol,ksp->abstol); } if (ksp->converged) { PetscCall(ksp->converged(ksp,iter,rnorm,&ksp->reason,ksp->cnvP)); } else { PetscCall(KSPConvergedSkip(ksp,iter,rnorm,&ksp->reason,NULL)); /*PetscCall(KSPConvergedDefault(ksp,iter,rnorm,&ksp->reason,NULL));*/ } ksp->rnorm = rnorm; if (reason) *reason = ksp->reason; PetscFunctionReturn(PETSC_SUCCESS); } static PetscErrorCode KSPLogHistory(KSP ksp,PetscReal rnorm) { PetscFunctionBegin; PetscValidHeaderSpecific(ksp,KSP_CLASSID,1); PetscCall(KSPLogResidualHistory(ksp,rnorm)); PetscFunctionReturn(PETSC_SUCCESS); } /* ---------------------------------------------------------------- */ static PetscErrorCode SNESConvergenceTestCall(SNES snes, PetscInt its, PetscReal xnorm, PetscReal ynorm, PetscReal fnorm, SNESConvergedReason *reason) { PetscFunctionBegin; PetscValidHeaderSpecific(snes,SNES_CLASSID,1); PetscAssertPointer(reason,4); PetscCheck(its >= 0,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"iteration number must be nonnegative"); PetscCheck(xnorm >= 0,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"solution norm must be nonnegative"); PetscCheck(ynorm >= 0,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"step norm must be nonnegative"); PetscCheck(fnorm >= 0,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"function norm must be nonnegative"); PetscUseTypeMethod(snes,converged,its,xnorm,ynorm,fnorm,reason,snes->cnvP); PetscFunctionReturn(PETSC_SUCCESS); } static PetscErrorCode SNESLogHistory(SNES snes,PetscReal rnorm,PetscInt lits) { PetscFunctionBegin; PetscValidHeaderSpecific(snes,SNES_CLASSID,1); PetscCall(SNESLogConvergenceHistory(snes,rnorm,lits)); PetscFunctionReturn(PETSC_SUCCESS); } static PetscErrorCode SNESGetUseMFFD(SNES snes,PetscBool *flag) { PetscErrorCode (*jac)(SNES,Vec,Mat,Mat,void*) = NULL; Mat J = NULL; PetscFunctionBegin; PetscValidHeaderSpecific(snes,SNES_CLASSID,1); PetscAssertPointer(flag,2); *flag = PETSC_FALSE; PetscCall(SNESGetJacobian(snes,&J,0,&jac,0)); if (J) PetscCall(PetscObjectTypeCompare((PetscObject)J,MATMFFD,flag)); else if (jac == MatMFFDComputeJacobian) *flag = PETSC_TRUE; PetscFunctionReturn(PETSC_SUCCESS); } static PetscErrorCode SNESSetUseMFFD(SNES snes,PetscBool flag) { const char* prefix = NULL; PetscBool flg = PETSC_FALSE; Vec r = NULL; Mat A = NULL,B = NULL,J = NULL; void* funP = NULL; void* jacP = NULL; PetscFunctionBegin; PetscValidHeaderSpecific(snes,SNES_CLASSID,1); PetscCall(SNESGetUseMFFD(snes,&flg)); if (flg && flag) PetscFunctionReturn(PETSC_SUCCESS); if (!flg && !flag) PetscFunctionReturn(PETSC_SUCCESS); if (flg && !flag) { SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "cannot change matrix-free once it is set"); PetscFunctionReturn(PETSC_ERR_ARG_WRONGSTATE); } PetscCall(SNESGetOptionsPrefix(snes,&prefix)); PetscCall(SNESGetFunction(snes,&r,0,&funP)); PetscCall(SNESGetJacobian(snes,&A,&B,0,&jacP)); if (!r) { SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"SNESSetFunction() must be called first"); PetscFunctionReturn(PETSC_ERR_ARG_WRONGSTATE); } PetscCall(MatCreateSNESMF(snes,&J)); PetscCall(MatSetOptionsPrefix(J,prefix)); PetscCall(MatSetFromOptions(J)); if (!B) { KSP ksp; PC pc; PetscBool shell,python; PetscCall(SNESSetJacobian(snes,J,J,MatMFFDComputeJacobian,jacP)); PetscCall(SNESGetKSP(snes,&ksp)); PetscCall(KSPGetPC(ksp,&pc)); PetscCall(PetscObjectTypeCompare((PetscObject)pc,PCSHELL,&shell)); PetscCall(PetscObjectTypeCompare((PetscObject)pc,PCPYTHON,&python)); if (!shell && !python) PetscCall(PCSetType(pc,PCNONE)); } else PetscCall(SNESSetJacobian(snes,J,0,0,0)); PetscCall(MatDestroy(&J)); PetscFunctionReturn(PETSC_SUCCESS); } static PetscErrorCode SNESGetUseFDColoring(SNES snes,PetscBool *flag) { PetscErrorCode (*jac)(SNES,Vec,Mat,Mat,void*) = NULL; PetscFunctionBegin; PetscValidHeaderSpecific(snes,SNES_CLASSID,1); PetscAssertPointer(flag,2); *flag = PETSC_FALSE; PetscCall(SNESGetJacobian(snes,0,0,&jac,0)); if (jac == SNESComputeJacobianDefaultColor) *flag = PETSC_TRUE; PetscFunctionReturn(PETSC_SUCCESS); } static PetscErrorCode SNESSetUseFDColoring(SNES snes,PetscBool flag) { PetscBool flg = PETSC_FALSE; PetscErrorCode (*fun)(SNES,Vec,Vec,void*) = NULL; void* funP = NULL; Mat A = NULL,B = NULL; PetscErrorCode (*jac)(SNES,Vec,Mat,Mat,void*) = NULL; void* jacP = NULL; PetscFunctionBegin; PetscValidHeaderSpecific(snes,SNES_CLASSID,1); PetscCall(SNESGetUseFDColoring(snes,&flg)); if (flg && flag) PetscFunctionReturn(PETSC_SUCCESS); if (!flg && !flag) PetscFunctionReturn(PETSC_SUCCESS); if (flg && !flag) { SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "cannot change colored finite differences once it is set"); PetscFunctionReturn(PETSC_ERR_ARG_WRONGSTATE); } PetscCall(SNESGetFunction(snes,NULL,&fun,&funP)); PetscCall(SNESGetJacobian(snes,&A,&B,&jac,&jacP)); PetscCall(SNESSetJacobian(snes,A,B,SNESComputeJacobianDefaultColor,0)); { DM dm; DMSNES sdm; PetscCall(SNESGetDM(snes,&dm)); PetscCall(DMGetDMSNES(dm,&sdm)); PetscCall(DMSNESUnsetJacobianContext_Internal(dm)); } PetscFunctionReturn(PETSC_SUCCESS); } /* ---------------------------------------------------------------- */ static PetscErrorCode TaoConverged(Tao tao, TaoConvergedReason *reason) { PetscFunctionBegin; PetscValidHeaderSpecific(tao,TAO_CLASSID,1); PetscAssertPointer(reason,2); if (tao->ops->convergencetest) { PetscUseTypeMethod(tao,convergencetest,tao->cnvP); } else { PetscCall(TaoDefaultConvergenceTest(tao,tao->cnvP)); } *reason = tao->reason; PetscFunctionReturn(PETSC_SUCCESS); } static PetscErrorCode TaoCheckReals(Tao tao, PetscReal f, PetscReal g) { PetscFunctionBegin; PetscValidHeaderSpecific(tao,TAO_CLASSID,1); PetscCheck(!PetscIsInfOrNanReal(f) && !PetscIsInfOrNanReal(g),PetscObjectComm((PetscObject)tao),PETSC_ERR_USER,"User provided compute function generated Inf or NaN"); PetscFunctionReturn(PETSC_SUCCESS); } static PetscErrorCode TaoCreateDefaultKSP(Tao tao) { PetscFunctionBegin; PetscValidHeaderSpecific(tao,TAO_CLASSID,1); PetscCall(KSPDestroy(&tao->ksp)); PetscCall(KSPCreate(((PetscObject)tao)->comm,&tao->ksp)); PetscCall(PetscObjectIncrementTabLevel((PetscObject)tao->ksp,(PetscObject)tao,1)); PetscFunctionReturn(PETSC_SUCCESS); } static PetscErrorCode TaoCreateDefaultLineSearch(Tao tao) { PetscFunctionBegin; PetscValidHeaderSpecific(tao,TAO_CLASSID,1); PetscCall(TaoLineSearchDestroy(&tao->linesearch)); PetscCall(TaoLineSearchCreate(((PetscObject)tao)->comm,&tao->linesearch)); PetscCall(PetscObjectIncrementTabLevel((PetscObject)tao->linesearch,(PetscObject)tao,1)); PetscCall(TaoLineSearchSetType(tao->linesearch,TAOLINESEARCHMT)); PetscCall(TaoLineSearchUseTaoRoutines(tao->linesearch,tao)); PetscCall(TaoLineSearchSetInitialStepLength(tao->linesearch,1.0)); PetscFunctionReturn(PETSC_SUCCESS); } static PetscErrorCode TaoHasGradientRoutine(Tao tao, PetscBool* flg) { PetscFunctionBegin; PetscValidHeaderSpecific(tao,TAO_CLASSID,1); PetscAssertPointer(flg,2); *flg = (PetscBool)(tao->ops->computegradient || tao->ops->computeobjectiveandgradient); PetscFunctionReturn(PETSC_SUCCESS); } #if 0 static PetscErrorCode TaoHasHessianRoutine(Tao tao, PetscBool* flg) { PetscFunctionBegin; PetscValidHeaderSpecific(tao,TAO_CLASSID,1); PetscAssertPointer(flg,2); *flg = tao->ops->computehessian; PetscFunctionReturn(PETSC_SUCCESS); } #endif static PetscErrorCode TaoComputeUpdate(Tao tao) { PetscFunctionBegin; PetscValidHeaderSpecific(tao,TAO_CLASSID,1); PetscTryTypeMethod(tao,update,tao->niter,tao->user_update); PetscFunctionReturn(PETSC_SUCCESS); } static PetscErrorCode TaoGetVecs(Tao tao, Vec *X, Vec *G, Vec *S) { PetscBool has_g; PetscFunctionBegin; PetscValidHeaderSpecific(tao,TAO_CLASSID,1); PetscCall(TaoHasGradientRoutine(tao,&has_g)); if (X) *X = tao->solution; if (G) { if (has_g && !tao->gradient) PetscCall(VecDuplicate(tao->solution,&tao->gradient)); *G = has_g ? tao->gradient : NULL; } if (S) { if (has_g && !tao->stepdirection) PetscCall(VecDuplicate(tao->solution,&tao->stepdirection)); *S = has_g ? tao->stepdirection : NULL; } PetscFunctionReturn(PETSC_SUCCESS); } static PetscErrorCode TaoApplyLineSearch(Tao tao, PetscReal* f, PetscReal *s, TaoLineSearchConvergedReason *lsr) { PetscFunctionBegin; PetscValidHeaderSpecific(tao,TAO_CLASSID,1); PetscAssertPointer(f,2); PetscAssertPointer(s,3); PetscCall(TaoLineSearchApply(tao->linesearch,tao->solution,f,tao->gradient,tao->stepdirection,s,lsr)); PetscCall(TaoAddLineSearchCounts(tao)); PetscFunctionReturn(PETSC_SUCCESS); } /* ---------------------------------------------------------------- */ static PetscErrorCode DMDACreateND(MPI_Comm comm, PetscInt dim,PetscInt dof, PetscInt M,PetscInt N,PetscInt P, PetscInt m,PetscInt n,PetscInt p, const PetscInt lx[],const PetscInt ly[],const PetscInt lz[], DMBoundaryType bx,DMBoundaryType by,DMBoundaryType bz, DMDAStencilType stencil_type,PetscInt stencil_width, DM *dm) { DM da; PetscFunctionBegin; PetscAssertPointer(dm,18); PetscCall(DMDACreate(comm,&da)); PetscCall(DMSetDimension(da,dim)); PetscCall(DMDASetDof(da,dof)); PetscCall(DMDASetSizes(da,M,N,P)); PetscCall(DMDASetNumProcs(da,m,n,p)); PetscCall(DMDASetOwnershipRanges(da,lx,ly,lz)); PetscCall(DMDASetBoundaryType(da,bx,by,bz)); PetscCall(DMDASetStencilType(da,stencil_type)); PetscCall(DMDASetStencilWidth(da,stencil_width)); *dm = (DM)da; PetscFunctionReturn(PETSC_SUCCESS); } /* ---------------------------------------------------------------- */ #endif/* PETSC4PY_CUSTOM_H*/ /* Local variables: c-basic-offset: 2 indent-tabs-mode: nil End: */ ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/src/lib-petsc/initpkg.h0000644000175000017500000000173614567251135016665 0ustar00balaybalaystatic PetscErrorCode PetscInitializePackageAll(void) { PetscFunctionBegin; PetscCall(PetscSysInitializePackage()); PetscCall(PetscDrawInitializePackage()); PetscCall(PetscViewerInitializePackage()); PetscCall(PetscRandomInitializePackage()); PetscCall(PetscDeviceInitializePackage()); PetscCall(ISInitializePackage()); PetscCall(AOInitializePackage()); PetscCall(PFInitializePackage()); PetscCall(PetscSFInitializePackage()); PetscCall(VecInitializePackage()); PetscCall(MatInitializePackage()); PetscCall(PCInitializePackage()); PetscCall(KSPInitializePackage()); PetscCall(SNESInitializePackage()); PetscCall(TaoInitializePackage()); PetscCall(TSInitializePackage()); PetscCall(PetscPartitionerInitializePackage()); PetscCall(DMInitializePackage()); PetscCall(PetscDSInitializePackage()); PetscCall(PetscFEInitializePackage()); PetscFunctionReturn(PETSC_SUCCESS); } /* Local variables: c-basic-offset: 2 indent-tabs-mode: nil End: */ ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1709010084.3993752 petsc4py-3.20.5/src/petsc4py/0000755000175000017500000000000014567266244014740 5ustar00balaybalay././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1709010084.4363751 petsc4py-3.20.5/src/petsc4py/PETSc/0000755000175000017500000000000014567266244015656 5ustar00balaybalay././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/src/petsc4py/PETSc/AO.pyx0000644000175000017500000002211714567251135016713 0ustar00balaybalay# -------------------------------------------------------------------- class AOType(object): BASIC = S_(AOBASIC) ADVANCED = S_(AOADVANCED) MAPPING = S_(AOMAPPING) MEMORYSCALABLE = S_(AOMEMORYSCALABLE) # -------------------------------------------------------------------- cdef class AO(Object): """Application ordering object.""" Type = AOType def __cinit__(self): self.obj = &self.ao self.ao = NULL def view(self, Viewer viewer=None) -> None: """Display the application ordering. Collective. Parameters ---------- viewer A `Viewer` to display the ordering. See Also -------- petsc.AOView """ cdef PetscViewer cviewer = NULL if viewer is not None: cviewer = viewer.vwr CHKERR( AOView(self.ao, cviewer) ) def destroy(self) -> Self: """Destroy the application ordering. Collective. See Also -------- petsc.AODestroy """ CHKERR( AODestroy(&self.ao) ) return self def createBasic( self, app: Sequence[int] | IS, petsc: Sequence[int] | IS | None = None, comm: Comm | None = None, ) -> Self: """Return a basic application ordering using two orderings. Collective. The arrays/indices ``app`` and ``petsc`` must contain all the integers ``0`` to ``len(app)-1`` with no duplicates; that is there cannot be any "holes" in the indices. Use ``createMapping`` if you wish to have "holes" in the indices. Parameters ---------- app The application ordering. petsc Another ordering (may be `None` to indicate the natural ordering, that is 0, 1, 2, 3, ...). comm MPI communicator, defaults to `Sys.getDefaultComm`. See Also -------- createMemoryScalable, createMapping, petsc.AOCreateBasicIS petsc.AOCreateBasic """ cdef PetscIS isapp = NULL, ispetsc = NULL cdef PetscInt napp = 0, *idxapp = NULL, cdef PetscInt npetsc = 0, *idxpetsc = NULL cdef MPI_Comm ccomm = def_Comm(comm, PETSC_COMM_DEFAULT) cdef PetscAO newao = NULL if isinstance(app, IS): isapp = (app).iset if petsc is not None: ispetsc = (petsc).iset CHKERR( AOCreateBasicIS(isapp, ispetsc, &newao) ) else: app = iarray_i(app, &napp, &idxapp) if petsc is not None: petsc = iarray_i(petsc, &npetsc, &idxpetsc) assert napp == npetsc, "incompatible array sizes" CHKERR( AOCreateBasic(ccomm, napp, idxapp, idxpetsc, &newao) ) CHKERR( PetscCLEAR(self.obj) ); self.ao = newao return self def createMemoryScalable( self, app: Sequence[int] | IS, petsc: Sequence[int] | IS | None = None, comm: Comm | None = None, ) -> Self: """Return a memory scalable application ordering using two orderings. Collective. The arrays/indices ``app`` and ``petsc`` must contain all the integers ``0`` to ``len(app)-1`` with no duplicates; that is there cannot be any "holes" in the indices. Use ``createMapping`` if you wish to have "holes" in the indices. Comparing with ``createBasic``, this routine trades memory with message communication. Parameters ---------- app The application ordering. petsc Another ordering (may be `None` to indicate the natural ordering, that is 0, 1, 2, 3, ...). comm MPI communicator, defaults to `Sys.getDefaultComm`. See Also -------- createBasic, createMapping, petsc.AOCreateMemoryScalableIS petsc.AOCreateMemoryScalable """ cdef PetscIS isapp = NULL, ispetsc = NULL cdef PetscInt napp = 0, *idxapp = NULL, cdef PetscInt npetsc = 0, *idxpetsc = NULL cdef MPI_Comm ccomm = def_Comm(comm, PETSC_COMM_DEFAULT) cdef PetscAO newao = NULL if isinstance(app, IS): isapp = (app).iset if petsc is not None: ispetsc = (petsc).iset CHKERR( AOCreateMemoryScalableIS(isapp, ispetsc, &newao) ) else: app = iarray_i(app, &napp, &idxapp) if petsc is not None: petsc = iarray_i(petsc, &npetsc, &idxpetsc) assert napp == npetsc, "incompatible array sizes" CHKERR( AOCreateMemoryScalable(ccomm, napp, idxapp, idxpetsc, &newao) ) CHKERR( PetscCLEAR(self.obj) ); self.ao = newao return self def createMapping( self, app: Sequence[int] | IS, petsc: Sequence[int] | IS | None = None, comm: Comm | None = None, ) -> Self: """Return an application mapping using two orderings. Collective. The arrays ``app`` and ``petsc`` need NOT contain all the integers ``0`` to ``len(app)-1``, that is there CAN be "holes" in the indices. Use ``createBasic`` if they do not have holes for better performance. Parameters ---------- app The application ordering. petsc Another ordering. May be `None` to indicate the identity ordering. comm MPI communicator, defaults to `Sys.getDefaultComm`. See Also -------- createBasic, petsc.AOCreateMappingIS, petsc.AOCreateMapping """ cdef PetscIS isapp = NULL, ispetsc = NULL cdef PetscInt napp = 0, *idxapp = NULL, cdef PetscInt npetsc = 0, *idxpetsc = NULL cdef MPI_Comm ccomm = def_Comm(comm, PETSC_COMM_DEFAULT) cdef PetscAO newao = NULL if isinstance(app, IS): isapp = (app).iset if petsc is not None: ispetsc = (petsc).iset CHKERR( AOCreateMappingIS(isapp, ispetsc, &newao) ) else: app = iarray_i(app, &napp, &idxapp) if petsc is not None: petsc = iarray_i(petsc, &npetsc, &idxpetsc) assert napp == npetsc, "incompatible array sizes" CHKERR( AOCreateMapping(ccomm, napp, idxapp, idxpetsc, &newao) ) CHKERR( PetscCLEAR(self.obj) ); self.ao = newao return self def getType(self) -> str: """Return the application ordering type. Not collective. See Also -------- petsc.AOGetType """ cdef PetscAOType cval = NULL CHKERR( AOGetType(self.ao, &cval) ) return bytes2str(cval) def app2petsc(self, indices: Sequence[int] | IS) -> Sequence[int] | IS: """Map an application-defined ordering to the PETSc ordering. Collective. Any integers in ``indices`` that are negative are left unchanged. This allows one to convert, for example, neighbor lists that use negative entries to indicate nonexistent neighbors due to boundary conditions, etc. Integers that are out of range are mapped to -1. If ``IS`` is used, it cannot be of type stride or block. Parameters ---------- indices The indices; to be replaced with their mapped values. See Also -------- petsc2app, petsc.AOApplicationToPetscIS, petsc.AOApplicationToPetsc """ cdef PetscIS iset = NULL cdef PetscInt nidx = 0, *idx = NULL if isinstance(indices, IS): iset = (indices).iset CHKERR( AOApplicationToPetscIS(self.ao, iset) ) else: indices = oarray_i(indices, &nidx, &idx) CHKERR( AOApplicationToPetsc(self.ao, nidx, idx) ) return indices def petsc2app(self, indices: Sequence[int] | IS) -> Sequence[int] | IS: """Map a PETSc ordering to the application-defined ordering. Collective. Any integers in ``indices`` that are negative are left unchanged. This allows one to convert, for example, neighbor lists that use negative entries to indicate nonexistent neighbors due to boundary conditions, etc. Integers that are out of range are mapped to -1. If ``IS`` is used, it cannot be of type stride or block. Parameters ---------- indices The indices; to be replaced with their mapped values. See Also -------- app2petsc, petsc.AOPetscToApplicationIS, petsc.AOPetscToApplication """ cdef PetscIS iset = NULL cdef PetscInt nidx = 0, *idx = NULL if isinstance(indices, IS): iset = (indices).iset CHKERR( AOPetscToApplicationIS(self.ao, iset) ) else: indices = oarray_i(indices, &nidx, &idx) CHKERR( AOPetscToApplication(self.ao, nidx, idx) ) return indices # -------------------------------------------------------------------- del AOType # -------------------------------------------------------------------- ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/src/petsc4py/PETSc/CAPI.pyx0000644000175000017500000002310214567251135017123 0ustar00balaybalay#--------------------------------------------------------------------- cdef inline int setref(void *d, void *s) except -1: cdef PetscObject *dest = d cdef PetscObject source = s CHKERR( PetscINCREF(&source) ) dest[0] = source return 0 #--------------------------------------------------------------------- # -- Error -- cdef api int PyPetscError_Set(PetscErrorCode ierr): return SETERR(ierr) # -- Comm -- cdef api object PyPetscComm_New(MPI_Comm arg): cdef Comm retv = Comm() retv.comm = arg return retv cdef api MPI_Comm PyPetscComm_Get(object arg) except? MPI_COMM_NULL: cdef MPI_Comm retv = MPI_COMM_NULL cdef Comm ob = arg retv = ob.comm return retv cdef api MPI_Comm* PyPetscComm_GetPtr(object arg) except NULL: cdef MPI_Comm *retv = NULL cdef Comm ob = arg retv = &ob.comm return retv # -- Object -- cdef api object PyPetscObject_New(PetscObject arg): cdef Object retv = subtype_Object(arg)() setref(&retv.obj[0], arg) return retv cdef api PetscObject PyPetscObject_Get(object arg) except ? NULL: cdef PetscObject retv = NULL cdef Object ob = arg retv = ob.obj[0] return retv cdef api PetscObject* PyPetscObject_GetPtr(object arg) except NULL: cdef PetscObject *retv = NULL cdef Object ob = arg retv = ob.obj return retv # -- Viewer -- cdef api object PyPetscViewer_New(PetscViewer arg): cdef Viewer retv = Viewer() setref(&retv.vwr, arg) return retv cdef api PetscViewer PyPetscViewer_Get(object arg) except ? NULL: cdef PetscViewer retv = NULL cdef Viewer ob = arg retv = ob.vwr return retv # -- Random -- cdef api object PyPetscRandom_New(PetscRandom arg): cdef Random retv = Random() setref(&retv.rnd, arg) return retv cdef api PetscRandom PyPetscRandom_Get(object arg) except ? NULL: cdef PetscRandom retv = NULL cdef Random ob = arg retv = ob.rnd return retv # -- Device -- cdef api Device PyPetscDevice_New(PetscDevice arg): cdef Device ret = Device() ret.device = arg return ret cdef api PetscDevice PyPetscDevice_Get(object arg) except ? NULL: cdef Device obj = arg cdef PetscDevice ret = obj.device return ret # -- DeviceContext -- cdef api DeviceContext PyPetscDeviceContext_New(PetscDeviceContext arg): cdef DeviceContext retv = DeviceContext() setref(&retv.dctx, arg) return retv cdef api PetscDeviceContext PyPetscDeviceContext_Get(object arg) except ? NULL: cdef DeviceContext obj = arg cdef PetscDeviceContext ret = obj.dctx return ret # -- IS -- cdef api object PyPetscIS_New(PetscIS arg): cdef IS retv = IS() setref(&retv.iset, arg) return retv cdef api PetscIS PyPetscIS_Get(object arg) except? NULL: cdef PetscIS retv = NULL cdef IS ob = arg retv = ob.iset return retv # -- LGMap -- cdef api object PyPetscLGMap_New(PetscLGMap arg): cdef LGMap retv = LGMap() setref(&retv.lgm, arg) return retv cdef api PetscLGMap PyPetscLGMap_Get(object arg) except ? NULL: cdef PetscLGMap retv = NULL cdef LGMap ob = arg retv = ob.lgm return retv # -- SF -- cdef api object PyPetscSF_New(PetscSF arg): cdef SF retv = SF() setref(&retv.sf, arg) return retv cdef api PetscSF PyPetscSF_Get(object arg) except? NULL: cdef PetscSF retv = NULL cdef SF ob = arg retv = ob.sf return retv # -- Vec -- cdef api object PyPetscVec_New(PetscVec arg): cdef Vec retv = Vec() setref(&retv.vec, arg) return retv cdef api PetscVec PyPetscVec_Get(object arg) except ? NULL: cdef PetscVec retv = NULL cdef Vec ob = arg retv = ob.vec return retv # -- Scatter -- cdef api object PyPetscScatter_New(PetscScatter arg): cdef Scatter retv = Scatter() setref(&retv.sct, arg) return retv cdef api PetscScatter PyPetscScatter_Get(object arg) except ? NULL: cdef PetscScatter retv = NULL cdef Scatter ob = arg retv = ob.sct return retv # -- Section -- cdef api object PyPetscSection_New(PetscSection arg): cdef Section retv = Section() setref(&retv.sec, arg) return retv cdef api PetscSection PyPetscSection_Get(object arg) except ? NULL: cdef PetscSection retv = NULL cdef Section ob = arg retv = ob.sec return retv # -- Mat -- cdef api object PyPetscMat_New(PetscMat arg): cdef Mat retv = Mat() setref(&retv.mat, arg) return retv cdef api PetscMat PyPetscMat_Get(object arg) except ? NULL: cdef PetscMat retv = NULL cdef Mat ob = arg retv = ob.mat return retv # -- MatPartitioning -- cdef api object PyPetscMatPartitioning_New(PetscMatPartitioning arg): cdef MatPartitioning retv = MatPartitioning() setref(&retv.part, arg) return retv cdef api PetscMatPartitioning PyPetscMatPartitioning_Get(object arg) except ? NULL: cdef PetscMatPartitioning retv = NULL cdef MatPartitioning ob = arg retv = ob.part return retv # -- PC -- cdef api object PyPetscPC_New(PetscPC arg): cdef PC retv = PC() setref(&retv.pc, arg) return retv cdef api PetscPC PyPetscPC_Get(object arg) except ? NULL: cdef PetscPC retv = NULL cdef PC ob = arg retv = ob.pc return retv # -- KSP -- cdef api object PyPetscKSP_New(PetscKSP arg): cdef KSP retv = KSP() setref(&retv.ksp, arg) return retv cdef api PetscKSP PyPetscKSP_Get(object arg) except ? NULL: cdef PetscKSP retv = NULL cdef KSP ob = arg retv = ob.ksp return retv # -- SNES -- cdef api object PyPetscSNES_New(PetscSNES arg): cdef SNES retv = SNES() setref(&retv.snes, arg) return retv cdef api PetscSNES PyPetscSNES_Get(object arg) except ? NULL: cdef PetscSNES retv = NULL cdef SNES ob = arg retv = ob.snes return retv # -- TS -- cdef api object PyPetscTS_New(PetscTS arg): cdef TS retv = TS() setref(&retv.ts, arg) return retv cdef api PetscTS PyPetscTS_Get(object arg) except ? NULL: cdef PetscTS retv = NULL cdef TS ob = arg retv = ob.ts return retv # -- TAO -- cdef api object PyPetscTAO_New(PetscTAO arg): cdef TAO retv = TAO() setref(&retv.tao, arg) return retv cdef api PetscTAO PyPetscTAO_Get(object arg) except ? NULL: cdef PetscTAO retv = NULL cdef TAO ob = arg retv = ob.tao return retv cdef api object PyPetscTAOLineSearch_New(PetscTAOLineSearch arg): cdef TAOLineSearch retv = TAOLineSearch() setref(&retv.taols, arg) return retv cdef api PetscTAOLineSearch PyPetscTAOLineSearch_Get(object arg) except ? NULL: cdef PetscTAOLineSearch retv = NULL cdef TAOLineSearch ob = arg retv = ob.taols return retv # -- AO -- cdef api object PyPetscAO_New(PetscAO arg): cdef AO retv = AO() setref(&retv.ao, arg) return retv cdef api PetscAO PyPetscAO_Get(object arg) except ? NULL: cdef PetscAO retv = NULL cdef AO ob = arg retv = ob.ao return retv # -- DM -- cdef api object PyPetscDM_New(PetscDM arg): cdef DM retv = subtype_DM(arg)() setref(&retv.dm, arg) return retv cdef api PetscDM PyPetscDM_Get(object arg) except ? NULL: cdef PetscDM retv = NULL cdef DM ob = arg retv = ob.dm return retv # -- DS -- cdef api object PyPetscDS_New(PetscDS arg): cdef DS retv = DS() setref(&retv.ds, arg) return retv cdef api PetscDS PyPetscDS_Get(object arg) except ? NULL: cdef PetscDS retv = NULL cdef DS ob = arg retv = ob.ds return retv # -- Partitioner -- cdef api object PyPetscPartitioner_New(PetscPartitioner arg): cdef Partitioner retv = Partitioner() setref(&retv.part, arg) return retv cdef api PetscPartitioner PyPetscPartitioner_Get(object arg) except ? NULL: cdef PetscPartitioner retv = NULL cdef Partitioner ob = arg retv = ob.part return retv # -- FE -- cdef api object PyPetscFE_New(PetscFE arg): cdef FE retv = FE() setref(&retv.fe, arg) return retv cdef api PetscFE PyPetscFE_Get(object arg) except ? NULL: cdef PetscFE retv = NULL cdef FE ob = arg retv = ob.fe return retv # -- QUAD -- cdef api object PyPetscQuad_New(PetscQuadrature arg): cdef Quad retv = Quad() setref(&retv.quad, arg) return retv cdef api PetscQuadrature PyPetscQuad_Get(object arg) except ? NULL: cdef PetscQuadrature retv = NULL cdef Quad ob = arg retv = ob.quad return retv # -- DMLabel -- cdef api object PyPetscDMLabel_New(PetscDMLabel arg): cdef DMLabel retv = DMLabel() setref(&retv.dmlabel, arg) return retv cdef api PetscDMLabel PyPetscDMLabel_Get(object arg) except ? NULL: cdef PetscDMLabel retv = NULL cdef DMLabel ob = arg retv = ob.dmlabel return retv # -- SPACE -- cdef api object PyPetscSpace_New(PetscSpace arg): cdef Space retv = Space() setref(&retv.space, arg) return retv cdef api PetscSpace PyPetscSpace_Get(object arg) except ? NULL: cdef PetscSpace retv = NULL cdef Space ob = arg retv = ob.space return retv # -- DUALSPACE -- cdef api object PyPetscDualSpace_New(PetscDualSpace arg): cdef DualSpace retv = DualSpace() setref(&retv.dualspace, arg) return retv cdef api PetscDualSpace PyPetscDualSpace_Get(object arg) except ? NULL: cdef PetscDualSpace retv = NULL cdef DualSpace ob = arg retv = ob.dualspace return retv #--------------------------------------------------------------------- ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/src/petsc4py/PETSc/Comm.pyx0000644000175000017500000001175714567251135017317 0ustar00balaybalay# -------------------------------------------------------------------- cdef class Comm: """Communicator object. Predefined instances: `COMM_NULL` The *null* (or invalid) communicator. `COMM_SELF` The *self* communicator. `COMM_WORLD` The *world* communicator. See Also -------- Sys.setDefaultComm, Sys.getDefaultComm """ # def __cinit__(self, comm=None): self.comm = def_Comm(comm, MPI_COMM_NULL) self.isdup = 0 if self.comm != MPI_COMM_NULL: self.base = comm else: self.base = None def __dealloc__(self): if self.isdup: CHKERR( PetscCommDEALLOC(&self.comm) ) self.comm = MPI_COMM_NULL self.isdup = 0 self.base = None def __richcmp__(self, other, int op): if not isinstance(self, Comm): return NotImplemented if not isinstance(other, Comm): return NotImplemented if op!=2 and op!=3: raise TypeError("only '==' and '!='") cdef Comm s = self cdef Comm o = other cdef int eq = (op == 2) cdef MPI_Comm comm1 = s.comm cdef MPI_Comm comm2 = o.comm cdef int flag = 0 if comm1 != MPI_COMM_NULL and comm2 != MPI_COMM_NULL: CHKERR( MPI_Comm_compare(comm1, comm2, &flag) ) if eq: return (flag==MPI_IDENT or flag==MPI_CONGRUENT) else: return (flag!=MPI_IDENT and flag!=MPI_CONGRUENT) else: if eq: return (comm1 == comm2) else: return (comm1 != comm2) def __bool__(self) -> bool: return self.comm != MPI_COMM_NULL # def destroy(self) -> None: """Destroy the communicator. Collective. See Also -------- petsc.PetscCommDestroy """ if self.comm == MPI_COMM_NULL: return if not self.isdup: raise ValueError("communicator not owned") CHKERR( PetscCommDestroy(&self.comm) ) self.comm = MPI_COMM_NULL self.isdup = 0 self.base = None def duplicate(self) -> Self: """Duplicate the communicator. Collective. See Also -------- petsc.PetscCommDuplicate """ if self.comm == MPI_COMM_NULL: raise ValueError("null communicator") cdef MPI_Comm newcomm = MPI_COMM_NULL CHKERR( PetscCommDuplicate(self.comm, &newcomm, NULL) ) cdef Comm comm = type(self)() comm.comm = newcomm comm.isdup = 1 comm.base = self.base return comm def getSize(self) -> int: """Return the number of processes in the communicator. Not collective. """ if self.comm == MPI_COMM_NULL: raise ValueError("null communicator") cdef int size=0 CHKERRMPI( MPI_Comm_size(self.comm, &size) ) return size def getRank(self) -> int: """Return the rank of the calling processes in the communicator. Not collective. """ if self.comm == MPI_COMM_NULL: raise ValueError("null communicator") cdef int rank=0 CHKERRMPI( MPI_Comm_rank(self.comm, &rank) ) return rank def barrier(self) -> None: """Barrier synchronization. Collective. """ if self.comm == MPI_COMM_NULL: raise ValueError("null communicator") CHKERRMPI( MPI_Barrier(self.comm) ) # --- properties --- property size: """Communicator size.""" def __get__(self) -> int: return self.getSize() property rank: """Communicator rank.""" def __get__(self) -> int: return self.getRank() # --- Fortran support --- property fortran: """Fortran handle.""" def __get__(self) -> int: cdef MPI_Comm comm = self.comm return MPI_Comm_c2f(comm) # --- mpi4py support --- def tompi4py(self) -> Intracomm: """Convert communicator to `mpi4py`. Not collective. See Also -------- mpi4py.MPI.Comm, mpi4py.MPI.Intracomm """ cdef MPI_Comm comm = self.comm return mpi4py_Comm_New(comm) # --- mpi4py compatibility API --- Free = destroy Clone = duplicate Dup = duplicate Get_size = getSize Get_rank = getRank Barrier = barrier # -------------------------------------------------------------------- cdef Comm __COMM_NULL__ = Comm() cdef Comm __COMM_SELF__ = Comm() cdef Comm __COMM_WORLD__ = Comm() COMM_NULL = __COMM_NULL__ COMM_SELF = __COMM_SELF__ COMM_WORLD = __COMM_WORLD__ # -------------------------------------------------------------------- cdef MPI_Comm PETSC_COMM_DEFAULT = MPI_COMM_NULL cdef MPI_Comm GetComm( object comm, MPI_Comm defv, ) except? MPI_COMM_NULL: return def_Comm(comm, defv) cdef MPI_Comm GetCommDefault(): return PETSC_COMM_DEFAULT # -------------------------------------------------------------------- ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/src/petsc4py/PETSc/Const.pyx0000644000175000017500000000674314567251135017511 0ustar00balaybalay# ------------------------------------------------------------------------------ DECIDE = PETSC_DECIDE DEFAULT = PETSC_DEFAULT DETERMINE = PETSC_DETERMINE __doc__ += """ Basic constants: `DECIDE` Use a default value for an `int` or `float` parameter. `DEFAULT` Use a default value for an `int` or `float` parameter. `DETERMINE` Compute a default value for an `int` or `float` parameter. """ # ------------------------------------------------------------------------------ INFINITY = toReal(PETSC_INFINITY) NINFINITY = toReal(PETSC_NINFINITY) PINFINITY = toReal(PETSC_INFINITY) __doc__ += """ More constants: `INFINITY` Very large real value. `NINFINITY` Very large negative real value. `PINFINITY` Very large positive real value, same as `INFINITY`. """ # ------------------------------------------------------------------------------ class InsertMode(object): """Insertion mode. Most commonly used insertion modes are: `INSERT` Insert provided value/s discarding previous value/s. `ADD` Add provided value/s to current value/s. `MAX` Insert the maximum of provided value/s and current value/s. See Also -------- petsc.InsertMode """ # native NOT_SET_VALUES = PETSC_NOT_SET_VALUES INSERT_VALUES = PETSC_INSERT_VALUES ADD_VALUES = PETSC_ADD_VALUES MAX_VALUES = PETSC_MAX_VALUES INSERT_ALL_VALUES = PETSC_INSERT_ALL_VALUES ADD_ALL_VALUES = PETSC_ADD_ALL_VALUES INSERT_BC_VALUES = PETSC_INSERT_BC_VALUES ADD_BC_VALUES = PETSC_ADD_BC_VALUES # aliases INSERT = INSERT_VALUES ADD = ADD_VALUES MAX = MAX_VALUES INSERT_ALL = INSERT_ALL_VALUES ADD_ALL = ADD_ALL_VALUES INSERT_BC = INSERT_BC_VALUES ADD_BC = ADD_BC_VALUES # ------------------------------------------------------------------------------ class ScatterMode(object): """Scatter mode. Most commonly used scatter modes are: `FORWARD` Scatter values in the forward direction. `REVERSE` Scatter values in the reverse direction. See Also -------- Scatter.create, Scatter.begin, Scatter.end petsc.ScatterMode """ # native SCATTER_FORWARD = PETSC_SCATTER_FORWARD SCATTER_REVERSE = PETSC_SCATTER_REVERSE SCATTER_FORWARD_LOCAL = PETSC_SCATTER_FORWARD_LOCAL SCATTER_REVERSE_LOCAL = PETSC_SCATTER_REVERSE_LOCAL # aliases FORWARD = SCATTER_FORWARD REVERSE = SCATTER_REVERSE FORWARD_LOCAL = SCATTER_FORWARD_LOCAL REVERSE_LOCAL = SCATTER_REVERSE_LOCAL # ------------------------------------------------------------------------------ class NormType(object): """Norm type. Commonly used norm types: `N1` The one norm. `N2` The two norm. `FROBENIUS` The Frobenius norm. `INFINITY` The infinity norm. See Also -------- petsc.NormType """ # native NORM_1 = PETSC_NORM_1 NORM_2 = PETSC_NORM_2 NORM_1_AND_2 = PETSC_NORM_1_AND_2 NORM_FROBENIUS = PETSC_NORM_FROBENIUS NORM_INFINITY = PETSC_NORM_INFINITY NORM_MAX = PETSC_NORM_MAX # aliases N1 = NORM_1 N2 = NORM_2 N12 = NORM_1_AND_2 MAX = NORM_MAX FROBENIUS = NORM_FROBENIUS INFINITY = NORM_INFINITY # extra aliases FRB = FROBENIUS INF = INFINITY # ------------------------------------------------------------------------------ ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/src/petsc4py/PETSc/DM.pyx0000644000175000017500000015221114567251135016713 0ustar00balaybalay# -------------------------------------------------------------------- class DMType(object): """`DM` types.""" DA = S_(DMDA_type) COMPOSITE = S_(DMCOMPOSITE) SLICED = S_(DMSLICED) SHELL = S_(DMSHELL) PLEX = S_(DMPLEX) REDUNDANT = S_(DMREDUNDANT) PATCH = S_(DMPATCH) MOAB = S_(DMMOAB) NETWORK = S_(DMNETWORK) FOREST = S_(DMFOREST) P4EST = S_(DMP4EST) P8EST = S_(DMP8EST) SWARM = S_(DMSWARM) PRODUCT = S_(DMPRODUCT) STAG = S_(DMSTAG) class DMBoundaryType(object): """`DM` Boundary types.""" NONE = DM_BOUNDARY_NONE GHOSTED = DM_BOUNDARY_GHOSTED MIRROR = DM_BOUNDARY_MIRROR PERIODIC = DM_BOUNDARY_PERIODIC TWIST = DM_BOUNDARY_TWIST class DMPolytopeType(object): POINT = DM_POLYTOPE_POINT SEGMENT = DM_POLYTOPE_SEGMENT POINT_PRISM_TENSOR = DM_POLYTOPE_POINT_PRISM_TENSOR TRIANGLE = DM_POLYTOPE_TRIANGLE QUADRILATERAL = DM_POLYTOPE_QUADRILATERAL SEG_PRISM_TENSOR = DM_POLYTOPE_SEG_PRISM_TENSOR TETRAHEDRON = DM_POLYTOPE_TETRAHEDRON HEXAHEDRON = DM_POLYTOPE_HEXAHEDRON TRI_PRISM = DM_POLYTOPE_TRI_PRISM TRI_PRISM_TENSOR = DM_POLYTOPE_TRI_PRISM_TENSOR QUAD_PRISM_TENSOR = DM_POLYTOPE_QUAD_PRISM_TENSOR PYRAMID = DM_POLYTOPE_PYRAMID FV_GHOST = DM_POLYTOPE_FV_GHOST INTERIOR_GHOST = DM_POLYTOPE_INTERIOR_GHOST UNKNOWN = DM_POLYTOPE_UNKNOWN # -------------------------------------------------------------------- cdef class DM(Object): """An object describing a computational grid or mesh. """ Type = DMType BoundaryType = DMBoundaryType PolytopeType = DMPolytopeType # def __cinit__(self): self.obj = &self.dm self.dm = NULL def view(self, Viewer viewer=None) -> None: """View the `DM`. Collective. Parameters ---------- viewer The DM viewer. See Also -------- petsc.DMView """ cdef PetscViewer vwr = NULL if viewer is not None: vwr = viewer.vwr CHKERR( DMView(self.dm, vwr) ) def load(self, Viewer viewer) -> Self: """Return a `DM` stored in binary. Collective. Parameters ---------- viewer Viewer used to store the `DM`, like `Viewer.Type.BINARY` or `Viewer.Type.HDF5`. Notes ----- When using `Viewer.Type.HDF5` format, one can save multiple `DMPlex` meshes in a single HDF5 files. This in turn requires one to name the `DMPlex` object with `Object.setName` before saving it with `DM.view` and before loading it with `DM.load` for identification of the mesh object. See Also -------- DM.view, DM.load, Object.setName, petsc.DMLoad """ CHKERR( DMLoad(self.dm, viewer.vwr) ) return self def destroy(self) -> Self: """Destroy the object. Collective. See Also -------- petsc.DMDestroy """ CHKERR( DMDestroy(&self.dm) ) return self def create(self, comm: Comm | None = None) -> Self: """Return an empty `DM`. Collective. Parameters ---------- comm MPI communicator, defaults to `Sys.getDefaultComm`. See Also -------- petsc.DMCreate """ cdef MPI_Comm ccomm = def_Comm(comm, PETSC_COMM_DEFAULT) cdef PetscDM newdm = NULL CHKERR( DMCreate(ccomm, &newdm) ) CHKERR( PetscCLEAR(self.obj) ); self.dm = newdm return self def clone(self) -> DM: """Return the cloned `DM` . Collective. See Also -------- petsc.DMClone """ cdef DM dm = type(self)() CHKERR( DMClone(self.dm, &dm.dm) ) return dm def setType(self, dm_type: DM.Type | str) -> None: """Build a `DM`. Collective. Parameters ---------- dm_type The type of `DM`. Notes ----- `DM` types are available in `DM.Type` class. See Also -------- DM.Type, petsc.DMSetType """ cdef PetscDMType cval = NULL dm_type = str2bytes(dm_type, &cval) CHKERR( DMSetType(self.dm, cval) ) def getType(self) -> str: """Return the `DM` type name. Not collective. See Also -------- petsc.DMGetType """ cdef PetscDMType cval = NULL CHKERR( DMGetType(self.dm, &cval) ) return bytes2str(cval) def getDimension(self) -> int: """Return the topological dimension of the `DM`. Not collective. See Also -------- petsc.DMGetDimension """ cdef PetscInt dim = 0 CHKERR( DMGetDimension(self.dm, &dim) ) return toInt(dim) def setDimension(self, dim: int) -> None: """Set the topological dimension of the `DM`. Collective. Parameters ---------- dim Topological dimension. See Also -------- petsc.DMSetDimension """ cdef PetscInt cdim = asInt(dim) CHKERR( DMSetDimension(self.dm, cdim) ) def getCoordinateDim(self) -> int: """Return the dimension of embedding space for coordinates values. Not collective. See Also -------- petsc.DMGetCoordinateDim """ cdef PetscInt dim = 0 CHKERR( DMGetCoordinateDim(self.dm, &dim) ) return toInt(dim) def setCoordinateDim(self, dim: int) -> None: """Set the dimension of embedding space for coordinates values. Not collective. Parameters ---------- dim The embedding dimension. See Also -------- petsc.DMSetCoordinateDim """ cdef PetscInt cdim = asInt(dim) CHKERR( DMSetCoordinateDim(self.dm, cdim) ) def setOptionsPrefix(self, prefix: str) -> None: """Set the prefix used for searching for options in the database. Logically collective. See Also -------- petsc_options, getOptionsPrefix, petsc.DMSetOptionsPrefix """ cdef const char *cval = NULL prefix = str2bytes(prefix, &cval) CHKERR( DMSetOptionsPrefix(self.dm, cval) ) def getOptionsPrefix(self) -> str: """Return the prefix used for searching for options in the database. Not collective. See Also -------- petsc_options, setOptionsPrefix, petsc.DMGetOptionsPrefix """ cdef const char *cval = NULL CHKERR( DMGetOptionsPrefix(self.dm, &cval) ) return bytes2str(cval) def appendOptionsPrefix(self, prefix: str) -> None: """Append to the prefix used for searching for options in the database. Logically collective. See Also -------- petsc_options, setOptionsPrefix, petsc.DMAppendOptionsPrefix """ cdef const char *cval = NULL prefix = str2bytes(prefix, &cval) CHKERR( DMAppendOptionsPrefix(self.dm, cval) ) def setFromOptions(self) -> None: """Configure the object from the options database. Collective. See Also -------- petsc_options, petsc.DMSetFromOptions """ CHKERR( DMSetFromOptions(self.dm) ) def viewFromOptions(self, name: str, Object obj=None) -> None: """View a `DM` based in the options. Collective. Parameters ---------- name Name used to activate the viewing. obj Object provides the prefix for the options database. See Also -------- petsc.DMViewFromOptions """ cdef const char *cname = NULL _ = str2bytes(name, &cname) cdef PetscObject cobj = NULL if obj is not None: cobj = obj.obj[0] CHKERR( DMViewFromOptions(self.dm, cobj, cname) ) def setUp(self) -> Self: """Return the data structure. Collective. See Also -------- petsc.DMSetUp """ CHKERR( DMSetUp(self.dm) ) return self # --- application context --- def setAppCtx(self, appctx): self.set_attr('__appctx__', appctx) def getAppCtx(self): return self.get_attr('__appctx__') # def setBasicAdjacency(self, useCone: bool, useClosure: bool) -> None: """Set the flags for determining variable influence. Not collective. Parameters ---------- useCone : bool Whether adjacency uses cone information. useClosure : bool Whether adjacency is computed using full closure information. See Also -------- petsc.DMSetBasicAdjacency """ cdef PetscBool uC = useCone cdef PetscBool uCl = useClosure CHKERR( DMSetBasicAdjacency(self.dm, uC, uCl) ) def getBasicAdjacency(self) -> tuple[bool, bool]: """Return the flags for determining variable influence. Not collective. Returns ------- useCone : bool Whether adjacency uses cone information. useClosure : bool Whether adjacency is computed using full closure information. See Also -------- petsc.DMGetBasicAdjacency """ cdef PetscBool uC = PETSC_FALSE cdef PetscBool uCl = PETSC_FALSE CHKERR( DMGetBasicAdjacency(self.dm, &uC, &uCl) ) return toBool(uC), toBool(uCl) def setFieldAdjacency(self, field: int, useCone: bool, useClosure: bool) -> None: """Set the flags for determining variable influence. Not collective. Parameters ---------- field : int The field number. useCone : bool Whether adjacency uses cone information. useClosure : bool Whether adjacency is computed using full closure information. See Also -------- petsc.DMSetAdjacency """ cdef PetscInt f = asInt(field) cdef PetscBool uC = useCone cdef PetscBool uCl = useClosure CHKERR( DMSetAdjacency(self.dm, f, uC, uCl) ) def getFieldAdjacency(self, field: int) -> tuple[bool, bool]: """Return the flags for determining variable influence. Not collective. Parameters ---------- field The field number. Returns ------- useCone : bool Whether adjacency uses cone information. useClosure : bool Whether adjacency is computed using full closure information. See Also -------- petsc.DMGetAdjacency """ cdef PetscInt f = asInt(field) cdef PetscBool uC = PETSC_FALSE cdef PetscBool uCl = PETSC_FALSE CHKERR( DMGetAdjacency(self.dm, f, &uC, &uCl) ) return toBool(uC), toBool(uCl) # def createSubDM(self, fields: Sequence[int]) -> tuple[IS, DM]: """Return `IS` and `DM` encapsulating a subproblem. Not collective. Returns ------- iset : IS The global indices for all the degrees of freedom. subdm : DM The `DM` for the subproblem. See Also -------- petsc.DMCreateSubDM """ cdef IS iset = IS() cdef DM subdm = DM() cdef PetscInt *ifields = NULL cdef PetscInt numFields = 0 fields = iarray_i(fields, &numFields, &ifields) CHKERR( DMCreateSubDM( self.dm, numFields, ifields, &iset.iset, &subdm.dm) ) return iset, subdm # def setAuxiliaryVec(self, Vec aux, label: DMLabel | None, value=0, part=0) -> None: """Set an auxiliary vector for a specific region. Not collective. Parameters ---------- aux The auxiliary vector. label The name of the `DMLabel`. value Indicate the region. part The equation part, or 0 is unused. See Also -------- petsc.DMGetLabel, petsc.DMSetAuxiliaryVec """ cdef PetscInt cvalue = asInt(value) cdef PetscInt cpart = asInt(part) cdef const char *cval = NULL cdef PetscDMLabel clbl = NULL label = str2bytes(label, &cval) if cval == NULL: cval = b"" # XXX Should be fixed upstream CHKERR( DMGetLabel(self.dm, cval, &clbl) ) CHKERR( DMSetAuxiliaryVec(self.dm, clbl, cvalue, cpart, aux.vec) ) def getAuxiliaryVec(self, label: str | None = None, value: int | None = 0, part: int | None = 0) -> Vec: """Return an auxiliary vector for region. Not collective. Parameters ---------- label The name of the `DMLabel`. value Indicate the region. part The equation part, or 0 is unused. See Also -------- DM.getLabel, petsc.DMGetAuxiliaryVec """ cdef PetscInt cvalue = asInt(value) cdef PetscInt cpart = asInt(part) cdef const char *cval = NULL cdef PetscDMLabel clbl = NULL cdef Vec aux = Vec() label = str2bytes(label, &cval) if cval == NULL: cval = b"" # XXX Should be fixed upstream CHKERR( DMGetLabel(self.dm, cval, &clbl) ) CHKERR( DMGetAuxiliaryVec(self.dm, clbl, cvalue, cpart, &aux.vec) ) return aux def setNumFields(self, numFields: int) -> None: """Set the number of fields in the `DM`. Logically collective. See Also -------- petsc.DMSetNumFields """ cdef PetscInt cnum = asInt(numFields) CHKERR( DMSetNumFields(self.dm, cnum) ) def getNumFields(self) -> int: """Return the number of fields in the `DM`. Not collective. See Also -------- petsc.DMGetNumFields """ cdef PetscInt cnum = 0 CHKERR( DMGetNumFields(self.dm, &cnum) ) return toInt(cnum) def setField(self, index: int, Object field, label: str | None = None) -> None: """Set the discretization object for a given `DM` field. Logically collective. Parameters ---------- index The field number. field The discretization object. label The name of the label indicating the support of the field, or `None` for the entire mesh. See Also -------- petsc.DMSetField """ cdef PetscInt cidx = asInt(index) cdef PetscObject cobj = field.obj[0] cdef PetscDMLabel clbl = NULL assert label is None CHKERR( DMSetField(self.dm, cidx, clbl, cobj) ) def getField(self, index: int) -> tuple[Object, None]: """Return the discretization object for a given `DM` field. Not collective. Parameters ---------- index The field number. See Also -------- petsc.DMGetField """ cdef PetscInt cidx = asInt(index) cdef PetscObject cobj = NULL cdef PetscDMLabel clbl = NULL CHKERR( DMGetField(self.dm, cidx, &clbl, &cobj) ) assert clbl == NULL cdef Object field = subtype_Object(cobj)() field.obj[0] = cobj CHKERR( PetscINCREF(field.obj) ) return (field, None) # TODO REVIEW def addField(self, Object field, label: str | None = None) -> None: """Add a field to a `DM` object. Logically collective. Parameters ---------- field The discretization object. label The name of the label indicating the support of the field, or `None` for the entire mesh. See Also -------- petsc.DMAddField """ cdef PetscObject cobj = field.obj[0] cdef PetscDMLabel clbl = NULL assert label is None CHKERR( DMAddField(self.dm, clbl, cobj) ) def clearFields(self) -> None: """Remove all fields from the `DM`. Logically collective. See Also -------- petsc.DMClearFields """ CHKERR( DMClearFields(self.dm) ) def copyFields(self, DM dm) -> None: """Copy the discretizations of this `DM` into another `DM`. Collective. Parameters ---------- dm The `DM` that the fields are copied into. See Also -------- petsc.DMCopyFields """ CHKERR( DMCopyFields(self.dm, dm.dm) ) def createDS(self) -> None: """Create discrete systems. Collective. See Also -------- petsc.DMCreateDS """ CHKERR( DMCreateDS(self.dm) ) def clearDS(self) -> None: """Remove all discrete systems from the `DM`. Logically collective. See Also -------- petsc.DMClearDS """ CHKERR( DMClearDS(self.dm) ) def getDS(self) -> DS: """Return default `DS`. Not collective. See Also -------- petsc.DMGetDS """ cdef DS ds = DS() CHKERR( DMGetDS(self.dm, &ds.ds) ) CHKERR( PetscINCREF(ds.obj) ) return ds def copyDS(self, DM dm) -> None: """Copy the discrete systems for this `DM` into another `DM`. Collective. Parameters ---------- dm The `DM` that the discrete fields are copied into. See Also -------- petsc.DMCopyDS """ CHKERR( DMCopyDS(self.dm, dm.dm) ) def copyDisc(self, DM dm) -> None: """Copy fields and discrete systems of a `DM` into another `DM`. Collective. Parameters ---------- dm The `DM` that the fields and discrete systems are copied into. See Also -------- petsc.DMCopyDisc """ CHKERR( DMCopyDisc(self.dm, dm.dm) ) # def getBlockSize(self) -> int: """Return the inherent block size associated with a `DM`. Not collective. See Also -------- petsc.DMGetBlockSize """ cdef PetscInt bs = 1 CHKERR( DMGetBlockSize(self.dm, &bs) ) return toInt(bs) def setVecType(self, vec_type: Vec.Type | str) -> None: """Set the type of vector. Logically collective. See Also -------- Vec.Type, petsc.DMSetVecType """ cdef PetscVecType vtype = NULL vec_type = str2bytes(vec_type, &vtype) CHKERR( DMSetVecType(self.dm, vtype) ) def createGlobalVec(self) -> Vec: """Return a global vector. Collective. See Also -------- petsc.DMCreateGlobalVector """ cdef Vec vg = Vec() CHKERR( DMCreateGlobalVector(self.dm, &vg.vec) ) return vg def createLocalVec(self) -> Vec: """Return a local vector. Not collective. See Also -------- petsc.DMCreateLocalVector """ cdef Vec vl = Vec() CHKERR( DMCreateLocalVector(self.dm, &vl.vec) ) return vl def getGlobalVec(self) -> Vec: """Return a global vector. Collective. See Also -------- petsc.DMGetGlobalVector """ cdef Vec vg = Vec() CHKERR( DMGetGlobalVector(self.dm, &vg.vec) ) CHKERR( PetscINCREF(vg.obj) ) return vg def restoreGlobalVec(self, Vec vg) -> None: """Restore a global vector. Not collective. Parameters ---------- vg The global vector. See Also -------- petsc.DMRestoreGlobalVector """ CHKERR( PetscObjectDereference(vg.vec) ) CHKERR( DMRestoreGlobalVector(self.dm, &vg.vec) ) def getLocalVec(self) -> Vec: """Return a local vector. Not collective. See Also -------- petsc.DMGetLocalVector """ cdef Vec vl = Vec() CHKERR( DMGetLocalVector(self.dm, &vl.vec) ) CHKERR( PetscINCREF(vl.obj) ) return vl def restoreLocalVec(self, Vec vl) -> None: """Restore a local vector. Not collective. Parameters ---------- vl The local vector. See Also -------- petsc.DMRestoreLocalVector """ CHKERR( PetscObjectDereference(vl.vec) ) CHKERR( DMRestoreLocalVector(self.dm, &vl.vec) ) def globalToLocal(self, Vec vg, Vec vl, addv: InsertModeSpec | None = None) -> None: """Update local vectors from global vector. Neighborwise collective. Parameters ---------- vg The global vector. vl The local vector. addv Insertion mode. See Also -------- petsc.DMGlobalToLocalBegin, petsc.DMGlobalToLocalEnd """ cdef PetscInsertMode im = insertmode(addv) CHKERR( DMGlobalToLocalBegin(self.dm, vg.vec, im, vl.vec) ) CHKERR( DMGlobalToLocalEnd (self.dm, vg.vec, im, vl.vec) ) def localToGlobal(self, Vec vl, Vec vg, addv: InsertModeSpec | None = None) -> None: """Update global vectors from local vector. Neighborwise collective. Parameters ---------- vl The local vector. vg The global vector. addv Insertion mode. See Also -------- petsc.DMLocalToGlobalBegin, petsc.DMLocalToGlobalEnd """ cdef PetscInsertMode im = insertmode(addv) CHKERR( DMLocalToGlobalBegin(self.dm, vl.vec, im, vg.vec) ) CHKERR( DMLocalToGlobalEnd(self.dm, vl.vec, im, vg.vec) ) def localToLocal(self, Vec vl, Vec vlg, addv: InsertModeSpec | None = None) -> None: """Map the values from a local vector to another local vector. Neighborwise collective. Parameters ---------- vl The local vector. vlg The global vector. addv Insertion mode. See Also -------- petsc.DMLocalToLocalBegin, petsc.DMLocalToLocalEnd """ cdef PetscInsertMode im = insertmode(addv) CHKERR( DMLocalToLocalBegin(self.dm, vl.vec, im, vlg.vec) ) CHKERR( DMLocalToLocalEnd (self.dm, vl.vec, im, vlg.vec) ) def getLGMap(self) -> LGMap: """Return local mapping to global mapping. Collective. See Also -------- petsc.DMGetLocalToGlobalMapping """ cdef LGMap lgm = LGMap() CHKERR( DMGetLocalToGlobalMapping(self.dm, &lgm.lgm) ) CHKERR( PetscINCREF(lgm.obj) ) return lgm # def getCoarseDM(self) -> DM: """Return the coarse `DM`. Collective. See Also -------- petsc.DMGetCoarseDM """ cdef DM cdm = type(self)() CHKERR( DMGetCoarseDM(self.dm, &cdm.dm) ) CHKERR( PetscINCREF(cdm.obj) ) return cdm def setCoarseDM(self, DM dm) -> None: """Set the coarse `DM`. Collective. See Also -------- petsc.DMSetCoarseDM """ CHKERR( DMSetCoarseDM(self.dm, dm.dm) ) return def getCoordinateDM(self) -> DM: """Return the coordinate `DM`. Collective. See Also -------- petsc.DMGetCoordinateDM """ cdef DM cdm = type(self)() CHKERR( DMGetCoordinateDM(self.dm, &cdm.dm) ) CHKERR( PetscINCREF(cdm.obj) ) return cdm def getCoordinateSection(self) -> Section: """Return coordinate values layout over the mesh. Collective. See Also -------- petsc.DMGetCoordinateSection """ cdef Section sec = Section() CHKERR( DMGetCoordinateSection(self.dm, &sec.sec) ) CHKERR( PetscINCREF(sec.obj) ) return sec def setCoordinates(self, Vec c) -> None: """Set a global vector that holds the coordinates. Collective. Parameters ---------- c Coordinate Vector. See Also -------- petsc.DMSetCoordinates """ CHKERR( DMSetCoordinates(self.dm, c.vec) ) def getCoordinates(self) -> Vec: """Return a global vector with the coordinates associated. Collective. See Also -------- petsc.DMGetCoordinates """ cdef Vec c = Vec() CHKERR( DMGetCoordinates(self.dm, &c.vec) ) CHKERR( PetscINCREF(c.obj) ) return c def setCoordinatesLocal(self, Vec c) -> None: """Set a local vector with the ghost point holding the coordinates. Not collective. Parameters ---------- c Coordinate Vector. See Also -------- petsc.DMSetCoordinatesLocal """ CHKERR( DMSetCoordinatesLocal(self.dm, c.vec) ) def getCoordinatesLocal(self) -> Vec: """Return a local vector with the coordinates associated. Collective the first time it is called. See Also -------- petsc.DMGetCoordinatesLocal """ cdef Vec c = Vec() CHKERR( DMGetCoordinatesLocal(self.dm, &c.vec) ) CHKERR( PetscINCREF(c.obj) ) return c def projectCoordinates(self, FE disc) -> Self: """Project coordinates to a different space. Parameters ---------- disc The new coordinates discretization. See Also -------- petsc.DMProjectCoordinates """ CHKERR( DMProjectCoordinates(self.dm, disc.fe)) return self def getBoundingBox(self) -> tuple[tuple[float, float], ...]: """Return the dimension of embedding space for coordinates values. Not collective. See Also -------- petsc.DMGetBoundingBox """ cdef PetscInt i,dim=0 CHKERR( DMGetCoordinateDim(self.dm, &dim) ) cdef PetscReal gmin[3], gmax[3] CHKERR( DMGetBoundingBox(self.dm, gmin, gmax) ) return tuple([(toReal(gmin[i]), toReal(gmax[i])) for i from 0 <= i < dim]) def getLocalBoundingBox(self) -> tuple[tuple[float, float], ...]: """Return the bounding box for the piece of the `DM`. Not collective. See Also -------- petsc.DMGetLocalBoundingBox """ cdef PetscInt i,dim=0 CHKERR( DMGetCoordinateDim(self.dm, &dim) ) cdef PetscReal lmin[3], lmax[3] CHKERR( DMGetLocalBoundingBox(self.dm, lmin, lmax) ) return tuple([(toReal(lmin[i]), toReal(lmax[i])) for i from 0 <= i < dim]) def localizeCoordinates(self) -> None: """Create local coordinates for cells having periodic faces. Collective. Notes ----- Used if the mesh is periodic. See Also -------- petsc.DMLocalizeCoordinates """ CHKERR( DMLocalizeCoordinates(self.dm) ) # def setMatType(self, mat_type: Mat.Type | str) -> None: """Set matrix type to be used by `DM.createMat`. Logically collective. Parameters ---------- mat_type The matrix type. Notes ----- The option ``-dm_mat_type`` is used to set the matrix type. See Also -------- petsc_options, petsc.DMSetMatType """ cdef PetscMatType mtype = NULL mat_type = str2bytes(mat_type, &mtype) CHKERR( DMSetMatType(self.dm, mtype) ) def createMat(self) -> Mat: """Return an empty matrix. Collective. See Also -------- petsc.DMCreateMatrix """ cdef Mat mat = Mat() CHKERR( DMCreateMatrix(self.dm, &mat.mat) ) return mat def createMassMatrix(self, DM dmf) -> Mat: """Return the mass matrix between this `DM` and the given `DM`. Collective. Parameters ---------- dmf The second `DM`. See Also -------- petsc.DMCreateMassMatrix """ cdef Mat mat = Mat() CHKERR( DMCreateMassMatrix(self.dm, dmf.dm, &mat.mat) ) return mat def createInterpolation(self, DM dm) -> tuple[Mat, Vec]: """Return the interpolation matrix to a finer `DM`. Collective. Parameters ---------- dm The second, finer `DM`. See Also -------- petsc.DMCreateInterpolation """ cdef Mat A = Mat() cdef Vec scale = Vec() CHKERR( DMCreateInterpolation(self.dm, dm.dm, &A.mat, &scale.vec)) return (A, scale) def createInjection(self, DM dm) -> Mat: """Return the injection matrix into a finer `DM`. Collective. Parameters ---------- dm The second, finer `DM` object. See Also -------- petsc.DMCreateInjection """ cdef Mat inject = Mat() CHKERR( DMCreateInjection(self.dm, dm.dm, &inject.mat) ) return inject def createRestriction(self, DM dm) -> Mat: """Return the restriction matrix between this `DM` and the given `DM`. Collective. Parameters ---------- dm The second, finer `DM` object. See Also -------- petsc.DMCreateRestriction """ cdef Mat mat = Mat() CHKERR( DMCreateRestriction(self.dm, dm.dm, &mat.mat) ) return mat def convert(self, dm_type: DM.Type | str) -> DM: """Return a `DM` converted to another `DM`. Collective. Parameters ---------- dm_type The new `DM.Type`, use ``“same”`` for the same type. See Also -------- DM.Type, petsc.DMConvert """ cdef PetscDMType cval = NULL dm_type = str2bytes(dm_type, &cval) cdef PetscDM newdm = NULL CHKERR( DMConvert(self.dm, cval, &newdm) ) cdef DM dm = subtype_DM(newdm)() dm.dm = newdm return dm def refine(self, comm: Comm | None = None) -> DM: """Return a refined `DM` object. Collective. Parameters ---------- comm MPI communicator, defaults to `Sys.getDefaultComm`. See Also -------- petsc.DMRefine """ cdef MPI_Comm dmcomm = MPI_COMM_NULL CHKERR( PetscObjectGetComm(self.dm, &dmcomm) ) dmcomm = def_Comm(comm, dmcomm) cdef PetscDM newdm = NULL CHKERR( DMRefine(self.dm, dmcomm, &newdm) ) cdef DM dm = subtype_DM(newdm)() dm.dm = newdm return dm def coarsen(self, comm: Comm | None = None) -> DM: """Return a coarsened `DM` object. Collective. Parameters ---------- comm MPI communicator, defaults to `Sys.getDefaultComm`. See Also -------- petsc.DMCoarsen """ cdef MPI_Comm dmcomm = MPI_COMM_NULL CHKERR( PetscObjectGetComm(self.dm, &dmcomm) ) dmcomm = def_Comm(comm, dmcomm) cdef PetscDM newdm = NULL CHKERR( DMCoarsen(self.dm, dmcomm, &newdm) ) cdef DM dm = subtype_DM(newdm)() dm.dm = newdm return dm def refineHierarchy(self, nlevels: int) -> list: """Refine this `DM` and return the refined `DM` hierarchy. Collective. Parameters ---------- nlevels The number of levels of refinement. See Also -------- petsc.DMRefineHierarchy """ cdef PetscInt i, n = asInt(nlevels) cdef PetscDM *newdmf = NULL cdef object tmp = oarray_p(empty_p(n), NULL, &newdmf) CHKERR( DMRefineHierarchy(self.dm, n, newdmf) ) cdef DM dmf = None cdef list hierarchy = [] for i from 0 <= i < n: dmf = subtype_DM(newdmf[i])() dmf.dm = newdmf[i] hierarchy.append(dmf) return hierarchy def coarsenHierarchy(self, nlevels: int) -> list: """Coarsen this `DM` and return the coarsened `DM` hierarchy. Collective. Parameters ---------- nlevels The number of levels of coarsening. See Also -------- petsc.DMCoarsenHierarchy """ cdef PetscInt i, n = asInt(nlevels) cdef PetscDM *newdmc = NULL cdef object tmp = oarray_p(empty_p(n),NULL, &newdmc) CHKERR( DMCoarsenHierarchy(self.dm, n, newdmc) ) cdef DM dmc = None cdef list hierarchy = [] for i from 0 <= i < n: dmc = subtype_DM(newdmc[i])() dmc.dm = newdmc[i] hierarchy.append(dmc) return hierarchy def getRefineLevel(self) -> int: """Return the refinement level. Not collective. See Also -------- petsc.DMGetRefineLevel """ cdef PetscInt n = 0 CHKERR( DMGetRefineLevel(self.dm, &n) ) return toInt(n) def setRefineLevel(self, level: int) -> None: """Set the number of refinements. Not collective. Parameters ---------- nlevels The number of refinement. See Also -------- petsc.DMSetRefineLevel """ cdef PetscInt clevel = asInt(level) CHKERR( DMSetRefineLevel(self.dm, clevel) ) def getCoarsenLevel(self) -> int: """Return the number of coarsenings. Not collective. See Also -------- petsc.DMGetCoarsenLevel """ cdef PetscInt n = 0 CHKERR( DMGetCoarsenLevel(self.dm, &n) ) return toInt(n) # def adaptLabel(self, label: str) -> DM: """Adapt a `DM` based on a `DMLabel`. Collective. Parameters ---------- label The name of the `DMLabel`. See Also -------- petsc.DMAdaptLabel """ cdef const char *cval = NULL cdef PetscDMLabel clbl = NULL label = str2bytes(label, &cval) CHKERR( DMGetLabel(self.dm, cval, &clbl) ) cdef DM newdm = DMPlex() CHKERR( DMAdaptLabel(self.dm, clbl, &newdm.dm) ) return newdm def adaptMetric( self, Vec metric, bdLabel: str | None = None, rgLabel: str | None = None, ) -> DM: """Return a mesh adapted to the specified metric field. Parameters ---------- metric The metric to which the mesh is adapted, defined vertex-wise. bdLabel Label for boundary tags. rgLabel Label for cell tag. See Also -------- petsc.DMAdaptMetric """ cdef const char *cval = NULL cdef PetscDMLabel cbdlbl = NULL cdef PetscDMLabel crglbl = NULL bdLabel = str2bytes(bdLabel, &cval) if cval == NULL: cval = b"" # XXX Should be fixed upstream CHKERR( DMGetLabel(self.dm, cval, &cbdlbl) ) rgLabel = str2bytes(rgLabel, &cval) if cval == NULL: cval = b"" # XXX Should be fixed upstream CHKERR( DMGetLabel(self.dm, cval, &crglbl) ) cdef DM newdm = DMPlex() CHKERR( DMAdaptMetric(self.dm, metric.vec, cbdlbl, crglbl, &newdm.dm) ) return newdm def getLabel(self, name: str) -> DMLabel: """Return the label of a given name. Not collective. See Also -------- petsc.DMGetLabel """ cdef const char *cname = NULL cdef DMLabel dmlabel = DMLabel() name = str2bytes(name, &cname) CHKERR( DMGetLabel(self.dm, cname, &dmlabel.dmlabel) ) CHKERR( PetscINCREF(dmlabel.obj) ) return dmlabel # def setLocalSection(self, Section sec) -> None: """Set the `Section` encoding the local data layout for the `DM`. See Also -------- petsc.DMSetLocalSection """ CHKERR( DMSetLocalSection(self.dm, sec.sec) ) def getLocalSection(self) -> Section: """Return the `Section` encoding the local data layout for the `DM`. See Also -------- petsc.DMGetGlobalSection """ cdef Section sec = Section() CHKERR( DMGetLocalSection(self.dm, &sec.sec) ) CHKERR( PetscINCREF(sec.obj) ) return sec def setGlobalSection(self, Section sec) -> None: """Set the `Section` encoding the global data layout for the `DM`. See Also -------- petsc.DMSetGlobalSection """ CHKERR( DMSetGlobalSection(self.dm, sec.sec) ) def getGlobalSection(self) -> Section: """Return the `Section` encoding the global data layout for the `DM`. See Also -------- petsc.DMGetGlobalSection """ cdef Section sec = Section() CHKERR( DMGetGlobalSection(self.dm, &sec.sec) ) CHKERR( PetscINCREF(sec.obj) ) return sec setSection = setLocalSection getSection = getLocalSection setDefaultSection = setLocalSection getDefaultSection = getLocalSection setDefaultLocalSection = setLocalSection getDefaultLocalSection = getLocalSection setDefaultGlobalSection = setGlobalSection getDefaultGlobalSection = getGlobalSection def createSectionSF(self, Section localsec, Section globalsec) -> None: """Create the `SF` encoding the parallel DOF overlap for the `DM`. Parameters ---------- localsec Describe the local data layout. globalsec Describe the global data layout. Notes ----- Encoding based on the `Section` describing the data layout. See Also -------- DM.getSectionSF, petsc.DMCreateSectionSF """ CHKERR( DMCreateSectionSF(self.dm, localsec.sec, globalsec.sec) ) def getSectionSF(self) -> SF: """Return the `Section` encoding the parallel DOF overlap. See Also -------- petsc.DMGetSectionSF """ cdef SF sf = SF() CHKERR( DMGetSectionSF(self.dm, &sf.sf) ) CHKERR( PetscINCREF(sf.obj) ) return sf def setSectionSF(self, SF sf) -> None: """Set the `Section` encoding the parallel DOF overlap for the `DM`. See Also -------- petsc.DMSetSectionSF """ CHKERR( DMSetSectionSF(self.dm, sf.sf) ) createDefaultSF = createSectionSF getDefaultSF = getSectionSF setDefaultSF = setSectionSF def getPointSF(self) -> SF: """Return the `SF` encoding the parallel DOF overlap for the `DM`. See Also -------- petsc.DMGetPointSF """ cdef SF sf = SF() CHKERR( DMGetPointSF(self.dm, &sf.sf) ) CHKERR( PetscINCREF(sf.obj) ) return sf def setPointSF(self, SF sf) -> None: """Set the `SF` encoding the parallel DOF overlap for the `DM`. See Also -------- petsc.DMSetPointSF """ CHKERR( DMSetPointSF(self.dm, sf.sf) ) def getNumLabels(self) -> int: """Return the number of labels defined by on the `DM`. Not collective. See Also -------- petsc.DMGetNumLabels """ cdef PetscInt nLabels = 0 CHKERR( DMGetNumLabels(self.dm, &nLabels) ) return toInt(nLabels) def getLabelName(self, index: int) -> str: """Return the name of nth label. Not collective. Parameters ---------- index The label number. See Also -------- petsc.DMGetLabelName """ cdef PetscInt cindex = asInt(index) cdef const char *cname = NULL CHKERR( DMGetLabelName(self.dm, cindex, &cname) ) return bytes2str(cname) def hasLabel(self, name: str) -> bool: """Determine whether the `DM` has a label. Not collective. Parameters ---------- name The label name. See Also -------- petsc.DMHasLabel """ cdef PetscBool flag = PETSC_FALSE cdef const char *cname = NULL name = str2bytes(name, &cname) CHKERR( DMHasLabel(self.dm, cname, &flag) ) return toBool(flag) def createLabel(self, name: str) -> None: """Create a label of the given name if it does not already exist. Not collective. Parameters ---------- name The label name. See Also -------- petsc.DMCreateLabel """ cdef const char *cname = NULL name = str2bytes(name, &cname) CHKERR( DMCreateLabel(self.dm, cname) ) def removeLabel(self, name: str) -> None: """Remove and destroy the label by name. Not collective. Parameters ---------- name The label name. See Also -------- petsc.DMRemoveLabel """ cdef const char *cname = NULL cdef PetscDMLabel clbl = NULL name = str2bytes(name, &cname) CHKERR( DMRemoveLabel(self.dm, cname, &clbl) ) # TODO: Once DMLabel is wrapped, this should return the label, like the C function. CHKERR( DMLabelDestroy(&clbl) ) def getLabelValue(self, name: str, point: int) -> int: """Return the value in `DMLabel` for the given point. Not collective. Parameters ---------- name The label name. point The mesh point See Also -------- petsc.DMGetLabelValue """ cdef PetscInt cpoint = asInt(point), value = 0 cdef const char *cname = NULL name = str2bytes(name, &cname) CHKERR( DMGetLabelValue(self.dm, cname, cpoint, &value) ) return toInt(value) def setLabelValue(self, name: str, point: int, value: int) -> None: """Set a point to a `DMLabel` with a given value. Not collective. Parameters ---------- name The label name. point The mesh point. value The label value for the point. See Also -------- petsc.DMSetLabelValue """ cdef PetscInt cpoint = asInt(point), cvalue = asInt(value) cdef const char *cname = NULL name = str2bytes(name, &cname) CHKERR( DMSetLabelValue(self.dm, cname, cpoint, cvalue) ) def clearLabelValue(self, name: str, point: int, value: int) -> None: """Remove a point from a `DMLabel` with given value. Not collective. Parameters ---------- name The label name. point The mesh point. value The label value for the point. See Also -------- petsc.DMClearLabelValue """ cdef PetscInt cpoint = asInt(point), cvalue = asInt(value) cdef const char *cname = NULL name = str2bytes(name, &cname) CHKERR( DMClearLabelValue(self.dm, cname, cpoint, cvalue) ) def getLabelSize(self, name: str) -> int: """Return the number of values that the `DMLabel` takes. Not collective. Parameters ---------- name The label name. See Also -------- petsc.DMLabelGetNumValues, petsc.DMGetLabelSize """ cdef PetscInt size = 0 cdef const char *cname = NULL name = str2bytes(name, &cname) CHKERR( DMGetLabelSize(self.dm, cname, &size) ) return toInt(size) def getLabelIdIS(self, name: str) -> IS: """Return an `IS` of all values that the `DMLabel` takes. Not collective. Parameters ---------- name The label name. See Also -------- petsc.DMLabelGetValueIS, petsc.DMGetLabelIdIS """ cdef const char *cname = NULL name = str2bytes(name, &cname) cdef IS lis = IS() CHKERR( DMGetLabelIdIS(self.dm, cname, &lis.iset) ) return lis def getStratumSize(self, name: str, value: int) -> int: """Return the number of points in a label stratum. Not collective. Parameters ---------- name The label name. value The stratum value. See Also -------- petsc.DMGetStratumSize """ cdef PetscInt size = 0 cdef PetscInt cvalue = asInt(value) cdef const char *cname = NULL name = str2bytes(name, &cname) CHKERR( DMGetStratumSize(self.dm, cname, cvalue, &size) ) return toInt(size) def getStratumIS(self, name: str, value: int) -> IS: """Return the points in a label stratum. Not collective. Parameters ---------- name The label name. value The stratum value. See Also -------- petsc.DMGetStratumIS """ cdef PetscInt cvalue = asInt(value) cdef const char *cname = NULL name = str2bytes(name, &cname) cdef IS sis = IS() CHKERR( DMGetStratumIS(self.dm, cname, cvalue, &sis.iset) ) return sis def clearLabelStratum(self, name: str, value: int) -> None: """Remove all points from a stratum. Not collective. Parameters ---------- name The label name. value The stratum value. See Also -------- petsc.DMClearLabelStratum """ cdef PetscInt cvalue = asInt(value) cdef const char *cname = NULL name = str2bytes(name, &cname) CHKERR( DMClearLabelStratum(self.dm, cname, cvalue) ) def setLabelOutput(self, name: str, output: bool) -> None: """Set if a given label should be saved to a view. Not collective. Parameters ---------- name The label name. output If `True`, the label is saved to the viewer. See Also -------- petsc.DMSetLabelOutput """ cdef const char *cname = NULL name = str2bytes(name, &cname) cdef PetscBool coutput = output CHKERR( DMSetLabelOutput(self.dm, cname, coutput) ) def getLabelOutput(self, name: str) -> bool: """Return the output flag for a given label. Not collective. Parameters ---------- name The label name. See Also -------- petsc.DMGetLabelOutput """ cdef const char *cname = NULL name = str2bytes(name, &cname) cdef PetscBool coutput = PETSC_FALSE CHKERR( DMGetLabelOutput(self.dm, cname, &coutput) ) return coutput # backward compatibility createGlobalVector = createGlobalVec createLocalVector = createLocalVec getMatrix = createMatrix = createMat def setKSPComputeOperators( self, operators, args: tuple[Any, ...] | None = None, kargs: dict[str, Any] | None = None, ) -> None: """Matrix associated with the linear system. Collective. Parameters ---------- operator Callback function to compute the operators. args Positional arguments for the callback. kargs Keyword arguments for the callback. See Also -------- petsc.DMKSPSetComputeOperators """ if args is None: args = () if kargs is None: kargs = {} context = (operators, args, kargs) self.set_attr('__operators__', context) CHKERR( DMKSPSetComputeOperators(self.dm, KSP_ComputeOps, context) ) def createFieldDecomposition(self) -> tuple[list, list, list] : """Return a list of `IS` objects. Not collective. Notes ----- The user is responsible for freeing all requested arrays. See Also -------- petsc.DMCreateFieldDecomposition """ cdef PetscInt clen = 0 cdef PetscIS *cis = NULL cdef PetscDM *cdm = NULL cdef char** cnamelist = NULL CHKERR( DMCreateFieldDecomposition(self.dm, &clen, &cnamelist, &cis, &cdm) ) cdef list isets = [ref_IS(cis[i]) for i from 0 <= i < clen] cdef list dms = [] cdef list names = [] cdef DM dm = None for i from 0 <= i < clen: if cdm != NULL: dm = subtype_DM(cdm[i])() dm.dm = cdm[i] CHKERR( PetscINCREF(dm.obj) ) dms.append(dm) else: dms.append(None) name = bytes2str(cnamelist[i]) names.append(name) CHKERR( PetscFree(cnamelist[i]) ) CHKERR( ISDestroy(&cis[i]) ) CHKERR( DMDestroy(&cdm[i]) ) CHKERR( PetscFree(cis) ) CHKERR( PetscFree(cdm) ) CHKERR( PetscFree(cnamelist) ) return (names, isets, dms) # TODO REVIEW def setSNESFunction( self, function: SNESFunction, args: tuple[Any, ...] | None = None, kargs: dict[str, Any] | None = None, ) -> None: """Set `SNES` residual evaluation function. Not collective. Parameters ---------- function The callback. args Positional arguments for the callback. kargs Keyword arguments for the callback. See Also -------- SNES.setFunction, petsc.DMSNESSetFunction """ if function is not None: if args is None: args = () if kargs is None: kargs = {} context = (function, args, kargs) self.set_attr('__function__', context) CHKERR( DMSNESSetFunction(self.dm, SNES_Function, context) ) else: CHKERR( DMSNESSetFunction(self.dm, NULL, NULL) ) def setSNESJacobian( self, jacobian: SNESJacobianFunction, args: tuple[Any, ...] | None = None, kargs: dict[str, Any] | None = None, ) -> None: """Set the `SNES` Jacobian evaluation function. Not collective. Parameters ---------- jacobian The Jacobian callback. args Positional arguments for the callback. kargs Keyword arguments for the callback. See Also -------- SNES.setJacobian, petsc.DMSNESSetJacobian """ if jacobian is not None: if args is None: args = () if kargs is None: kargs = {} context = (jacobian, args, kargs) self.set_attr('__jacobian__', context) CHKERR( DMSNESSetJacobian(self.dm, SNES_Jacobian, context) ) else: CHKERR( DMSNESSetJacobian(self.dm, NULL, NULL) ) def addCoarsenHook( self, coarsenhook: DMCoarsenHookFunction, restricthook: DMRestrictHookFunction, args: tuple[Any, ...] | None = None, kargs: dict[str, Any] | None = None, ) -> None: """Add a callback to be executed when restricting to a coarser grid. Logically collective. Parameters ---------- coarsenhook The coarsen hook function. restricthook The restrict hook function. args Positional arguments for the hooks. kargs Keyword arguments for the hooks. See Also -------- petsc.DMCoarsenHookAdd """ if args is None: args = () if kargs is None: kargs = {} if coarsenhook is not None: coarsencontext = (coarsenhook, args, kargs) coarsenhooks = self.get_attr('__coarsenhooks__') if coarsenhooks is None: coarsenhooks = [coarsencontext] CHKERR( DMCoarsenHookAdd(self.dm, DM_PyCoarsenHook, NULL, NULL) ) else: coarsenhooks.append(coarsencontext) self.set_attr('__coarsenhooks__', coarsenhooks) if restricthook is not None: restrictcontext = (restricthook, args, kargs) restricthooks = self.get_attr('__restricthooks__') if restricthooks is None: restricthooks = [restrictcontext] CHKERR( DMCoarsenHookAdd(self.dm, NULL, DM_PyRestrictHook, NULL) ) else: restricthooks.append(restrictcontext) self.set_attr('__restricthooks__', restricthooks) # --- application context --- property appctx: def __get__(self): return self.getAppCtx() def __set__(self, value): self.setAppCtx(value) # --- discretization space --- property ds: def __get__(self): return self.getDS() def __set__(self, value): self.setDS(value) # -------------------------------------------------------------------- del DMType del DMBoundaryType del DMPolytopeType # -------------------------------------------------------------------- ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/src/petsc4py/PETSc/DMComposite.pyx0000644000175000017500000001515714567251135020605 0ustar00balaybalay# -------------------------------------------------------------------- cdef class DMComposite(DM): """A DM object that is used to manage data for a collection of DMs.""" def create(self, comm: Comm | None = None) -> Self: """Create a composite object. Collective. Parameters ---------- comm MPI communicator, defaults to `Sys.getDefaultComm`. See Also -------- petsc.DMCompositeCreate """ cdef MPI_Comm ccomm = def_Comm(comm, PETSC_COMM_DEFAULT) cdef PetscDM newdm = NULL CHKERR( DMCompositeCreate(ccomm, &newdm) ) CHKERR( PetscCLEAR(self.obj) ); self.dm = newdm return self def addDM(self, DM dm, *args: DM) -> None: """Add a DM vector to the composite. Collective. Parameters ---------- dm The DM object. *args Additional DM objects. See Also -------- petsc.DMCompositeAddDM """ CHKERR( DMCompositeAddDM(self.dm, dm.dm) ) cdef object item for item in args: dm = item CHKERR( DMCompositeAddDM(self.dm, dm.dm) ) def getNumber(self) -> int: """Get number of sub-DMs contained in the composite. Not collective. See Also -------- petsc.DMCompositeGetNumberDM """ cdef PetscInt n = 0 CHKERR( DMCompositeGetNumberDM(self.dm, &n) ) return toInt(n) getNumberDM = getNumber def getEntries(self) -> list[DM]: """Return sub-DMs contained in the composite. Not collective. See Also -------- petsc.DMCompositeGetEntriesArray """ cdef PetscInt i, n = 0 cdef PetscDM *cdms = NULL CHKERR( DMCompositeGetNumberDM(self.dm, &n) ) cdef object tmp = oarray_p(empty_p(n), NULL, &cdms) CHKERR( DMCompositeGetEntriesArray(self.dm, cdms) ) cdef DM entry = None cdef list entries = [] for i from 0 <= i < n: entry = subtype_DM(cdms[i])() entry.dm = cdms[i] CHKERR( PetscINCREF(entry.obj) ) entries.append(entry) return entries def scatter(self, Vec gvec, lvecs: Sequence[Vec]) -> None: """Scatter coupled global vector into split local vectors. Collective. Parameters ---------- gvec The global vector. lvecs Array of local vectors. See Also -------- gather, petsc.DMCompositeScatterArray """ cdef PetscInt i, n = 0 CHKERR( DMCompositeGetNumberDM(self.dm, &n) ) cdef PetscVec *clvecs = NULL cdef object tmp = oarray_p(empty_p(n), NULL, &clvecs) for i from 0 <= i < n: clvecs[i] = (lvecs[i]).vec CHKERR( DMCompositeScatterArray(self.dm, gvec.vec, clvecs) ) def gather(self, Vec gvec, imode: InsertModeSpec, lvecs: Sequence[Vec]) -> None: """Gather split local vectors into a coupled global vector. Collective. Parameters ---------- gvec The global vector. imode The insertion mode. lvecs The individual sequential vectors. See Also -------- scatter, petsc.DMCompositeGatherArray """ cdef PetscInsertMode cimode = insertmode(imode) cdef PetscInt i, n = 0 CHKERR( DMCompositeGetNumberDM(self.dm, &n) ) cdef PetscVec *clvecs = NULL cdef object tmp = oarray_p(empty_p(n), NULL, &clvecs) for i from 0 <= i < n: clvecs[i] = (lvecs[i]).vec CHKERR( DMCompositeGatherArray(self.dm, cimode, gvec.vec, clvecs) ) def getGlobalISs(self) -> list[IS]: """Return the index sets for each composed object in the composite. Collective. These could be used to extract a subset of vector entries for a "multi-physics" preconditioner. Use `getLocalISs` for index sets in the packed local numbering, and `getLGMaps` for to map local sub-DM (including ghost) indices to packed global indices. See Also -------- petsc.DMCompositeGetGlobalISs """ cdef PetscInt i, n = 0 cdef PetscIS *cis = NULL CHKERR( DMCompositeGetNumberDM(self.dm, &n) ) CHKERR( DMCompositeGetGlobalISs(self.dm, &cis) ) cdef object isets = [ref_IS(cis[i]) for i from 0 <= i < n] for i from 0 <= i < n: CHKERR( ISDestroy(&cis[i]) ) CHKERR( PetscFree(cis) ) return isets def getLocalISs(self) -> list[IS]: """Return index sets for each component of a composite local vector. Not collective. To get the composite global indices at all local points (including ghosts), use `getLGMaps`. To get index sets for pieces of the composite global vector, use `getGlobalISs`. See Also -------- petsc.DMCompositeGetLocalISs """ cdef PetscInt i, n = 0 cdef PetscIS *cis = NULL CHKERR( DMCompositeGetNumberDM(self.dm, &n) ) CHKERR( DMCompositeGetLocalISs(self.dm, &cis) ) cdef object isets = [ref_IS(cis[i]) for i from 0 <= i < n] for i from 0 <= i < n: CHKERR( ISDestroy(&cis[i]) ) CHKERR( PetscFree(cis) ) return isets def getLGMaps(self) -> list[LGMap]: """Return a local-to-global mapping for each DM in the composite. Collective. Note that this includes all the ghost points that individual ghosted DMDA may have. See Also -------- petsc.DMCompositeGetISLocalToGlobalMappings """ cdef PetscInt i, n = 0 cdef PetscLGMap *clgm = NULL CHKERR( DMCompositeGetNumberDM(self.dm, &n) ) CHKERR( DMCompositeGetISLocalToGlobalMappings(self.dm, &clgm) ) cdef object lgms = [ref_LGMap(clgm[i]) for i from 0 <= i < n] for i from 0 <= i < n: CHKERR( ISLocalToGlobalMappingDestroy(&clgm[i]) ) CHKERR( PetscFree(clgm) ) return lgms def getAccess(self, Vec gvec, locs: Sequence[int] | None = None) -> Any: """Get access to the individual vectors from the global vector. Not collective. Use via `with` context manager (PEP 343). Parameters ---------- gvec The global vector. locs Indices of vectors wanted, or `None` to get all vectors. """ return _DMComposite_access(self, gvec, locs) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/src/petsc4py/PETSc/DMDA.pyx0000644000175000017500000010476114567251135017127 0ustar00balaybalay# -------------------------------------------------------------------- class DMDAStencilType(object): STAR = DMDA_STENCIL_STAR BOX = DMDA_STENCIL_BOX class DMDAInterpolationType(object): Q0 = DMDA_INTERPOLATION_Q0 Q1 = DMDA_INTERPOLATION_Q1 class DMDAElementType(object): P1 = DMDA_ELEMENT_P1 Q1 = DMDA_ELEMENT_Q1 # -------------------------------------------------------------------- cdef class DMDA(DM): """A DM object that is used to manage data for a structured grid.""" StencilType = DMDAStencilType InterpolationType = DMDAInterpolationType ElementType = DMDAElementType # def create( self, dim: int | None = None, dof: int | None = None, sizes: DimsSpec | None = None, proc_sizes: DimsSpec | None = None, boundary_type: tuple[DM.BoundaryType | int | str | bool, ...] | None = None, stencil_type: StencilType | None = None, stencil_width: int | None = None, bint setup: bool = True, ownership_ranges: tuple[Sequence[int], ...] | None = None, comm: Comm | None = None, ) -> Self: """Create a ``DMDA`` object. Collective. This routine performs the following steps of the C API: - ``petsc.DMDACreate`` - ``petsc.DMSetDimension`` - ``petsc.DMDASetDof`` - ``petsc.DMDASetSizes`` - ``petsc.DMDASetNumProcs`` - ``petsc.DMDASetOwnershipRanges`` - ``petsc.DMDASetBoundaryType`` - ``petsc.DMDASetStencilType`` - ``petsc.DMDASetStencilWidth`` - ``petsc.DMSetUp`` (optionally) Parameters ---------- dim The number of dimensions. dof The number of degrees of freedom. sizes The number of elements in each dimension. proc_sizes The number of processes in x, y, z dimensions. boundary_type The boundary types. stencil_type The ghost/halo stencil type. stencil_width The width of the ghost/halo region. setup Whether to call the setup routine after creating the object. ownership_ranges Local x, y, z element counts, of length equal to ``proc_sizes``, summing to ``sizes``. comm MPI communicator, defaults to `Sys.getDefaultComm`. See Also -------- petsc.DMDACreate, petsc.DMSetDimension, petsc.DMDASetDof petsc.DMDASetSizes, petsc.DMDASetNumProcs petsc.DMDASetOwnershipRanges, petsc.DMDASetBoundaryType petsc.DMDASetStencilType, petsc.DMDASetStencilWidth, petsc.DMSetUp """ # cdef object arg = None try: arg = tuple(dim) except TypeError: pass else: dim, sizes = None, arg # cdef PetscInt ndim = PETSC_DECIDE cdef PetscInt ndof = PETSC_DECIDE cdef PetscInt M = 1, m = PETSC_DECIDE, *lx = NULL cdef PetscInt N = 1, n = PETSC_DECIDE, *ly = NULL cdef PetscInt P = 1, p = PETSC_DECIDE, *lz = NULL cdef PetscDMBoundaryType btx = DM_BOUNDARY_NONE cdef PetscDMBoundaryType bty = DM_BOUNDARY_NONE cdef PetscDMBoundaryType btz = DM_BOUNDARY_NONE cdef PetscDMDAStencilType stype = DMDA_STENCIL_BOX cdef PetscInt swidth = PETSC_DECIDE # grid and proc sizes cdef object gsizes = sizes cdef object psizes = proc_sizes cdef PetscInt gdim = PETSC_DECIDE cdef PetscInt pdim = PETSC_DECIDE if sizes is not None: gdim = asDims(gsizes, &M, &N, &P) if psizes is not None: pdim = asDims(psizes, &m, &n, &p) if gdim>=0 and pdim>=0: assert gdim == pdim # dim and dof if dim is not None: ndim = asInt(dim) if dof is not None: ndof = asInt(dof) if ndim==PETSC_DECIDE: ndim = gdim if ndof==PETSC_DECIDE: ndof = 1 # vertex distribution if ownership_ranges is not None: ownership_ranges = asOwnershipRanges(ownership_ranges, ndim, &m, &n, &p, &lx, &ly, &lz) # periodicity, stencil type & width if boundary_type is not None: asBoundary(boundary_type, &btx, &bty, &btz) if stencil_type is not None: stype = asStencil(stencil_type) if stencil_width is not None: swidth = asInt(stencil_width) if setup and swidth == PETSC_DECIDE: swidth = 0 # create the DMDA object cdef MPI_Comm ccomm = def_Comm(comm, PETSC_COMM_DEFAULT) cdef PetscDM newda = NULL CHKERR( DMDACreateND(ccomm, ndim, ndof, M, N, P, m, n, p, lx, ly, lz, btx, bty, btz, stype, swidth, &newda) ) if setup and ndim > 0: CHKERR( DMSetUp(newda) ) CHKERR( PetscCLEAR(self.obj) ); self.dm = newda return self def duplicate( self, dof: int | None = None, boundary_type: tuple[DM.BoundaryType | int | str | bool, ...] | None = None, stencil_type: StencilType | None = None, stencil_width: int | None = None, ) -> DMDA: """Duplicate a DMDA. Collective. This routine retrieves the information from the DMDA and recreates it. Parameters ``dof``, ``boundary_type``, ``stencil_type``, ``stencil_width`` will be overwritten, if provided. Parameters ---------- dof The number of degrees of freedom. boundary_type Boundary types. stencil_type The ghost/halo stencil type. stencil_width The width of the ghost/halo region. See Also -------- create, petsc.DMDAGetInfo, petsc.DMSetUp """ cdef PetscInt ndim = 0, ndof = 0 cdef PetscInt M = 1, N = 1, P = 1 cdef PetscInt m = 1, n = 1, p = 1 cdef PetscDMBoundaryType btx = DM_BOUNDARY_NONE cdef PetscDMBoundaryType bty = DM_BOUNDARY_NONE cdef PetscDMBoundaryType btz = DM_BOUNDARY_NONE cdef PetscDMDAStencilType stype = DMDA_STENCIL_BOX cdef PetscInt swidth = PETSC_DECIDE CHKERR( DMDAGetInfo(self.dm, &ndim, &M, &N, &P, &m, &n, &p, &ndof, &swidth, &btx, &bty, &btz, &stype) ) cdef const PetscInt *lx = NULL, *ly = NULL, *lz = NULL CHKERR( DMDAGetOwnershipRanges(self.dm, &lx, &ly, &lz) ) cdef MPI_Comm comm = MPI_COMM_NULL CHKERR( PetscObjectGetComm(self.dm, &comm) ) # if dof is not None: ndof = asInt(dof) if boundary_type is not None: asBoundary(boundary_type, &btx, &bty, &btz) if stencil_type is not None: stype = asStencil(stencil_type) if stencil_width is not None: swidth = asInt(stencil_width) # cdef DMDA da = DMDA() CHKERR( DMDACreateND(comm, ndim, ndof, M, N, P, m, n, p, lx, ly, lz, btx, bty, btz, stype, swidth, &da.dm) ) CHKERR( DMSetUp(da.dm) ) return da # def setDim(self, dim: int) -> None: """Set the topological dimension. Collective. Parameters ---------- dim Topological dimension. See Also -------- getDim, petsc.DMSetDimension """ return self.setDimension(dim) def getDim(self) -> int: """Return the topological dimension. Not collective. See Also -------- setDim, petsc.DMGetDimension """ return self.getDimension() def setDof(self, dof: int) -> None: """Set the number of degrees of freedom per vertex. Not collective. Parameters ---------- dof The number of degrees of freedom. See Also -------- getDof, petsc.DMDASetDof """ cdef PetscInt ndof = asInt(dof) CHKERR( DMDASetDof(self.dm, ndof) ) def getDof(self) -> int: """Return the number of degrees of freedom per node. Not collective. See Also -------- setDof, petsc.DMDAGetInfo """ cdef PetscInt dof = 0 CHKERR( DMDAGetInfo(self.dm, NULL, NULL, NULL, NULL, NULL, NULL, NULL, &dof, NULL, NULL, NULL, NULL, NULL) ) return toInt(dof) def setSizes(self, sizes: DimsSpec) -> None: """Set the number of grid points in each dimension. Logically collective. Parameters ---------- sizes The global (x,), (x, y), or (x, y, z) size. See Also -------- getSizes, petsc.DMDASetSizes """ cdef tuple gsizes = tuple(sizes) cdef PetscInt gdim = PETSC_DECIDE cdef PetscInt M = 1 cdef PetscInt N = 1 cdef PetscInt P = 1 gdim = asDims(gsizes, &M, &N, &P) cdef PetscInt dim = PETSC_DECIDE CHKERR( DMDAGetDim(self.dm, &dim) ) if dim == PETSC_DECIDE: CHKERR( DMSetDimension(self.dm, gdim) ) CHKERR( DMDASetSizes(self.dm, M, N, P) ) def getSizes(self) -> tuple[int, ...]: """Return the number of grid points in each dimension. Not collective. See Also -------- setSizes, petsc.DMDAGetInfo """ cdef PetscInt dim = 0 cdef PetscInt M = PETSC_DECIDE cdef PetscInt N = PETSC_DECIDE cdef PetscInt P = PETSC_DECIDE CHKERR( DMDAGetInfo(self.dm, &dim, &M, &N, &P, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL) ) return toDims(dim, M, N, P) def setProcSizes(self, proc_sizes: DimsSpec) -> None: """Set the number of processes in each dimension. Logically collective. Parameters ---------- proc_sizes The number of processes in (x,), (x, y), or (x, y, z) dimensions. See Also -------- getProcSizes, petsc.DMDASetNumProcs """ cdef tuple psizes = tuple(proc_sizes) cdef PetscInt pdim = PETSC_DECIDE cdef PetscInt m = PETSC_DECIDE cdef PetscInt n = PETSC_DECIDE cdef PetscInt p = PETSC_DECIDE pdim = asDims(psizes, &m, &n, &p) cdef PetscInt dim = PETSC_DECIDE CHKERR( DMDAGetDim(self.dm, &dim) ) if dim == PETSC_DECIDE: CHKERR( DMSetDimension(self.dm, pdim) ) CHKERR( DMDASetNumProcs(self.dm, m, n, p) ) def getProcSizes(self) -> tuple[int, ...]: """Return the number of processes in each dimension. Not collective. See Also -------- setProcSizes, petsc.DMDAGetInfo """ cdef PetscInt dim = 0 cdef PetscInt m = PETSC_DECIDE cdef PetscInt n = PETSC_DECIDE cdef PetscInt p = PETSC_DECIDE CHKERR( DMDAGetInfo(self.dm, &dim, NULL, NULL, NULL, &m, &n, &p, NULL, NULL, NULL, NULL, NULL, NULL) ) return toDims(dim, m, n, p) def setBoundaryType( self, boundary_type: tuple[DM.BoundaryType | int | str | bool, ...], ) -> None: """Set the type of ghost nodes on domain boundaries. Not collective. Parameters ---------- boundary_type The boundary type in (x), (x, y), or (x, y, z) dimensions. See Also -------- getBoundaryType, petsc.DMDASetBoundaryType """ cdef PetscDMBoundaryType btx = DM_BOUNDARY_NONE cdef PetscDMBoundaryType bty = DM_BOUNDARY_NONE cdef PetscDMBoundaryType btz = DM_BOUNDARY_NONE asBoundary(boundary_type, &btx, &bty, &btz) CHKERR( DMDASetBoundaryType(self.dm, btx, bty, btz) ) def getBoundaryType(self) -> tuple[DM.BoundaryType, ...]: """Return the type of ghost nodes at boundary in each dimension. Not collective. See Also -------- setBoundaryType """ cdef PetscInt dim = 0 cdef PetscDMBoundaryType btx = DM_BOUNDARY_NONE cdef PetscDMBoundaryType bty = DM_BOUNDARY_NONE cdef PetscDMBoundaryType btz = DM_BOUNDARY_NONE CHKERR( DMDAGetInfo(self.dm, &dim, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, &btx, &bty, &btz, NULL) ) return toDims(dim, btx, bty, btz) def setStencilType(self, stencil_type: StencilType) -> None: """Set the stencil type. Logically collective. Parameters ---------- stype The stencil type. See Also -------- getStencilType, setStencil, petsc.DMDASetStencilType """ cdef PetscDMDAStencilType stype = asStencil(stencil_type) CHKERR( DMDASetStencilType(self.dm, stype) ) def getStencilType(self) -> StencilType: """Return the stencil type. Not collective. See Also -------- setStencilType, petsc.DMDAGetInfo """ cdef PetscDMDAStencilType stype = DMDA_STENCIL_BOX CHKERR( DMDAGetInfo(self.dm, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, &stype) ) return stype def setStencilWidth(self, stencil_width: int) -> None: """Set the stencil width. Logically collective. Parameters ---------- stencil_width The stencil width. See Also -------- getStencilWidth, setStencil, petsc.DMDASetStencilWidth """ cdef PetscInt swidth = asInt(stencil_width) CHKERR( DMDASetStencilWidth(self.dm, swidth) ) def getStencilWidth(self) -> int: """Return the stencil width. Not collective. See Also -------- setStencilWidth """ cdef PetscInt swidth = 0 CHKERR( DMDAGetInfo(self.dm, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, &swidth, NULL, NULL, NULL, NULL) ) return toInt(swidth) def setStencil( self, stencil_type: StencilType, stencil_width: int, ) -> None: """Set the stencil type and width. Not collective. Parameters ---------- stencil_type The stencil type. stencil_width The stencil width. See Also -------- setStencilWidth, setStencilType, petsc.DMDASetStencilType petsc.DMDASetStencilWidth """ cdef PetscDMDAStencilType stype = asStencil(stencil_type) cdef PetscInt swidth = asInt(stencil_width) CHKERR( DMDASetStencilType(self.dm, stype) ) CHKERR( DMDASetStencilWidth(self.dm, swidth) ) def getStencil(self) -> tuple[StencilType, int]: """Return the stencil type and width. Not collective. See Also -------- getStencilType, getStencilWidth """ cdef PetscDMDAStencilType stype = DMDA_STENCIL_BOX cdef PetscInt swidth = 0 CHKERR( DMDAGetInfo(self.dm, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, &swidth, NULL, NULL, NULL, &stype) ) return (toStencil(stype), toInt(swidth)) # def getRanges(self) -> tuple[tuple[int, int], ...]: """Return the ranges of the owned local region in each dimension. Not collective. Excluding ghost nodes. See Also -------- getGhostRanges, getOwnershipRanges, getCorners, getGhostCorners petsc.DMDAGetCorners """ cdef PetscInt dim=0, x=0, y=0, z=0, m=0, n=0, p=0 CHKERR( DMDAGetDim(self.dm, &dim) ) CHKERR( DMDAGetCorners(self.dm, &x, &y, &z, &m, &n, &p) ) return ((toInt(x), toInt(x+m)), (toInt(y), toInt(y+n)), (toInt(z), toInt(z+p)))[:dim] def getGhostRanges(self) -> tuple[tuple[int, int], ...]: """Return the ranges of the local region in each dimension, including ghost nodes. Not collective. See Also -------- getRanges, getOwnershipRanges, getCorners, getGhostCorners petsc.DMDAGetGhostCorners """ cdef PetscInt dim=0, x=0, y=0, z=0, m=0, n=0, p=0 CHKERR( DMDAGetDim(self.dm, &dim) ) CHKERR( DMDAGetGhostCorners(self.dm, &x, &y, &z, &m, &n, &p) ) return ((toInt(x), toInt(x+m)), (toInt(y), toInt(y+n)), (toInt(z), toInt(z+p)))[:dim] def getOwnershipRanges(self) -> tuple[ArrayInt, ...]: """Return the ranges of indices in each dimension owned by each process. Not collective. These numbers are not multiplied by the number of DOFs per node. See Also -------- getRanges, getGhostRanges, getCorners, getGhostCorners petsc.DMDAGetOwnershipRanges """ cdef PetscInt dim=0, m=0, n=0, p=0 cdef const PetscInt *lx = NULL, *ly = NULL, *lz = NULL CHKERR( DMDAGetInfo(self.dm, &dim, NULL, NULL, NULL, &m, &n, &p, NULL, NULL, NULL, NULL, NULL, NULL) ) CHKERR( DMDAGetOwnershipRanges(self.dm, &lx, &ly, &lz) ) return toOwnershipRanges(dim, m, n, p, lx, ly, lz) def getCorners(self) -> tuple[tuple[int, ...], tuple[int, ...]]: """Return the lower left corner and the sizes of the owned local region. Not collective. Returns the global (x,y,z) indices of the lower left corner (first tuple) and size of the local region (second tuple). Excluding ghost points. The corner information is independent of the number of degrees of freedom per node. Thus the returned values can be thought of as coordinates on a logical grid, where each grid point has (potentially) several degrees of freedom. See Also -------- getRanges, getGhostRanges, getOwnershipRanges, getGhostCorners petsc.DMDAGetCorners """ cdef PetscInt dim=0, x=0, y=0, z=0, m=0, n=0, p=0 CHKERR( DMDAGetDim(self.dm, &dim) ) CHKERR( DMDAGetCorners(self.dm, &x, &y, &z, &m, &n, &p) ) return ((toInt(x), toInt(y), toInt(z))[:dim], (toInt(m), toInt(n), toInt(p))[:dim]) def getGhostCorners(self) -> tuple[tuple[int, ...], tuple[int, ...]]: """Return the lower left corner and the size of the ghosted local region. Not collective. Returns the global (x,y,z) indices of the lower left corner (first tuple) and size of the local region (second tuple). See Also -------- getRanges, getGhostRanges, getOwnershipRanges, getCorners petsc.DMDAGetGhostCorners """ cdef PetscInt dim=0, x=0, y=0, z=0, m=0, n=0, p=0 CHKERR( DMDAGetDim(self.dm, &dim) ) CHKERR( DMDAGetGhostCorners(self.dm, &x, &y, &z, &m, &n, &p) ) return ((toInt(x), toInt(y), toInt(z))[:dim], (toInt(m), toInt(n), toInt(p))[:dim]) # def setFieldName(self, field: int, name: str) -> None: """Set the name of individual field components. Logically collective. Parameters ---------- field The field number for the DMDA (``0``, ``1``, ..., ``dof-1``), where ``dof`` indicates the number of degrees of freedom per node within the `DMDA`. name The name of the field (component). See Also -------- getFieldName, petsc.DMDASetFieldName """ cdef PetscInt ival = asInt(field) cdef const char *cval = NULL name = str2bytes(name, &cval) CHKERR( DMDASetFieldName(self.dm, ival, cval) ) def getFieldName(self, field: int) -> str: """Return the name of an individual field component. Not collective. Parameters ---------- field The field number for the DMDA (``0``, ``1``, ..., ``dof-1``), where ``dof`` indicates the number of degrees of freedom per node within the `DMDA`. See Also -------- setFieldName, petsc.DMDAGetFieldName """ cdef PetscInt ival = asInt(field) cdef const char *cval = NULL CHKERR( DMDAGetFieldName(self.dm, ival, &cval) ) return bytes2str(cval) # def getVecArray(self, Vec vec) -> Any: """Get access to the vector. Not collective. Use via `with` context manager (PEP 343). Parameters ---------- vec The vector to which access is being requested. """ return _DMDA_Vec_array(self, vec) # def setUniformCoordinates( self, xmin: float = 0, xmax: float = 1, ymin: float = 0, ymax: float = 1, zmin: float = 0, zmax: float = 1, ) -> None: """Set the DMDA coordinates to be a uniform grid. Collective. Parameters ---------- xmin The minimum in the ``x`` dimension. xmax The maximum in the ``x`` dimension. ymin The minimum in the ``y`` dimension (value ignored for 1 dimensional problems). ymax The maximum in the ``y`` dimension (value ignored for 1 dimensional problems). zmin The minimum in the ``z`` dimension (value ignored for 1 or 2 dimensional problems). zmax The maximum in the ``z`` dimension (value ignored for 1 or 2 dimensional problems). See Also -------- petsc.DMDASetUniformCoordinates """ cdef PetscReal _xmin = asReal(xmin), _xmax = asReal(xmax) cdef PetscReal _ymin = asReal(ymin), _ymax = asReal(ymax) cdef PetscReal _zmin = asReal(zmin), _zmax = asReal(zmax) CHKERR( DMDASetUniformCoordinates(self.dm, _xmin, _xmax, _ymin, _ymax, _zmin, _zmax) ) def setCoordinateName(self, index: int, name: str) -> None: """Set the name of the coordinate dimension. Logically collective. Parameters ---------- index The coordinate number for the DMDA (``0``, ``1``, ..., ``dim-1``). name The name of the coordinate. See Also -------- getCoordinateName, petsc.DMDASetCoordinateName """ cdef PetscInt ival = asInt(index) cdef const char *cval = NULL name = str2bytes(name, &cval) CHKERR( DMDASetCoordinateName(self.dm, ival, cval) ) def getCoordinateName(self, index: int) -> str: """Return the name of a coordinate dimension. Not collective. Parameters ---------- index The coordinate number for the DMDA (``0``, ``1``, ..., ``dim-1``). See Also -------- setCoordinateName, petsc.DMDAGetCoordinateName """ cdef PetscInt ival = asInt(index) cdef const char *cval = NULL CHKERR( DMDAGetCoordinateName(self.dm, ival, &cval) ) return bytes2str(cval) # def createNaturalVec(self) -> Vec: """Create a vector that will hold values in the natural numbering. Collective. The number of local entries in the vector on each process is the same as in a vector created with `DM.createGlobalVec`. See Also -------- petsc.DMDACreateNaturalVector """ cdef Vec vn = Vec() CHKERR( DMDACreateNaturalVector(self.dm, &vn.vec) ) return vn def globalToNatural( self, Vec vg, Vec vn, addv: InsertMode | None = None, ) -> None: """Map values to the "natural" grid ordering. Neighborwise collective. You must call `createNaturalVec` before using this routine. Parameters ---------- vg The global vector in a grid ordering. vn The global vector in a "natural" ordering. addv The insertion mode. See Also -------- naturalToGlobal, petsc.DMDAGlobalToNaturalBegin petsc.DMDAGlobalToNaturalEnd """ cdef PetscInsertMode im = insertmode(addv) CHKERR( DMDAGlobalToNaturalBegin(self.dm, vg.vec, im, vn.vec) ) CHKERR( DMDAGlobalToNaturalEnd (self.dm, vg.vec, im, vn.vec) ) def naturalToGlobal( self, Vec vn, Vec vg, addv: InsertMode | None = None, ) -> None: """Map values the to grid ordering. Neighborwise collective. Parameters ---------- vn The global vector in a natural ordering. vg the global vector in a grid ordering. addv The insertion mode. See Also -------- globalToNatural, petsc.DMDANaturalToGlobalBegin petsc.DMDANaturalToGlobalEnd """ cdef PetscInsertMode im = insertmode(addv) CHKERR( DMDANaturalToGlobalBegin(self.dm, vn.vec, im, vg.vec) ) CHKERR( DMDANaturalToGlobalEnd (self.dm, vn.vec, im, vg.vec) ) # def getAO(self) -> AO: """Return the application ordering context for a distributed array. Collective. The returned `AO` maps to the natural grid ordering that would be used for the `DMDA` if only 1 processor were employed (ordering most rapidly in the x-dimension, then y, then z). Multiple degrees of freedom are numbered for each node (rather than 1 component for the whole grid, then the next component, etc.). See Also -------- petsc.DMDAGetAO """ cdef AO ao = AO() CHKERR( DMDAGetAO(self.dm, &ao.ao) ) CHKERR( PetscINCREF(ao.obj) ) return ao def getScatter(self) -> tuple[Scatter, Scatter]: """Return the global-to-local, and local-to-local scatter contexts. Collective. See Also -------- petsc.DMDAGetScatter """ cdef Scatter l2g = Scatter() cdef Scatter g2l = Scatter() CHKERR( DMDAGetScatter(self.dm, &l2g.sct, &g2l.sct) ) CHKERR( PetscINCREF(l2g.obj) ) CHKERR( PetscINCREF(g2l.obj) ) return (l2g, g2l) # def setRefinementFactor( self, refine_x: int = 2, refine_y: int = 2, refine_z: int = 2, ) -> None: """Set the ratios for the DMDA grid refinement. Logically collective. Parameters ---------- refine_x Ratio of fine grid to coarse in x dimension. refine_y Ratio of fine grid to coarse in y dimension. refine_z Ratio of fine grid to coarse in z dimension. See Also -------- getRefinementFactor, petsc.DMDASetRefinementFactor """ cdef PetscInt refine[3] refine[0] = asInt(refine_x) refine[1] = asInt(refine_y) refine[2] = asInt(refine_z) CHKERR( DMDASetRefinementFactor(self.dm, refine[0], refine[1], refine[2]) ) def getRefinementFactor(self) -> tuple[int, ...]: """Return the ratios that the DMDA grid is refined in each dimension. Not collective. See Also -------- setRefinementFactor, petsc.DMDAGetRefinementFactor """ cdef PetscInt i, dim = 0, refine[3] CHKERR( DMDAGetDim(self.dm, &dim) ) CHKERR( DMDAGetRefinementFactor(self.dm, &refine[0], &refine[1], &refine[2]) ) return tuple([toInt(refine[i]) for 0 <= i < dim]) def setInterpolationType(self, interp_type: InterpolationType) -> None: """Set the type of interpolation. Logically collective. You should call this on the coarser of the two DMDAs you pass to `DM.createInterpolation`. Parameters ---------- interp_type The interpolation type. See Also -------- getInterpolationType, petsc.DMDASetInterpolationType """ cdef PetscDMDAInterpolationType ival = dainterpolationtype(interp_type) CHKERR( DMDASetInterpolationType(self.dm, ival) ) def getInterpolationType(self) -> InterpolationType: """Return the type of interpolation. Not collective. See Also -------- setInterpolationType, petsc.DMDAGetInterpolationType """ cdef PetscDMDAInterpolationType ival = DMDA_INTERPOLATION_Q0 CHKERR( DMDAGetInterpolationType(self.dm, &ival) ) return ival # def setElementType(self, elem_type: ElementType | str) -> None: """Set the element type to be returned by `getElements`. Not collective. See Also -------- getElementType, petsc.DMDASetElementType """ cdef PetscDMDAElementType ival = daelementtype(elem_type) CHKERR( DMDASetElementType(self.dm, ival) ) # FIXME: Return type def getElementType(self) -> ElementType: """Return the element type to be returned by `getElements`. Not collective. See Also -------- setElementType, petsc.DMDAGetElementType """ cdef PetscDMDAElementType ival = DMDA_ELEMENT_Q1 CHKERR( DMDAGetElementType(self.dm, &ival) ) return ival def getElements(self, elem_type: ElementType | None = None) -> ArrayInt: """Return an array containing the indices of all the local elements. Not collective. The elements are in local coordinates. Each process uniquely owns a subset of the elements. That is, no element is owned by two or more processes. Parameters ---------- elem_type The element type. See Also -------- petsc.DMDAGetElements """ cdef PetscInt dim=0 cdef PetscDMDAElementType etype cdef PetscInt nel=0, nen=0 cdef const PetscInt *elems=NULL cdef object elements CHKERR( DMDAGetDim(self.dm, &dim) ) if elem_type is not None: etype = daelementtype(elem_type) CHKERR( DMDASetElementType(self.dm, etype) ) try: CHKERR( DMDAGetElements(self.dm, &nel, &nen, &elems) ) elements = array_i(nel*nen, elems) elements.shape = (toInt(nel), toInt(nen)) finally: CHKERR( DMDARestoreElements(self.dm, &nel, &nen, &elems) ) return elements # property dim: """The grid dimension.""" def __get__(self) -> int: return self.getDim() property dof: """The number of DOFs associated with each stratum of the grid.""" def __get__(self) -> int: return self.getDof() property sizes: """The global dimension.""" def __get__(self) -> tuple[int, ...]: return self.getSizes() property proc_sizes: """The number of processes in each dimension in the global decomposition.""" def __get__(self) -> tuple[int, ...]: return self.getProcSizes() property boundary_type: """Boundary types in each dimension.""" def __get__(self) -> tuple[DM.BoundaryType, ...]: return self.getBoundaryType() property stencil: """Stencil type and width.""" def __get__(self) -> tuple[StencilType, int]: return self.getStencil() property stencil_type: """Stencil type.""" def __get__(self) -> str: return self.getStencilType() property stencil_width: """Elementwise stencil width.""" def __get__(self) -> int: return self.getStencilWidth() property ranges: """Ranges of the local region in each dimension.""" def __get__(self) -> tuple[tuple[int, int], ...]: return self.getRanges() property ghost_ranges: """Ranges of local region, including ghost nodes.""" def __get__(self) -> tuple[tuple[int, int], ...]: return self.getGhostRanges() property corners: """The lower left corner and size of local region in each dimension.""" def __get__(self) -> tuple[tuple[int, ...], tuple[int, ...]]: return self.getCorners() property ghost_corners: """The lower left corner and size of local region in each dimension.""" def __get__(self) -> tuple[tuple[int, ...], tuple[int, ...]]: return self.getGhostCorners() # backward compatibility createNaturalVector = createNaturalVec # backward compatibility alias DA = DMDA # -------------------------------------------------------------------- del DMDAStencilType del DMDAInterpolationType del DMDAElementType # -------------------------------------------------------------------- ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/src/petsc4py/PETSc/DMLabel.pyx0000644000175000017500000003607614567251135017665 0ustar00balaybalay cdef class DMLabel(Object): """An object representing a subset of mesh entities from a `DM`.""" def __cinit__(self): self.obj = &self.dmlabel self.dmlabel = NULL def destroy(self) -> Self: """Destroy the label. Collective. See Also -------- petsc.DMLabelDestroy """ CHKERR( DMLabelDestroy(&self.dmlabel) ) return self def view(self, Viewer viewer=None) -> None: """View the label. Collective. Parameters ---------- viewer A `Viewer` to display the graph. See Also -------- petsc.DMLabelView """ cdef PetscViewer vwr = NULL if viewer is not None: vwr = viewer.vwr CHKERR( DMLabelView(self.dmlabel, vwr) ) def create(self, name: str, comm: Comm | None = None) -> Self: """Create a `DMLabel` object, which is a multimap. Collective. Parameters ---------- name The label name. comm MPI communicator, defaults to `COMM_SELF`. See Also -------- petsc.DMLabelCreate """ cdef MPI_Comm ccomm = def_Comm(comm, PETSC_COMM_SELF) cdef PetscDMLabel newdmlabel = NULL cdef const char *cname = NULL name = str2bytes(name, &cname) CHKERR( DMLabelCreate(ccomm, cname, &newdmlabel) ) CHKERR( PetscCLEAR(self.obj) ); self.dmlabel = newdmlabel return self def duplicate(self) -> DMLabel: """Duplicate the `DMLabel`. Collective. See Also -------- petsc.DMLabelDuplicate """ cdef DMLabel new = DMLabel() CHKERR( DMLabelDuplicate(self.dmlabel, &new.dmlabel) ) return new def reset(self) -> None: """Destroy internal data structures in the `DMLabel`. Not collective. See Also -------- petsc.DMLabelReset """ CHKERR( DMLabelReset(self.dmlabel) ) def insertIS(self, IS iset, value: int) -> Self: """Set all points in the `IS` to a value. Not collective. Parameters ---------- iset The point IS. value The point value. See Also -------- petsc.DMLabelInsertIS """ cdef PetscInt cvalue = asInt(value) CHKERR( DMLabelInsertIS(self.dmlabel, iset.iset, cvalue) ) return self def setValue(self, point: int, value: int) -> None: """Set the value a label assigns to a point. Not collective. If the value is the same as the label's default value (which is initially ``-1``, and can be changed with `setDefaultValue`), this function will do nothing. Parameters ---------- point The point. value The point value. See Also -------- getValue, setDefaultValue, petsc.DMLabelSetValue """ cdef PetscInt cpoint = asInt(point) cdef PetscInt cvalue = asInt(value) CHKERR( DMLabelSetValue(self.dmlabel, cpoint, cvalue) ) def getValue(self, point: int) -> int: """Return the value a label assigns to a point. Not collective. If no value was assigned, a default value will be returned The default value, initially ``-1``, can be changed with `setDefaultValue`. Parameters ---------- point The point. See Also -------- setValue, setDefaultValue, petsc.DMLabelGetValue """ cdef PetscInt cpoint = asInt(point) cdef PetscInt cvalue = 0 CHKERR( DMLabelGetValue(self.dmlabel, cpoint, &cvalue) ) return toInt(cvalue) def getDefaultValue(self) -> int: """Return the default value returned by `getValue`. Not collective. The default value is returned if a point has not been explicitly given a value. When a label is created, it is initialized to ``-1``. See Also -------- setDefaultValue, petsc.DMLabelGetDefaultValue """ cdef PetscInt cvalue = 0 CHKERR( DMLabelGetDefaultValue(self.dmlabel, &cvalue) ) return toInt(cvalue) def setDefaultValue(self, value: int) -> None: """Set the default value returned by `getValue`. Not collective. The value is used if a point has not been explicitly given a value. When a label is created, the default value is initialized to ``-1``. Parameters ---------- value The default value. See Also -------- getDefaultValue, petsc.DMLabelSetDefaultValue """ cdef PetscInt cvalue = asInt(value) CHKERR( DMLabelSetDefaultValue(self.dmlabel, cvalue) ) def clearValue(self, point: int, value: int) -> None: """Clear the value a label assigns to a point. Not collective. Parameters ---------- point The point. value The point value. See Also -------- petsc.DMLabelClearValue """ cdef PetscInt cpoint = asInt(point) cdef PetscInt cvalue = asInt(value) CHKERR( DMLabelClearValue(self.dmlabel, cpoint, cvalue) ) def addStratum(self, value: int) -> None: """Add a new stratum value in a `DMLabel`. Parameters ---------- value The stratum value. See Also -------- addStrata, addStrataIS, petsc.DMLabelAddStratum """ cdef PetscInt cvalue = asInt(value) CHKERR( DMLabelAddStratum(self.dmlabel, cvalue) ) def addStrata(self, strata: Sequence[int]) -> None: """Add new stratum values in a `DMLabel`. Not collective. Parameters ---------- strata The stratum values. See Also -------- addStrataIS, addStratum, petsc.DMLabelAddStrata """ cdef PetscInt *istrata = NULL cdef PetscInt numStrata = 0 fields = iarray_i(strata, &numStrata, &istrata) CHKERR( DMLabelAddStrata(self.dmlabel, numStrata, istrata) ) def addStrataIS(self, IS iset) -> None: """Add new stratum values in a `DMLabel`. Not collective. Parameters ---------- iset Index set with stratum values. See Also -------- addStrata, addStratum, petsc.DMLabelAddStrataIS """ CHKERR( DMLabelAddStrataIS(self.dmlabel, iset.iset) ) def getNumValues(self) -> int: """Return the number of values that the `DMLabel` takes. Not collective. See Also -------- petsc.DMLabelGetNumValues """ cdef PetscInt numValues = 0 CHKERR( DMLabelGetNumValues(self.dmlabel, &numValues) ) return toInt(numValues) def getValueIS(self) -> IS: """Return an `IS` of all values that the `DMLabel` takes. Not collective. See Also -------- petsc.DMLabelGetValueIS """ cdef IS iset = IS() CHKERR( DMLabelGetValueIS(self.dmlabel, &iset.iset) ) return iset def stratumHasPoint(self, value: int, point: int) -> bool: """Return whether the stratum contains a point. Not collective. Parameters ---------- value The stratum value. point The point. See Also -------- petsc.DMLabelStratumHasPoint """ cdef PetscInt cpoint = asInt(point) cdef PetscInt cvalue = asInt(value) cdef PetscBool ccontains = PETSC_FALSE CHKERR( DMLabelStratumHasPoint(self.dmlabel, cvalue, cpoint, &ccontains) ) return toBool(ccontains) def hasStratum(self, value: int) -> bool: """Determine whether points exist with the given value. Not collective. Parameters ---------- value The stratum value. See Also -------- petsc.DMLabelHasStratum """ cdef PetscInt cvalue = asInt(value) cdef PetscBool cexists = PETSC_FALSE CHKERR( DMLabelHasStratum(self.dmlabel, cvalue, &cexists) ) return toBool(cexists) def getStratumSize(self, stratum: int) -> int: """Return the size of a stratum. Not collective. Parameters ---------- stratum The stratum value. See Also -------- petsc.DMLabelGetStratumSize """ cdef PetscInt cstratum = asInt(stratum) cdef PetscInt csize = 0 CHKERR( DMLabelGetStratumSize(self.dmlabel, cstratum, &csize) ) return toInt(csize) def getStratumIS(self, stratum: int) -> IS: """Return an `IS` with the stratum points. Not collective. Parameters ---------- stratum The stratum value. See Also -------- setStratumIS, petsc.DMLabelGetStratumIS """ cdef PetscInt cstratum = asInt(stratum) cdef IS iset = IS() CHKERR( DMLabelGetStratumIS(self.dmlabel, cstratum, &iset.iset) ) return iset def setStratumIS(self, stratum: int, IS iset) -> None: """Set the stratum points using an `IS`. Not collective. Parameters ---------- stratum The stratum value. iset The stratum points. See Also -------- getStratumIS, petsc.DMLabelSetStratumIS """ cdef PetscInt cstratum = asInt(stratum) CHKERR( DMLabelSetStratumIS(self.dmlabel, cstratum, iset.iset) ) def clearStratum(self, stratum: int) -> None: """Remove a stratum. Not collective. Parameters ---------- stratum The stratum value. See Also -------- petsc.DMLabelClearStratum """ cdef PetscInt cstratum = asInt(stratum) CHKERR( DMLabelClearStratum(self.dmlabel, cstratum) ) def computeIndex(self) -> None: """Create an index structure for membership determination. Not collective. Automatically determines the bounds. See Also -------- petsc.DMLabelComputeIndex """ CHKERR( DMLabelComputeIndex(self.dmlabel) ) def createIndex(self, pStart: int, pEnd: int) -> None: """Create an index structure for membership determination. Not collective. Parameters ---------- pStart The smallest point. pEnd The largest point + 1. See Also -------- destroyIndex, petsc.DMLabelCreateIndex """ cdef PetscInt cpstart = asInt(pStart), cpend = asInt(pEnd) CHKERR( DMLabelCreateIndex(self.dmlabel, cpstart, cpend) ) def destroyIndex(self) -> None: """Destroy the index structure. Not collective. See Also -------- createIndex, petsc.DMLabelDestroyIndex """ CHKERR( DMLabelDestroyIndex(self.dmlabel) ) def hasValue(self, value: int) -> bool: """Determine whether a label assigns the value to any point. Not collective. Parameters ---------- value The value. See Also -------- hasPoint, petsc.DMLabelHasValue """ cdef PetscInt cvalue = asInt(value) cdef PetscBool cexists = PETSC_FALSE CHKERR( DMLabelHasValue(self.dmlabel, cvalue, &cexists) ) return toBool(cexists) def hasPoint(self, point: int) -> bool: """Determine whether the label contains a point. Not collective. The user must call `createIndex` before this function. Parameters ---------- point The point. See Also -------- hasValue, petsc.DMLabelHasPoint """ cdef PetscInt cpoint = asInt(point) cdef PetscBool cexists = PETSC_FALSE CHKERR( DMLabelHasPoint(self.dmlabel, cpoint, &cexists) ) return toBool(cexists) def getBounds(self) -> tuple[int, int]: """Return the smallest and largest point in the label. Not collective. The returned values are the smallest point and the largest point + 1. See Also -------- petsc.DMLabelGetBounds """ cdef PetscInt cpstart = 0, cpend = 0 CHKERR( DMLabelGetBounds(self.dmlabel, &cpstart, &cpend) ) return toInt(cpstart), toInt(cpend) def filter(self, start: int, end: int) -> None: """Remove all points outside of [start, end). Not collective. Parameters ---------- start The first point kept. end One more than the last point kept. See Also -------- petsc.DMLabelFilter """ cdef PetscInt cstart = asInt(start), cend = asInt(end) CHKERR( DMLabelFilter(self.dmlabel, cstart, cend) ) def permute(self, IS permutation) -> DMLabel: """Create a new label with permuted points. Not collective. Parameters ---------- permutation The point permutation. See Also -------- petsc.DMLabelPermute """ cdef DMLabel new = DMLabel() CHKERR( DMLabelPermute(self.dmlabel, permutation.iset, &new.dmlabel) ) return new def distribute(self, SF sf) -> DMLabel: """Create a new label pushed forward over the `SF`. Collective. Parameters ---------- sf The map from old to new distribution. See Also -------- gather, petsc.DMLabelDistribute """ cdef DMLabel new = DMLabel() CHKERR( DMLabelDistribute(self.dmlabel, sf.sf, &new.dmlabel) ) return new def gather(self, SF sf) -> DMLabel: """Gather all label values from leaves into roots. Collective. This is the inverse operation to `distribute`. Parameters ---------- sf The `SF` communication map. See Also -------- distribute, petsc.DMLabelGather """ cdef DMLabel new = DMLabel() CHKERR( DMLabelGather(self.dmlabel, sf.sf, &new.dmlabel) ) return new def convertToSection(self) -> tuple[Section, IS]: """Return a `Section` and `IS` that encode the label. Not collective. See Also -------- petsc.DMLabelConvertToSection """ cdef Section section = Section() cdef IS iset = IS() CHKERR( DMLabelConvertToSection(self.dmlabel, §ion.sec, &iset.iset) ) return section, iset def getNonEmptyStratumValuesIS(self) -> IS: """Return an `IS` of all values that the `DMLabel` takes. Not collective. See Also -------- petsc.DMLabelGetNonEmptyStratumValuesIS """ cdef IS iset = IS() CHKERR( DMLabelGetNonEmptyStratumValuesIS(self.dmlabel, &iset.iset) ) return iset ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/src/petsc4py/PETSc/DMPlex.pyx0000644000175000017500000031546114567251135017554 0ustar00balaybalay# -------------------------------------------------------------------- class DMPlexReorderDefaultFlag(object): NOTSET = DMPLEX_REORDER_DEFAULT_NOTSET FALSE = DMPLEX_REORDER_DEFAULT_FALSE TRUE = DMPLEX_REORDER_DEFAULT_TRUE # -------------------------------------------------------------------- cdef class DMPlex(DM): """Encapsulate an unstructured mesh. DMPlex encapsulates both topology and geometry. It is capable of parallel refinement and coarsening (using Pragmatic or ParMmg) and parallel redistribution for load balancing. It is designed to interface with the `FE` and ``FV`` trial discretization objects. """ ReorderDefaultFlag = DMPlexReorderDefaultFlag """Flag indicating whether `DMPlex` is reordered by default.""" # def create(self, comm: Comm | None = None) -> Self: """Create a `DMPlex` object, which encapsulates an unstructured mesh. Collective. Parameters ---------- comm MPI communicator, defaults to `Sys.getDefaultComm`. See Also -------- DM, DMPlex, DM.create, DM.setType, petsc.DMPlexCreate """ cdef MPI_Comm ccomm = def_Comm(comm, PETSC_COMM_DEFAULT) cdef PetscDM newdm = NULL CHKERR( DMPlexCreate(ccomm, &newdm) ) CHKERR( PetscCLEAR(self.obj) ); self.dm = newdm return self def createFromCellList(self, dim: int, cells: Sequence[int], coords: Sequence[float], interpolate: bool | None = True, comm: Comm | None = None) -> Self: """Create a `DMPlex` from a list of vertices for each cell on process 0. Collective. Parameters ---------- dim The topological dimension of the mesh. cells An array of number of cells times number of vertices on each cell. coords An array of number of vertices times spatial dimension for coordinates. interpolate Flag to interpolate the mesh. comm MPI communicator, defaults to `Sys.getDefaultComm`. See Also -------- DM, DMPlex, DMPlex.create, DMPlex.interpolate, petsc.DMPlexCreateFromCellListPetsc """ cdef MPI_Comm ccomm = def_Comm(comm, PETSC_COMM_DEFAULT) cdef PetscBool interp = interpolate cdef PetscDM newdm = NULL cdef PetscInt cdim = asInt(dim) cdef PetscInt numCells = 0 cdef PetscInt numCorners = 0 cdef PetscInt *cellVertices = NULL cdef PetscInt numVertices = 0 cdef PetscInt spaceDim= 0 cdef PetscReal *vertexCoords = NULL cdef int npy_flags = NPY_ARRAY_ALIGNED|NPY_ARRAY_NOTSWAPPED|NPY_ARRAY_CARRAY cells = PyArray_FROM_OTF(cells, NPY_PETSC_INT, npy_flags) coords = PyArray_FROM_OTF(coords, NPY_PETSC_REAL, npy_flags) if PyArray_NDIM(cells) != 2: raise ValueError( ("cell indices must have two dimensions: " "cells.ndim=%d") % (PyArray_NDIM(cells)) ) if PyArray_NDIM(coords) != 2: raise ValueError( ("coords vertices must have two dimensions: " "coords.ndim=%d") % (PyArray_NDIM(coords)) ) numCells = PyArray_DIM(cells, 0) numCorners = PyArray_DIM(cells, 1) numVertices = PyArray_DIM(coords, 0) spaceDim = PyArray_DIM(coords, 1) cellVertices = PyArray_DATA(cells) vertexCoords = PyArray_DATA(coords) CHKERR( DMPlexCreateFromCellListPetsc(ccomm, cdim, numCells, numVertices, numCorners, interp, cellVertices, spaceDim, vertexCoords, &newdm) ) CHKERR( PetscCLEAR(self.obj) ); self.dm = newdm return self def createBoxMesh(self, faces: Sequence[int], lower: Sequence[float] | None = (0,0,0), upper: Sequence[float] | None = (1,1,1), simplex: bool | None = True, periodic: Sequence | str | int | bool | None = False, interpolate: bool | None = True, comm: Comm | None = None) -> Self: """Create a mesh on the tensor product of intervals. Collective. Parameters ---------- faces Number of faces per dimension, or `None` for the default. lower The lower left corner. upper The upper right corner. simplex `True` for simplices, `False` for tensor cells. periodic The boundary type for the X,Y,Z direction, or `None` for `DM.BoundaryType.NONE`. interpolate Flag to create intermediate mesh entities (edges, faces). comm MPI communicator, defaults to `Sys.getDefaultComm`. See Also -------- DM, DMPlex, DM.setFromOptions, DMPlex.createFromFile, DM.setType DM.create, petsc.DMPlexCreateBoxMesh """ cdef Py_ssize_t i = 0 cdef PetscInt dim = 0, *cfaces = NULL faces = iarray_i(faces, &dim, &cfaces) assert dim >= 1 and dim <= 3 cdef PetscReal clower[3] clower[0] = clower[1] = clower[2] = 0 for i from 0 <= i < dim: clower[i] = lower[i] cdef PetscReal cupper[3] cupper[0] = cupper[1] = cupper[2] = 1 for i from 0 <= i < dim: cupper[i] = upper[i] cdef PetscDMBoundaryType btype[3]; asBoundary(periodic, &btype[0], &btype[1], &btype[2]) cdef PetscBool csimplex = simplex cdef PetscBool cinterp = interpolate cdef MPI_Comm ccomm = def_Comm(comm, PETSC_COMM_DEFAULT) cdef PetscDM newdm = NULL CHKERR( DMPlexCreateBoxMesh(ccomm, dim, csimplex, cfaces, clower, cupper, btype, cinterp, &newdm) ) CHKERR( PetscCLEAR(self.obj) ); self.dm = newdm return self def createBoxSurfaceMesh(self, faces: Sequence[int], lower: Sequence[float] | None = (0,0,0), upper: Sequence[float] | None = (1,1,1), interpolate: bool | None = True, comm: Comm | None = None) -> Self: """Create a mesh on the surface of a box mesh using tensor cells. Collective. Parameters ---------- faces Number of faces per dimension, or `None` for the default. lower The lower left corner. upper The upper right corner. interpolate Flag to create intermediate mesh pieces (edges, faces). comm MPI communicator, defaults to `Sys.getDefaultComm`. See Also -------- DM, DMPlex, DM.setFromOptions, DMPlex.createBoxMesh DMPlex.createFromFile, DM.setType, DM.create petsc.DMPlexCreateBoxSurfaceMesh """ cdef Py_ssize_t i = 0 cdef PetscInt dim = 0, *cfaces = NULL faces = iarray_i(faces, &dim, &cfaces) assert dim >= 1 and dim <= 3 cdef PetscReal clower[3] clower[0] = clower[1] = clower[2] = 0 for i from 0 <= i < dim: clower[i] = lower[i] cdef PetscReal cupper[3] cupper[0] = cupper[1] = cupper[2] = 1 for i from 0 <= i < dim: cupper[i] = upper[i] cdef PetscBool cinterp = interpolate cdef MPI_Comm ccomm = def_Comm(comm, PETSC_COMM_DEFAULT) cdef PetscDM newdm = NULL CHKERR( DMPlexCreateBoxSurfaceMesh(ccomm, dim, cfaces, clower, cupper, cinterp, &newdm) ) CHKERR( PetscCLEAR(self.obj) ); self.dm = newdm return self def createFromFile(self, filename: str, plexname: str | None = "unnamed", interpolate: bool | None = True, comm: Comm | None = None): """Create `DMPlex` from a file. Collective. Parameters ---------- filename A file name. plexname The name of the resulting `DMPlex`, also used for intra-datafile lookup by some formats. interpolate Flag to create intermediate mesh pieces (edges, faces). comm MPI communicator, defaults to `Sys.getDefaultComm`. See Also -------- DM, DMPlex, DMPlex.createFromCellList, DMPlex.create, Object.setName DM.view, DM.load, petsc_options, petsc.DMPlexCreateFromFile """ cdef MPI_Comm ccomm = def_Comm(comm, PETSC_COMM_DEFAULT) cdef PetscBool interp = interpolate cdef PetscDM newdm = NULL cdef const char *cfile = NULL cdef const char *pname = NULL filename = str2bytes(filename, &cfile) plexname = str2bytes(plexname, &pname) CHKERR( DMPlexCreateFromFile(ccomm, cfile, pname, interp, &newdm) ) CHKERR( PetscCLEAR(self.obj) ); self.dm = newdm return self def createCGNS(self, cgid: int, interpolate: bool | None = True, comm: Comm | None = None) -> Self: """Create a `DMPlex` mesh from a CGNS file. Collective. Parameters ---------- cgid The CG id associated with a file and obtained using cg_open. interpolate Create faces and edges in the mesh. comm MPI communicator, defaults to `Sys.getDefaultComm`. See Also -------- DM, DMPlex, DMPlex.create, DMPlex.createCGNSFromFile DMPlex.createExodus, petsc.DMPlexCreateCGNS """ cdef MPI_Comm ccomm = def_Comm(comm, PETSC_COMM_DEFAULT) cdef PetscBool interp = interpolate cdef PetscDM newdm = NULL cdef PetscInt ccgid = asInt(cgid) CHKERR( DMPlexCreateCGNS(ccomm, ccgid, interp, &newdm) ) CHKERR( PetscCLEAR(self.obj) ); self.dm = newdm return self def createCGNSFromFile(self, filename: str, interpolate: bool | None = True, comm: Comm | None = None) -> Self: """"Create a `DMPlex` mesh from a CGNS file. Collective. Parameters ---------- filename The name of the CGNS file. interpolate Create faces and edges in the mesh. comm MPI communicator, defaults to `Sys.getDefaultComm`. See Also -------- DM, DMPlex, DMPlex.create, DMPlex.createCGNS, DMPlex.createExodus petsc.DMPlexCreateCGNS """ cdef MPI_Comm ccomm = def_Comm(comm, PETSC_COMM_DEFAULT) cdef PetscBool interp = interpolate cdef PetscDM newdm = NULL cdef const char *cfile = NULL filename = str2bytes(filename, &cfile) CHKERR( DMPlexCreateCGNSFromFile(ccomm, cfile, interp, &newdm) ) CHKERR( PetscCLEAR(self.obj) ); self.dm = newdm return self def createExodusFromFile(self, filename: str, interpolate: bool | None = True, comm: Comm | None = None) -> Self: """Create a `DMPlex` mesh from an ExodusII file. Collective. Parameters ---------- filename The name of the ExodusII file. interpolate Create faces and edges in the mesh. comm MPI communicator, defaults to `Sys.getDefaultComm`. See Also -------- DM, DMPlex, DM.create, DMPlex.createExodus petsc.DMPlexCreateExodusFromFile """ cdef MPI_Comm ccomm = def_Comm(comm, PETSC_COMM_DEFAULT) cdef PetscBool interp = interpolate cdef PetscDM newdm = NULL cdef const char *cfile = NULL filename = str2bytes(filename, &cfile) CHKERR( DMPlexCreateExodusFromFile(ccomm, cfile, interp, &newdm) ) CHKERR( PetscCLEAR(self.obj) ); self.dm = newdm return self def createExodus(self, exoid: int, interpolate: bool | None = True, comm: Comm | None = None) -> Self: """Create a `DMPlex` mesh from an ExodusII file ID. Collective. Parameters ---------- exoid The ExodusII id associated with a exodus file and obtained using ex_open. interpolate Create faces and edges in the mesh, comm MPI communicator, defaults to `Sys.getDefaultComm`. See Also -------- DM, DMPlex, DM.create, petsc.DMPlexCreateExodus """ cdef MPI_Comm ccomm = def_Comm(comm, PETSC_COMM_DEFAULT) cdef PetscBool interp = interpolate cdef PetscDM newdm = NULL cdef PetscInt cexoid = asInt(exoid) CHKERR( DMPlexCreateExodus(ccomm, cexoid, interp, &newdm) ) CHKERR( PetscCLEAR(self.obj) ); self.dm = newdm return self def createGmsh(self, Viewer viewer, interpolate: bool | None = True, comm: Comm | None = None) -> Self: """Create a `DMPlex` mesh from a Gmsh file viewer. Collective. Parameters ---------- viewer The `Viewer` associated with a Gmsh file. interpolate Create faces and edges in the mesh. comm MPI communicator, defaults to `Sys.getDefaultComm`. Notes ----- ``-dm_plex_gmsh_hybrid`` forces triangular prisms to use tensor order.\n ``-dm_plex_gmsh_periodic`` allows for reading Gmsh periodic section.\n ``-dm_plex_gmsh_highorder`` allows for generating high-order coordinates.\n ``-dm_plex_gmsh_project`` projects high-order coordinates to a different space, use the prefix ``-dm_plex_gmsh_project_`` to define the space.\n ``-dm_plex_gmsh_use_regions`` generates labels with region names.\n ``-dm_plex_gmsh_mark_vertices`` adds vertices to generated labels.\n ``-dm_plex_gmsh_multiple_tags`` allows multiple tags for default labels.\n ``-dm_plex_gmsh_spacedim `` embedding space dimension. See Also -------- DM, DMPlex, DM.create, petsc_options, petsc.DMPlexCreateGmsh """ cdef MPI_Comm ccomm = def_Comm(comm, PETSC_COMM_DEFAULT) cdef PetscBool interp = interpolate cdef PetscDM newdm = NULL CHKERR( DMPlexCreateGmsh(ccomm, viewer.vwr, interp, &newdm) ) CHKERR( PetscCLEAR(self.obj) ); self.dm = newdm return self def createCohesiveSubmesh(self, hasLagrange: bool, value: int) -> DMPlex: """Extract the hypersurface defined by one face of the cohesive cells. Parameters ---------- hasLagrange Flag indicating whether the mesh has Lagrange dofs in the cohesive cells. value A label value. See Also -------- DM, DMPlex, petsc.DMPlexCreateCohesiveSubmesh """ cdef PetscBool flag = hasLagrange cdef PetscInt cvalue = asInt(value) cdef DM subdm = DMPlex() CHKERR( DMPlexCreateCohesiveSubmesh(self.dm, flag, NULL, cvalue, &subdm.dm) ) return subdm def getChart(self) -> tuple[int, int]: """Return the interval for all mesh points [``pStart``, ``pEnd``). Not collective. Returns ------- pStart : int The first mesh point. pEnd : int The upper bound for mesh points. See Also -------- DM, DMPlex, DMPlex.create, DMPlex.setChart, petsc.DMPlexGetChart """ cdef PetscInt pStart = 0, pEnd = 0 CHKERR( DMPlexGetChart(self.dm, &pStart, &pEnd) ) return toInt(pStart), toInt(pEnd) def setChart(self, pStart: int, pEnd: int) -> None: """Set the interval for all mesh points [``pStart``, ``pEnd``). Not collective. Parameters ---------- pStart The first mesh point. pEnd The upper bound for mesh points. See Also -------- DM, DMPlex, DMPlex.create, DMPlex.getChart, petsc.DMPlexSetChart """ cdef PetscInt cStart = asInt(pStart) cdef PetscInt cEnd = asInt(pEnd) CHKERR( DMPlexSetChart(self.dm, cStart, cEnd) ) def getConeSize(self, p: int) -> int: """Return the number of in-edges for this point in the DAG. Not collective. Parameters ---------- p The point, which must lie in the chart set with `DMPlex.setChart`. See Also -------- DM, DMPlex, DMPlex.create, DMPlex.setConeSize, DMPlex.setChart petsc.DMPlexGetConeSize """ cdef PetscInt cp = asInt(p) cdef PetscInt pStart = 0, pEnd = 0 CHKERR( DMPlexGetChart(self.dm, &pStart, &pEnd) ) assert cp>=pStart and cp None: """Set the number of in-edges for this point in the DAG. Not collective. Parameters ---------- p The point, which must lie in the chart set with `DMPlex.setChart`. size The cone size for point ``p``. See Also -------- DM, DMPlex, DMPlex.create, DMPlex.getConeSize, DMPlex.setChart petsc.DMPlexSetConeSize """ cdef PetscInt cp = asInt(p) cdef PetscInt pStart = 0, pEnd = 0 CHKERR( DMPlexGetChart(self.dm, &pStart, &pEnd) ) assert cp>=pStart and cp ArrayInt: """Return the points on the in-edges for this point in the DAG. Not collective. Parameters ---------- p The point, which must lie in the chart set with `DMPlex.setChart`. See Also -------- DM, DMPlex, DMPlex.getConeSize, DMPlex.setCone, DMPlex.setChart petsc.DMPlexGetCone """ cdef PetscInt cp = asInt(p) cdef PetscInt pStart = 0, pEnd = 0 CHKERR( DMPlexGetChart(self.dm, &pStart, &pEnd) ) assert cp>=pStart and cp None: """Set the points on the in-edges for this point in the DAG. Not collective. Parameters ---------- p The point, which must lie in the chart set with `DMPlex.setChart`. cone An array of points which are on the in-edges for point ``p``. orientation An array of orientations, defaults to `None`. See Also -------- DM, DMPlex, DMPlex.create, DMPlex.getCone, DMPlex.setChart DMPlex.setConeSize, DM.setUp, DMPlex.setSupport DMPlex.setSupportSize, petsc.DMPlexSetCone """ cdef PetscInt cp = asInt(p) cdef PetscInt pStart = 0, pEnd = 0 CHKERR( DMPlexGetChart(self.dm, &pStart, &pEnd) ) assert cp>=pStart and cp None: """DMPlexInsertCone - Insert a point into the in-edges for the point p in the DAG. Not collective. Parameters ---------- p The point, which must lie in the chart set with `DMPlex.setChart`. conePos The local index in the cone where the point should be put. conePoint The mesh point to insert. See Also -------- DM, DMPlex, DMPlex.create, DMPlex.getCone, DMPlex.setChart DMPlex.setConeSize, DM.setUp, petsc.DMPlexInsertCone """ cdef PetscInt cp = asInt(p) cdef PetscInt cconePos = asInt(conePos) cdef PetscInt cconePoint = asInt(conePoint) CHKERR( DMPlexInsertCone(self.dm,cp,cconePos,cconePoint) ) def insertConeOrientation(self, p: int, conePos: int, coneOrientation: int) -> None: """Insert a point orientation for the in-edge for the point p in the DAG. Not collective. Parameters ---------- p The point, which must lie in the chart set with `DMPlex.setChart` conePos The local index in the cone where the point should be put. coneOrientation The point orientation to insert. See Also -------- DM, DMPlex, DMPlex.create, DMPlex.getCone, DMPlex.setChart DMPlex.setConeSize, DM.setUp, petsc.DMPlexInsertConeOrientation """ cdef PetscInt cp = asInt(p) cdef PetscInt cconePos = asInt(conePos) cdef PetscInt cconeOrientation = asInt(coneOrientation) CHKERR( DMPlexInsertConeOrientation(self.dm, cp, cconePos, cconeOrientation) ) def getConeOrientation(self, p: int) -> ArrayInt: """Return the orientations on the in-edges for this point in the DAG. Not collective. Parameters ---------- p The point, which must lie in the chart set with `DMPlex.setChart`. See Also -------- DM, DMPlex, DMPlex.create, DMPlex.getCone, DMPlex.setCone DMPlex.setChart, petsc.DMPlexGetConeOrientation """ cdef PetscInt cp = asInt(p) cdef PetscInt pStart = 0, pEnd = 0 CHKERR( DMPlexGetChart(self.dm, &pStart, &pEnd) ) assert cp>=pStart and cp None: """Set the orientations on the in-edges for this point in the DAG. Not collective. Parameters ---------- p The point, which must lie in the chart set with `DMPlex.setChart`. orientation An array of orientations. See Also -------- DM, DMPlex, DMPlex.create, DMPlex.getConeOrientation, DMPlex.setCone DMPlex.setChart, DMPlex.setConeSize, DM.setUp petsc.DMPlexSetConeOrientation """ cdef PetscInt cp = asInt(p) cdef PetscInt pStart = 0, pEnd = 0 CHKERR( DMPlexGetChart(self.dm, &pStart, &pEnd) ) assert cp>=pStart and cp None: """Set the polytope type of a given cell. Not collective. Parameters ---------- p The cell. ctype The polytope type of the cell. See Also -------- DM, DMPlex, DMPlex.getCellTypeLabel, DMPlex.getDepth, DM.createLabel petsc.DMPlexSetCellType """ cdef PetscInt cp = asInt(p) cdef PetscDMPolytopeType val = ctype CHKERR( DMPlexSetCellType(self.dm, cp, val) ) def getCellType(self, p: int) -> DM.PolytopeType: """Return the polytope type of a given cell. Not collective. Parameters ---------- p The cell. See Also -------- DM, DMPlex, DM.PolytopeType, DMPlex.getCellTypeLabel, DMPlex.getDepth petsc.DMPlexGetCellType """ cdef PetscInt cp = asInt(p) cdef PetscDMPolytopeType ctype = DM_POLYTOPE_UNKNOWN CHKERR( DMPlexGetCellType(self.dm, cp, &ctype) ) return toInt(ctype) def getCellTypeLabel(self) -> DMLabel: """Return the `DMLabel` recording the polytope type of each cell. Not collective. See Also -------- DM, DMPlex, DMPlex.getCellType, DM.createLabel petsc.DMPlexGetCellTypeLabel """ cdef DMLabel label = DMLabel() CHKERR( DMPlexGetCellTypeLabel(self.dm, &label.dmlabel) ) CHKERR( PetscINCREF(label.obj) ) return label def getSupportSize(self, p: int) -> int: """Return the number of out-edges for this point in the DAG. Not collective. Parameters ---------- p The point, which must lie in the chart set with `DMPlex.setChart`. See Also -------- DM, DMPlex, DMPlex.create, DMPlex.setConeSize, DMPlex.setChart DMPlex.getConeSize, petsc.DMPlexGetSupportSize """ cdef PetscInt cp = asInt(p) cdef PetscInt pStart = 0, pEnd = 0 CHKERR( DMPlexGetChart(self.dm, &pStart, &pEnd) ) assert cp>=pStart and cp None: """Set the number of out-edges for this point in the DAG. Not collective. Parameters ---------- p The point, which must lie in the chart set with `DMPlex.setChart`. size The support size for point ``p``. See Also -------- DM, DMPlex, DMPlex.create, DMPlex.getSupportSize, DMPlex.setChart petsc.DMPlexSetSupportSize """ cdef PetscInt cp = asInt(p) cdef PetscInt pStart = 0, pEnd = 0 CHKERR( DMPlexGetChart(self.dm, &pStart, &pEnd) ) assert cp>=pStart and cp ArrayInt: """Return the points on the out-edges for this point in the DAG. Not collective. Parameters ---------- p The point, which must lie in the chart set with `DMPlex.setChart`. See Also -------- DM, DMPlex, DMPlex.getSupportSize, DMPlex.setSupport, DMPlex.getCone DMPlex.setChart, petsc.DMPlexGetSupport """ cdef PetscInt cp = asInt(p) cdef PetscInt pStart = 0, pEnd = 0 CHKERR( DMPlexGetChart(self.dm, &pStart, &pEnd) ) assert cp>=pStart and cp None: """Set the points on the out-edges for this point in the DAG. Not collective. Parameters ---------- p The point, which must lie in the chart set with `DMPlex.setChart`. supp An array of points which are on the out-edges for point ``p``. See Also -------- DM, DMPlex, DMPlex.setCone, DMPlex.setConeSize, DMPlex.create DMPlex.getSupport, DMPlex.setChart, DMPlex.setSupportSize, DM.setUp petsc.DMPlexSetSupport """ cdef PetscInt cp = asInt(p) cdef PetscInt pStart = 0, pEnd = 0 CHKERR( DMPlexGetChart(self.dm, &pStart, &pEnd) ) assert cp>=pStart and cp tuple[int, int]: """Return the maximum number of in-edges and out-edges of the DAG. Not collective. Returns ------- maxConeSize : int The maximum number of in-edges. maxSupportSize : int The maximum number of out-edges. See Also -------- DM, DMPlex, DMPlex.create, DMPlex.setConeSize, DMPlex.setChart petsc.DMPlexGetMaxSizes """ cdef PetscInt maxConeSize = 0, maxSupportSize = 0 CHKERR( DMPlexGetMaxSizes(self.dm, &maxConeSize, &maxSupportSize) ) return toInt(maxConeSize), toInt(maxSupportSize) def symmetrize(self) -> None: """Create support (out-edge) information from cone (in-edge) information. Not collective. See Also -------- DM, DMPlex, DMPlex.create, DMPlex.setChart, DMPlex.setConeSize DMPlex.setCone, petsc.DMPlexSymmetrize """ CHKERR( DMPlexSymmetrize(self.dm) ) def stratify(self) -> None: """Calculate the strata of DAG. Collective. See Also -------- DM, DMPlex, DMPlex.create, DMPlex.symmetrize, petsc.DMPlexStratify """ CHKERR( DMPlexStratify(self.dm) ) def orient(self) -> None: """Give a consistent orientation to the input mesh. See Also -------- DM, DMPlex, DM.create, petsc.DMPlexOrient """ CHKERR( DMPlexOrient(self.dm) ) def getCellNumbering(self) -> IS: """Return a global cell numbering for all cells on this process. See Also -------- DM, DMPlex, DMPlex.getVertexNumbering, petsc.DMPlexGetCellNumbering """ cdef IS iset = IS() CHKERR( DMPlexGetCellNumbering(self.dm, &iset.iset) ) CHKERR( PetscINCREF(iset.obj) ) return iset def getVertexNumbering(self) -> IS: """Return a global vertex numbering for all vertices on this process. See Also -------- DM, DMPlex, DMPlex.getCellNumbering, petsc.DMPlexGetVertexNumbering """ cdef IS iset = IS() CHKERR( DMPlexGetVertexNumbering(self.dm, &iset.iset) ) CHKERR( PetscINCREF(iset.obj) ) return iset def createPointNumbering(self) -> IS: """Create a global numbering for all points. Collective. See Also -------- DM, DMPlex, DMPlex.getCellNumbering, petsc.DMPlexCreatePointNumbering """ cdef IS iset = IS() CHKERR( DMPlexCreatePointNumbering(self.dm, &iset.iset) ) return iset def getDepth(self) -> int: """Return the depth of the DAG representing this mesh. Not collective. See Also -------- DM, DMPlex, DMPlex.getDepthStratum, DMPlex.symmetrize petsc.DMPlexGetDepth """ cdef PetscInt depth = 0 CHKERR( DMPlexGetDepth(self.dm,&depth) ) return toInt(depth) def getDepthStratum(self, svalue: int) -> tuple[int, int]: """Return the bounds [``start``, ``end``) for all points at a certain depth. Not collective. Parameters ---------- svalue The requested depth. Returns ------- pStart : int The first stratum point. pEnd : int The upper bound for stratum points. See Also -------- DM, DMPlex, DMPlex.getHeightStratum, DMPlex.getDepth DMPlex.symmetrize, DMPlex.interpolate, petsc.DMPlexGetDepthStratum """ cdef PetscInt csvalue = asInt(svalue), sStart = 0, sEnd = 0 CHKERR( DMPlexGetDepthStratum(self.dm, csvalue, &sStart, &sEnd) ) return (toInt(sStart), toInt(sEnd)) def getHeightStratum(self, svalue: int) -> tuple[int, int]: """Return the bounds [``start``, ``end``) for all points at a certain height. Not collective. Parameters ---------- svalue The requested height. Returns ------- pStart : int The first stratum point. pEnd : int The upper bound for stratum points. See Also -------- DM, DMPlex, DMPlex.getDepthStratum, DMPlex.getDepth petsc.DMPlexGetHeightStratum """ cdef PetscInt csvalue = asInt(svalue), sStart = 0, sEnd = 0 CHKERR( DMPlexGetHeightStratum(self.dm, csvalue, &sStart, &sEnd) ) return (toInt(sStart), toInt(sEnd)) def getPointDepth(self, point: int) -> int: """Return the *depth* of a given point. Not collective. Parameters ---------- point The point. See Also -------- DM, DMPlex, DMPlex.getDepthStratum, DMPlex.getDepth petsc.DMPlexGetPointDepth """ cdef PetscInt cpoint = asInt(point) cdef PetscInt depth = 0 CHKERR( DMPlexGetPointDepth(self.dm, cpoint, &depth) ) return toInt(depth) def getPointHeight(self, point: int) -> int: """Return the *height* of a given point. Not collective. Parameters ---------- point The point. See Also -------- DM, DMPlex, DMPlex.getHeightStratum petsc.DMPlexGetPointHeight """ cdef PetscInt cpoint = asInt(point) cdef PetscInt height = 0 CHKERR( DMPlexGetPointHeight(self.dm, cpoint, &height) ) return toInt(height) def getMeet(self, points: Sequence[int]) -> ArrayInt: """Return an array for the meet of the set of points. Not collective. Parameters ---------- points The input points. See Also -------- DM, DMPlex, DMPlex.getJoin, petsc.DMPlexGetMeet """ cdef PetscInt numPoints = 0 cdef PetscInt *ipoints = NULL cdef PetscInt numCoveringPoints = 0 cdef const PetscInt *coveringPoints = NULL points = iarray_i(points, &numPoints, &ipoints) CHKERR( DMPlexGetMeet(self.dm, numPoints, ipoints, &numCoveringPoints, &coveringPoints) ) try: return array_i(numCoveringPoints, coveringPoints) finally: CHKERR( DMPlexRestoreMeet(self.dm, numPoints, ipoints, &numCoveringPoints, &coveringPoints) ) def getJoin(self, points: Sequence[int]) -> ArrayInt: """Return an array for the join of the set of points. Not collective. Parameters ---------- points The input points. See Also -------- DM, DMPlex, DMPlex.getMeet, petsc.DMPlexGetJoin """ cdef PetscInt numPoints = 0 cdef PetscInt *ipoints = NULL cdef PetscInt numCoveringPoints = 0 cdef const PetscInt *coveringPoints = NULL points = iarray_i(points, &numPoints, &ipoints) CHKERR( DMPlexGetJoin(self.dm, numPoints, ipoints, &numCoveringPoints, &coveringPoints) ) try: return array_i(numCoveringPoints, coveringPoints) finally: CHKERR( DMPlexRestoreJoin(self.dm, numPoints, ipoints, &numCoveringPoints, &coveringPoints) ) def getFullJoin(self, points: Sequence[int]) -> ArrayInt: """Return an array for the join of the set of points. Not collective. Parameters ---------- points The input points. See Also -------- DM, DMPlex, DMPlex.getJoin, DMPlex.getMeet, petsc.DMPlexGetFullJoin """ cdef PetscInt numPoints = 0 cdef PetscInt *ipoints = NULL cdef PetscInt numCoveringPoints = 0 cdef const PetscInt *coveringPoints = NULL points = iarray_i(points, &numPoints, &ipoints) CHKERR( DMPlexGetFullJoin(self.dm, numPoints, ipoints, &numCoveringPoints, &coveringPoints) ) try: return array_i(numCoveringPoints, coveringPoints) finally: CHKERR( DMPlexRestoreJoin(self.dm, numPoints, ipoints, &numCoveringPoints, &coveringPoints) ) def getTransitiveClosure(self, p: int, useCone: bool | None = True) -> tuple[ArrayInt, ArrayInt]: """Return the points and orientations on the transitive closure of this point. Not collective. Parameters ---------- p The mesh point. useCone `True` for the closure, otherwise return the star. Returns ------- points : ArrayInt The points. orientations : ArrayInt The orientations. See Also -------- DM, DMPlex, DMPlex.create, DMPlex.setCone, DMPlex.setChart DMPlex.getCone, petsc.DMPlexGetTransitiveClosure """ cdef PetscInt cp = asInt(p) cdef PetscInt pStart = 0, pEnd = 0 CHKERR( DMPlexGetChart(self.dm, &pStart, &pEnd) ) assert cp>=pStart and cp ArrayScalar: """Return an array of values on the closure of ``p``. Not collective. Parameters ---------- sec The section describing the layout in ``vec``. vec The local vector. p The point in the `DMPlex`. See Also -------- DM, DMPlex, petsc.DMPlexVecRestoreClosure """ cdef PetscInt cp = asInt(p), csize = 0 cdef PetscScalar *cvals = NULL CHKERR( DMPlexVecGetClosure(self.dm, sec.sec, vec.vec, cp, &csize, &cvals) ) try: closure = array_s(csize, cvals) finally: CHKERR( DMPlexVecRestoreClosure(self.dm, sec.sec, vec.vec, cp, &csize, &cvals) ) return closure def getVecClosure(self, Section sec or None, Vec vec, point: int) -> ArrayScalar: """Return an array of the values on the closure of a point. Not collective. Parameters ---------- sec The `Section` describing the layout in ``vec`` or `None` to use the default section. vec The local vector. point The point in the `DMPlex`. See Also -------- DM, DMPlex, petsc.DMPlexVecRestoreClosure """ cdef PetscSection csec = sec.sec if sec is not None else NULL cdef PetscInt cp = asInt(point), csize = 0 cdef PetscScalar *cvals = NULL CHKERR( DMPlexVecGetClosure(self.dm, csec, vec.vec, cp, &csize, &cvals) ) try: closure = array_s(csize, cvals) finally: CHKERR( DMPlexVecRestoreClosure(self.dm, csec, vec.vec, cp, &csize, &cvals) ) return closure def setVecClosure(self, Section sec or None, Vec vec, point: int, values: Sequence[Scalar], addv: InsertModeSpec | None = None) -> None: """Set an array of the values on the closure of ``point``. Not collective. Parameters ---------- sec The section describing the layout in ``vec``, or `None` to use the default section. vec The local vector. point The point in the `DMPlex`. values The array of values. mode The insertion mode. See Also -------- DM, DMPlex, petsc.DMPlexVecSetClosure """ cdef PetscSection csec = sec.sec if sec is not None else NULL cdef PetscInt cp = asInt(point) cdef PetscInt csize = 0 cdef PetscScalar *cvals = NULL cdef object tmp = iarray_s(values, &csize, &cvals) cdef PetscInsertMode im = insertmode(addv) CHKERR( DMPlexVecSetClosure(self.dm, csec, vec.vec, cp, cvals, im) ) def setMatClosure(self, Section sec or None, Section gsec or None, Mat mat, point: int, values: Sequence[Scalar], addv: InsertModeSpec | None = None) -> None: """Set an array of the values on the closure of ``point``. Not collective. Parameters ---------- sec The section describing the layout in ``mat``, or `None` to use the default section. gsec The section describing the layout in ``mat``, or `None` to use the default global section. mat The matrix. point The point in the `DMPlex`. values The array of values. mode The insertion mode. See Also -------- DM, DMPlex, petsc.DMPlexMatSetClosure """ cdef PetscSection csec = sec.sec if sec is not None else NULL cdef PetscSection cgsec = gsec.sec if gsec is not None else NULL cdef PetscInt cp = asInt(point) cdef PetscInt csize = 0 cdef PetscScalar *cvals = NULL cdef object tmp = iarray_s(values, &csize, &cvals) cdef PetscInsertMode im = insertmode(addv) CHKERR( DMPlexMatSetClosure(self.dm, csec, cgsec, mat.mat, cp, cvals, im) ) def generate(self, DMPlex boundary, name: str | None = None, interpolate: bool | None = True) -> Self: """Generate a mesh. Not collective. Parameters ---------- boundary The `DMPlex` boundary object. name The mesh generation package name. interpolate Flag to create intermediate mesh elements. See Also -------- DM, DMPlex, DMPlex.create, DM.refine, petsc_options petsc.DMPlexGenerate """ cdef PetscBool interp = interpolate cdef const char *cname = NULL if name: name = str2bytes(name, &cname) cdef PetscDM newdm = NULL CHKERR( DMPlexGenerate(boundary.dm, cname, interp, &newdm) ) CHKERR( PetscCLEAR(self.obj) ); self.dm = newdm return self def setTriangleOptions(self, opts: str) -> None: """Set the options used for the Triangle mesh generator. Not collective. Parameters ---------- opts The command line options. See Also -------- petsc_options, DM, DMPlex, DMPlex.setTetGenOptions, DMPlex.generate petsc.DMPlexTriangleSetOptions """ cdef const char *copts = NULL opts = str2bytes(opts, &copts) CHKERR( DMPlexTriangleSetOptions(self.dm, copts) ) def setTetGenOptions(self, opts: str) -> None: """Set the options used for the Tetgen mesh generator. Not collective. Parameters ---------- opts The command line options. See Also -------- petsc_options, DM, DMPlex, DMPlex.setTriangleOptions, DMPlex.generate petsc.DMPlexTetgenSetOptions """ cdef const char *copts = NULL opts = str2bytes(opts, &copts) CHKERR( DMPlexTetgenSetOptions(self.dm, copts) ) def markBoundaryFaces(self, label: str, value: int | None = None) -> DMLabel: """Mark all faces on the boundary. Not collective. Parameters ---------- value The marker value, or `DETERMINE` or `None` to use some value in the closure (or 1 if none are found). See Also -------- DM, DMPlex, DMLabel.create, DM.createLabel petsc.DMPlexMarkBoundaryFaces """ cdef PetscInt ival = PETSC_DETERMINE if value is not None: ival = asInt(value) if not self.hasLabel(label): self.createLabel(label) cdef const char *cval = NULL label = str2bytes(label, &cval) cdef PetscDMLabel clbl = NULL CHKERR( DMGetLabel(self.dm, cval, &clbl) ) CHKERR( DMPlexMarkBoundaryFaces(self.dm, ival, clbl) ) def labelComplete(self, DMLabel label) -> None: """Add the transitive closure to the surface. Parameters ---------- label A `DMLabel` marking the surface points. See Also -------- DM, DMPlex, DMPlex.labelCohesiveComplete, petsc.DMPlexLabelComplete """ CHKERR( DMPlexLabelComplete(self.dm, label.dmlabel) ) def labelCohesiveComplete(self, DMLabel label, DMLabel bdlabel, bdvalue: int, flip: bool, DMPlex subdm) -> None: """Add all other mesh pieces to complete the surface. Parameters ---------- label A `DMLabel` marking the surface. bdlabel A `DMLabel` marking the vertices on the boundary which will not be duplicated. bdvalue Value of `DMLabel` marking the vertices on the boundary. flip Flag to flip the submesh normal and replace points on the other side. subdm The `DMPlex` associated with the label. See Also -------- DM, DMPlex, DMPlex.labelComplete petsc.DMPlexLabelCohesiveComplete """ cdef PetscBool flg = flip cdef PetscInt val = asInt(bdvalue) CHKERR( DMPlexLabelCohesiveComplete(self.dm, label.dmlabel, bdlabel.dmlabel, val, flg, subdm.dm) ) def setAdjacencyUseAnchors(self, useAnchors: bool = True) -> None: """Define adjacency in the mesh using the point-to-point constraints. Parameters ---------- useAnchors Flag to use the constraints. If `True`, then constrained points are omitted from `DMPlex.getAdjacency`, and their anchor points appear in their place. See Also -------- DMPlex, DMPlex.getAdjacency, DMPlex.distribute petsc.DMPlexSetAdjacencyUseAnchors """ cdef PetscBool flag = useAnchors CHKERR( DMPlexSetAdjacencyUseAnchors(self.dm, flag) ) def getAdjacencyUseAnchors(self) -> bool: """Query whether adjacency in the mesh uses the point-to-point constraints. See Also -------- DMPlex, DMPlex.getAdjacency, DMPlex.distribute petsc.DMPlexGetAdjacencyUseAnchors """ cdef PetscBool flag = PETSC_FALSE CHKERR( DMPlexGetAdjacencyUseAnchors(self.dm, &flag) ) return toBool(flag) def getAdjacency(self, p: int) -> ArrayInt: """Return all points adjacent to the given point. Parameters ---------- p The point. See Also -------- DMPlex, DMPlex.distribute, petsc.DMPlexGetAdjacency """ cdef PetscInt cp = asInt(p) cdef PetscInt nadj = PETSC_DETERMINE cdef PetscInt *iadj = NULL CHKERR( DMPlexGetAdjacency(self.dm, cp, &nadj, &iadj) ) try: adjacency = array_i(nadj, iadj) finally: CHKERR( PetscFree(iadj) ) return adjacency def setPartitioner(self, Partitioner part): """Set the mesh partitioner. Logically collective. Parameters ---------- part The partitioner. See Also -------- DM, DMPlex, Partitioner, DMPlex.distribute, DMPlex.getPartitioner Partitioner.create, petsc.DMPlexSetPartitioner """ CHKERR( DMPlexSetPartitioner(self.dm, part.part) ) def getPartitioner(self) -> Partitioner: """Return the mesh partitioner. Not collective. See Also -------- DM, DMPlex, Partitioner, Section, DMPlex.distribute DMPlex.setPartitioner, Partitioner.create petsc.PetscPartitionerDMPlexPartition, petsc.DMPlexGetPartitioner """ cdef Partitioner part = Partitioner() CHKERR( DMPlexGetPartitioner(self.dm, &part.part) ) CHKERR( PetscINCREF(part.obj) ) return part def rebalanceSharedPoints(self, entityDepth: int | None = 0, useInitialGuess: bool | None = True, parallel: bool | None = True) -> bool: """Redistribute shared points in order to achieve better balancing. Parameters ---------- entityDepth Depth of the entity to balance (e.g., 0 -> balance vertices). useInitialGuess Whether to use the current distribution as initial guess. parallel Whether to use ParMETIS and do the partition in parallel or gather the graph onto a single process. Returns ------- success : bool Whether the graph partitioning was successful or not. Unsuccessful simply means no change to the partitioning. See Also -------- DM, DMPlex, DMPlex.distribute, petsc_options petsc.DMPlexRebalanceSharedPoints """ cdef PetscInt centityDepth = asInt(entityDepth) cdef PetscBool cuseInitialGuess = asBool(useInitialGuess) cdef PetscBool cparallel = asBool(parallel) cdef PetscBool csuccess = PETSC_FALSE CHKERR( DMPlexRebalanceSharedPoints(self.dm, centityDepth, cuseInitialGuess, cparallel, &csuccess) ) return toBool(csuccess) def distribute(self, overlap: int | None = 0) -> SF or None: """Distribute the mesh and any associated sections. Collective. Parameters ---------- overlap The overlap of partitions. Returns ------- sf : SF or None The `SF` used for point distribution, or `None` if not distributed. See Also -------- DM, DMPlex, DMPlex.create, petsc.DMPlexDistribute """ cdef PetscDM dmParallel = NULL cdef PetscInt coverlap = asInt(overlap) cdef SF sf = SF() CHKERR( DMPlexDistribute(self.dm, coverlap, &sf.sf, &dmParallel) ) if dmParallel != NULL: CHKERR( PetscCLEAR(self.obj) ); self.dm = dmParallel return sf def distributeOverlap(self, overlap: int | None = 0) -> SF: """Add partition overlap to a distributed non-overlapping `DMPlex`. Collective. Parameters ---------- overlap The overlap of partitions (the same on all ranks). Returns ------- sf : SF The `SF` used for point distribution. See Also -------- DM, DMPlex, SF, DMPlex.create, DMPlex.distribute, petsc.DMPlexDistributeOverlap """ cdef PetscInt coverlap = asInt(overlap) cdef SF sf = SF() cdef PetscDM dmOverlap = NULL CHKERR( DMPlexDistributeOverlap(self.dm, coverlap, &sf.sf, &dmOverlap) ) CHKERR( PetscCLEAR(self.obj) ); self.dm = dmOverlap return sf def isDistributed(self) -> bool: """Return the flag indicating if the mesh is distributed. Collective. See Also -------- DM, DMPlex, DMPlex.distribute, petsc.DMPlexIsDistributed """ cdef PetscBool flag = PETSC_FALSE CHKERR( DMPlexIsDistributed(self.dm, &flag) ) return toBool(flag) def isSimplex(self) -> bool: """Return the flag indicating if the first cell is a simplex. See Also -------- DM, DMPlex, DMPlex.getCellType, DMPlex.getHeightStratum petsc.DMPlexIsSimplex """ cdef PetscBool flag = PETSC_FALSE CHKERR( DMPlexIsSimplex(self.dm, &flag) ) return toBool(flag) def distributeGetDefault(self) -> bool: """Return a flag indicating whether the `DM` should be distributed by default. Not collective. Returns ------- dist : bool Flag indicating whether the `DMPlex` should be distributed by default. See Also -------- DM, DMPlex, DMPlex.distributeSetDefault, DMPlex.distribute petsc.DMPlexDistributeGetDefault """ cdef PetscBool dist = PETSC_FALSE CHKERR( DMPlexDistributeGetDefault(self.dm, &dist) ) return toBool(dist) def distributeSetDefault(self, flag: bool) -> None: """Set flag indicating whether the `DMPlex` should be distributed by default. Logically collective. Parameters ---------- flag Flag indicating whether the `DMPlex` should be distributed by default. See Also -------- DMPlex, DMPlex.distributeGetDefault, DMPlex.distribute petsc.DMPlexDistributeSetDefault """ cdef PetscBool dist = asBool(flag) CHKERR( DMPlexDistributeSetDefault(self.dm, dist) ) return def distributionSetName(self, name: str) -> None: """Set the name of the specific parallel distribution. Parameters ---------- name The name of the specific parallel distribution. See Also -------- DMPlex, DMPlex.distributionGetName, DMPlex.topologyView DMPlex.topologyLoad, petsc.DMPlexDistributionSetName """ cdef const char *cname = NULL if name is not None: name = str2bytes(name, &cname) CHKERR( DMPlexDistributionSetName(self.dm, cname) ) def distributionGetName(self) -> str: """Retrieve the name of the specific parallel distribution. Returns ------- name : str The name of the specific parallel distribution. See Also -------- DMPlex, DMPlex.distributionSetName, DMPlex.topologyView DMPlex.topologyLoad, petsc.DMPlexDistributionGetName """ cdef const char *cname = NULL CHKERR( DMPlexDistributionGetName(self.dm, &cname) ) return bytes2str(cname) def interpolate(self) -> None: """Convert to a mesh with all intermediate faces, edges, etc. Collective. See Also -------- DMPlex, DMPlex.uninterpolate, DMPlex.createFromCellList petsc.DMPlexInterpolate """ cdef PetscDM newdm = NULL CHKERR( DMPlexInterpolate(self.dm, &newdm) ) CHKERR( PetscCLEAR(self.obj) ); self.dm = newdm def uninterpolate(self) -> None: """Convert to a mesh with only cells and vertices. Collective. See Also -------- DMPlex, DMPlex.interpolate, DMPlex.createFromCellList petsc.DMPlexUninterpolate """ cdef PetscDM newdm = NULL CHKERR( DMPlexUninterpolate(self.dm, &newdm) ) CHKERR( PetscCLEAR(self.obj) ); self.dm = newdm def distributeField(self, SF sf, Section sec, Vec vec, Section newsec=None, Vec newvec=None) -> tuple[Section, Vec]: """Distribute field data with a with a given `SF`. Collective. Parameters ---------- sf The `SF` describing the communication pattern. sec The `Section` for existing data layout. vec The existing data in a local vector. newsec The `SF` describing the new data layout. newvec The new data in a local vector. Returns ------- newSection : Section The `SF` describing the new data layout. newVec : Vec The new data in a local vector. See Also -------- DMPlex, DMPlex.distribute, petsc.DMPlexDistributeField """ cdef MPI_Comm ccomm = MPI_COMM_NULL if newsec is None: newsec = Section() if newvec is None: newvec = Vec() if newsec.sec == NULL: CHKERR( PetscObjectGetComm(sec.sec, &ccomm) ) CHKERR( PetscSectionCreate(ccomm, &newsec.sec) ) if newvec.vec == NULL: CHKERR( PetscObjectGetComm(vec.vec, &ccomm) ) CHKERR( VecCreate(ccomm, &newvec.vec) ) CHKERR( DMPlexDistributeField(self.dm, sf.sf, sec.sec, vec.vec, newsec.sec, newvec.vec)) return (newsec, newvec) def getMinRadius(self) -> float: """Return the minimum distance from any cell centroid to a face. Not collective. See Also -------- DMPlex, DM.getCoordinates, petsc.DMPlexGetMinRadius """ cdef PetscReal cminradius = 0. CHKERR( DMPlexGetMinRadius(self.dm, &cminradius)) return asReal(cminradius) def createCoarsePointIS(self) -> IS: """Create an `IS` covering the coarse `DMPlex` chart with the fine points as data. Collective. Returns ------- fpointIS : IS The `IS` of all the fine points which exist in the original coarse mesh. See Also -------- DM, DMPlex, IS, DM.refine, DMPlex.setRefinementUniform petsc.DMPlexCreateCoarsePointIS """ cdef IS fpoint = IS() CHKERR( DMPlexCreateCoarsePointIS(self.dm, &fpoint.iset) ) return fpoint def createSection(self, numComp: Sequence[int], numDof: Sequence[int], bcField: Sequence[int] | None = None, bcComps: Sequence[IS] | None = None, bcPoints: Sequence[IS] | None = None, IS perm=None) -> Section: """Create a `Section` based upon the DOF layout specification provided. Not collective. Parameters ---------- numComp An array of size ``numFields`` holding the number of components per field. numDof An array of size ``numFields*(dim+1)`` holding the number of DOFs per field on a mesh piece of dimension ``dim``. bcField An array of size ``numBC`` giving the field number for each boundary condition, where ``numBC`` is the number of boundary conditions. bcComps An array of size ``numBC`` giving an `IS` holding the field components to which each boundary condition applies. bcPoints An array of size ``numBC`` giving an `IS` holding the `DMPlex` points to which each boundary condition applies. perm Permutation of the chart. See Also -------- DM, DMPlex, DMPlex.create, Section.create, Section.setPermutation petsc.DMPlexCreateSection """ # topological dimension cdef PetscInt dim = 0 CHKERR( DMGetDimension(self.dm, &dim) ) # components and DOFs cdef PetscInt ncomp = 0, ndof = 0 cdef PetscInt *icomp = NULL, *idof = NULL numComp = iarray_i(numComp, &ncomp, &icomp) numDof = iarray_i(numDof, &ndof, &idof) assert ndof == ncomp*(dim+1) # boundary conditions cdef PetscInt nbc = 0, i = 0 cdef PetscInt *bcfield = NULL cdef PetscIS *bccomps = NULL cdef PetscIS *bcpoints = NULL if bcField is not None: bcField = iarray_i(bcField, &nbc, &bcfield) if bcComps is not None: bcComps = list(bcComps) assert len(bcComps) == nbc tmp1 = oarray_p(empty_p(nbc), NULL, &bccomps) for i from 0 <= i < nbc: bccomps[i] = (bcComps[i]).iset if bcPoints is not None: bcPoints = list(bcPoints) assert len(bcPoints) == nbc tmp2 = oarray_p(empty_p(nbc), NULL, &bcpoints) for i from 0 <= i < nbc: bcpoints[i] = (bcPoints[i]).iset else: raise ValueError("bcPoints is a required argument") else: assert bcComps is None assert bcPoints is None # optional chart permutations cdef PetscIS cperm = NULL if perm is not None: cperm = perm.iset # create section cdef Section sec = Section() CHKERR( DMPlexCreateSection(self.dm, NULL, icomp, idof, nbc, bcfield, bccomps, bcpoints, cperm, &sec.sec) ) return sec def getPointLocal(self, point: int) -> tuple[int, int]: """Return location of point data in local `Vec`. Not collective. Parameters ---------- point The topological point. Returns ------- start : int Start of point data. end : int End of point data. See Also -------- DM, DMPlex, DMPlex.getPointLocalField, Section.getOffset Section.getDof, petsc.DMPlexGetPointLocal """ cdef PetscInt start = 0, end = 0 cdef PetscInt cpoint = asInt(point) CHKERR( DMPlexGetPointLocal(self.dm, cpoint, &start, &end) ) return toInt(start), toInt(end) def getPointLocalField(self, point: int, field: int) -> tuple[int, int]: """Return location of point field data in local `Vec`. Not collective. Parameters ---------- point The topological point. field The field number. Returns ------- start : int Start of point data. end : int End of point data. See Also -------- DM, DMPlex, DMPlex.getPointLocal, Section.getOffset petsc.DMPlexGetPointLocalField """ cdef PetscInt start = 0, end = 0 cdef PetscInt cpoint = asInt(point) cdef PetscInt cfield = asInt(field) CHKERR( DMPlexGetPointLocalField(self.dm, cpoint, cfield, &start, &end) ) return toInt(start), toInt(end) def getPointGlobal(self, point: int) -> tuple[int, int]: """Return location of point data in global `Vec`. Not collective. Parameters ---------- point The topological point. Returns ------- start : int Start of point data; returns ``-(globalStart+1)`` if point is not owned. end : int End of point data; returns ``-(globalEnd+1)`` if point is not owned. See Also -------- DM, DMPlex, DMPlex.getPointGlobalField, Section.getOffset Section.getDof, DMPlex.getPointLocal, petsc.DMPlexGetPointGlobal """ cdef PetscInt start = 0, end = 0 cdef PetscInt cpoint = asInt(point) CHKERR( DMPlexGetPointGlobal(self.dm, cpoint, &start, &end) ) return toInt(start), toInt(end) def getPointGlobalField(self, point: int, field: int) -> tuple[int, int]: """Return location of point field data in global `Vec`. Not collective. Parameters ---------- point The topological point. field The field number. Returns ------- start : int Start of point data; returns ``-(globalStart+1)`` if point is not owned. end : int End of point data; returns ``-(globalEnd+1)`` if point is not owned. See Also -------- DM, DMPlex, DMPlex.getPointGlobal, Section.getOffset, Section.getDof DMPlex.getPointLocal, petsc.DMPlexGetPointGlobalField """ cdef PetscInt start = 0, end = 0 cdef PetscInt cpoint = asInt(point) cdef PetscInt cfield = asInt(field) CHKERR( DMPlexGetPointGlobalField(self.dm, cpoint, cfield, &start, &end) ) return toInt(start), toInt(end) def createClosureIndex(self, Section sec or None) -> None: """Calculate an index for ``sec`` for the closure operation. Not collective. Parameters ---------- sec The `Section` describing the layout in the local vector, or `None` to use the default section. See Also -------- DM, DMPlex, Section, DMPlex.vecGetClosure petsc.DMPlexCreateClosureIndex """ cdef PetscSection csec = sec.sec if sec is not None else NULL CHKERR( DMPlexCreateClosureIndex(self.dm, csec) ) # def setRefinementUniform(self, refinementUniform: bool | None = True) -> None: """Set the flag for uniform refinement. Parameters ---------- refinementUniform The flag for uniform refinement. See Also -------- DM, DMPlex, DM.refine, DMPlex.getRefinementUniform DMPlex.getRefinementLimit, DMPlex.setRefinementLimit petsc.DMPlexSetRefinementUniform """ cdef PetscBool flag = refinementUniform CHKERR( DMPlexSetRefinementUniform(self.dm, flag) ) def getRefinementUniform(self) -> bool: """Retrieve the flag for uniform refinement. Returns ------- refinementUniform : bool The flag for uniform refinement. See Also -------- DM, DMPlex, DM.refine, DMPlex.setRefinementUniform DMPlex.getRefinementLimit, DMPlex.setRefinementLimit petsc.DMPlexGetRefinementUniform """ cdef PetscBool flag = PETSC_FALSE CHKERR( DMPlexGetRefinementUniform(self.dm, &flag) ) return toBool(flag) def setRefinementLimit(self, refinementLimit: float) -> None: """Set the maximum cell volume for refinement. Parameters ---------- refinementLimit The maximum cell volume in the refined mesh. See Also -------- DM, DMPlex, DM.refine, DMPlex.getRefinementLimit DMPlex.getRefinementUniform, DMPlex.setRefinementUniform petsc.DMPlexSetRefinementLimit """ cdef PetscReal rval = asReal(refinementLimit) CHKERR( DMPlexSetRefinementLimit(self.dm, rval) ) def getRefinementLimit(self) -> float: """Retrieve the maximum cell volume for refinement. See Also -------- DM, DMPlex, DM.refine, DMPlex.setRefinementLimit DMPlex.getRefinementUniform, DMPlex.setRefinementUniform petsc.DMPlexGetRefinementLimit """ cdef PetscReal rval = 0.0 CHKERR( DMPlexGetRefinementLimit(self.dm, &rval) ) return toReal(rval) def getOrdering(self, otype: Mat.OrderingType) -> IS: """Calculate a reordering of the mesh. Collective. Parameters ---------- otype Type of reordering, see `Mat.OrderingType`. Returns ------- perm : IS The point permutation. See Also -------- DMPlex, DMPlex.permute, Mat.OrderingType, Mat.getOrdering petsc.DMPlexGetOrdering """ cdef PetscMatOrderingType cval = NULL cdef PetscDMLabel label = NULL otype = str2bytes(otype, &cval) cdef IS perm = IS() CHKERR( DMPlexGetOrdering(self.dm, cval, label, &perm.iset) ) return perm def permute(self, IS perm) -> DMPlex: """Reorder the mesh according to the input permutation. Collective. Parameters ---------- perm The point permutation, ``perm[old point number] = new point number``. Returns ------- pdm : DMPlex The permuted `DMPlex`. See Also -------- DMPlex, Mat.permute, petsc.DMPlexPermute """ cdef DMPlex dm = type(self)() CHKERR( DMPlexPermute(self.dm, perm.iset, &dm.dm) ) return dm def reorderGetDefault(self) -> DMPlex.ReorderDefaultFlag: """Return flag indicating whether the `DMPlex` should be reordered by default. Not collective. See Also -------- `DMPlex.reorderSetDefault`, petsc.DMPlexReorderGetDefault """ cdef PetscDMPlexReorderDefaultFlag reorder = DMPLEX_REORDER_DEFAULT_NOTSET CHKERR( DMPlexReorderGetDefault(self.dm, &reorder) ) return reorder def reorderSetDefault(self, flag: DMPlex.ReorderDefaultFlag): """Set flag indicating whether the DM should be reordered by default. Logically collective. Parameters ---------- reorder Flag for reordering. See Also -------- DMPlex.reorderGetDefault, petsc.DMPlexReorderSetDefault """ cdef PetscDMPlexReorderDefaultFlag reorder = flag CHKERR( DMPlexReorderSetDefault(self.dm, reorder) ) return # def computeCellGeometryFVM(self, cell: int) -> tuple[float, ArrayReal, ArrayReal]: """Compute the volume for a given cell. Collective. Parameters ---------- cell The cell. Returns ------- volume : float The cell volume. centroid : ArrayReal The cell centroid. normal : ArrayReal The cell normal, if appropriate. See Also -------- DMPlex, DM.getCoordinateSection, DM.getCoordinates petsc.DMPlexComputeCellGeometryFVM """ cdef PetscInt cdim = 0 cdef PetscInt ccell = asInt(cell) CHKERR( DMGetCoordinateDim(self.dm, &cdim) ) cdef PetscReal vol = 0, centroid[3], normal[3] CHKERR( DMPlexComputeCellGeometryFVM(self.dm, ccell, &vol, centroid, normal) ) return (toReal(vol), array_r(cdim, centroid), array_r(cdim, normal)) def constructGhostCells(self, labelName: str | None = None) -> int: """Construct ghost cells which connect to every boundary face. Collective. Parameters ---------- labelName The name of the label specifying the boundary faces. Defaults to ``"Face Sets"``. Returns ------- numGhostCells : int The number of ghost cells added to the `DMPlex`. See Also -------- DM, DMPlex, DM.create, petsc.DMPlexConstructGhostCells """ cdef const char *cname = NULL labelName = str2bytes(labelName, &cname) cdef PetscInt numGhostCells = 0 cdef PetscDM dmGhosted = NULL CHKERR( DMPlexConstructGhostCells(self.dm, cname, &numGhostCells, &dmGhosted)) CHKERR( PetscCLEAR(self.obj) ); self.dm = dmGhosted return toInt(numGhostCells) # Metric def metricSetFromOptions(self) -> None: CHKERR( DMPlexMetricSetFromOptions(self.dm) ) def metricSetUniform(self, uniform: bool) -> None: """Record whether the metric is uniform or not. Parameters ---------- uniform Flag indicating whether the metric is uniform or not. See Also -------- DMPlex.metricIsUniform, DMPlex.metricSetIsotropic DMPlex.metricSetRestrictAnisotropyFirst, petsc.DMPlexMetricSetUniform """ cdef PetscBool bval = asBool(uniform) CHKERR( DMPlexMetricSetUniform(self.dm, bval) ) def metricIsUniform(self) -> bool: """Return the flag indicating whether the metric is uniform or not. See Also -------- DMPlex.metricSetUniform, DMPlex.metricRestrictAnisotropyFirst petsc.DMPlexMetricIsUniform """ cdef PetscBool uniform = PETSC_FALSE CHKERR( DMPlexMetricIsUniform(self.dm, &uniform) ) return toBool(uniform) def metricSetIsotropic(self, isotropic: bool) -> None: """Record whether the metric is isotropic or not. Parameters ---------- isotropic Flag indicating whether the metric is isotropic or not. See Also -------- DMPlex.metricIsIsotropic, DMPlex.metricSetUniform DMPlex.metricSetRestrictAnisotropyFirst, petsc.DMPlexMetricSetIsotropic """ cdef PetscBool bval = asBool(isotropic) CHKERR( DMPlexMetricSetIsotropic(self.dm, bval) ) def metricIsIsotropic(self) -> bool: """Return the flag indicating whether the metric is isotropic or not. See Also -------- DMPlex.metricSetIsotropic, DMPlex.metricIsUniform DMPlex.metricRestrictAnisotropyFirst, petsc.DMPlexMetricIsIsotropic """ cdef PetscBool isotropic = PETSC_FALSE CHKERR( DMPlexMetricIsIsotropic(self.dm, &isotropic) ) return toBool(isotropic) def metricSetRestrictAnisotropyFirst(self, restrictAnisotropyFirst: bool) -> None: """Record whether anisotropy is be restricted before normalization or after. Parameters ---------- restrictAnisotropyFirst Flag indicating if anisotropy is restricted before normalization or after. See Also -------- DMPlex.metricSetIsotropic, DMPlex.metricRestrictAnisotropyFirst petsc.DMPlexMetricSetRestrictAnisotropyFirst """ cdef PetscBool bval = asBool(restrictAnisotropyFirst) CHKERR( DMPlexMetricSetRestrictAnisotropyFirst(self.dm, bval) ) def metricRestrictAnisotropyFirst(self) -> bool: """Return ``true`` if anisotropy is restricted before normalization. See Also -------- DMPlex.metricIsIsotropic, DMPlex.metricSetRestrictAnisotropyFirst petsc.DMPlexMetricRestrictAnisotropyFirst """ cdef PetscBool restrictAnisotropyFirst = PETSC_FALSE CHKERR( DMPlexMetricRestrictAnisotropyFirst(self.dm, &restrictAnisotropyFirst) ) return toBool(restrictAnisotropyFirst) def metricSetNoInsertion(self, noInsert: bool) -> None: """Set the flag indicating whether node insertion should be turned off. Parameters ---------- noInsert Flag indicating whether node insertion and deletion should be turned off. See Also -------- DMPlex.metricNoInsertion, DMPlex.metricSetNoSwapping DMPlex.metricSetNoMovement, DMPlex.metricSetNoSurf petsc.DMPlexMetricSetNoInsertion """ cdef PetscBool bval = asBool(noInsert) CHKERR( DMPlexMetricSetNoInsertion(self.dm, bval) ) def metricNoInsertion(self) -> bool: """Return the flag indicating whether node insertion and deletion are turned off. See Also -------- DMPlex.metricSetNoInsertion, DMPlex.metricNoSwapping DMPlex.metricNoMovement, DMPlex.metricNoSurf petsc.DMPlexMetricNoInsertion """ cdef PetscBool noInsert = PETSC_FALSE CHKERR( DMPlexMetricNoInsertion(self.dm, &noInsert) ) return toBool(noInsert) def metricSetNoSwapping(self, noSwap: bool) -> None: """Set the flag indicating whether facet swapping should be turned off. Parameters ---------- noSwap Flag indicating whether facet swapping should be turned off. See Also -------- DMPlex.metricNoSwapping, DMPlex.metricSetNoInsertion DMPlex.metricSetNoMovement, DMPlex.metricSetNoSurf petsc.DMPlexMetricSetNoSwapping """ cdef PetscBool bval = asBool(noSwap) CHKERR( DMPlexMetricSetNoSwapping(self.dm, bval) ) def metricNoSwapping(self) -> bool: """Return the flag indicating whether facet swapping is turned off. See Also -------- DMPlex.metricSetNoSwapping, DMPlex.metricNoInsertion DMPlex.metricNoMovement, DMPlex.metricNoSurf petsc.DMPlexMetricNoSwapping """ cdef PetscBool noSwap = PETSC_FALSE CHKERR( DMPlexMetricNoSwapping(self.dm, &noSwap) ) return toBool(noSwap) def metricSetNoMovement(self, noMove: bool) -> None: """Set the flag indicating whether node movement should be turned off. Parameters ---------- noMove Flag indicating whether node movement should be turned off. See Also -------- DMPlex.metricNoMovement, DMPlex.metricSetNoInsertion DMPlex.metricSetNoSwapping, DMPlex.metricSetNoSurf petsc.DMPlexMetricSetNoMovement """ cdef PetscBool bval = asBool(noMove) CHKERR( DMPlexMetricSetNoMovement(self.dm, bval) ) def metricNoMovement(self) -> bool: """Return the flag indicating whether node movement is turned off. See Also -------- DMPlex.metricSetNoMovement, DMPlex.metricNoInsertion DMPlex.metricNoSwapping, DMPlex.metricNoSurf petsc.DMPlexMetricNoMovement """ cdef PetscBool noMove = PETSC_FALSE CHKERR( DMPlexMetricNoMovement(self.dm, &noMove) ) return toBool(noMove) def metricSetNoSurf(self, noSurf: bool) -> None: """Set the flag indicating whether surface modification should be turned off. Parameters ---------- noSurf Flag indicating whether surface modification should be turned off. See Also -------- DMPlex.metricNoSurf, DMPlex.metricSetNoMovement DMPlex.metricSetNoInsertion, DMPlex.metricSetNoSwapping petsc.DMPlexMetricSetNoSurf """ cdef PetscBool bval = asBool(noSurf) CHKERR( DMPlexMetricSetNoSurf(self.dm, bval) ) def metricNoSurf(self) -> bool: """Return the flag indicating whether surface modification is turned off. See Also -------- DMPlex.metricSetNoSurf, DMPlex.metricNoMovement DMPlex.metricNoInsertion, DMPlex.metricNoSwapping petsc.DMPlexMetricNoSurf """ cdef PetscBool noSurf = PETSC_FALSE CHKERR( DMPlexMetricNoSurf(self.dm, &noSurf) ) return toBool(noSurf) def metricSetVerbosity(self, verbosity: int) -> None: """Set the verbosity of the mesh adaptation package. Parameters ---------- verbosity The verbosity, where -1 is silent and 10 is maximum. See Also -------- DMPlex.metricGetVerbosity, DMPlex.metricSetNumIterations petsc.DMPlexMetricSetVerbosity """ cdef PetscInt ival = asInt(verbosity) CHKERR( DMPlexMetricSetVerbosity(self.dm, ival) ) def metricGetVerbosity(self) -> int: """Return the verbosity of the mesh adaptation package. Returns ------- verbosity : int The verbosity, where -1 is silent and 10 is maximum. See Also -------- DMPlex.metricSetVerbosity, DMPlex.metricGetNumIterations petsc.DMPlexMetricGetVerbosity """ cdef PetscInt verbosity = 0 CHKERR( DMPlexMetricGetVerbosity(self.dm, &verbosity) ) return toInt(verbosity) def metricSetNumIterations(self, numIter: int) -> None: """Set the number of parallel adaptation iterations. Parameters ---------- numIter The number of parallel adaptation iterations. See Also -------- DMPlex.metricSetVerbosity, DMPlex.metricGetNumIterations petsc.DMPlexMetricSetNumIterations """ cdef PetscInt ival = asInt(numIter) CHKERR( DMPlexMetricSetNumIterations(self.dm, ival) ) def metricGetNumIterations(self) -> int: """Return the number of parallel adaptation iterations. See Also -------- DMPlex.metricSetNumIterations, DMPlex.metricGetVerbosity petsc.DMPlexMetricGetNumIterations """ cdef PetscInt numIter = 0 CHKERR( DMPlexMetricGetNumIterations(self.dm, &numIter) ) return toInt(numIter) def metricSetMinimumMagnitude(self, h_min: float) -> None: """Set the minimum tolerated metric magnitude. Parameters ---------- h_min The minimum tolerated metric magnitude. See Also -------- DMPlex.metricGetMinimumMagnitude, DMPlex.metricSetMaximumMagnitude petsc.DMPlexMetricSetMinimumMagnitude """ cdef PetscReal rval = asReal(h_min) CHKERR( DMPlexMetricSetMinimumMagnitude(self.dm, rval) ) def metricGetMinimumMagnitude(self) -> float: """Return the minimum tolerated metric magnitude. See Also -------- DMPlex.metricSetMinimumMagnitude, DMPlex.metricGetMaximumMagnitude petsc.DMPlexMetricGetMinimumMagnitude """ cdef PetscReal h_min = 0 CHKERR( DMPlexMetricGetMinimumMagnitude(self.dm, &h_min) ) return toReal(h_min) def metricSetMaximumMagnitude(self, h_max: float) -> None: """Set the maximum tolerated metric magnitude. Parameters ---------- h_max The maximum tolerated metric magnitude. See Also -------- DMPlex.metricGetMaximumMagnitude, DMPlex.metricSetMinimumMagnitude petsc.DMPlexMetricSetMaximumMagnitude """ cdef PetscReal rval = asReal(h_max) CHKERR( DMPlexMetricSetMaximumMagnitude(self.dm, rval) ) def metricGetMaximumMagnitude(self) -> float: """Return the maximum tolerated metric magnitude. See Also -------- DMPlex.metricSetMaximumMagnitude, DMPlex.metricGetMinimumMagnitude petsc.DMPlexMetricGetMaximumMagnitude """ cdef PetscReal h_max = 0 CHKERR( DMPlexMetricGetMaximumMagnitude(self.dm, &h_max) ) return toReal(h_max) def metricSetMaximumAnisotropy(self, a_max: float) -> None: """Set the maximum tolerated metric anisotropy. Parameters ---------- a_max The maximum tolerated metric anisotropy. See Also -------- DMPlex.metricGetMaximumAnisotropy, DMPlex.metricSetMaximumMagnitude petsc.DMPlexMetricSetMaximumAnisotropy """ cdef PetscReal rval = asReal(a_max) CHKERR( DMPlexMetricSetMaximumAnisotropy(self.dm, rval) ) def metricGetMaximumAnisotropy(self) -> float: """Return the maximum tolerated metric anisotropy. See Also -------- DMPlex.metricSetMaximumAnisotropy, DMPlex.metricGetMaximumMagnitude petsc.DMPlexMetricGetMaximumAnisotropy """ cdef PetscReal a_max = 0 CHKERR( DMPlexMetricGetMaximumAnisotropy(self.dm, &a_max) ) return toReal(a_max) def metricSetTargetComplexity(self, targetComplexity: float) -> None: """Set the target metric complexity. Parameters ---------- targetComplexity The target metric complexity. See Also -------- DMPlex.metricGetTargetComplexity, DMPlex.metricSetNormalizationOrder petsc.DMPlexMetricSetTargetComplexity """ cdef PetscReal rval = asReal(targetComplexity) CHKERR( DMPlexMetricSetTargetComplexity(self.dm, rval) ) def metricGetTargetComplexity(self) -> float: """Return the target metric complexity. See Also -------- DMPlex.metricSetTargetComplexity, DMPlex.metricGetNormalizationOrder petsc.DMPlexMetricGetTargetComplexity """ cdef PetscReal targetComplexity = 0 CHKERR( DMPlexMetricGetTargetComplexity(self.dm, &targetComplexity) ) return toReal(targetComplexity) def metricSetNormalizationOrder(self, p: float) -> None: """Set the order p for L-p normalization. Parameters ---------- p The normalization order. See Also -------- DMPlex.metricGetNormalizationOrder, DMPlex.metricSetTargetComplexity petsc.DMPlexMetricSetNormalizationOrder """ cdef PetscReal rval = asReal(p) CHKERR( DMPlexMetricSetNormalizationOrder(self.dm, rval) ) def metricGetNormalizationOrder(self) -> float: """Return the order p for L-p normalization. See Also -------- DMPlex.metricSetNormalizationOrder, DMPlex.metricGetTargetComplexity petsc.DMPlexMetricGetNormalizationOrder """ cdef PetscReal p = 0 CHKERR( DMPlexMetricGetNormalizationOrder(self.dm, &p) ) return toReal(p) def metricSetGradationFactor(self, beta: float) -> None: """Set the metric gradation factor. Parameters ---------- beta The metric gradation factor. See Also -------- DMPlex.metricGetGradationFactor, DMPlex.metricSetHausdorffNumber petsc.DMPlexMetricSetGradationFactor """ cdef PetscReal rval = asReal(beta) CHKERR( DMPlexMetricSetGradationFactor(self.dm, rval) ) def metricGetGradationFactor(self) -> float: """Return the metric gradation factor. See Also -------- DMPlex.metricSetGradationFactor, DMPlex.metricGetHausdorffNumber petsc.DMPlexMetricGetGradationFactor """ cdef PetscReal beta = 0 CHKERR( DMPlexMetricGetGradationFactor(self.dm, &beta) ) return toReal(beta) def metricSetHausdorffNumber(self, hausd: float) -> None: """Set the metric Hausdorff number. Parameters ---------- hausd The metric Hausdorff number. See Also -------- DMPlex.metricSetGradationFactor, DMPlex.metricGetHausdorffNumber petsc.DMPlexMetricSetHausdorffNumber """ cdef PetscReal rval = asReal(hausd) CHKERR( DMPlexMetricSetHausdorffNumber(self.dm, rval) ) def metricGetHausdorffNumber(self) -> float: """Return the metric Hausdorff number. See Also -------- DMPlex.metricGetGradationFactor, DMPlex.metricSetHausdorffNumber petsc.DMPlexMetricGetHausdorffNumber """ cdef PetscReal hausd = 0 CHKERR( DMPlexMetricGetHausdorffNumber(self.dm, &hausd) ) return toReal(hausd) def metricCreate(self, field: int | None = 0) -> Vec: """Create a Riemannian metric field. Parameters ---------- field The field number to use. See Also -------- DMPlex.metricCreateUniform, DMPlex.metricCreateIsotropic petsc_options, petsc.DMPlexMetricCreate """ cdef PetscInt ival = asInt(field) cdef Vec metric = Vec() CHKERR( DMPlexMetricCreate(self.dm, ival, &metric.vec) ) return metric def metricCreateUniform(self, alpha: float, field: int | None = 0) -> Vec: """Construct a uniform isotropic metric. Parameters ---------- alpha Scaling parameter for the diagonal. field The field number to use. See Also -------- DMPlex.metricCreate, DMPlex.metricCreateIsotropic petsc.DMPlexMetricCreateUniform """ cdef PetscInt ival = asInt(field) cdef PetscReal rval = asReal(alpha) cdef Vec metric = Vec() CHKERR( DMPlexMetricCreateUniform(self.dm, ival, rval, &metric.vec) ) return metric def metricCreateIsotropic(self, Vec indicator, field: int | None = 0) -> Vec: """Construct an isotropic metric from an error indicator. Parameters ---------- indicator The error indicator. field The field number to use. See Also -------- DMPlex.metricCreate, DMPlex.metricCreateUniform petsc.DMPlexMetricCreateIsotropic """ cdef PetscInt ival = asInt(field) cdef Vec metric = Vec() CHKERR( DMPlexMetricCreateIsotropic(self.dm, ival, indicator.vec, &metric.vec) ) return metric def metricDeterminantCreate(self, field: int | None = 0) -> tuple[Vec, DM]: """Create the determinant field for a Riemannian metric. Parameters ---------- field The field number to use. Returns ------- determinant : Vec The determinant field. dmDet : DM The corresponding DM See Also -------- DMPlex.metricCreateUniform, DMPlex.metricCreateIsotropic DMPlex.metricCreate, petsc.DMPlexMetricDeterminantCreate """ cdef PetscInt ival = asInt(field) cdef Vec determinant = Vec() cdef DM dmDet = DM() CHKERR( DMPlexMetricDeterminantCreate(self.dm, ival, &determinant.vec, &dmDet.dm) ) return (determinant, dmDet) def metricEnforceSPD(self, Vec metric, Vec ometric, Vec determinant, restrictSizes: bool | None = False, restrictAnisotropy: bool | None = False) -> tuple[Vec, Vec]: """Enforce symmetric positive-definiteness of a metric. Parameters ---------- metric The metric. ometric The output metric. determinant The output determinant. restrictSizes Flag indicating whether maximum/minimum magnitudes should be enforced. restrictAnisotropy Flag indicating whether maximum anisotropy should be enforced. Returns ------- ometric : Vec The output metric. determinant : Vec The output determinant. See Also -------- DMPlex.metricNormalize, DMPlex.metricIntersection2 DMPlex.metricIntersection3, petsc_options, petsc.DMPlexMetricEnforceSPD """ cdef PetscBool bval_rs = asBool(restrictSizes) cdef PetscBool bval_ra = asBool(restrictAnisotropy) cdef DM dmDet = DM() CHKERR( DMPlexMetricEnforceSPD(self.dm, metric.vec, bval_rs, bval_ra, ometric.vec, determinant.vec) ) return (ometric, determinant) def metricNormalize(self, Vec metric, Vec ometric, Vec determinant, restrictSizes: bool | None = True, restrictAnisotropy: bool | None = True) -> tuple[Vec, Vec]: """Apply L-p normalization to a metric. Parameters ---------- metric The metric. ometric The output metric. determinant The output determinant. restrictSizes Flag indicating whether maximum/minimum magnitudes should be enforced. restrictAnisotropy Flag indicating whether maximum anisotropy should be enforced. Returns ------- ometric : Vec The output normalized metric. determinant : Vec The output determinant. See Also -------- DMPlex.metricEnforceSPD, DMPlex.metricIntersection2 DMPlex.metricIntersection3, petsc_options, petsc.DMPlexMetricNormalize """ cdef PetscBool bval_rs = asBool(restrictSizes) cdef PetscBool bval_ra = asBool(restrictAnisotropy) CHKERR( DMPlexMetricNormalize(self.dm, metric.vec, bval_rs, bval_ra, ometric.vec, determinant.vec) ) return (ometric, determinant) def metricAverage2(self, Vec metric1, Vec metric2, Vec metricAvg) -> Vec: """Compute and return the unweighted average of two metrics. Parameters ---------- metric1 The first metric to be averaged. metric2 The second metric to be averaged. metricAvg The output averaged metric. See Also -------- DMPlex.metricAverage3, petsc.DMPlexMetricAverage2 """ CHKERR( DMPlexMetricAverage2(self.dm, metric1.vec, metric2.vec, metricAvg.vec) ) return metricAvg def metricAverage3(self, Vec metric1, Vec metric2, Vec metric3, Vec metricAvg) -> Vec: """Compute and return the unweighted average of three metrics. Parameters ---------- metric1 The first metric to be averaged. metric2 The second metric to be averaged. metric3 The third metric to be averaged. metricAvg The output averaged metric. See Also -------- DMPlex.metricAverage2, petsc.DMPlexMetricAverage3 """ CHKERR( DMPlexMetricAverage3(self.dm, metric1.vec, metric2.vec, metric3.vec, metricAvg.vec) ) return metricAvg def metricIntersection2(self, Vec metric1, Vec metric2, Vec metricInt) -> Vec: """Compute and return the intersection of two metrics. Parameters ---------- metric1 The first metric to be intersected. metric2 The second metric to be intersected. metricInt The output intersected metric. See Also -------- DMPlex.metricIntersection3, petsc.DMPlexMetricIntersection2 """ CHKERR( DMPlexMetricIntersection2(self.dm, metric1.vec, metric2.vec, metricInt.vec) ) return metricInt def metricIntersection3(self, Vec metric1, Vec metric2, Vec metric3, Vec metricInt) -> Vec: """Compute the intersection of three metrics. Parameters ---------- metric1 The first metric to be intersected. metric2 The second metric to be intersected. metric3 The third metric to be intersected. metricInt The output intersected metric. See Also -------- DMPlex.metricIntersection2, petsc.DMPlexMetricIntersection3 """ CHKERR( DMPlexMetricIntersection3(self.dm, metric1.vec, metric2.vec, metric3.vec, metricInt.vec) ) return metricInt def computeGradientClementInterpolant(self, Vec locX, Vec locC) -> Vec: """Return the L2 projection of the cellwise gradient of a function onto P1. Collective. Parameters ---------- locX The coefficient vector of the function. locC The output `Vec` which holds the Clement interpolant of the gradient. See Also -------- DM, DMPlex, petsc.DMPlexComputeGradientClementInterpolant """ CHKERR( DMPlexComputeGradientClementInterpolant(self.dm, locX.vec, locC.vec) ) return locC # View def topologyView(self, Viewer viewer) -> None: """Save a `DMPlex` topology into a file. Collective. Parameters ---------- viewer The `Viewer` for saving. See Also -------- DM, DMPlex, DM.view, DMPlex.coordinatesView, DMPlex.labelsView DMPlex.topologyLoad, Viewer, petsc.DMPlexTopologyView """ CHKERR( DMPlexTopologyView(self.dm, viewer.vwr)) def coordinatesView(self, Viewer viewer) -> None: """Save `DMPlex` coordinates into a file. Collective. Parameters ---------- viewer The `Viewer` for saving. See Also -------- DM, DMPlex, DM.view, DMPlex.topologyView, DMPlex.labelsView DMPlex.coordinatesLoad, Viewer, petsc.DMPlexCoordinatesView """ CHKERR( DMPlexCoordinatesView(self.dm, viewer.vwr)) def labelsView(self, Viewer viewer) -> None: """Save `DMPlex` labels into a file. Collective. Parameters ---------- viewer The `Viewer` for saving. See Also -------- DM, DMPlex, DM.view, DMPlex.topologyView, DMPlex.coordinatesView DMPlex.labelsLoad, Viewer, petsc.DMPlexLabelsView """ CHKERR( DMPlexLabelsView(self.dm, viewer.vwr)) def sectionView(self, Viewer viewer, DM sectiondm) -> None: """Save a section associated with a `DMPlex`. Collective. Parameters ---------- viewer The `Viewer` for saving. sectiondm The `DM` that contains the section to be saved. See Also -------- DM, DMPlex, DM.view, DMPlex.topologyView, DMPlex.coordinatesView DMPlex.labelsView, DMPlex.globalVectorView, DMPlex.localVectorView DMPlex.sectionLoad, Viewer, petsc.DMPlexSectionView """ CHKERR( DMPlexSectionView(self.dm, viewer.vwr, sectiondm.dm)) def globalVectorView(self, Viewer viewer, DM sectiondm, Vec vec) -> None: """Save a global vector. Collective. Parameters ---------- viewer The `Viewer` to save data with. sectiondm The `DM` containing the global section on which ``vec`` is defined; may be the same as this `DMPlex` object. vec The global vector to be saved. See Also -------- DM, DMPlex, DMPlex.topologyView, DMPlex.sectionView DMPlex.localVectorView, DMPlex.globalVectorLoad DMPlex.localVectorLoad, petsc.DMPlexGlobalVectorView """ CHKERR( DMPlexGlobalVectorView(self.dm, viewer.vwr, sectiondm.dm, vec.vec)) def localVectorView(self, Viewer viewer, DM sectiondm, Vec vec) -> None: """Save a local vector. Collective. Parameters ---------- viewer The `Viewer` to save data with. sectiondm The `DM` that contains the local section on which ``vec`` is defined; may be the same as this `DMPlex` object. vec The local vector to be saved. See Also -------- DM, DMPlex, DMPlex.topologyView, DMPlex.sectionView DMPlex.globalVectorView, DMPlex.globalVectorLoad DMPlex.localVectorLoad, petsc.DMPlexLocalVectorView """ CHKERR( DMPlexLocalVectorView(self.dm, viewer.vwr, sectiondm.dm, vec.vec)) # Load def topologyLoad(self, Viewer viewer) -> SF: """Load a topology into this `DMPlex` object. Collective. Parameters ---------- viewer The `Viewer` for the saved topology Returns ------- sfxc : SF The `SF` that pushes points in ``[0, N)`` to the associated points in the loaded `DMPlex`, where ``N`` is the global number of points. See Also -------- DM, DMPlex, DM.load, DMPlex.coordinatesLoad, DMPlex.labelsLoad DM.view, SF, Viewer, petsc.DMPlexTopologyLoad """ cdef SF sf = SF() CHKERR( DMPlexTopologyLoad(self.dm, viewer.vwr, &sf.sf)) return sf def coordinatesLoad(self, Viewer viewer, SF sfxc) -> None: """Load coordinates into this `DMPlex` object. Collective. Parameters ---------- viewer The `Viewer` for the saved coordinates. sfxc The `SF` returned by `topologyLoad`. See Also -------- DM, DMPlex, DM.load, DMPlex.topologyLoad, DMPlex.labelsLoad, DM.view SF, Viewer, petsc.DMPlexCoordinatesLoad """ CHKERR( DMPlexCoordinatesLoad(self.dm, viewer.vwr, sfxc.sf)) def labelsLoad(self, Viewer viewer, SF sfxc) -> None: """Load labels into this `DMPlex` object. Collective. Parameters ---------- viewer The `Viewer` for the saved labels. sfxc The `SF` returned by `topologyLoad`. See Also -------- DM, DMPlex, DM.load, DMPlex.topologyLoad, DMPlex.coordinatesLoad DM.view, SF, Viewer, petsc.DMPlexLabelsLoad """ CHKERR( DMPlexLabelsLoad(self.dm, viewer.vwr, sfxc.sf)) def sectionLoad(self, Viewer viewer, DM sectiondm, SF sfxc) -> tuple[SF, SF]: """Load section into a `DM`. Collective. Parameters ---------- viewer The `Viewer` that represents the on-disk section (``sectionA``). sectiondm The `DM` into which the on-disk section (``sectionA``) is migrated. sfxc The `SF` returned by `topologyLoad`. Returns ------- gsf : SF The `SF` that migrates any on-disk `Vec` data associated with ``sectionA`` into a global `Vec` associated with the ``sectiondm``'s global section (`None` if not needed). lsf : SF The `SF` that migrates any on-disk `Vec` data associated with ``sectionA`` into a local `Vec` associated with the ``sectiondm``'s local section (`None` if not needed). See Also -------- DM, DMPlex, DM.load, DMPlex.topologyLoad, DMPlex.coordinatesLoad DMPlex.labelsLoad, DMPlex.globalVectorLoad, DMPlex.localVectorLoad DMPlex.sectionView, SF, Viewer, petsc.DMPlexSectionLoad """ cdef SF gsf = SF() cdef SF lsf = SF() CHKERR( DMPlexSectionLoad(self.dm, viewer.vwr, sectiondm.dm, sfxc.sf, &gsf.sf, &lsf.sf)) return gsf, lsf def globalVectorLoad(self, Viewer viewer, DM sectiondm, SF sf, Vec vec) -> None: """Load on-disk vector data into a global vector. Collective. Parameters ---------- viewer The `Viewer` that represents the on-disk vector data. sectiondm The `DM` that contains the global section on which vec is defined. sf The `SF` that migrates the on-disk vector data into vec. vec The global vector to set values of. See Also -------- DM, DMPlex, DMPlex.topologyLoad, DMPlex.sectionLoad DMPlex.localVectorLoad, DMPlex.globalVectorView DMPlex.localVectorView, SF, Viewer, petsc.DMPlexGlobalVectorLoad """ CHKERR( DMPlexGlobalVectorLoad(self.dm, viewer.vwr, sectiondm.dm, sf.sf, vec.vec)) def localVectorLoad(self, Viewer viewer, DM sectiondm, SF sf, Vec vec) -> None: """Load on-disk vector data into a local vector. Collective. Parameters ---------- viewer The `Viewer` that represents the on-disk vector data. sectiondm The `DM` that contains the local section on which vec is defined. sf The `SF` that migrates the on-disk vector data into vec. vec The local vector to set values of. See Also -------- DM, DMPlex, DMPlex.topologyLoad, DMPlex.sectionLoad DMPlex.globalVectorLoad, DMPlex.globalVectorView DMPlex.localVectorView, SF, Viewer, petsc.DMPlexLocalVectorLoad """ CHKERR( DMPlexLocalVectorLoad(self.dm, viewer.vwr, sectiondm.dm, sf.sf, vec.vec)) # -------------------------------------------------------------------- del DMPlexReorderDefaultFlag # -------------------------------------------------------------------- class DMPlexTransformType(object): REFINEREGULAR = S_(DMPLEXREFINEREGULAR) REFINEALFELD = S_(DMPLEXREFINEALFELD) REFINEPOWELLSABIN = S_(DMPLEXREFINEPOWELLSABIN) REFINEBOUNDARYLAYER = S_(DMPLEXREFINEBOUNDARYLAYER) REFINESBR = S_(DMPLEXREFINESBR) REFINETOBOX = S_(DMPLEXREFINETOBOX) REFINETOSIMPLEX = S_(DMPLEXREFINETOSIMPLEX) REFINE1D = S_(DMPLEXREFINE1D) EXTRUDE = S_(DMPLEXEXTRUDE) TRANSFORMFILTER = S_(DMPLEXTRANSFORMFILTER) cdef class DMPlexTransform(Object): def __cinit__(self): self.obj = &self.tr self.tr = NULL def apply(self, DM dm): cdef DMPlex newdm = DMPlex() CHKERR( DMPlexTransformApply(self.tr, dm.dm, &newdm.dm) ) return newdm def create(self, comm=None): cdef MPI_Comm ccomm = def_Comm(comm, PETSC_COMM_DEFAULT) cdef PetscDMPlexTransform newtr = NULL CHKERR( DMPlexTransformCreate(ccomm, &newtr) ) CHKERR( PetscCLEAR(self.obj) ) self.tr = newtr return self def destroy(self): CHKERR( DMPlexTransformDestroy(&self.tr) ) return self def getType(self): cdef PetscDMPlexTransformType cval = NULL CHKERR( DMPlexTransformGetType(self.tr, &cval) ) return bytes2str(cval) def setUp(self): CHKERR( DMPlexTransformSetUp(self.tr) ) return self def setType(self, tr_type): cdef PetscDMPlexTransformType cval = NULL tr_type = str2bytes(tr_type, &cval) CHKERR( DMPlexTransformSetType(self.tr, cval) ) def setDM(self, DM dm): CHKERR( DMPlexTransformSetDM(self.tr, dm.dm) ) def setFromOptions(self): CHKERR( DMPlexTransformSetFromOptions(self.tr) ) def view(self, Viewer viewer=None): cdef PetscViewer vwr = NULL if viewer is not None: vwr = viewer.vwr CHKERR( DMPlexTransformView(self.tr, vwr) ) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/src/petsc4py/PETSc/DMShell.pyx0000644000175000017500000005103414567251135017704 0ustar00balaybalaycdef class DMShell(DM): """A shell DM object, used to manage user-defined problem data.""" def create(self, comm: Comm | None = None) -> Self: """Creates a shell DM object. Collective. Parameters ---------- comm MPI communicator, defaults to `Sys.getDefaultComm`. See Also -------- petsc.DMShellCreate """ cdef MPI_Comm ccomm = def_Comm(comm, PETSC_COMM_DEFAULT) cdef PetscDM newdm = NULL CHKERR( DMShellCreate(ccomm, &newdm) ) CHKERR( PetscCLEAR(self.obj) ); self.dm = newdm return self def setMatrix(self, Mat mat) -> None: """Set a template matrix. Collective. Parameters ---------- mat The template matrix. See Also -------- petsc.DMShellSetMatrix """ CHKERR( DMShellSetMatrix(self.dm, mat.mat) ) def setGlobalVector(self, Vec gv) -> None: """Set a template global vector. Logically collective. Parameters ---------- gv Template vector. See Also -------- setLocalVector, petsc.DMShellSetGlobalVector """ CHKERR( DMShellSetGlobalVector(self.dm, gv.vec) ) def setLocalVector(self, Vec lv) -> None: """Set a template local vector. Logically collective. Parameters ---------- lv Template vector. See Also -------- setGlobalVector, petsc.DMShellSetLocalVector """ CHKERR( DMShellSetLocalVector(self.dm, lv.vec) ) def setCreateGlobalVector( self, create_gvec: Callable[[DM], Vec] | None, args: tuple[Any, ...] | None = None, kargs: dict[str, Any] | None = None, ) -> None: """Set the routine to create a global vector. Logically collective. Parameters ---------- create_gvec The creation routine. args Additional positional arguments for ``create_gvec``. kargs Additional keyword arguments for ``create_gvec``. See Also -------- setCreateLocalVector, petsc.DMShellSetCreateGlobalVector """ if create_gvec is not None: if args is None: args = () if kargs is None: kargs = {} context = (create_gvec, args, kargs) self.set_attr('__create_global_vector__', context) CHKERR( DMShellSetCreateGlobalVector(self.dm, DMSHELL_CreateGlobalVector) ) else: CHKERR( DMShellSetCreateGlobalVector(self.dm, NULL) ) def setCreateLocalVector( self, create_lvec: Callable[[DM], Vec] | None, args: tuple[Any, ...] | None = None, kargs: dict[str, Any] | None = None, ) -> None: """Set the routine to create a local vector. Logically collective. Parameters ---------- create_lvec The creation routine. args Additional positional arguments for ``create_lvec``. kargs Additional keyword arguments for ``create_lvec``. See Also -------- setCreateGlobalVector, petsc.DMShellSetCreateLocalVector """ if create_lvec is not None: if args is None: args = () if kargs is None: kargs = {} context = (create_lvec, args, kargs) self.set_attr('__create_local_vector__', context) CHKERR( DMShellSetCreateLocalVector(self.dm, DMSHELL_CreateLocalVector) ) else: CHKERR( DMShellSetCreateLocalVector(self.dm, NULL) ) def setGlobalToLocal( self, begin: Callable[[DM, Vec, InsertMode, Vec], None] | None, end: Callable[[DM, Vec, InsertMode, Vec], None] | None, begin_args: tuple[Any, ...] | None = None, begin_kargs: dict[str, Any] | None = None, end_args: tuple[Any, ...] | None = None, end_kargs: dict[str, Any] | None = None, ) -> None: """Set the routines used to perform a global to local scatter. Logically collective. Parameters ---------- dm The `DMShell`. begin The routine which begins the global to local scatter. end The routine which ends the global to local scatter. begin_args Additional positional arguments for ``begin``. begin_kargs Additional keyword arguments for ``begin``. end_args Additional positional arguments for ``end``. end_kargs Additional keyword arguments for ``end``. See Also -------- petsc.DMShellSetGlobalToLocal """ cdef PetscDMShellXToYFunction cbegin = NULL, cend = NULL if begin is not None: if begin_args is None: begin_args = () if begin_kargs is None: begin_kargs = {} context = (begin, begin_args, begin_kargs) self.set_attr('__g2l_begin__', context) cbegin = &DMSHELL_GlobalToLocalBegin if end is not None: if end_args is None: end_args = () if end_kargs is None: end_kargs = {} context = (end, end_args, end_kargs) self.set_attr('__g2l_end__', context) cend = &DMSHELL_GlobalToLocalEnd CHKERR( DMShellSetGlobalToLocal(self.dm, cbegin, cend) ) def setGlobalToLocalVecScatter(self, Scatter gtol) -> None: """Set a `Scatter` context for global to local communication. Logically collective. Parameters ---------- gtol The global to local `Scatter` context. See Also -------- petsc.DMShellSetGlobalToLocalVecScatter """ CHKERR( DMShellSetGlobalToLocalVecScatter(self.dm, gtol.sct) ) def setLocalToGlobal( self, begin: Callable[[DM, Vec, InsertMode, Vec], None] | None, end: Callable[[DM, Vec, InsertMode, Vec], None] | None, begin_args: tuple[Any, ...] | None = None, begin_kargs: dict[str, Any] | None = None, end_args: tuple[Any, ...] | None = None, end_kargs: dict[str, Any] | None = None, ) -> None: """Set the routines used to perform a local to global scatter. Logically collective. Parameters ---------- begin The routine which begins the local to global scatter. end The routine which ends the local to global scatter. begin_args Additional positional arguments for ``begin``. begin_kargs Additional keyword arguments for ``begin``. end_args Additional positional arguments for ``end``. end_kargs Additional keyword arguments for ``end``. See Also -------- petsc.DMShellSetLocalToGlobal """ cdef PetscDMShellXToYFunction cbegin = NULL, cend = NULL if begin is not None: if begin_args is None: begin_args = () if begin_kargs is None: begin_kargs = {} context = (begin, begin_args, begin_kargs) self.set_attr('__l2g_begin__', context) cbegin = &DMSHELL_LocalToGlobalBegin if end is not None: if end_args is None: end_args = () if end_kargs is None: end_kargs = {} context = (end, end_args, end_kargs) self.set_attr('__l2g_end__', context) cend = &DMSHELL_LocalToGlobalEnd CHKERR( DMShellSetLocalToGlobal(self.dm, cbegin, cend) ) def setLocalToGlobalVecScatter(self, Scatter ltog) -> None: """Set a `Scatter` context for local to global communication. Logically collective. Parameters ---------- ltog The local to global `Scatter` context. See Also -------- petsc.DMShellSetLocalToGlobalVecScatter """ CHKERR( DMShellSetLocalToGlobalVecScatter(self.dm, ltog.sct) ) def setLocalToLocal( self, begin: Callable[[DM, Vec, InsertMode, Vec], None] | None, end: Callable[[DM, Vec, InsertMode, Vec], None] | None, begin_args: tuple[Any, ...] | None = None, begin_kargs: dict[str, Any] | None = None, end_args: tuple[Any, ...] | None = None, end_kargs: dict[str, Any] | None = None, ) -> None: """Set the routines used to perform a local to local scatter. Logically collective. Parameters ---------- begin The routine which begins the local to local scatter. end The routine which ends the local to local scatter. begin_args Additional positional arguments for ``begin``. begin_kargs Additional keyword arguments for ``begin``. end_args Additional positional arguments for ``end``. end_kargs Additional keyword arguments for ``end``. See Also -------- petsc.DMShellSetLocalToLocal """ cdef PetscDMShellXToYFunction cbegin = NULL, cend = NULL cbegin = NULL cend = NULL if begin is not None: if begin_args is None: begin_args = () if begin_kargs is None: begin_kargs = {} context = (begin, begin_args, begin_kargs) self.set_attr('__l2l_begin__', context) cbegin = &DMSHELL_LocalToLocalBegin if end is not None: if end_args is None: end_args = () if end_kargs is None: end_kargs = {} context = (end, end_args, end_kargs) self.set_attr('__l2l_end__', context) cend = &DMSHELL_LocalToLocalEnd CHKERR( DMShellSetLocalToLocal(self.dm, cbegin, cend) ) def setLocalToLocalVecScatter(self, Scatter ltol) -> None: """Set a ``Scatter`` context for local to local communication. Logically collective. Parameters ---------- ltol The local to local ``Scatter`` context. See Also -------- petsc.DMShellSetLocalToLocalVecScatter """ CHKERR( DMShellSetLocalToLocalVecScatter(self.dm, ltol.sct) ) def setCreateMatrix( self, create_matrix: Callable[[DM], Mat] | None, args: tuple[Any, ...] | None = None, kargs: dict[str, Any] | None = None, ) -> None: """Set the routine to create a matrix. Logically collective. Parameters ---------- create_matrix The function to create a matrix. args Additional positional arguments for ``create_matrix``. kargs Additional keyword arguments for ``create_matrix``. See Also -------- petsc.DMShellSetCreateMatrix """ if create_matrix is not None: if args is None: args = () if kargs is None: kargs = {} context = (create_matrix, args, kargs) self.set_attr('__create_matrix__', context) CHKERR( DMShellSetCreateMatrix(self.dm, DMSHELL_CreateMatrix) ) else: CHKERR( DMShellSetCreateMatrix(self.dm, NULL) ) def setCoarsen( self, coarsen: Callable[[DM, Comm], DM] | None, args: tuple[Any, ...] | None = None, kargs: dict[str, Any] | None = None, ) -> None: """Set the routine used to coarsen the `DMShell`. Logically collective. Parameters ---------- coarsen The routine which coarsens the DM. args Additional positional arguments for ``coarsen``. kargs Additional keyword arguments for ``coarsen``. See Also -------- setRefine, petsc.DMShellSetCoarsen """ if coarsen is not None: if args is None: args = () if kargs is None: kargs = {} context = (coarsen, args, kargs) self.set_attr('__coarsen__', context) CHKERR( DMShellSetCoarsen(self.dm, DMSHELL_Coarsen) ) else: CHKERR( DMShellSetCoarsen(self.dm, NULL) ) def setRefine( self, refine: Callable[[DM, Comm], DM] | None, args: tuple[Any, ...] | None = None, kargs: dict[str, Any] | None = None, ) -> None: """Set the routine used to refine the `DMShell`. Logically collective. Parameters ---------- refine The routine which refines the DM. args Additional positional arguments for ``refine``. kargs Additional keyword arguments for ``refine``. See Also -------- setCoarsen, petsc.DMShellSetRefine """ if refine is not None: if args is None: args = () if kargs is None: kargs = {} context = (refine, args, kargs) self.set_attr('__refine__', context) CHKERR( DMShellSetRefine(self.dm, DMSHELL_Refine) ) else: CHKERR( DMShellSetRefine(self.dm, NULL) ) def setCreateInterpolation( self, create_interpolation: Callable[[DM, DM], tuple[Mat, Vec]] | None, args: tuple[Any, ...] | None = None, kargs: dict[str, Any] | None = None, ) -> None: """Set the routine used to create the interpolation operator. Logically collective. Parameters ---------- create_interpolation The routine to create the interpolation. args Additional positional arguments for ``create_interpolation``. kargs Additional keyword arguments for ``create_interpolation``. See Also -------- petsc.DMShellSetCreateInterpolation """ if create_interpolation is not None: if args is None: args = () if kargs is None: kargs = {} context = (create_interpolation, args, kargs) self.set_attr('__create_interpolation__', context) CHKERR( DMShellSetCreateInterpolation(self.dm, DMSHELL_CreateInterpolation) ) else: CHKERR( DMShellSetCreateInterpolation(self.dm, NULL) ) def setCreateInjection( self, create_injection: Callable[[DM, DM], Mat] | None, args: tuple[Any, ...] | None = None, kargs: dict[str, Any] | None = None, ) -> None: """Set the routine used to create the injection operator. Logically collective. Parameters ---------- create_injection The routine to create the injection. args Additional positional arguments for ``create_injection``. kargs Additional keyword arguments for ``create_injection``. See Also -------- petsc.DMShellSetCreateInjection """ if create_injection is not None: if args is None: args = () if kargs is None: kargs = {} context = (create_injection, args, kargs) self.set_attr('__create_injection__', context) CHKERR( DMShellSetCreateInjection(self.dm, DMSHELL_CreateInjection) ) else: CHKERR( DMShellSetCreateInjection(self.dm, NULL) ) def setCreateRestriction( self, create_restriction: Callable[[DM, DM], Mat] | None, args: tuple[Any, ...] | None = None, kargs: dict[str, Any] | None = None, ) -> None: """Set the routine used to create the restriction operator. Logically collective. Parameters ---------- create_restriction The routine to create the restriction args Additional positional arguments for ``create_restriction``. kargs Additional keyword arguments for ``create_restriction``. See Also -------- petsc.DMShellSetCreateRestriction """ if create_restriction is not None: if args is None: args = () if kargs is None: kargs = {} context = (create_restriction, args, kargs) self.set_attr('__create_restriction__', context) CHKERR( DMShellSetCreateRestriction(self.dm, DMSHELL_CreateRestriction) ) else: CHKERR( DMShellSetCreateRestriction(self.dm, NULL) ) def setCreateFieldDecomposition( self, decomp: Callable[[DM], tuple[list[str] | None, list[IS] | None, list[DM] | None]] | None, args: tuple[Any, ...] | None = None, kargs: dict[str, Any] | None = None, ) -> None: """Set the routine used to create a field decomposition. Logically collective. Parameters ---------- decomp The routine to create the decomposition. args Additional positional arguments for ``decomp``. kargs Additional keyword arguments for ``decomp``. See Also -------- petsc.DMShellSetCreateFieldDecomposition """ if decomp is not None: if args is None: args = () if kargs is None: kargs = {} context = (decomp, args, kargs) self.set_attr('__create_field_decomp__', context) CHKERR( DMShellSetCreateFieldDecomposition(self.dm, DMSHELL_CreateFieldDecomposition) ) else: CHKERR( DMShellSetCreateFieldDecomposition(self.dm, NULL) ) def setCreateDomainDecomposition( self, decomp: Callable[[DM], tuple[list[str] | None, list[IS] | None, list[IS] | None, list[DM] | None]] | None, args: tuple[Any, ...] | None = None, kargs: dict[str, Any] | None = None, ) -> None: """Set the routine used to create a domain decomposition. Logically collective. Parameters ---------- decomp The routine to create the decomposition. args Additional positional arguments for ``decomp``. kargs Additional keyword arguments for ``decomp``. See Also -------- petsc.DMShellSetCreateDomainDecomposition """ if decomp is not None: if args is None: args = () if kargs is None: kargs = {} context = (decomp, args, kargs) self.set_attr('__create_domain_decomp__', context) CHKERR( DMShellSetCreateDomainDecomposition(self.dm, DMSHELL_CreateDomainDecomposition) ) else: CHKERR( DMShellSetCreateDomainDecomposition(self.dm, NULL) ) def setCreateDomainDecompositionScatters( self, scatter: Callable[[DM, list[DM]], tuple[list[Scatter], list[Scatter], list[Scatter]]] | None, args: tuple[Any, ...] | None = None, kargs: dict[str, Any] | None = None, ) -> None: """Set the routine used to create the scatter contexts for domain decomposition. Logically collective. Parameters ---------- scatter The routine to create the scatters. args Additional positional arguments for ``scatter``. kargs Additional keyword arguments for ``scatter``. See Also -------- petsc.DMShellSetCreateDomainDecompositionScatters """ if scatter is not None: if args is None: args = () if kargs is None: kargs = {} context = (scatter, args, kargs) self.set_attr('__create_domain_decomp_scatters__', context) CHKERR( DMShellSetCreateDomainDecompositionScatters(self.dm, DMSHELL_CreateDomainDecompositionScatters) ) else: CHKERR( DMShellSetCreateDomainDecompositionScatters(self.dm, NULL) ) def setCreateSubDM( self, create_subdm: Callable[[DM, Sequence[int]], tuple[IS, DM]] | None, args: tuple[Any, ...] | None = None, kargs: dict[str, Any] | None = None, ) -> None: """Set the routine used to create a sub DM from the `DMShell`. Logically collective. Parameters ---------- subdm The routine to create the decomposition. args Additional positional arguments for ``subdm``. kargs Additional keyword arguments for ``subdm``. See Also -------- petsc.DMShellSetCreateSubDM """ if create_subdm is not None: if args is None: args = () if kargs is None: kargs = {} context = (create_subdm, args, kargs) self.set_attr('__create_subdm__', context) CHKERR( DMShellSetCreateSubDM(self.dm, DMSHELL_CreateSubDM) ) else: CHKERR( DMShellSetCreateSubDM(self.dm, NULL) ) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/src/petsc4py/PETSc/DMStag.pyx0000644000175000017500000007021614567251135017536 0ustar00balaybalay# -------------------------------------------------------------------- class DMStagStencilType(object): STAR = DMSTAG_STENCIL_STAR BOX = DMSTAG_STENCIL_BOX NONE = DMSTAG_STENCIL_NONE class DMStagStencilLocation(object): NULLLOC = DMSTAG_NULL_LOCATION BACK_DOWN_LEFT = DMSTAG_BACK_DOWN_LEFT BACK_DOWN = DMSTAG_BACK_DOWN BACK_DOWN_RIGHT = DMSTAG_BACK_DOWN_RIGHT BACK_LEFT = DMSTAG_BACK_LEFT BACK = DMSTAG_BACK BACK_RIGHT = DMSTAG_BACK_RIGHT BACK_UP_LEFT = DMSTAG_BACK_UP_LEFT BACK_UP = DMSTAG_BACK_UP BACK_UP_RIGHT = DMSTAG_BACK_UP_RIGHT DOWN_LEFT = DMSTAG_DOWN_LEFT DOWN = DMSTAG_DOWN DOWN_RIGHT = DMSTAG_DOWN_RIGHT LEFT = DMSTAG_LEFT ELEMENT = DMSTAG_ELEMENT RIGHT = DMSTAG_RIGHT UP_LEFT = DMSTAG_UP_LEFT UP = DMSTAG_UP UP_RIGHT = DMSTAG_UP_RIGHT FRONT_DOWN_LEFT = DMSTAG_FRONT_DOWN_LEFT FRONT_DOWN = DMSTAG_FRONT_DOWN FRONT_DOWN_RIGHT = DMSTAG_FRONT_DOWN_RIGHT FRONT_LEFT = DMSTAG_FRONT_LEFT FRONT = DMSTAG_FRONT FRONT_RIGHT = DMSTAG_FRONT_RIGHT FRONT_UP_LEFT = DMSTAG_FRONT_UP_LEFT FRONT_UP = DMSTAG_FRONT_UP FRONT_UP_RIGHT = DMSTAG_FRONT_UP_RIGHT # -------------------------------------------------------------------- cdef class DMStag(DM): """A DM object representing a "staggered grid" or a structured cell complex.""" StencilType = DMStagStencilType StencilLocation = DMStagStencilLocation def create( self, dim: int, dofs: tuple[int, ...] | None = None, sizes: tuple[int, ...] | None = None, boundary_types: tuple[DM.BoundaryType | int | str | bool, ...] | None = None, stencil_type: StencilType | None = None, stencil_width: int | None = None, proc_sizes: tuple[int, ...] | None = None, ownership_ranges: tuple[Sequence[int], ...] | None = None, comm: Comm | None = None, setUp: bool | None = False, ) -> Self: """Create a DMDA object. Collective. Creates an object to manage data living on the elements and vertices / the elements, faces, and vertices / the elements, faces, edges, and vertices of a parallelized regular 1D / 2D / 3D grid. Parameters ---------- dim The number of dimensions. dofs The number of degrees of freedom per vertex, element (1D); vertex, face, element (2D); or vertex, edge, face, element (3D). sizes The number of elements in each dimension. boundary_types The boundary types. stencil_type The ghost/halo stencil type. stencil_width The width of the ghost/halo region. proc_sizes The number of processes in x, y, z dimensions. ownership_ranges Local x, y, z element counts, of length equal to ``proc_sizes``, summing to ``sizes``. comm MPI communicator, defaults to `Sys.getDefaultComm`. setUp Whether to call the setup routine after creating the object. See Also -------- petsc.DMStagCreate1d, petsc.DMStagCreate2d, petsc.DMStagCreate3d petsc.DMSetUp """ # ndim cdef PetscInt ndim = asInt(dim) # sizes cdef object gsizes = sizes cdef PetscInt nsizes=PETSC_DECIDE, M=1, N=1, P=1 if sizes is not None: nsizes = asStagDims(gsizes, &M, &N, &P) assert(nsizes==ndim) # dofs cdef object cdofs = dofs cdef PetscInt ndofs=PETSC_DECIDE, dof0=1, dof1=0, dof2=0, dof3=0 if dofs is not None: ndofs = asDofs(cdofs, &dof0, &dof1, &dof2, &dof3) assert(ndofs==ndim+1) # boundary types cdef PetscDMBoundaryType btx = DM_BOUNDARY_NONE cdef PetscDMBoundaryType bty = DM_BOUNDARY_NONE cdef PetscDMBoundaryType btz = DM_BOUNDARY_NONE asBoundary(boundary_types, &btx, &bty, &btz) # stencil cdef PetscInt swidth = 0 if stencil_width is not None: swidth = asInt(stencil_width) cdef PetscDMStagStencilType stype = DMSTAG_STENCIL_NONE if stencil_type is not None: stype = asStagStencil(stencil_type) # comm cdef MPI_Comm ccomm = def_Comm(comm, PETSC_COMM_DEFAULT) # proc sizes cdef object psizes = proc_sizes cdef PetscInt nprocs=PETSC_DECIDE, m=PETSC_DECIDE, n=PETSC_DECIDE, p=PETSC_DECIDE if proc_sizes is not None: nprocs = asStagDims(psizes, &m, &n, &p) assert(nprocs==ndim) # ownership ranges cdef PetscInt *lx = NULL, *ly = NULL, *lz = NULL if ownership_ranges is not None: nranges = asStagOwnershipRanges(ownership_ranges, ndim, &m, &n, &p, &lx, &ly, &lz) assert(nranges==ndim) # create cdef PetscDM newda = NULL if dim == 1: CHKERR( DMStagCreate1d(ccomm, btx, M, dof0, dof1, stype, swidth, lx, &newda) ) if dim == 2: CHKERR( DMStagCreate2d(ccomm, btx, bty, M, N, m, n, dof0, dof1, dof2, stype, swidth, lx, ly, &newda) ) if dim == 3: CHKERR( DMStagCreate3d(ccomm, btx, bty, btz, M, N, P, m, n, p, dof0, dof1, dof2, dof3, stype, swidth, lx, ly, lz, &newda) ) CHKERR( PetscCLEAR(self.obj) ); self.dm = newda if setUp: CHKERR( DMSetUp(self.dm) ) return self # Setters def setStencilWidth(self, swidth: int) -> None: """Set elementwise stencil width. Logically collective. The width value is not used when `StencilType.NONE` is specified. Parameters ---------- swidth Stencil/halo/ghost width in elements. See Also -------- petsc.DMStagSetStencilWidth """ cdef PetscInt sw = asInt(swidth) CHKERR( DMStagSetStencilWidth(self.dm, sw) ) def setStencilType(self, stenciltype: StencilType | str) -> None: """Set elementwise ghost/halo stencil type. Logically collective. Parameters ---------- stenciltype The elementwise ghost stencil type. See Also -------- getStencilType, petsc.DMStagSetStencilType """ cdef PetscDMStagStencilType stype = asStagStencil(stenciltype) CHKERR( DMStagSetStencilType(self.dm, stype) ) def setBoundaryTypes( self, boundary_types: tuple[DM.BoundaryType | int | str | bool, ...], ) -> None: """Set the boundary types. Logically collective. Parameters ---------- boundary_types Boundary types for one/two/three dimensions. See Also -------- getBoundaryTypes, petsc.DMStagSetBoundaryTypes """ cdef PetscDMBoundaryType btx = DM_BOUNDARY_NONE cdef PetscDMBoundaryType bty = DM_BOUNDARY_NONE cdef PetscDMBoundaryType btz = DM_BOUNDARY_NONE asBoundary(boundary_types, &btx, &bty, &btz) CHKERR( DMStagSetBoundaryTypes(self.dm, btx, bty, btz) ) def setDof(self, dofs: tuple[int, ...]) -> None: """Set DOFs/stratum. Logically collective. Parameters ---------- dofs The number of points per 0-cell (vertex/node), 1-cell (element in 1D, edge in 2D and 3D), 2-cell (element in 2D, face in 3D), or 3-cell (element in 3D). See Also -------- petsc.DMStagSetDOF """ cdef tuple gdofs = tuple(dofs) cdef PetscInt gdim=PETSC_DECIDE, dof0=1, dof1=0, dof2=0, dof3=0 gdim = asDofs(gdofs, &dof0, &dof1, &dof2, &dof3) CHKERR( DMStagSetDOF(self.dm, dof0, dof1, dof2, dof3) ) def setGlobalSizes(self, sizes: tuple[int, ...]) -> None: """Set global element counts in each dimension. Logically collective. Parameters ---------- sizes Global elementwise size in the one/two/three dimensions. See Also -------- petsc.DMStagSetGlobalSizes """ cdef tuple gsizes = tuple(sizes) cdef PetscInt gdim=PETSC_DECIDE, M=1, N=1, P=1 gdim = asStagDims(gsizes, &M, &N, &P) CHKERR( DMStagSetGlobalSizes(self.dm, M, N, P) ) def setProcSizes(self, sizes: tuple[int, ...]) -> None: """Set the number of processes in each dimension in the global process grid. Logically collective. Parameters ---------- sizes Number of processes in one/two/three dimensions. See Also -------- petsc.DMStagSetNumRanks """ cdef tuple psizes = tuple(sizes) cdef PetscInt pdim=PETSC_DECIDE, m=PETSC_DECIDE, n=PETSC_DECIDE, p=PETSC_DECIDE pdim = asStagDims(psizes, &m, &n, &p) CHKERR( DMStagSetNumRanks(self.dm, m, n, p) ) def setOwnershipRanges(self, ranges: tuple[Sequence[int], ...]) -> None: """Set elements per process in each dimension. Logically collective. Parameters ---------- ranges Element counts for each process in one/two/three dimensions. See Also -------- getOwnershipRanges, petsc.DMStagSetOwnershipRanges """ cdef PetscInt dim=0, m=PETSC_DECIDE, n=PETSC_DECIDE, p=PETSC_DECIDE cdef PetscInt *lx = NULL, *ly = NULL, *lz = NULL CHKERR( DMGetDimension(self.dm, &dim) ) CHKERR( DMStagGetNumRanks(self.dm, &m, &n, &p) ) ownership_ranges = asStagOwnershipRanges(ranges, dim, &m, &n, &p, &lx, &ly, &lz) CHKERR( DMStagSetOwnershipRanges(self.dm, lx, ly, lz) ) # Getters def getDim(self) -> int: """Return the number of dimensions. Not collective. """ return self.getDimension() def getEntriesPerElement(self) -> int: """Return the number of entries per element in the local representation. Not collective. This is the natural block size for most local operations. See Also -------- petsc.DMStagGetEntriesPerElement """ cdef PetscInt epe=0 CHKERR( DMStagGetEntriesPerElement(self.dm, &epe) ) return toInt(epe) def getStencilWidth(self) -> int: """Return elementwise stencil width. Not collective. See Also -------- petsc.DMStagGetStencilWidth """ cdef PetscInt swidth=0 CHKERR( DMStagGetStencilWidth(self.dm, &swidth) ) return toInt(swidth) def getDof(self) -> tuple[int, ...]: """Get number of DOFs associated with each stratum of the grid. Not collective. See Also -------- petsc.DMStagGetDOF """ cdef PetscInt dim=0, dof0=0, dof1=0, dof2=0, dof3=0 CHKERR( DMStagGetDOF(self.dm, &dof0, &dof1, &dof2, &dof3) ) CHKERR( DMGetDimension(self.dm, &dim) ) return toDofs(dim+1,dof0,dof1,dof2,dof3) def getCorners(self) -> tuple[tuple[int, ...], tuple[int, ...], tuple[int, ...]]: """Return starting element index, width and number of partial elements. Not collective. The returned value is calculated excluding ghost points. The number of extra partial elements is either ``1`` or ``0``. The value is ``1`` on right, top, and front non-periodic domain ("physical") boundaries, in the x, y, and z dimensions respectively, and otherwise ``0``. See Also -------- getGhostCorners, petsc.DMStagGetCorners, petsc.DMGetDimension """ cdef PetscInt dim=0, x=0, y=0, z=0, m=0, n=0, p=0, nExtrax=0, nExtray=0, nExtraz=0 CHKERR( DMGetDimension(self.dm, &dim) ) CHKERR( DMStagGetCorners(self.dm, &x, &y, &z, &m, &n, &p, &nExtrax, &nExtray, &nExtraz) ) return (asInt(x), asInt(y), asInt(z))[:dim], (asInt(m), asInt(n), asInt(p))[:dim], (asInt(nExtrax), asInt(nExtray), asInt(nExtraz))[:dim] def getGhostCorners(self) -> tuple[tuple[int, ...], tuple[int, ...]]: """Return starting element index and width of local region. Not collective. See Also -------- getCorners, petsc.DMStagGetGhostCorners """ cdef PetscInt dim=0, x=0, y=0, z=0, m=0, n=0, p=0 CHKERR( DMGetDimension(self.dm, &dim) ) CHKERR( DMStagGetGhostCorners(self.dm, &x, &y, &z, &m, &n, &p) ) return (asInt(x), asInt(y), asInt(z))[:dim], (asInt(m), asInt(n), asInt(p))[:dim] def getLocalSizes(self) -> tuple[int, ...]: """Return local elementwise sizes in each dimension. Not collective. The returned value is calculated excluding ghost points. See Also -------- getGlobalSizes, petsc.DMStagGetLocalSizes """ cdef PetscInt dim=0, m=PETSC_DECIDE, n=PETSC_DECIDE, p=PETSC_DECIDE CHKERR( DMGetDimension(self.dm, &dim) ) CHKERR( DMStagGetLocalSizes(self.dm, &m, &n, &p) ) return toStagDims(dim, m, n, p) def getGlobalSizes(self) -> tuple[int, ...]: """Return global element counts in each dimension. Not collective. See Also -------- getLocalSizes, petsc.DMStagGetGlobalSizes """ cdef PetscInt dim=0, m=PETSC_DECIDE, n=PETSC_DECIDE, p=PETSC_DECIDE CHKERR( DMGetDimension(self.dm, &dim) ) CHKERR( DMStagGetGlobalSizes(self.dm, &m, &n, &p) ) return toStagDims(dim, m, n, p) def getProcSizes(self) -> tuple[int, ...]: """Return number of processes in each dimension. Not collective. See Also -------- petsc.DMStagGetNumRanks """ cdef PetscInt dim=0, m=PETSC_DECIDE, n=PETSC_DECIDE, p=PETSC_DECIDE CHKERR( DMGetDimension(self.dm, &dim) ) CHKERR( DMStagGetNumRanks(self.dm, &m, &n, &p) ) return toStagDims(dim, m, n, p) def getStencilType(self) -> str: """Return elementwise ghost/halo stencil type. Not collective. See Also -------- setStencilType, petsc.DMStagGetStencilType """ cdef PetscDMStagStencilType stype = DMSTAG_STENCIL_BOX CHKERR( DMStagGetStencilType(self.dm, &stype) ) return toStagStencil(stype) def getOwnershipRanges(self) -> tuple[Sequence[int], ...]: """Return elements per process in each dimension. Not collective. See Also -------- setOwnershipRanges, petsc.DMStagGetOwnershipRanges """ cdef PetscInt dim=0, m=0, n=0, p=0 cdef const PetscInt *lx = NULL, *ly = NULL, *lz = NULL CHKERR( DMGetDimension(self.dm, &dim) ) CHKERR( DMStagGetNumRanks(self.dm, &m, &n, &p) ) CHKERR( DMStagGetOwnershipRanges(self.dm, &lx, &ly, &lz) ) return toStagOwnershipRanges(dim, m, n, p, lx, ly, lz) def getBoundaryTypes(self) -> tuple[str, ...]: """Return boundary types in each dimension. Not collective. See Also -------- setBoundaryTypes, petsc.DMStagGetBoundaryTypes """ cdef PetscInt dim=0 cdef PetscDMBoundaryType btx = DM_BOUNDARY_NONE cdef PetscDMBoundaryType bty = DM_BOUNDARY_NONE cdef PetscDMBoundaryType btz = DM_BOUNDARY_NONE CHKERR( DMGetDimension(self.dm, &dim) ) CHKERR( DMStagGetBoundaryTypes(self.dm, &btx, &bty, &btz) ) return toStagBoundaryTypes(dim, btx, bty, btz) def getIsFirstRank(self) -> tuple[int, ...]: """Return whether this process is first in each dimension in the process grid. Not collective. See Also -------- petsc.DMStagGetIsFirstRank """ cdef PetscBool rank0=PETSC_FALSE, rank1=PETSC_FALSE, rank2=PETSC_FALSE cdef PetscInt dim=0 CHKERR( DMGetDimension(self.dm, &dim) ) CHKERR( DMStagGetIsFirstRank(self.dm, &rank0, &rank1, &rank2) ) return toStagDims(dim, rank0, rank1, rank2) def getIsLastRank(self) -> tuple[int, ...]: """Return whether this process is last in each dimension in the process grid. Not collective. See Also -------- petsc.DMStagGetIsLastRank """ cdef PetscBool rank0=PETSC_FALSE, rank1=PETSC_FALSE, rank2=PETSC_FALSE cdef PetscInt dim=0 CHKERR( DMGetDimension(self.dm, &dim) ) CHKERR( DMStagGetIsLastRank(self.dm, &rank0, &rank1, &rank2) ) return toStagDims(dim, rank0, rank1, rank2) # Coordinate-related functions def setUniformCoordinatesExplicit( self, xmin: float = 0, xmax: float = 1, ymin: float = 0, ymax: float = 1, zmin: float = 0, zmax: float = 1, ) -> None: """Set coordinates to be a uniform grid, storing all values. Collective. Parameters ---------- xmin The minimum global coordinate value in the x dimension. xmax The maximum global coordinate value in the x dimension. ymin The minimum global coordinate value in the y dimension. ymax The maximum global coordinate value in the y dimension. zmin The minimum global coordinate value in the z dimension. zmax The maximum global coordinate value in the z dimension. See Also -------- setUniformCoordinatesProduct, setUniformCoordinates petsc.DMStagSetUniformCoordinatesExplicit """ cdef PetscReal _xmin = asReal(xmin), _xmax = asReal(xmax) cdef PetscReal _ymin = asReal(ymin), _ymax = asReal(ymax) cdef PetscReal _zmin = asReal(zmin), _zmax = asReal(zmax) CHKERR( DMStagSetUniformCoordinatesExplicit(self.dm, _xmin, _xmax, _ymin, _ymax, _zmin, _zmax) ) def setUniformCoordinatesProduct( self, xmin: float = 0, xmax: float = 1, ymin: float = 0, ymax: float = 1, zmin: float = 0, zmax: float = 1, ) -> None: """Create uniform coordinates, as a product of 1D arrays. Collective. The per-dimension 1-dimensional `DMStag` objects that comprise the product always have active 0-cells (vertices, element boundaries) and 1-cells (element centers). Parameters ---------- xmin The minimum global coordinate value in the x dimension. xmax The maximum global coordinate value in the x dimension. ymin The minimum global coordinate value in the y dimension. ymax The maximum global coordinate value in the y dimension. zmin The minimum global coordinate value in the z dimension. zmax The maximum global coordinate value in the z dimension. See Also -------- setUniformCoordinatesExplicit, setUniformCoordinates petsc.DMStagSetUniformCoordinatesProduct """ cdef PetscReal _xmin = asReal(xmin), _xmax = asReal(xmax) cdef PetscReal _ymin = asReal(ymin), _ymax = asReal(ymax) cdef PetscReal _zmin = asReal(zmin), _zmax = asReal(zmax) CHKERR( DMStagSetUniformCoordinatesProduct(self.dm, _xmin, _xmax, _ymin, _ymax, _zmin, _zmax) ) def setUniformCoordinates( self, xmin: float = 0, xmax: float = 1, ymin: float = 0, ymax: float = 1, zmin: float = 0, zmax: float = 1, ) -> None: """Set the coordinates to be a uniform grid.. Collective. Local coordinates are populated, linearly extrapolated to ghost cells, including those outside the physical domain. This is also done in case of periodic boundaries, meaning that the same global point may have different coordinates in different local representations, which are equivalent assuming a periodicity implied by the arguments to this function, i.e., two points are equivalent if their difference is a multiple of ``xmax-xmin`` in the x dimension, ``ymax-ymin`` in the y dimension, and ``zmax-zmin`` in the z dimension. Parameters ---------- xmin The minimum global coordinate value in the x dimension. xmax The maximum global coordinate value in the x dimension. ymin The minimum global coordinate value in the y dimension. ymax The maximum global coordinate value in the y dimension. zmin The minimum global coordinate value in the z dimension. zmax The maximum global coordinate value in the z dimension. See Also -------- setUniformCoordinatesExplicit, setUniformCoordinatesProduct petsc.DMStagSetUniformCoordinates """ cdef PetscReal _xmin = asReal(xmin), _xmax = asReal(xmax) cdef PetscReal _ymin = asReal(ymin), _ymax = asReal(ymax) cdef PetscReal _zmin = asReal(zmin), _zmax = asReal(zmax) CHKERR( DMStagSetUniformCoordinates(self.dm, _xmin, _xmax, _ymin, _ymax, _zmin, _zmax) ) def setCoordinateDMType(self, dmtype: DM.Type) -> None: """Set the type to store coordinates. Logically collective. Parameters ---------- dmtype The type to store coordinates. See Also -------- petsc.DMStagSetCoordinateDMType """ cdef PetscDMType cval = NULL dmtype = str2bytes(dmtype, &cval) CHKERR( DMStagSetCoordinateDMType(self.dm, cval) ) # Location slot related functions def getLocationSlot(self, loc: StencilLocation, c: int) -> int: """Return index to use in accessing raw local arrays. Not collective. Parameters ---------- loc Location relative to an element. c Component. See Also -------- petsc.DMStagGetLocationSlot """ cdef PetscInt slot=0 cdef PetscInt comp=asInt(c) cdef PetscDMStagStencilLocation sloc = asStagStencilLocation(loc) CHKERR( DMStagGetLocationSlot(self.dm, sloc, comp, &slot) ) return toInt(slot) def getProductCoordinateLocationSlot(self, loc: StencilLocation) -> None: """Return slot for use with local product coordinate arrays. Not collective. Parameters ---------- loc The grid location. See Also -------- petsc.DMStagGetProductCoordinateLocationSlot """ cdef PetscInt slot=0 cdef PetscDMStagStencilLocation sloc = asStagStencilLocation(loc) CHKERR( DMStagGetProductCoordinateLocationSlot(self.dm, sloc, &slot) ) return toInt(slot) def getLocationDof(self, loc: StencilLocation) -> int: """Return number of DOFs associated with a given point on the grid. Not collective. Parameters ---------- loc The grid point. See Also -------- petsc.DMStagGetLocationDOF """ cdef PetscInt dof=0 cdef PetscDMStagStencilLocation sloc = asStagStencilLocation(loc) CHKERR( DMStagGetLocationDOF(self.dm, sloc, &dof) ) return toInt(dof) # Random other functions def migrateVec(self, Vec vec, DM dmTo, Vec vecTo) -> None: """Transfer a vector between two ``DMStag`` objects. Collective. Currently only implemented to migrate global vectors to global vectors. Parameters ---------- vec The source vector. dmTo The compatible destination object. vecTo The destination vector. See Also -------- petsc.DMStagMigrateVec """ CHKERR( DMStagMigrateVec(self.dm, vec.vec, dmTo.dm, vecTo.vec ) ) def createCompatibleDMStag(self, dofs: tuple[int, ...]) -> DM: """Create a compatible ``DMStag`` with different DOFs/stratum. Collective. Parameters ---------- dofs The number of DOFs on the strata in the new `DMStag`. See Also -------- petsc.DMStagCreateCompatibleDMStag """ cdef tuple gdofs = tuple(dofs) cdef PetscInt gdim=PETSC_DECIDE, dof0=1, dof1=0, dof2=0, dof3=0 gdim = asDofs(gdofs, &dof0, &dof1, &dof2, &dof3) cdef PetscDM newda = NULL CHKERR( DMStagCreateCompatibleDMStag(self.dm, dof0, dof1, dof2, dof3, &newda) ) cdef DM newdm = type(self)() CHKERR( PetscCLEAR(newdm.obj) ); newdm.dm = newda return newdm def VecSplitToDMDA( self, Vec vec, loc: StencilLocation, c: int, ) -> tuple[DMDA, Vec]: """Return ``DMDA``, ``Vec`` from a subgrid of a ``DMStag``, its ``Vec``. Collective. If a ``c`` value of ``-k`` is provided, the first ``k`` DOFs for that position are extracted, padding with zero values if needed. If a non-negative value is provided, a single DOF is extracted. Parameters ---------- vec The ``Vec`` object. loc Which subgrid to extract. c Which component to extract. See Also -------- petsc.DMStagVecSplitToDMDA """ cdef PetscInt pc = asInt(c) cdef PetscDMStagStencilLocation sloc = asStagStencilLocation(loc) cdef PetscDM pda = NULL cdef PetscVec pdavec = NULL CHKERR( DMStagVecSplitToDMDA(self.dm, vec.vec, sloc, pc, &pda, &pdavec) ) cdef DM da = DMDA() CHKERR( PetscCLEAR(da.obj) ); da.dm = pda cdef Vec davec = Vec() CHKERR( PetscCLEAR(davec.obj) ); davec.vec = pdavec return (da,davec) def getVecArray(self, Vec vec) -> None: """**Not implemented in petsc4py.**""" raise NotImplementedError('getVecArray for DMStag not yet implemented in petsc4py') def get1dCoordinatecArrays(self) -> None: """**Not implemented in petsc4py.**""" raise NotImplementedError('get1dCoordinatecArrays for DMStag not yet implemented in petsc4py') property dim: """The dimension.""" def __get__(self) -> int: return self.getDim() property dofs: """The number of DOFs associated with each stratum of the grid.""" def __get__(self) -> tuple[int, ...]: return self.getDof() property entries_per_element: """The number of entries per element in the local representation.""" def __get__(self) -> int: return self.getEntriesPerElement() property global_sizes: """Global element counts in each dimension.""" def __get__(self) -> tuple[int, ...]: return self.getGlobalSizes() property local_sizes: """Local elementwise sizes in each dimension.""" def __get__(self) -> tuple[int, ...]: return self.getLocalSizes() property proc_sizes: """The number of processes in each dimension in the global decomposition.""" def __get__(self) -> tuple[int, ...]: return self.getProcSizes() property boundary_types: """Boundary types in each dimension.""" def __get__(self) -> tuple[str, ...]: return self.getBoundaryTypes() property stencil_type: """Stencil type.""" def __get__(self) -> str: return self.getStencilType() property stencil_width: """Elementwise stencil width.""" def __get__(self) -> int: return self.getStencilWidth() property corners: """The lower left corner and size of local region in each dimension.""" def __get__(self) -> tuple[tuple[int, ...], tuple[int, ...]]: return self.getCorners() property ghost_corners: """The lower left corner and size of local region in each dimension.""" def __get__(self) -> tuple[tuple[int, ...], tuple[int, ...]]: return self.getGhostCorners() # -------------------------------------------------------------------- del DMStagStencilType del DMStagStencilLocation # -------------------------------------------------------------------- ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/src/petsc4py/PETSc/DMSwarm.pyx0000644000175000017500000006027514567251135017735 0ustar00balaybalay# -------------------------------------------------------------------- class DMSwarmType(object): BASIC = DMSWARM_BASIC PIC = DMSWARM_PIC class DMSwarmMigrateType(object): MIGRATE_BASIC = DMSWARM_MIGRATE_BASIC MIGRATE_DMCELLNSCATTER = DMSWARM_MIGRATE_DMCELLNSCATTER MIGRATE_DMCELLEXACT = DMSWARM_MIGRATE_DMCELLEXACT MIGRATE_USER = DMSWARM_MIGRATE_USER class DMSwarmCollectType(object): COLLECT_BASIC = DMSWARM_COLLECT_BASIC COLLECT_DMDABOUNDINGBOX = DMSWARM_COLLECT_DMDABOUNDINGBOX COLLECT_GENERAL = DMSWARM_COLLECT_GENERAL COLLECT_USER = DMSWARM_COLLECT_USER class DMSwarmPICLayoutType(object): LAYOUT_REGULAR = DMSWARMPIC_LAYOUT_REGULAR LAYOUT_GAUSS = DMSWARMPIC_LAYOUT_GAUSS LAYOUT_SUBDIVISION = DMSWARMPIC_LAYOUT_SUBDIVISION cdef class DMSwarm(DM): """A `DM` object used to represent arrays of data (fields) of arbitrary type.""" Type = DMSwarmType MigrateType = DMSwarmMigrateType CollectType = DMSwarmCollectType PICLayoutType = DMSwarmPICLayoutType def create(self, comm: Comm | None = None) -> Self: """Create an empty DM object and set its type to `DM.Type.SWARM`. Collective. DMs are the abstract objects in PETSc that mediate between meshes and discretizations and the algebraic solvers, time integrators, and optimization algorithms. Parameters ---------- comm MPI communicator, defaults to `Sys.getDefaultComm`. See Also -------- petsc.DMCreate, petsc.DMSetType """ cdef MPI_Comm ccomm = def_Comm(comm, PETSC_COMM_DEFAULT) cdef PetscDM newdm = NULL CHKERR( DMCreate(ccomm, &newdm) ) CHKERR( PetscCLEAR(self.obj) ); self.dm = newdm CHKERR( DMSetType(self.dm, DMSWARM) ) return self def createGlobalVectorFromField(self, fieldname: str) -> Vec: """Create a global `Vec` object associated with a given field. Collective. The vector must be returned to the `DMSwarm` using a matching call to `destroyGlobalVectorFromField`. Parameters ---------- fieldname The textual name given to a registered field. See Also -------- destroyGlobalVectorFromField, petsc.DMSwarmCreateGlobalVectorFromField """ cdef const char *cfieldname = NULL cdef Vec vg = Vec() fieldname = str2bytes(fieldname, &cfieldname) CHKERR( DMSwarmCreateGlobalVectorFromField(self.dm, cfieldname, &vg.vec) ) return vg def destroyGlobalVectorFromField(self, fieldname: str) -> None: """Destroy the global `Vec` object associated with a given field. Collective. Parameters ---------- fieldname The textual name given to a registered field. See Also -------- createGlobalVectorFromField, petsc.DMSwarmDestroyGlobalVectorFromField """ cdef const char *cfieldname = NULL cdef PetscVec vec = NULL fieldname = str2bytes(fieldname, &cfieldname) CHKERR( DMSwarmDestroyGlobalVectorFromField(self.dm, cfieldname, &vec) ) def createLocalVectorFromField(self, fieldname: str) -> Vec: """Create a local `Vec` object associated with a given field. Collective. The vector must be returned to the `DMSwarm` using a matching call to `destroyLocalVectorFromField`. Parameters ---------- fieldname The textual name given to a registered field. See Also -------- destroyLocalVectorFromField, petsc.DMSwarmCreateLocalVectorFromField """ cdef const char *cfieldname = NULL cdef Vec vl = Vec() fieldname = str2bytes(fieldname, &cfieldname) CHKERR( DMSwarmCreateLocalVectorFromField(self.dm, cfieldname, &vl.vec) ) return vl def destroyLocalVectorFromField(self, fieldname: str) -> None: """Destroy the local `Vec` object associated with a given field. Collective. Parameters ---------- fieldname The textual name given to a registered field. See Also -------- createLocalVectorFromField, petsc.DMSwarmDestroyLocalVectorFromField """ cdef const char *cfieldname = NULL cdef PetscVec vec fieldname = str2bytes(fieldname, &cfieldname) CHKERR( DMSwarmDestroyLocalVectorFromField(self.dm, cfieldname, &vec) ) def initializeFieldRegister(self) -> None: """Initiate the registration of fields to a `DMSwarm`. Collective. After all fields have been registered, you must call `finalizeFieldRegister`. See Also -------- finalizeFieldRegister, petsc.DMSwarmInitializeFieldRegister """ CHKERR( DMSwarmInitializeFieldRegister(self.dm) ) def finalizeFieldRegister(self) -> None: """Finalize the registration of fields to a `DMSwarm`. Collective. See Also -------- initializeFieldRegister, petsc.DMSwarmFinalizeFieldRegister """ CHKERR( DMSwarmFinalizeFieldRegister(self.dm) ) def setLocalSizes(self, nlocal: int, buffer: int) -> Self: """Set the length of all registered fields on the `DMSwarm`. Not collective. Parameters ---------- nlocal The length of each registered field. buffer The length of the buffer used for efficient dynamic resizing. See Also -------- petsc.DMSwarmSetLocalSizes """ cdef PetscInt cnlocal = asInt(nlocal) cdef PetscInt cbuffer = asInt(buffer) CHKERR( DMSwarmSetLocalSizes(self.dm, cnlocal, cbuffer) ) return self def registerField(self, fieldname: str, blocksize: int, dtype: dtype = ScalarType) -> None: """Register a field to a `DMSwarm` with a native PETSc data type. Collective. Parameters ---------- fieldname The textual name to identify this field. blocksize The number of each data type. dtype A valid PETSc data type. See Also -------- petsc.DMSwarmRegisterPetscDatatypeField """ cdef const char *cfieldname = NULL cdef PetscInt cblocksize = asInt(blocksize) cdef PetscDataType ctype = PETSC_DATATYPE_UNKNOWN if dtype == IntType: ctype = PETSC_INT if dtype == RealType: ctype = PETSC_REAL if dtype == ScalarType: ctype = PETSC_SCALAR if dtype == ComplexType: ctype = PETSC_COMPLEX assert ctype != PETSC_DATATYPE_UNKNOWN fieldname = str2bytes(fieldname, &cfieldname) CHKERR( DMSwarmRegisterPetscDatatypeField(self.dm, cfieldname, cblocksize, ctype) ) def getField(self, fieldname: str) -> Sequence[int | float | complex]: """Return arrays storing all entries associated with a field. Not collective. The returned array contains underlying values of the field. The array must be returned to the `DMSwarm` using a matching call to `restoreField`. Parameters ---------- fieldname The textual name to identify this field. Returns ------- `numpy.ndarray` The type of the entries in the array will match the type of the field. See Also -------- restoreField, petsc.DMSwarmGetField """ cdef const char *cfieldname = NULL cdef PetscInt blocksize = 0 cdef PetscDataType ctype = PETSC_DATATYPE_UNKNOWN cdef PetscReal *data = NULL cdef PetscInt nlocal = 0 fieldname = str2bytes(fieldname, &cfieldname) CHKERR( DMSwarmGetField(self.dm, cfieldname, &blocksize, &ctype, &data) ) CHKERR( DMSwarmGetLocalSize(self.dm, &nlocal) ) cdef int typenum = -1 if ctype == PETSC_INT: typenum = NPY_PETSC_INT if ctype == PETSC_REAL: typenum = NPY_PETSC_REAL if ctype == PETSC_SCALAR: typenum = NPY_PETSC_SCALAR if ctype == PETSC_COMPLEX: typenum = NPY_PETSC_COMPLEX assert typenum != -1 cdef npy_intp s = nlocal * blocksize return PyArray_SimpleNewFromData(1, &s, typenum, data) def restoreField(self, fieldname: str) -> None: """Restore accesses associated with a registered field. Not collective. Parameters ---------- fieldname The textual name to identify this field. See Also -------- getField, petsc.DMSwarmRestoreField """ cdef const char *cfieldname = NULL cdef PetscInt blocksize = 0 cdef PetscDataType ctype = PETSC_DATATYPE_UNKNOWN fieldname = str2bytes(fieldname, &cfieldname) CHKERR( DMSwarmRestoreField(self.dm, cfieldname, &blocksize, &ctype, 0) ) def vectorDefineField(self, fieldname: str) -> None: """Set the field from which to define a `Vec` object. Collective. The field will be used when `DM.createLocalVec`, or `DM.createGlobalVec` is called. Parameters ---------- fieldname The textual name given to a registered field. See Also -------- petsc.DMSwarmVectorDefineField """ cdef const char *cval = NULL fieldname = str2bytes(fieldname, &cval) CHKERR( DMSwarmVectorDefineField(self.dm, cval) ) def addPoint(self) -> None: """Add space for one new point in the `DMSwarm`. Not collective. See Also -------- petsc.DMSwarmAddPoint """ CHKERR( DMSwarmAddPoint(self.dm) ) def addNPoints(self, npoints: int) -> None: """Add space for a number of new points in the `DMSwarm`. Not collective. Parameters ---------- npoints The number of new points to add. See Also -------- petsc.DMSwarmAddNPoints """ cdef PetscInt cnpoints = asInt(npoints) CHKERR( DMSwarmAddNPoints(self.dm, cnpoints) ) def removePoint(self) -> None: """Remove the last point from the `DMSwarm`. Not collective. See Also -------- petsc.DMSwarmRemovePoint """ CHKERR( DMSwarmRemovePoint(self.dm) ) def removePointAtIndex(self, index: int) -> None: """Remove a specific point from the `DMSwarm`. Not collective. Parameters ---------- index Index of point to remove See Also -------- petsc.DMSwarmRemovePointAtIndex """ cdef PetscInt cindex = asInt(index) CHKERR( DMSwarmRemovePointAtIndex(self.dm, cindex) ) def copyPoint(self, pi: int, pj: int) -> None: """Copy point pi to point pj in the `DMSwarm`. Not collective. Parameters ---------- pi The index of the point to copy (source). pj The point index where the copy should be located (destination). See Also -------- petsc.DMSwarmCopyPoint """ cdef PetscInt cpi = asInt(pi) cdef PetscInt cpj = asInt(pj) CHKERR( DMSwarmCopyPoint(self.dm, cpi, cpj) ) def getLocalSize(self) -> int: """Return the local length of fields registered. Not collective. See Also -------- petsc.DMSwarmGetLocalSize """ cdef PetscInt size = asInt(0) CHKERR( DMSwarmGetLocalSize(self.dm, &size) ) return toInt(size) def getSize(self) -> int: """Return the total length of fields registered. Collective. See Also -------- petsc.DMSwarmGetSize """ cdef PetscInt size = asInt(0) CHKERR( DMSwarmGetSize(self.dm, &size) ) return toInt(size) def migrate(self, remove_sent_points: bool = False) -> None: """Relocate points defined in the `DMSwarm` to other MPI ranks. Collective. Parameters ---------- remove_sent_points Flag indicating if sent points should be removed from the current MPI rank. See Also -------- petsc.DMSwarmMigrate """ cdef PetscBool remove_pts = asBool(remove_sent_points) CHKERR( DMSwarmMigrate(self.dm, remove_pts) ) def collectViewCreate(self) -> None: """Apply a collection method and gather points in neighbor ranks. Collective. See Also -------- collectViewDestroy, petsc.DMSwarmCollectViewCreate """ CHKERR( DMSwarmCollectViewCreate(self.dm) ) def collectViewDestroy(self) -> None: """Reset the `DMSwarm` to the size prior to calling `collectViewCreate`. Collective. See Also -------- collectViewCreate, petsc.DMSwarmCollectViewDestroy """ CHKERR( DMSwarmCollectViewDestroy(self.dm) ) def setCellDM(self, DM dm) -> None: """Attach a `DM` to a `DMSwarm`. Collective. Parameters ---------- dm The `DM` to attach to the `DMSwarm`. See Also -------- getCellDM, petsc.DMSwarmSetCellDM """ CHKERR( DMSwarmSetCellDM(self.dm, dm.dm) ) def getCellDM(self) -> DM: """Return `DM` cell attached to `DMSwarm`. Collective. See Also -------- setCellDM, petsc.DMSwarmGetCellDM """ cdef PetscDM newdm = NULL CHKERR( DMSwarmGetCellDM(self.dm, &newdm) ) cdef DM dm = subtype_DM(newdm)() dm.dm = newdm CHKERR( PetscINCREF(dm.obj) ) return dm def setType(self, dmswarm_type: Type | str) -> None: """Set particular flavor of `DMSwarm`. Collective. Parameters ---------- dmswarm_type The `DMSwarm` type. See Also -------- petsc.DMSwarmSetType """ cdef PetscDMSwarmType cval = dmswarm_type CHKERR( DMSwarmSetType(self.dm, cval) ) def setPointsUniformCoordinates( self, min: Sequence[float], max: Sequence[float], npoints: Sequence[int], mode: InsertMode | None = None, ) -> Self: """Set point coordinates in a `DMSwarm` on a regular (ijk) grid. Collective. Parameters ---------- min Minimum coordinate values in the x, y, z directions (array of length ``dim``). max Maximum coordinate values in the x, y, z directions (array of length ``dim``). npoints Number of points in each spatial direction (array of length ``dim``). mode Indicates whether to append points to the swarm (`InsertMode.ADD`), or override existing points (`InsertMode.INSERT`). See Also -------- petsc.DMSwarmSetPointsUniformCoordinates """ cdef PetscInt dim = asInt(0) CHKERR( DMGetDimension(self.dm, &dim) ) cdef PetscReal cmin[3] cmin[0] = cmin[1] = cmin[2] = asReal(0.) for i from 0 <= i < dim: cmin[i] = min[i] cdef PetscReal cmax[3] cmax[0] = cmax[1] = cmax[2] = asReal(0.) for i from 0 <= i < dim: cmax[i] = max[i] cdef PetscInt cnpoints[3] cnpoints[0] = cnpoints[1] = cnpoints[2] = asInt(0) for i from 0 <= i < dim: cnpoints[i] = npoints[i] cdef PetscInsertMode cmode = insertmode(mode) CHKERR( DMSwarmSetPointsUniformCoordinates(self.dm, cmin, cmax, cnpoints, cmode) ) return self def setPointCoordinates( self, coordinates: Sequence[float], redundant: bool = False, mode: InsertMode | None = None ) -> None: """Set point coordinates in a `DMSwarm` from a user-defined list. Collective. Parameters ---------- coordinates The coordinate values. redundant If set to `True`, it is assumed that coordinates are only valid on rank 0 and should be broadcast to other ranks. mode Indicates whether to append points to the swarm (`InsertMode.ADD`), or override existing points (`InsertMode.INSERT`). See Also -------- petsc.DMSwarmSetPointCoordinates """ cdef ndarray xyz = iarray(coordinates, NPY_PETSC_REAL) if PyArray_ISFORTRAN(xyz): xyz = PyArray_Copy(xyz) if PyArray_NDIM(xyz) != 2: raise ValueError( ("coordinates must have two dimensions: " "coordinates.ndim=%d") % (PyArray_NDIM(xyz)) ) cdef PetscInt cnpoints = PyArray_DIM(xyz, 0) cdef PetscBool credundant = asBool(redundant) cdef PetscInsertMode cmode = insertmode(mode) cdef PetscReal *coords = PyArray_DATA(xyz) CHKERR( DMSwarmSetPointCoordinates(self.dm, cnpoints, coords, credundant, cmode) ) def insertPointUsingCellDM(self, layoutType: PICLayoutType, fill_param: int) -> None: """Insert point coordinates within each cell. Not collective. Parameters ---------- layout_type Method used to fill each cell with the cell DM. fill_param Parameter controlling how many points per cell are added (the meaning of this parameter is dependent on the layout type). See Also -------- petsc.DMSwarmInsertPointsUsingCellDM """ cdef PetscDMSwarmPICLayoutType clayoutType = layoutType cdef PetscInt cfill_param = asInt(fill_param) CHKERR( DMSwarmInsertPointsUsingCellDM(self.dm, clayoutType, cfill_param) ) def setPointCoordinatesCellwise(self, coordinates: Sequence[float]) -> None: """Insert point coordinates within each cell. Not collective. Point coordinates are defined over the reference cell. Parameters ---------- coordinates The coordinates (defined in the local coordinate system for each cell) to insert. See Also -------- petsc.DMSwarmSetPointCoordinatesCellwise """ cdef ndarray xyz = iarray(coordinates, NPY_PETSC_REAL) if PyArray_ISFORTRAN(xyz): xyz = PyArray_Copy(xyz) if PyArray_NDIM(xyz) != 2: raise ValueError( ("coordinates must have two dimensions: " "coordinates.ndim=%d") % (PyArray_NDIM(xyz)) ) cdef PetscInt cnpoints = PyArray_DIM(xyz, 0) cdef PetscReal *coords = PyArray_DATA(xyz) CHKERR( DMSwarmSetPointCoordinatesCellwise(self.dm, cnpoints, coords) ) def viewFieldsXDMF(self, filename: str, fieldnames: Sequence[str]) -> None: """Write a selection of `DMSwarm` fields to an XDMF3 file. Collective. Parameters ---------- filename The file name of the XDMF file (must have the extension .xmf). fieldnames Array containing the textual names of fields to write. See Also -------- petsc.DMSwarmViewFieldsXDMF """ cdef const char *cval = NULL cdef const char *cfilename = NULL filename = str2bytes(filename, &cfilename) cdef PetscInt cnfields = len(fieldnames) cdef const char** cfieldnames = NULL cdef object tmp = oarray_p(empty_p(cnfields), NULL, &cfieldnames) fieldnames = list(fieldnames) for i from 0 <= i < cnfields: fieldnames[i] = str2bytes(fieldnames[i], &cval) cfieldnames[i] = cval CHKERR( DMSwarmViewFieldsXDMF(self.dm, cfilename, cnfields, cfieldnames ) ) def viewXDMF(self, filename: str) -> None: """Write this `DMSwarm` fields to an XDMF3 file. Collective. Parameters ---------- filename The file name of the XDMF file (must have the extension .xmf). See Also -------- petsc.DMSwarmViewXDMF """ cdef const char *cval = NULL filename = str2bytes(filename, &cval) CHKERR( DMSwarmViewXDMF(self.dm, cval) ) def sortGetAccess(self) -> None: """Setup up a `DMSwarm` point sort context. Not collective. The point sort context is used for efficient traversal of points within a cell. You must call `sortRestoreAccess` when you no longer need access to the sort context. See Also -------- sortRestoreAccess, petsc.DMSwarmSortGetAccess """ CHKERR( DMSwarmSortGetAccess(self.dm) ) def sortRestoreAccess(self) -> None: """Invalidate the `DMSwarm` point sorting context. Not collective. See Also -------- sortGetAccess, petsc.DMSwarmSortRestoreAccess """ CHKERR( DMSwarmSortRestoreAccess(self.dm) ) def sortGetPointsPerCell(self, e: int) -> list[int]: """Create an array of point indices for all points in a cell. Not collective. Parameters ---------- e The index of the cell. See Also -------- petsc.DMSwarmSortGetPointsPerCell """ cdef PetscInt ce = asInt(e) cdef PetscInt cnpoints = asInt(0) cdef PetscInt *cpidlist = NULL cdef list pidlist = [] CHKERR( DMSwarmSortGetPointsPerCell(self.dm, ce, &cnpoints, &cpidlist) ) npoints = asInt(cnpoints) for i from 0 <= i < npoints: pidlist.append(asInt(cpidlist[i])) return pidlist def sortGetNumberOfPointsPerCell(self, e: int) -> int: """Return the number of points in a cell. Not collective. Parameters ---------- e The index of the cell. See Also -------- petsc.DMSwarmSortGetNumberOfPointsPerCell """ cdef PetscInt ce = asInt(e) cdef PetscInt npoints = asInt(0) CHKERR( DMSwarmSortGetNumberOfPointsPerCell(self.dm, ce, &npoints) ) return toInt(npoints) def sortGetIsValid(self) -> bool: """Return whether the sort context is up-to-date. Not collective. Returns the flag associated with a `DMSwarm` point sorting context. See Also -------- petsc.DMSwarmSortGetIsValid """ cdef PetscBool isValid = asBool(False) CHKERR( DMSwarmSortGetIsValid(self.dm, &isValid) ) return toBool(isValid) def sortGetSizes(self) -> tuple[int, int]: """Return the sizes associated with a `DMSwarm` point sorting context. Not collective. Returns ------- ncells : int Number of cells within the sort context. npoints : int Number of points used to create the sort context. See Also -------- petsc.DMSwarmSortGetSizes """ cdef PetscInt ncells = asInt(0) cdef PetscInt npoints = asInt(0) CHKERR( DMSwarmSortGetSizes(self.dm, &ncells, &npoints) ) return (toInt(ncells), toInt(npoints)) def projectFields(self, fieldnames: Sequence[str], vecs: Sequence[Vec], mode: ScatterModeSpec = None) -> None: """Project a set of `DMSwarm` fields onto the cell `DM`. Collective. Parameters ---------- fieldnames The textual names of the swarm fields to project. See Also -------- petsc.DMSwarmProjectFields """ cdef const char *cval = NULL cdef PetscInt cnfields = len(fieldnames) cdef const char** cfieldnames = NULL cdef object tmp = oarray_p(empty_p(cnfields), NULL, &cfieldnames) cdef PetscVec *cfieldvecs cdef object tmp2 = oarray_p(empty_p(cnfields), NULL, &cfieldvecs) cdef PetscScatterMode cmode = scattermode(mode) fieldnames = list(fieldnames) for i from 0 <= i < cnfields: fieldnames[i] = str2bytes(fieldnames[i], &cval) cfieldnames[i] = cval cfieldvecs[i] = ((vecs[i])).vec CHKERR( DMSwarmProjectFields(self.dm, cnfields, cfieldnames, cfieldvecs, cmode) ) return del DMSwarmType del DMSwarmMigrateType del DMSwarmCollectType del DMSwarmPICLayoutType ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/src/petsc4py/PETSc/DMUtils.pyx0000644000175000017500000001300614567251135017732 0ustar00balaybalay cdef class DMInterpolation: """Interpolation on a mesh.""" cdef PetscDMInterpolation dminterp def __cinit__(self): self.dminterp = NULL def __dealloc__(self): self.destroy() def create(self, comm: Comm | None = None) -> Self: """Create a `DMInterpolation` context. Collective. Parameters ---------- comm MPI communicator, defaults to `COMM_SELF`. See Also -------- destroy, petsc.DMInterpolationCreate """ cdef MPI_Comm ccomm = def_Comm(comm, PETSC_COMM_SELF) cdef PetscDMInterpolation newdminterp = NULL CHKERR( DMInterpolationCreate(ccomm, &newdminterp) ) CHKERR( DMInterpolationDestroy(&self.dminterp)) self.dminterp = newdminterp return self def destroy(self) -> Self: """Destroy the `DMInterpolation` context. Collective. See Also -------- create, petsc.DMInterpolationDestroy """ CHKERR( DMInterpolationDestroy(&self.dminterp)) return self def evaluate(self, DM dm, Vec x, Vec v=None) -> Vec: """Calculate interpolated field values at the interpolation points. Collective. Parameters ---------- dm The `DM`. x The local vector containing the field to be interpolated. v A vector capable of holding the interpolated field values. See Also -------- petsc.DMInterpolationEvaluate """ if v is None: v = Vec() if v.vec == NULL: CHKERR( DMInterpolationGetVector(self.dminterp, &v.vec ) ) CHKERR( DMInterpolationEvaluate(self.dminterp, dm.dm, x.vec, v.vec ) ) return v def getCoordinates(self) -> Vec: """Return the coordinates of each interpolation point. Collective. The local vector entries correspond to interpolation points lying on this process, according to the associated DM. See Also -------- petsc.DMInterpolationGetCoordinates """ cdef Vec coords = Vec() CHKERR( DMInterpolationGetCoordinates(self.dminterp, &coords.vec) ) CHKERR( PetscINCREF(coords.obj) ) return coords def getDim(self) -> int: """Return the spatial dimension of the interpolation context. Not collective. See Also -------- setDim, petsc.DMInterpolationGetDim """ cdef PetscInt cdim = 0 CHKERR( DMInterpolationGetDim(self.dminterp, &cdim) ) return toInt(cdim) def getDof(self) -> int: """Return the number of fields interpolated at a point. Not collective. See Also -------- setDof, petsc.DMInterpolationGetDof """ cdef PetscInt cdof = 0 CHKERR( DMInterpolationGetDof(self.dminterp, &cdof) ) return toInt(cdof) def setDim(self, dim: int) -> None: """Set the spatial dimension for the interpolation context. Not collective. Parameters ---------- dim The spatial dimension. See Also -------- getDim, petsc.DMInterpolationSetDim """ cdef PetscInt cdim = asInt(dim) CHKERR( DMInterpolationSetDim(self.dminterp, cdim) ) def setDof(self, dof: int) -> None: """Set the number of fields interpolated at a point. Not collective. Parameters ---------- dof The number of fields. See Also -------- getDof, petsc.DMInterpolationSetDof """ cdef PetscInt cdof = asInt(dof) CHKERR( DMInterpolationSetDof(self.dminterp, cdof) ) def setUp( self, DM dm, redundantPoints: bool = False, ignoreOutsideDomain: bool = False, ) -> None: """Compute spatial indices for point location during interpolation. Collective. Parameters ---------- dm The DM for the function space used for interpolation. redundantPoints If `True`, all processes are passing in the same array of points. Otherwise, points need to be communicated among processes. ignoreOutsideDomain Ignore points outside of the domain if `True`; otherwise, return an error. See Also -------- petsc.DMInterpolationSetUp """ cdef PetscBool credundantPoints = asBool(redundantPoints) cdef PetscBool cignoreOutsideDomain = asBool(ignoreOutsideDomain) CHKERR( DMInterpolationSetUp(self.dminterp, dm.dm, credundantPoints, cignoreOutsideDomain) ) def getVector(self) -> Vec: """Return a `Vec` which can hold all the interpolated field values. Collective. This vector should be returned using `restoreVector`. See Also -------- restoreVector, petsc.DMInterpolationGetVector """ cdef Vec vec = Vec() CHKERR( DMInterpolationGetVector(self.dminterp, &vec.vec)) return vec def restoreVector(self, Vec vec) -> None: """Restore a Vec which can hold all the interpolated field values. Collective. Parameters ---------- vec A vector capable of holding the interpolated field values. See Also -------- getVector, petsc.DMInterpolationRestoreVector """ CHKERR( DMInterpolationRestoreVector(self.dminterp, &vec.vec) ) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/src/petsc4py/PETSc/DS.pyx0000644000175000017500000001504214567251135016721 0ustar00balaybalay# -------------------------------------------------------------------- class DSType(object): BASIC = S_(PETSCDSBASIC) # -------------------------------------------------------------------- cdef class DS(Object): """Discrete System object.""" Type = DSType # def __cinit__(self): self.obj = &self.ds self.ds = NULL def view(self, Viewer viewer=None) -> None: """View a discrete system. Collective. Parameters ---------- viewer A `Viewer` to display the system. See Also -------- petsc.PetscDSView """ cdef PetscViewer vwr = NULL if viewer is not None: vwr = viewer.vwr CHKERR( PetscDSView(self.ds, vwr) ) def destroy(self) -> Self: """Destroy the discrete system. Collective. See Also -------- create, petsc.PetscDSDestroy """ CHKERR( PetscDSDestroy(&self.ds) ) return self def create(self, comm: Comm | None = None) -> Self: """Create an empty DS. Collective. The type can then be set with `setType`. Parameters ---------- comm MPI communicator, defaults to `Sys.getDefaultComm`. See Also -------- setType, destroy, petsc.PetscDSCreate """ cdef MPI_Comm ccomm = def_Comm(comm, PETSC_COMM_DEFAULT) cdef PetscDS newds = NULL CHKERR( PetscDSCreate(ccomm, &newds) ) CHKERR( PetscCLEAR(self.obj) ); self.ds = newds return self def setType(self, ds_type: Type | str) -> None: """Build a particular type of a discrete system. Collective. Parameters ---------- ds_type The type of the discrete system. See Also -------- getType, petsc.PetscDSSetType """ cdef PetscDSType cval = NULL ds_type = str2bytes(ds_type, &cval) CHKERR( PetscDSSetType(self.ds, cval) ) def getType(self) -> str: """Return the type of the discrete system. Not collective. See Also -------- setType, petsc.PetscDSGetType """ cdef PetscDSType cval = NULL CHKERR( PetscDSGetType(self.ds, &cval) ) return bytes2str(cval) def setFromOptions(self) -> None: """Set parameters in a `DS` from the options database. Collective. See Also -------- petsc_options, petsc.PetscDSSetFromOptions """ CHKERR( PetscDSSetFromOptions(self.ds) ) def setUp(self) -> Self: """Construct data structures for the discrete system. Collective. See Also -------- petsc.PetscDSSetUp """ CHKERR( PetscDSSetUp(self.ds) ) return self # def getSpatialDimension(self) -> int: """Return the spatial dimension of the DS. Not collective. The spatial dimension of the `DS` is the topological dimension of the discretizations. See Also -------- petsc.PetscDSGetSpatialDimension """ cdef PetscInt dim = 0 CHKERR( PetscDSGetSpatialDimension(self.ds, &dim) ) return toInt(dim) def getCoordinateDimension(self) -> int: """Return the coordinate dimension of the DS. Not collective. The coordinate dimension of the `DS` is the dimension of the space into which the discretiaztions are embedded. See Also -------- petsc.PetscDSGetCoordinateDimension """ cdef PetscInt dim = 0 CHKERR( PetscDSGetCoordinateDimension(self.ds, &dim) ) return toInt(dim) def getNumFields(self) -> int: """Return the number of fields in the DS. Not collective. See Also -------- petsc.PetscDSGetNumFields """ cdef PetscInt nf = 0 CHKERR( PetscDSGetNumFields(self.ds, &nf) ) return toInt(nf) def getFieldIndex(self, Object disc) -> int: """Return the index of the given field. Not collective. Parameters ---------- disc The discretization object. See Also -------- petsc.PetscDSGetFieldIndex """ cdef PetscInt field = 0 CHKERR( PetscDSGetFieldIndex(self.ds, disc.obj[0], &field) ) return toInt(field) def getTotalDimensions(self) -> int: """Return the total size of the approximation space for this system. Not collective. See Also -------- petsc.PetscDSGetTotalDimension """ cdef PetscInt tdim = 0 CHKERR( PetscDSGetTotalDimension(self.ds, &tdim) ) return toInt(tdim) def getTotalComponents(self) -> int: """Return the total number of components in this system. Not collective. See Also -------- petsc.PetscDSGetTotalComponents """ cdef PetscInt tcmp = 0 CHKERR( PetscDSGetTotalComponents(self.ds, &tcmp) ) return toInt(tcmp) def getDimensions(self) -> ArrayInt: """Return the size of the space for each field on an evaluation point. Not collective. See Also -------- petsc.PetscDSGetDimensions """ cdef PetscInt nf = 0, *dims = NULL CHKERR( PetscDSGetNumFields(self.ds, &nf) ) CHKERR( PetscDSGetDimensions(self.ds, &dims) ) return array_i(nf, dims) def getComponents(self) -> ArrayInt: """Return the number of components for each field on an evaluation point. Not collective. See Also -------- petsc.PetscDSGetComponents """ cdef PetscInt nf = 0, *cmps = NULL CHKERR( PetscDSGetNumFields(self.ds, &nf) ) CHKERR( PetscDSGetComponents(self.ds, &cmps) ) return array_i(nf, cmps) def setDiscretisation(self, f: int, disc: Object) -> None: """Set the discretization object for the given field. Not collective. Parameters ---------- f The field number. disc The discretization object. See Also -------- petsc.PetscDSSetDiscretization """ cdef PetscInt cf = asInt(f) cdef FE fe = disc CHKERR( PetscDSSetDiscretization(self.ds, cf, fe.fe) ) # -------------------------------------------------------------------- del DSType # -------------------------------------------------------------------- ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/src/petsc4py/PETSc/DT.pyx0000644000175000017500000001032114567251135016715 0ustar00balaybalay# -------------------------------------------------------------------- cdef class Quad(Object): """Quadrature rule for integration.""" def __cinit__(self): self.obj = &self.quad self.quad = NULL def view(self, Viewer viewer=None) -> None: """View a `Quad` object. Collective. Parameters ---------- viewer A `Viewer` to display the graph. See Also -------- petsc.PetscQuadratureView """ cdef PetscViewer vwr = NULL if viewer is not None: vwr = viewer.vwr CHKERR( PetscQuadratureView(self.quad, vwr) ) def create(self, comm: Comm | None = None) -> Self: """Create a `Quad` object. Collective. Parameters ---------- comm MPI communicator, defaults to `Sys.getDefaultComm`. See Also -------- petsc.PetscQuadratureCreate """ cdef MPI_Comm ccomm = def_Comm(comm, PETSC_COMM_DEFAULT) cdef PetscQuadrature newquad = NULL CHKERR( PetscQuadratureCreate(ccomm, &newquad) ) CHKERR( PetscCLEAR(self.obj) ); self.quad = newquad return self def duplicate(self) -> Quad: """Create a deep copy of the `Quad` object. Collective. See Also -------- petsc.PetscQuadratureDuplicate """ cdef Quad newquad = Quad() CHKERR( PetscQuadratureDuplicate(self.quad, &newquad.quad) ) return newquad def destroy(self) -> Self: """Destroy the `Quad` object. Collective. See Also -------- petsc.PetscQuadratureDestroy """ CHKERR( PetscQuadratureDestroy(&self.quad) ) return self def getData(self) -> tuple(ArrayReal, ArrayReal): """Return the data defining the `Quad`. Not collective. Returns ------- points : ArrayReal The coordinates of the quadrature points. weights : ArrayReal The quadrature weights. See Also -------- petsc.PetscQuadratureGetData """ cdef PetscInt cdim = 0 cdef PetscInt cnc = 0 cdef PetscInt cnpoints = 0 cdef const PetscReal *cpoints = NULL cdef const PetscReal *cweights = NULL CHKERR( PetscQuadratureGetData(self.quad, &cdim, &cnc, &cnpoints, &cpoints, &cweights)) return array_r(cnpoints*cdim, cpoints), array_r(cnpoints*cnc, cweights) # FIXME: # def setData(???) def getNumComponents(self) -> int: """Return the number of components for functions to be integrated. Not collective. See Also -------- setNumComponents, petsc.PetscQuadratureGetNumComponents """ cdef PetscInt cnc = 0 CHKERR( PetscQuadratureGetNumComponents(self.quad, &cnc) ) return toInt(cnc) def setNumComponents(self, nc: int) -> None: """Return the number of components for functions to be integrated. Not collective. Parameters ---------- nc The number of components. See Also -------- getNumComponents, petsc.PetscQuadratureSetNumComponents """ cdef PetscInt cnc = asInt(nc) CHKERR( PetscQuadratureSetNumComponents(self.quad, cnc) ) def getOrder(self) -> int: """Return the order of the method in the `Quad`. Not collective. See Also -------- setOrder, petsc.PetscQuadratureGetOrder """ cdef PetscInt corder = 0 CHKERR( PetscQuadratureGetOrder(self.quad, &corder)) return toInt(corder) def setOrder(self, order: int) -> None: """Set the order of the method in the `Quad`. Not collective. Parameters ---------- order The order of the quadrature, i.e. the highest degree polynomial that is exactly integrated. See Also -------- getOrder, petsc.PetscQuadratureSetOrder """ cdef PetscInt corder = asInt(order) CHKERR( PetscQuadratureSetOrder(self.quad, corder)) # -------------------------------------------------------------------- ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/src/petsc4py/PETSc/Device.pyx0000644000175000017500000003151614567251135017616 0ustar00balaybalay# -------------------------------------------------------------------- class staticproperty(property): def __get__(self, *args, **kwargs): return self.fget.__get__(*args, **kwargs)() cdef object make_enum_class(str class_name, str class_docstring, tuple args): cdef dict enum2str = {} cdef dict attrs = {} for name, c_enum in args: enum2str[c_enum] = name attrs[name] = c_enum attrs['__enum2str'] = enum2str attrs['__doc__'] = class_docstring return type(class_name, (object, ), attrs) DeviceType = make_enum_class( "DeviceType", """The type of device. See Also -------- Device, Device.create, Device.getDeviceType, Device.type, petsc.PetscDeviceType """, ( ("HOST" , PETSC_DEVICE_HOST), ("CUDA" , PETSC_DEVICE_CUDA), ("HIP" , PETSC_DEVICE_HIP), ("SYCL" , PETSC_DEVICE_SYCL), ("DEFAULT" , staticproperty(lambda *_,**__: PETSC_DEVICE_DEFAULT())) ) ) StreamType = make_enum_class( "StreamType", """The type of stream. See Also -------- DeviceContext, DeviceContext.getStreamType, DeviceContext.setStreamType, petsc.PetscStreamType """, ( ("GLOBAL_BLOCKING" , PETSC_STREAM_GLOBAL_BLOCKING), ("DEFAULT_BLOCKING" , PETSC_STREAM_DEFAULT_BLOCKING), ("GLOBAL_NONBLOCKING" , PETSC_STREAM_GLOBAL_NONBLOCKING), ) ) DeviceJoinMode = make_enum_class( "DeviceJoinMode", """The type of join to perform. See Also -------- DeviceContext, DeviceContext.join, DeviceContext.fork, petsc.PetscDeviceContextJoinMode """, ( ("DESTROY" , PETSC_DEVICE_CONTEXT_JOIN_DESTROY), ("SYNC" , PETSC_DEVICE_CONTEXT_JOIN_SYNC), ("NO_SYNC" , PETSC_DEVICE_CONTEXT_JOIN_NO_SYNC), ) ) # -------------------------------------------------------------------- cdef class Device: """The device object. Represents a handle to an accelerator (which may be the host). See Also -------- DeviceContext, petsc.PetscDevice """ Type = DeviceType def __cinit__(self): self.device = NULL def __dealloc__(self): self.destroy() @classmethod def create(cls, dtype: Type | None = None, device_id: int = DECIDE) -> Device: """Create a device object. Not collective. Parameters ---------- dtype The type of device to create (or `None` for the default). device_id The numeric id of the device to create. See Also -------- destroy, petsc.PetscDeviceCreate """ cdef PetscInt cdevice_id = asInt(device_id) cdef PetscDeviceType cdevice_type = asDeviceType(dtype if dtype is not None else cls.Type.DEFAULT) cdef Device device = cls() CHKERR(PetscDeviceCreate(cdevice_type, cdevice_id, &device.device)) return device def destroy(self) -> None: """Destroy a device object. Not collective. See Also -------- create, petsc.PetscDeviceDestroy """ CHKERR(PetscDeviceDestroy(&self.device)) def configure(self) -> None: """Configure and setup a device object. Not collective. See Also -------- create, petsc.PetscDeviceConfigure """ CHKERR(PetscDeviceConfigure(self.device)) def view(self, Viewer viewer=None) -> None: """View a device object. Collective. Parameters ---------- viewer A `Viewer` instance or `None` for the default viewer. See Also -------- petsc.PetscDeviceView """ cdef PetscViewer vwr = NULL if viewer is not None: vwr = viewer.vwr CHKERR(PetscDeviceView(self.device, vwr)) def getDeviceType(self) -> str: """Return the type of the device. Not collective. See Also -------- type, petsc.PetscDeviceGetType """ cdef PetscDeviceType cdtype CHKERR(PetscDeviceGetType(self.device, &cdtype)) return toDeviceType(cdtype) def getDeviceId(self) -> int: """Return the device id. Not collective. See Also -------- create, petsc.PetscDeviceGetDeviceId """ cdef PetscInt cdevice_id = 0 CHKERR(PetscDeviceGetDeviceId(self.device, &cdevice_id)) return toInt(cdevice_id) @staticmethod def setDefaultType(device_type: Type | str) -> None: """Set the device type to be used as the default in subsequent calls to `create`. Not collective. See Also -------- create, petsc.PetscDeviceSetDefaultDeviceType """ cdef PetscDeviceType cdevice_type = asDeviceType(device_type) CHKERR(PetscDeviceSetDefaultDeviceType(cdevice_type)) property type: """The device type.""" def __get__(self) -> str: return self.getDeviceType() property device_id: """The device id.""" def __get__(self) -> int: return self.getDeviceId() # -------------------------------------------------------------------- cdef class DeviceContext(Object): """DeviceContext object. Represents an abstract handle to a device context. See Also -------- Device, petsc.PetscDeviceContext """ JoinMode = DeviceJoinMode StreamType = StreamType def __cinit__(self): self.obj = &self.dctx self.dctx = NULL def __dealloc__(self): self.destroy() @classmethod def create(cls) -> DeviceContext: """Create an empty DeviceContext. Not collective. See Also -------- Device, petsc.PetscDeviceContextCreate """ cdef DeviceContext dctx = cls() CHKERR(PetscDeviceContextCreate(&dctx.dctx)) return dctx def getStreamType(self) -> str: """Return the `StreamType`. Not collective. See Also -------- stream_type, setStreamType, petsc.PetscDeviceContextGetStreamType """ cdef PetscStreamType cstream_type = PETSC_STREAM_DEFAULT_BLOCKING CHKERR(PetscDeviceContextGetStreamType(self.dctx, &cstream_type)) return toStreamType(cstream_type) def setStreamType(self, stream_type: StreamType | str) -> None: """Set the `StreamType`. Not collective. Parameters ---------- stream_type The type of stream to set See Also -------- stream_type, getStreamType, petsc.PetscDeviceContextSetStreamType """ cdef PetscStreamType cstream_type = asStreamType(stream_type) CHKERR(PetscDeviceContextSetStreamType(self.dctx, cstream_type)) def getDevice(self) -> Device: """Get the `Device` which this instance is attached to. Not collective. See Also -------- setDevice, device, Device, petsc.PetscDeviceContextGetDevice """ cdef PetscDevice device = NULL CHKERR(PetscDeviceContextGetDevice(self.dctx, &device)) return PyPetscDevice_New(device) def setDevice(self, Device device not None) -> None: """Set the `Device` which this `DeviceContext` is attached to. Collective. Parameters ---------- device The `Device` to which this instance is attached to. See Also -------- getDevice, device, Device, petsc.PetscDeviceContextSetDevice """ cdef PetscDevice cdevice = PyPetscDevice_Get(device) CHKERR(PetscDeviceContextSetDevice(self.dctx, cdevice)) def setUp(self) -> None: """Set up the internal data structures for using the device context. Not collective. See Also -------- create, petsc.PetscDeviceContextSetUp """ CHKERR(PetscDeviceContextSetUp(self.dctx)) def duplicate(self) -> DeviceContext: """Duplicate a the device context. Not collective. See Also -------- create, petsc.PetscDeviceContextDuplicate """ cdef PetscDeviceContext octx = NULL CHKERR(PetscDeviceContextDuplicate(self.dctx, &octx)) return PyPetscDeviceContext_New(octx) def idle(self) -> bool: """Return whether the underlying stream for the device context is idle. Not collective. See Also -------- synchronize, petsc.PetscDeviceContextQueryIdle """ cdef PetscBool is_idle = PETSC_FALSE CHKERR(PetscDeviceContextQueryIdle(self.dctx, &is_idle)) return toBool(is_idle) def waitFor(self, other: DeviceContext | None) -> None: """Make this instance wait for ``other``. Not collective. Parameters ---------- other The other `DeviceContext` to wait for See Also -------- fork, join, petsc.PetscDeviceContextWaitForContext """ cdef PetscDeviceContext cother = NULL if other is not None: cother = PyPetscDeviceContext_Get(other) CHKERR(PetscDeviceContextWaitForContext(self.dctx, cother)) def fork(self, n: int, stream_type: DeviceContext.StreamType | str | None = None) -> list[DeviceContext]: """Create multiple device contexts which are all logically dependent on this one. Not collective. Parameters ---------- n The number of device contexts to create. stream_type The type of stream of the forked device context. See Also -------- join, waitFor, petsc.PetscDeviceContextFork """ cdef PetscDeviceContext *subctx = NULL cdef PetscStreamType cstream_type = PETSC_STREAM_DEFAULT_BLOCKING cdef PetscInt cn = asInt(n) try: if stream_type is None: CHKERR(PetscDeviceContextFork(self.dctx, cn, &subctx)) else: cstream_type = asStreamType(stream_type) CHKERR(PetscDeviceContextForkWithStreamType(self.dctx, cstream_type, cn, &subctx)) return [PyPetscDeviceContext_New(subctx[i]) for i in range(cn)] finally: CHKERR(PetscFree(subctx)) def join(self, join_mode: DeviceJoinMode | str, py_sub_ctxs: list[DeviceContext]) -> None: """Join a set of device contexts on this one. Not collective. Parameters ---------- join_mode The type of join to perform. py_sub_ctxs The list of device contexts to join. See Also -------- fork, waitFor, petsc.PetscDeviceContextJoin """ cdef PetscDeviceContext *np_subctx_copy = NULL cdef PetscDeviceContext *np_subctx = NULL cdef PetscInt nsub = 0 cdef PetscDeviceContextJoinMode cjoin_mode = asJoinMode(join_mode) tmp = oarray_p(py_sub_ctxs, &nsub, &np_subctx) try: CHKERR(PetscMalloc((nsub) * sizeof(PetscDeviceContext *), &np_subctx_copy)) CHKERR(PetscMemcpy(np_subctx_copy, np_subctx, (nsub) * sizeof(PetscDeviceContext *))) CHKERR(PetscDeviceContextJoin(self.dctx, nsub, cjoin_mode, &np_subctx_copy)) finally: CHKERR(PetscFree(np_subctx_copy)) if cjoin_mode == PETSC_DEVICE_CONTEXT_JOIN_DESTROY: for i in range(nsub): py_sub_ctxs[i] = None def synchronize(self) -> None: """Synchronize a device context. Not collective. Notes ----- The underlying stream is considered idle after this routine returns, i.e. `idle` will return ``True``. See Also -------- idle, petsc.PetscDeviceContextSynchronize """ CHKERR(PetscDeviceContextSynchronize(self.dctx)) def setFromOptions(self, comm: Comm | None = None) -> None: """Configure the `DeviceContext` from the options database. Collective. Parameters ---------- comm MPI communicator, defaults to `Sys.getDefaultComm`. See Also -------- Sys.getDefaultComm, petsc.PetscDeviceContextSetFromOptions """ cdef MPI_Comm ccomm = def_Comm(comm, PETSC_COMM_DEFAULT) CHKERR(PetscDeviceContextSetFromOptions(ccomm, self.dctx)) @staticmethod def getCurrent() -> DeviceContext: """Return the current device context. Not collective. See Also -------- current, setCurrent, petsc.PetscDeviceContextGetCurrentContext """ cdef PetscDeviceContext dctx = NULL CHKERR(PetscDeviceContextGetCurrentContext(&dctx)) return PyPetscDeviceContext_New(dctx) @staticmethod def setCurrent(dctx: DeviceContext | None) -> None: """Set the current device context. Not collective. Parameters ---------- dctx The `DeviceContext` to set as current (or `None` to use the default context). See Also -------- current, getCurrent, petsc.PetscDeviceContextSetCurrentContext """ cdef PetscDeviceContext cdctx = NULL if dctx is not None: cdctx = PyPetscDeviceContext_Get(dctx) CHKERR(PetscDeviceContextSetCurrentContext(cdctx)) property stream_type: """The stream type.""" def __get__(self) -> str: return self.getStreamType() def __set__(self, stype: StreamType | str) -> None: self.setStreamType(stype) property device: """The device associated to the device context.""" def __get__(self) -> Device: return self.getDevice() def __set__(self, Device device) -> None: self.setDevice(device) property current: """The current global device context.""" def __get__(self) -> DeviceContext: return self.getCurrent() def __set__(self, dctx: DeviceContext | None) -> None: self.setCurrent(dctx) # -------------------------------------------------------------------- del DeviceType del DeviceJoinMode del StreamType del staticproperty ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/src/petsc4py/PETSc/Error.pyx0000644000175000017500000000177114567251135017510 0ustar00balaybalay# -------------------------------------------------------------------- class Error(RuntimeError): """PETSc Error. Attributes ---------- ierr : int PETSc error code. """ _traceback_ = [] def __init__(self, int ierr=0): self.ierr = ierr RuntimeError.__init__(self, self.ierr) def __bool__(self): cdef int ierr = self.ierr return ierr != 0 def __repr__(self): return 'PETSc.Error(%d)' % self.ierr def __str__(self): cdef int csize=1, crank=0 if not (PetscFinalizeCalled): MPI_Comm_size(PETSC_COMM_WORLD, &csize) MPI_Comm_rank(PETSC_COMM_WORLD, &crank) width, rank = len(str(csize-1)), crank tblist = ['error code %d' % self.ierr] for entry in self._traceback_: tbline = '[%*d] %s' % (width, rank, entry) tblist.append(tbline) return '\n'.join(tblist) # -------------------------------------------------------------------- ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/src/petsc4py/PETSc/FE.pyx0000644000175000017500000003106514567251135016710 0ustar00balaybalay# -------------------------------------------------------------------- class FEType(object): BASIC = S_(PETSCFEBASIC) OPENCL = S_(PETSCFEOPENCL) COMPOSITE = S_(PETSCFECOMPOSITE) # -------------------------------------------------------------------- cdef class FE(Object): """A PETSc object that manages a finite element space.""" Type = FEType def __cinit__(self): self.obj = &self.fe self.fe = NULL def view(self, Viewer viewer=None) -> None: """View a `FE` object. Collective. Parameters ---------- viewer A `Viewer` to display the graph. See Also -------- petsc.PetscFEView """ cdef PetscViewer vwr = NULL if viewer is not None: vwr = viewer.vwr CHKERR( PetscFEView(self.fe, vwr) ) def destroy(self) -> Self: """Destroy the `FE` object. Collective. See Also -------- petsc.PetscFEDestroy """ CHKERR( PetscFEDestroy(&self.fe) ) return self def create(self, comm: Comm | None = None) -> Self: """Create an empty `FE` object. Collective. The type can then be set with `setType`. Parameters ---------- comm MPI communicator, defaults to `Sys.getDefaultComm`. See Also -------- setType, petsc.PetscFECreate """ cdef MPI_Comm ccomm = def_Comm(comm, PETSC_COMM_DEFAULT) cdef PetscFE newfe = NULL CHKERR( PetscFECreate(ccomm, &newfe) ) CHKERR( PetscCLEAR(self.obj) ); self.fe = newfe return self def createDefault( self, dim: int, nc: int, isSimplex: bool, qorder: int = DETERMINE, prefix: str = None, comm: Comm | None = None ) -> Self: """Create a `FE` for basic FEM computation. Collective. Parameters ---------- dim The spatial dimension. nc The number of components. isSimplex Flag for simplex reference cell, otherwise it's a tensor product. qorder The quadrature order or `DETERMINE` to use `Space` polynomial degree. prefix The options prefix, or `None`. comm MPI communicator, defaults to `Sys.getDefaultComm`. See Also -------- petsc.PetscFECreateDefault """ cdef MPI_Comm ccomm = def_Comm(comm, PETSC_COMM_DEFAULT) cdef PetscFE newfe = NULL cdef PetscInt cdim = asInt(dim) cdef PetscInt cnc = asInt(nc) cdef PetscInt cqorder = asInt(qorder) cdef PetscBool cisSimplex = asBool(isSimplex) cdef const char *cprefix = NULL if prefix: prefix = str2bytes(prefix, &cprefix) CHKERR( PetscFECreateDefault(ccomm, cdim, cnc, cisSimplex, cprefix, cqorder, &newfe)) CHKERR( PetscCLEAR(self.obj) ); self.fe = newfe return self def createLagrange( self, dim: int, nc: int, isSimplex: bool, k: int, qorder: int = DETERMINE, comm: Comm | None = None ) -> Self: """Create a `FE` for the basic Lagrange space of degree k. Collective. Parameters ---------- dim The spatial dimension. nc The number of components. isSimplex Flag for simplex reference cell, otherwise it's a tensor product. k The degree of the space. qorder The quadrature order or `DETERMINE` to use `Space` polynomial degree. comm MPI communicator, defaults to `Sys.getDefaultComm`. See Also -------- petsc.PetscFECreateLagrange """ cdef MPI_Comm ccomm = def_Comm(comm, PETSC_COMM_DEFAULT) cdef PetscFE newfe = NULL cdef PetscInt cdim = asInt(dim) cdef PetscInt cnc = asInt(nc) cdef PetscInt ck = asInt(k) cdef PetscInt cqorder = asInt(qorder) cdef PetscBool cisSimplex = asBool(isSimplex) CHKERR( PetscFECreateLagrange(ccomm, cdim, cnc, cisSimplex, ck, cqorder, &newfe)) CHKERR( PetscCLEAR(self.obj) ); self.fe = newfe return self def getQuadrature(self) -> Quad: """Return the `Quad` used to calculate inner products. Not collective. See Also -------- setQuadrature, petsc.PetscFEGetQuadrature """ cdef Quad quad = Quad() CHKERR( PetscFEGetQuadrature(self.fe, &quad.quad) ) return quad def getDimension(self) -> int: """Return the dimension of the finite element space on a cell. Not collective. See Also -------- petsc.PetscFEGetDimension """ cdef PetscInt cdim = 0 CHKERR( PetscFEGetDimension(self.fe, &cdim) ) return toInt(cdim) def getSpatialDimension(self) -> int: """Return the spatial dimension of the element. Not collective. See Also -------- petsc.PetscFEGetSpatialDimension """ cdef PetscInt csdim = 0 CHKERR( PetscFEGetSpatialDimension(self.fe, &csdim) ) return toInt(csdim) def getNumComponents(self) -> int: """Return the number of components in the element. Not collective. See Also -------- setNumComponents, petsc.PetscFEGetNumComponents """ cdef PetscInt comp = 0 CHKERR( PetscFEGetNumComponents(self.fe, &comp) ) return toInt(comp) def setNumComponents(self, comp: int) -> None: """Set the number of field components in the element. Not collective. Parameters ---------- comp The number of field components. See Also -------- getNumComponents, petsc.PetscFESetNumComponents """ cdef PetscInt ccomp = asInt(comp) CHKERR( PetscFESetNumComponents(self.fe, comp) ) def getNumDof(self) -> ndarray: """Return the number of DOFs. Not collective. Return the number of DOFs (dual basis vectors) associated with mesh points on the reference cell of a given dimension. See Also -------- petsc.PetscFEGetNumDof """ cdef const PetscInt *numDof = NULL cdef PetscInt cdim = 0 CHKERR( PetscFEGetDimension(self.fe, &cdim) ) CHKERR( PetscFEGetNumDof(self.fe, &numDof) ) return array_i(cdim, numDof) def getTileSizes(self) -> tuple(int, int, int, int): """Return the tile sizes for evaluation. Not collective. Returns ------- blockSize : int The number of elements in a block. numBlocks : int The number of blocks in a batch. batchSize : int The number of elements in a batch. numBatches : int The number of batches in a chunk. See Also -------- setTileSizes, petsc.PetscFEGetTileSizes """ cdef PetscInt blockSize = 0, numBlocks = 0 cdef PetscInt batchSize = 0, numBatches = 0 CHKERR( PetscFEGetTileSizes(self.fe, &blockSize, &numBlocks, &batchSize, &numBatches) ) return toInt(blockSize), toInt(numBlocks), toInt(batchSize), toInt(numBatches) def setTileSizes( self, blockSize: int, numBlocks: int, batchSize: int, numBatches: int, ) -> None: """Set the tile sizes for evaluation. Not collective. Parameters ---------- blockSize The number of elements in a block. numBlocks The number of blocks in a batch. batchSize The number of elements in a batch. numBatches The number of batches in a chunk. See Also -------- getTileSizes, petsc.PetscFESetTileSizes """ cdef PetscInt cblockSize = asInt(blockSize), cnumBlocks = asInt(numBlocks) cdef PetscInt cbatchSize = asInt(batchSize), cnumBatches = asInt(numBatches) CHKERR( PetscFESetTileSizes(self.fe, blockSize, numBlocks, batchSize, numBatches) ) def getFaceQuadrature(self) -> Quad: """Return the `Quad` used to calculate inner products on faces. Not collective. See Also -------- setFaceQuadrature, petsc.PetscFEGetFaceQuadrature """ cdef Quad quad = Quad() CHKERR( PetscFEGetFaceQuadrature(self.fe, &quad.quad) ) return quad def setQuadrature(self, Quad quad) -> Self: """Set the `Quad` used to calculate inner products. Not collective. Parameters ---------- quad The `Quad` object. See Also -------- getQuadrature, petsc.PetscFESetQuadrature """ CHKERR( PetscFESetQuadrature(self.fe, quad.quad) ) return self def setFaceQuadrature(self, Quad quad) -> Quad: """Set the `Quad` used to calculate inner products on faces. Not collective. Parameters ---------- quad The `Quad` object. See Also -------- getFaceQuadrature, petsc.PetscFESetFaceQuadrature """ CHKERR( PetscFESetFaceQuadrature(self.fe, quad.quad) ) return self def setType(self, fe_type: Type | str) -> Self: """Build a particular `FE`. Collective. Parameters ---------- fe_type The kind of FEM space. See Also -------- petsc.PetscFESetType """ cdef PetscFEType cval = NULL fe_type = str2bytes(fe_type, &cval) CHKERR( PetscFESetType(self.fe, cval) ) return self def getBasisSpace(self) -> Space: """Return the `Space` used for the approximation of the `FE` solution. Not collective. See Also -------- setBasisSpace, petsc.PetscFEGetBasisSpace """ cdef Space sp = Space() CHKERR( PetscFEGetBasisSpace(self.fe, &sp.space ) ) return sp def setBasisSpace(self, Space sp) -> None: """Set the `Space` used for the approximation of the solution. Not collective. Parameters ---------- sp The `Space` object. See Also -------- getBasisSpace, petsc.PetscFESetBasisSpace """ CHKERR( PetscFESetBasisSpace(self.fe, sp.space ) ) def setFromOptions(self) -> None: """Set parameters in a `FE` from the options database. Collective. See Also -------- petsc_options, petsc.PetscFESetFromOptions """ CHKERR( PetscFESetFromOptions(self.fe) ) def setUp(self) -> None: """Construct data structures for the `FE` after the `Type` has been set. Collective. See Also -------- petsc.PetscFESetUp """ CHKERR( PetscFESetUp(self.fe) ) def getDualSpace(self) -> DualSpace: """Return the `DualSpace` used to define the inner product for the `FE`. Not collective. See Also -------- setDualSpace, DualSpace, petsc.PetscFEGetDualSpace """ cdef DualSpace dspace = DualSpace() CHKERR( PetscFEGetDualSpace(self.fe, &dspace.dualspace) ) return dspace def setDualSpace(self, DualSpace dspace) -> None: """Set the `DualSpace` used to define the inner product. Not collective. Parameters ---------- dspace The `DualSpace` object. See Also -------- getDualSpace, DualSpace, petsc.PetscFESetDualSpace """ CHKERR( PetscFESetDualSpace(self.fe, dspace.dualspace) ) def viewFromOptions(self, name: str, Object obj=None) -> None: """View from a `FE` based on values in the options database. Collective. Parameters ---------- name Command line option name. obj Optional object that provides the options prefix. See Also -------- petsc_options, petsc.PetscFEViewFromOptions """ cdef const char *cname = NULL _ = str2bytes(name, &cname) cdef PetscObject cobj = NULL if obj is not None: cobj = obj.obj[0] CHKERR( PetscFEViewFromOptions(self.fe, cobj, cname) ) # -------------------------------------------------------------------- del FEType # -------------------------------------------------------------------- ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/src/petsc4py/PETSc/IS.pyx0000644000175000017500000012212214567251135016724 0ustar00balaybalay# -------------------------------------------------------------------- class ISType(object): GENERAL = S_(ISGENERAL) BLOCK = S_(ISBLOCK) STRIDE = S_(ISSTRIDE) # -------------------------------------------------------------------- cdef class IS(Object): """A collection of indices. IS objects are used to index into vectors and matrices and to set up vector scatters. See Also -------- petsc.IS """ Type = ISType # def __cinit__(self): self.obj = &self.iset self.iset = NULL # buffer interface (PEP 3118) def __getbuffer__(self, Py_buffer *view, int flags): cdef _IS_buffer buf = _IS_buffer(self) buf.acquirebuffer(view, flags) def __releasebuffer__(self, Py_buffer *view): cdef _IS_buffer buf = <_IS_buffer>(view.obj) buf.releasebuffer(view) self # unused # 'with' statement (PEP 343) def __enter__(self): cdef _IS_buffer buf = _IS_buffer(self) self.set_attr('__buffer__', buf) return buf.enter() def __exit__(self, *exc): cdef _IS_buffer buf = self.get_attr('__buffer__') self.set_attr('__buffer__', None) return buf.exit() # def view(self, Viewer viewer=None) -> None: """Display the index set. Collective. Parameters ---------- viewer Viewer used to display the IS. See Also -------- petsc.ISView """ cdef PetscViewer cviewer = NULL if viewer is not None: cviewer = viewer.vwr CHKERR( ISView(self.iset, cviewer) ) def destroy(self) -> Self: """Destroy the index set. Collective. See Also -------- petsc.ISDestroy """ CHKERR( ISDestroy(&self.iset) ) return self def create(self, comm: Comm | None = None) -> Self: """Create an IS. Collective. Parameters ---------- comm MPI communicator, defaults to `Sys.getDefaultComm`. See Also -------- petsc.ISCreate """ cdef MPI_Comm ccomm = def_Comm(comm, PETSC_COMM_DEFAULT) cdef PetscIS newiset = NULL CHKERR( ISCreate(ccomm, &newiset) ) CHKERR( PetscCLEAR(self.obj) ); self.iset = newiset return self def setType(self, is_type: IS.Type | str) -> None: """Set the type of the index set. Collective. Parameters ---------- is_type The index set type. See Also -------- petsc.ISSetType """ cdef PetscISType cval = NULL is_type = str2bytes(is_type, &cval) CHKERR( ISSetType(self.iset, cval) ) def getType(self) -> str: """Return the index set type associated with the IS. Not collective. See Also -------- petsc.ISGetType """ cdef PetscISType cval = NULL CHKERR( ISGetType(self.iset, &cval) ) return bytes2str(cval) def createGeneral( self, indices: Sequence[int], comm: Comm | None = None ) -> Self: """Create an IS with indices. Collective. Parameters ---------- indices Integer array. comm MPI communicator, defaults to `Sys.getDefaultComm`. See Also -------- petsc.ISCreateGeneral """ cdef MPI_Comm ccomm = def_Comm(comm, PETSC_COMM_DEFAULT) cdef PetscInt nidx = 0, *idx = NULL cdef PetscCopyMode cm = PETSC_COPY_VALUES cdef PetscIS newiset = NULL indices = iarray_i(indices, &nidx, &idx) CHKERR( ISCreateGeneral(ccomm, nidx, idx, cm, &newiset) ) CHKERR( PetscCLEAR(self.obj) ); self.iset = newiset return self def createBlock( self, bsize: int, indices: Sequence[int], comm: Comm | None = None ) -> Self: """Create a blocked index set. Collective. Parameters ---------- bsize Block size. indices Integer array of indices. comm MPI communicator, defaults to `Sys.getDefaultComm`. See Also -------- petsc.ISCreateBlock """ cdef MPI_Comm ccomm = def_Comm(comm, PETSC_COMM_DEFAULT) cdef PetscInt bs = asInt(bsize) cdef PetscInt nidx = 0, *idx = NULL cdef PetscCopyMode cm = PETSC_COPY_VALUES cdef PetscIS newiset = NULL indices = iarray_i(indices, &nidx, &idx) CHKERR( ISCreateBlock(ccomm, bs, nidx, idx, cm, &newiset) ) CHKERR( PetscCLEAR(self.obj) ); self.iset = newiset return self def createStride( self, size: int, first: int=0, step: int=0, comm: Comm | None = None ) -> Self: """Create an index set consisting of evenly spaced values. Collective. Parameters ---------- size The length of the locally owned portion of the index set. first The first element of the index set. step The difference between adjacent indices. comm MPI communicator, defaults to `Sys.getDefaultComm`. See Also -------- petsc.ISCreateStride """ cdef MPI_Comm ccomm = def_Comm(comm, PETSC_COMM_DEFAULT) cdef PetscInt csize = asInt(size) cdef PetscInt cfirst = asInt(first) cdef PetscInt cstep = asInt(step) cdef PetscIS newiset = NULL CHKERR( ISCreateStride(ccomm, csize, cfirst, cstep, &newiset) ) CHKERR( PetscCLEAR(self.obj) ); self.iset = newiset return self def duplicate(self) -> IS: """Create a copy of the index set. Collective. See Also -------- IS.copy, petsc.ISDuplicate """ cdef IS iset = type(self)() CHKERR( ISDuplicate(self.iset, &iset.iset) ) return iset def copy(self, IS result=None) -> IS: """Copy the contents of the index set into another. Collective. Parameters ---------- result The target index set. If `None` then `IS.duplicate` is called first. Returns ------- IS The copied index set. If ``result`` is not `None` then this is returned here. See Also -------- IS.duplicate, petsc.ISCopy """ if result is None: result = type(self)() if result.iset == NULL: CHKERR( ISDuplicate(self.iset, &result.iset) ) CHKERR( ISCopy(self.iset, result.iset) ) return result def load(self, Viewer viewer) -> Self: """Load a stored index set. Collective. Parameters ---------- viewer Binary file viewer, either `Viewer.Type.BINARY` or `Viewer.Type.HDF5`. See Also -------- petsc.ISLoad """ cdef MPI_Comm comm = MPI_COMM_NULL cdef PetscObject obj = (viewer.vwr) if self.iset == NULL: CHKERR( PetscObjectGetComm(obj, &comm) ) CHKERR( ISCreate(comm, &self.iset) ) CHKERR( ISLoad(self.iset, viewer.vwr) ) return self def allGather(self) -> IS: """Concatenate index sets stored across processors. Collective. The returned index set will be the same on every processor. See Also -------- petsc.ISAllGather """ cdef IS iset = IS() CHKERR( ISAllGather(self.iset, &iset.iset) ) return iset def toGeneral(self) -> Self: """Convert the index set type to `IS.Type.GENERAL`. Collective. See Also -------- petsc.ISToGeneral, petsc.ISType """ CHKERR( ISToGeneral(self.iset) ) return self def buildTwoSided(self, IS toindx=None) -> IS: """Create an index set describing a global mapping. Collective. This function generates an index set that contains new numbers from remote or local on the index set. Parameters ---------- toindx Index set describing which indices to send, default is to send natural numbering. Returns ------- IS New index set containing the new numbers from remote or local. See Also -------- petsc.ISBuildTwoSided """ cdef PetscIS ctoindx = NULL if toindx is not None: ctoindx = toindx.iset cdef IS result = IS() CHKERR( ISBuildTwoSided(self.iset, ctoindx, &result.iset) ) return result def invertPermutation(self, nlocal: int | None = None) -> IS: """Invert the index set. Collective. For this to be correct the index set must be a permutation. Parameters ---------- nlocal The number of indices on this processor in the resulting index set, defaults to ``PETSC_DECIDE``. See Also -------- petsc.ISInvertPermutation """ cdef PetscInt cnlocal = PETSC_DECIDE if nlocal is not None: cnlocal = asInt(nlocal) cdef IS iset = IS() CHKERR( ISInvertPermutation(self.iset, cnlocal, &iset.iset) ) return iset def getSize(self) -> int: """Return the global length of an index set. Not collective. See Also -------- petsc.ISGetSize """ cdef PetscInt N = 0 CHKERR( ISGetSize(self.iset, &N) ) return toInt(N) def getLocalSize(self) -> int: """Return the process-local length of the index set. Not collective. See Also -------- petsc.ISGetLocalSize """ cdef PetscInt n = 0 CHKERR( ISGetLocalSize(self.iset, &n) ) return toInt(n) def getSizes(self) -> tuple[int, int]: """Return the local and global sizes of the index set. Not collective. Returns ------- local_size : int The local size. global_size : int The global size. See Also -------- IS.getLocalSize, IS.getSize """ cdef PetscInt n = 0, N = 0 CHKERR( ISGetLocalSize(self.iset, &n) ) CHKERR( ISGetSize(self.iset, &N) ) return (toInt(n), toInt(N)) def getBlockSize(self) -> int: """Return the number of elements in a block. Not collective. See Also -------- petsc.ISGetBlockSize """ cdef PetscInt bs = 1 CHKERR( ISGetBlockSize(self.iset, &bs) ) return toInt(bs) def setBlockSize(self, bs: int) -> None: """Set the block size of the index set. Logically collective. Parameters ---------- bs Block size. See Also -------- petsc.ISSetBlockSize """ cdef PetscInt cbs = asInt(bs) CHKERR( ISSetBlockSize(self.iset, cbs) ) def sort(self) -> Self: """Sort the indices of an index set. Collective. See Also -------- petsc.ISSort """ CHKERR( ISSort(self.iset) ) return self def isSorted(self) -> bool: """Return whether the indices have been sorted. Collective. See Also -------- petsc.ISSorted """ cdef PetscBool flag = PETSC_FALSE CHKERR( ISSorted(self.iset, &flag) ) return toBool(flag) def setPermutation(self) -> Self: """Mark the index set as being a permutation. Logically collective. See Also -------- petsc.ISSetPermutation """ CHKERR( ISSetPermutation(self.iset) ) return self def isPermutation(self) -> bool: """Return whether an index set has been declared to be a permutation. Logically collective. See Also -------- petsc.ISPermutation """ cdef PetscBool flag = PETSC_FALSE CHKERR( ISPermutation(self.iset, &flag) ) return toBool(flag) def setIdentity(self) -> Self: """Mark the index set as being an identity. Logically collective. See Also -------- petsc.ISSetIdentity """ CHKERR( ISSetIdentity(self.iset) ) return self def isIdentity(self) -> bool: """Return whether the index set has been declared as an identity. Collective. See Also -------- petsc.ISIdentity """ cdef PetscBool flag = PETSC_FALSE CHKERR( ISIdentity(self.iset, &flag) ) return toBool(flag) def equal(self, IS iset) -> bool: """Return whether the index sets have the same set of indices or not. Collective. Parameters ---------- iset The index set to compare indices with. See Also -------- petsc.ISEqual """ cdef PetscBool flag = PETSC_FALSE CHKERR( ISEqual(self.iset, iset.iset, &flag) ) return toBool(flag) def sum(self, IS iset) -> IS: """Return the union of two (sorted) index sets. Collective. Parameters ---------- iset The index set to compute the union with. See Also -------- petsc.ISSum """ cdef IS out = IS() CHKERR( ISSum(self.iset, iset.iset, &out.iset) ) return out def expand(self, IS iset) -> IS: """Return the union of two (possibly unsorted) index sets. Collective. To compute the union, `expand` concatenates the two index sets and removes any duplicates. Parameters ---------- iset Index set to compute the union with. Returns ------- IS The new, combined, index set. See Also -------- petsc.ISExpand """ cdef IS out = IS() CHKERR( ISExpand(self.iset, iset.iset, &out.iset) ) return out def union(self, IS iset) -> IS: """Return the union of two (possibly unsorted) index sets. Collective. This function will call either `petsc.ISSum` or `petsc.ISExpand` depending on whether or not the input sets are already sorted. Sequential only (as `petsc.ISSum` is sequential only). Parameters ---------- iset Index set to compute the union with. Returns ------- IS The new, combined, index set. See Also -------- IS.expand, IS.sum """ cdef PetscBool flag1=PETSC_FALSE, flag2=PETSC_FALSE CHKERR( ISSorted(self.iset, &flag1) ) CHKERR( ISSorted(iset.iset, &flag2) ) cdef IS out = IS() if flag1==PETSC_TRUE and flag2==PETSC_TRUE: CHKERR( ISSum(self.iset, iset.iset, &out.iset) ) else: CHKERR( ISExpand(self.iset, iset.iset, &out.iset) ) return out def difference(self, IS iset: IS) -> IS: """Return the difference between two index sets. Collective. Parameters ---------- iset Index set to compute the difference with. Returns ------- IS Index set representing the difference between ``self`` and ``iset``. See Also -------- petsc.ISDifference """ cdef IS out = IS() CHKERR( ISDifference(self.iset, iset.iset, &out.iset) ) return out def complement(self, nmin: int, nmax: int) -> IS: """Create a complement index set. Collective. The complement set of indices is all indices that are not in the provided set (and within the provided bounds). Parameters ---------- nmin Minimum index that can be found in the local part of the complement index set. nmax One greater than the maximum index that can be found in the local part of the complement index set. Notes ----- For a parallel index set, this will generate the local part of the complement on each process. To generate the entire complement (on each process) of a parallel index set, first call `IS.allGather` and then call this method. See Also -------- IS.allGather, petsc.ISComplement """ cdef PetscInt cnmin = asInt(nmin) cdef PetscInt cnmax = asInt(nmax) cdef IS out = IS() CHKERR( ISComplement(self.iset, cnmin, cnmax, &out.iset) ) return out def embed(self, IS iset, drop: bool) -> IS: """Embed ``self`` into ``iset``. Not collective. The embedding is performed by finding the locations in ``iset`` that have the same indices as ``self``. Parameters ---------- iset The index set to embed into. drop Flag indicating whether to drop indices from ``self`` that are not in ``iset``. Returns ------- IS The embedded index set. See Also -------- petsc.ISEmbed """ cdef PetscBool bval = drop cdef IS out = IS() CHKERR( ISEmbed(self.iset, iset.iset, bval, &out.iset) ) return out def renumber(self, IS mult=None) -> tuple[int, IS]: """Renumber the non-negative entries of an index set, starting from 0. Collective. Parameters ---------- mult The multiplicity of each entry in ``self``, default implies a multiplicity of 1. Returns ------- int One past the largest entry of the new index set. IS The renumbered index set. See Also -------- petsc.ISRenumber """ cdef PetscIS mlt = NULL if mult is not None: mlt = mult.iset cdef IS out = IS() cdef PetscInt n = 0 CHKERR( ISRenumber(self.iset, mlt, &n, &out.iset) ) return (toInt(n), out) # def setIndices(self, indices: Sequence[int]) -> None: """Set the indices of an index set. Logically collective. The index set is assumed to be of type `IS.Type.GENERAL`. See Also -------- petsc.ISGeneralSetIndices """ cdef PetscInt nidx = 0, *idx = NULL cdef PetscCopyMode cm = PETSC_COPY_VALUES indices = iarray_i(indices, &nidx, &idx) CHKERR( ISGeneralSetIndices(self.iset, nidx, idx, cm) ) def getIndices(self) -> ArrayInt: """Return the indices of the index set. Not collective. See Also -------- petsc.ISGetIndices """ cdef PetscInt size = 0 cdef const PetscInt *indices = NULL CHKERR( ISGetLocalSize(self.iset, &size) ) CHKERR( ISGetIndices(self.iset, &indices) ) cdef object oindices = None try: oindices = array_i(size, indices) finally: CHKERR( ISRestoreIndices(self.iset, &indices) ) return oindices def setBlockIndices(self, bsize: int, indices: Sequence[int]) -> None: """Set the indices for an index set with type `IS.Type.BLOCK`. Collective. Parameters ---------- bsize Number of elements in each block. indices List of integers. See Also -------- petsc.ISBlockSetIndices """ cdef PetscInt bs = asInt(bsize) cdef PetscInt nidx = 0, *idx = NULL cdef PetscCopyMode cm = PETSC_COPY_VALUES indices = iarray_i(indices, &nidx, &idx) CHKERR( ISBlockSetIndices(self.iset, bs, nidx, idx, cm) ) def getBlockIndices(self) -> ArrayInt: """Return the indices of an index set with type `IS.Type.BLOCK`. Not collective. See Also -------- petsc.ISBlockGetIndices """ cdef PetscInt size = 0, bs = 1 cdef const PetscInt *indices = NULL CHKERR( ISGetLocalSize(self.iset, &size) ) CHKERR( ISGetBlockSize(self.iset, &bs) ) CHKERR( ISBlockGetIndices(self.iset, &indices) ) cdef object oindices = None try: oindices = array_i(size//bs, indices) finally: CHKERR( ISBlockRestoreIndices(self.iset, &indices) ) return oindices def setStride(self, size: int, first: int = 0, step: int = 1) -> None: """Set the stride information for an index set with type `IS.Type.STRIDE`. Logically collective. Parameters ---------- size Length of the locally owned portion of the index set. first First element of the index set. step Difference between adjacent indices. See Also -------- petsc.ISStrideSetStride """ cdef PetscInt csize = asInt(size) cdef PetscInt cfirst = asInt(first) cdef PetscInt cstep = asInt(step) CHKERR( ISStrideSetStride(self.iset, csize, cfirst, cstep) ) def getStride(self) -> tuple[int, int, int]: """Return size and stride information. Not collective. Returns ------- size : int Length of the locally owned portion of the index set. first : int First element of the index set. step : int Difference between adjacent indices. See Also -------- petsc.ISGetLocalSize, petsc.ISStrideGetInfo """ cdef PetscInt size=0, first=0, step=0 CHKERR( ISGetLocalSize(self.iset, &size) ) CHKERR( ISStrideGetInfo(self.iset, &first, &step) ) return (toInt(size), toInt(first), toInt(step)) def getInfo(self) -> tuple[int, int]: """Return stride information for an index set with type `IS.Type.STRIDE`. Not collective. Returns ------- first : int First element of the index set. step : int Difference between adjacent indices. See Also -------- IS.getStride, petsc.ISStrideGetInfo """ cdef PetscInt first = 0, step = 0 CHKERR( ISStrideGetInfo(self.iset, &first, &step) ) return (toInt(first), toInt(step)) # property permutation: """`True` if index set is a permutation, `False` otherwise. Logically collective. See Also -------- IS.isPermutation """ def __get__(self) -> bool: return self.isPermutation() property identity: """`True` if index set is an identity, `False` otherwise. Collective. See Also -------- IS.isIdentity """ def __get__(self) -> bool: return self.isIdentity() property sorted: """`True` if index set is sorted, `False` otherwise. Collective. See Also -------- IS.isSorted """ def __get__(self) -> bool: return self.isSorted() # property sizes: """The local and global sizes of the index set. Not collective. See Also -------- IS.getSizes """ def __get__(self) -> tuple[int, int]: return self.getSizes() property size: """The global size of the index set. Not collective. See Also -------- IS.getSize """ def __get__(self) -> int: return self.getSize() property local_size: """The local size of the index set. Not collective. See Also -------- IS.getLocalSize """ def __get__(self) -> int: return self.getLocalSize() property block_size: """The number of elements in a block. Not collective. See Also -------- IS.getBlockSize """ def __get__(self) -> int: return self.getBlockSize() property indices: """The indices of the index set. Not collective. See Also -------- IS.getIndices """ def __get__(self) -> ArrayInt: return self.getIndices() property array: """View of the index set as an array of integers. Not collective. """ def __get__(self) -> ArrayInt: return asarray(self) # --- NumPy array interface (legacy) --- property __array_interface__: def __get__(self): cdef _IS_buffer buf = _IS_buffer(self) return buf.__array_interface__ # -------------------------------------------------------------------- class GLMapMode(object): """Enum describing mapping behavior for global-to-local maps when global indices are missing. MASK Give missing global indices a local index of -1. DROP Drop missing global indices. See Also -------- petsc.ISGlobalToLocalMappingMode """ MASK = PETSC_IS_GTOLM_MASK DROP = PETSC_IS_GTOLM_DROP class LGMapType(object): BASIC = S_(ISLOCALTOGLOBALMAPPINGBASIC) HASH = S_(ISLOCALTOGLOBALMAPPINGHASH) # -------------------------------------------------------------------- cdef class LGMap(Object): """Mapping from an arbitrary local ordering from ``0`` to ``n-1`` to a global PETSc ordering used by a vector or matrix. See Also -------- petsc.ISLocalToGlobalMapping """ MapMode = GLMapMode Type = LGMapType # def __cinit__(self) -> None: self.obj = &self.lgm self.lgm = NULL def __call__( self, indices: Sequence[int], result: ArrayInt | None = None ) -> None: """Convert a locally numbered list of integers to a global numbering. Not collective. Parameters ---------- indices Input indices in local numbering. result Array to write the global numbering to. If `None` then a new array will be allocated. See Also -------- IS.apply, petsc.ISLocalToGlobalMappingApply """ self.apply(indices, result) # def setType(self, lgmap_type: LGMap.Type | str) -> None: """Set the type of the local-to-global map. Logically collective. Parameters ---------- lgmap_type The type of the local-to-global mapping. Notes ----- Use ``-islocaltoglobalmapping_type`` to set the type in the options database. See Also -------- petsc_options, petsc.ISLocalToGlobalMappingSetType """ cdef PetscISLocalToGlobalMappingType cval = NULL lgmap_type = str2bytes(lgmap_type, &cval) CHKERR( ISLocalToGlobalMappingSetType(self.lgm, cval) ) def setFromOptions(self) -> None: """Set mapping options from the options database. Not collective. See Also -------- petsc_options, petsc.ISLocalToGlobalMappingSetFromOptions """ CHKERR( ISLocalToGlobalMappingSetFromOptions(self.lgm) ) def view(self, Viewer viewer=None) -> None: """View the local-to-global mapping. Not collective. Parameters ---------- viewer Viewer instance, defaults to an instance of `Viewer.Type.ASCII`. See Also -------- petsc.ISLocalToGlobalMappingView """ cdef PetscViewer cviewer = NULL if viewer is not None: cviewer = viewer.vwr CHKERR( ISLocalToGlobalMappingView(self.lgm, cviewer) ) def destroy(self) -> Self: """Destroy the local-to-global mapping. Not collective. See Also -------- petsc.ISLocalToGlobalMappingDestroy """ CHKERR( ISLocalToGlobalMappingDestroy(&self.lgm) ) return self def create( self, indices: Sequence[int], bsize: int | None = None, comm: Comm | None = None ) -> Self: """Create a local-to-global mapping. Not collective. Parameters ---------- indices Global index for each local element. bsize Block size, defaults to 1. comm MPI communicator, defaults to `Sys.getDefaultComm`. See Also -------- petsc.ISLocalToGlobalMappingCreate """ cdef MPI_Comm ccomm = def_Comm(comm, PETSC_COMM_DEFAULT) cdef PetscInt bs = 1, nidx = 0, *idx = NULL cdef PetscCopyMode cm = PETSC_COPY_VALUES cdef PetscLGMap newlgm = NULL if bsize is not None: bs = asInt(bsize) if bs == PETSC_DECIDE: bs = 1 indices = iarray_i(indices, &nidx, &idx) CHKERR( ISLocalToGlobalMappingCreate( ccomm, bs, nidx, idx, cm, &newlgm) ) CHKERR( PetscCLEAR(self.obj) ); self.lgm = newlgm return self def createIS(self, IS iset) -> Self: """Create a local-to-global mapping from an index set. Not collective. Parameters ---------- iset Index set containing the global numbers for each local number. See Also -------- petsc.ISLocalToGlobalMappingCreateIS """ cdef PetscLGMap newlgm = NULL CHKERR( ISLocalToGlobalMappingCreateIS( iset.iset, &newlgm) ) CHKERR( PetscCLEAR(self.obj) ); self.lgm = newlgm return self def createSF(self, SF sf, start: int) -> Self: """Create a local-to-global mapping from a star forest. Collective. Parameters ---------- sf Star forest mapping contiguous local indices to (rank, offset). start First global index on this process. See Also -------- petsc.ISLocalToGlobalMappingCreateSF """ cdef PetscLGMap newlgm = NULL cdef PetscInt cstart = asInt(start) CHKERR( ISLocalToGlobalMappingCreateSF(sf.sf, cstart, &newlgm) ) CHKERR( PetscCLEAR(self.obj) ); self.lgm = newlgm return self def getSize(self) -> int: """Return the local size of the local-to-global mapping. Not collective. See Also -------- petsc.ISLocalToGlobalMappingGetSize """ cdef PetscInt n = 0 CHKERR( ISLocalToGlobalMappingGetSize(self.lgm, &n) ) return toInt(n) def getBlockSize(self) -> int: """Return the block size of the local-to-global mapping. Not collective. See Also -------- petsc.ISLocalToGlobalMappingGetBlockSize """ cdef PetscInt bs = 1 CHKERR( ISLocalToGlobalMappingGetBlockSize(self.lgm, &bs) ) return toInt(bs) def getIndices(self) -> ArrayInt: """Return the global indices for each local point in the mapping. Not collective. See Also -------- petsc.ISLocalToGlobalMappingGetIndices """ cdef PetscInt size = 0 cdef const PetscInt *indices = NULL CHKERR( ISLocalToGlobalMappingGetSize( self.lgm, &size) ) CHKERR( ISLocalToGlobalMappingGetIndices( self.lgm, &indices) ) cdef object oindices = None try: oindices = array_i(size, indices) finally: CHKERR( ISLocalToGlobalMappingRestoreIndices( self.lgm, &indices) ) return oindices def getBlockIndices(self) -> ArrayInt: """Return the global indices for each local block. Not collective. See Also -------- petsc.ISLocalToGlobalMappingGetBlockIndices """ cdef PetscInt size = 0, bs = 1 cdef const PetscInt *indices = NULL CHKERR( ISLocalToGlobalMappingGetSize( self.lgm, &size) ) CHKERR( ISLocalToGlobalMappingGetBlockSize( self.lgm, &bs) ) CHKERR( ISLocalToGlobalMappingGetBlockIndices( self.lgm, &indices) ) cdef object oindices = None try: oindices = array_i(size//bs, indices) finally: CHKERR( ISLocalToGlobalMappingRestoreBlockIndices( self.lgm, &indices) ) return oindices def getInfo(self) -> dict[int, ArrayInt]: """Determine the indices shared with neighboring processes. Collective. Returns ------- dict Mapping from neighboring processor number to an array of shared indices (in local numbering). See Also -------- petsc.ISLocalToGlobalMappingGetInfo """ cdef PetscInt i, nproc = 0, *procs = NULL, cdef PetscInt *numprocs = NULL, **indices = NULL cdef object neighs = { } CHKERR( ISLocalToGlobalMappingGetInfo( self.lgm, &nproc, &procs, &numprocs, &indices) ) try: for i from 0 <= i < nproc: neighs[toInt(procs[i])] = array_i(numprocs[i], indices[i]) finally: ISLocalToGlobalMappingRestoreInfo( self.lgm, &nproc, &procs, &numprocs, &indices) return neighs def getBlockInfo(self) -> dict[int, ArrayInt]: """Determine the block indices shared with neighboring processes. Collective. Returns ------- dict Mapping from neighboring processor number to an array of shared block indices (in local numbering). See Also -------- petsc.ISLocalToGlobalMappingGetBlockInfo """ cdef PetscInt i, nproc = 0, *procs = NULL, cdef PetscInt *numprocs = NULL, **indices = NULL cdef object neighs = { } CHKERR( ISLocalToGlobalMappingGetBlockInfo( self.lgm, &nproc, &procs, &numprocs, &indices) ) try: for i from 0 <= i < nproc: neighs[toInt(procs[i])] = array_i(numprocs[i], indices[i]) finally: ISLocalToGlobalMappingRestoreBlockInfo( self.lgm, &nproc, &procs, &numprocs, &indices) return neighs # def apply( self, indices: Sequence[int], result: ArrayInt | None = None, ) -> ArrayInt: """Convert a locally numbered list of integers to a global numbering. Not collective. Parameters ---------- indices Input indices in local numbering. result Array to write the global numbering to. If `None` then a new array will be allocated. Returns ------- ArrayInt Indices in global numbering. If ``result`` is not `None` then this is returned here. See Also -------- LGMap.applyBlock, petsc.ISLocalToGlobalMappingApply """ cdef PetscInt niidx = 0, *iidx = NULL cdef PetscInt noidx = 0, *oidx = NULL indices = iarray_i(indices, &niidx, &iidx) if result is None: result = empty_i(niidx) result = oarray_i(result, &noidx, &oidx) assert niidx == noidx, "incompatible array sizes" CHKERR( ISLocalToGlobalMappingApply( self.lgm, niidx, iidx, oidx) ) return result def applyBlock( self, indices: Sequence[int], result: ArrayInt | None = None, ) -> ArrayInt: """Convert a local block numbering to a global block numbering. Not collective. Parameters ---------- indices Input block indices in local numbering. result Array to write the global numbering to. If `None` then a new array will be allocated. Returns ------- ArrayInt Block indices in global numbering. If ``result`` is not `None` then this is returned here. See Also -------- LGMap.apply, petsc.ISLocalToGlobalMappingApplyBlock """ cdef PetscInt niidx = 0, *iidx = NULL cdef PetscInt noidx = 0, *oidx = NULL indices = iarray_i(indices, &niidx, &iidx) if result is None: result = empty_i(niidx) result = oarray_i(result, &noidx, &oidx) assert niidx == noidx, "incompatible array sizes" CHKERR( ISLocalToGlobalMappingApplyBlock( self.lgm, niidx, iidx, oidx) ) return result def applyIS(self, IS iset) -> IS: """Create an index set with global numbering from a local numbering. Collective. Parameters ---------- iset Index set with local numbering. Returns ------- IS Index set with global numbering. See Also -------- petsc.ISLocalToGlobalMappingApplyIS """ cdef IS result = IS() CHKERR( ISLocalToGlobalMappingApplyIS( self.lgm, iset.iset, &result.iset) ) return result def applyInverse( self, indices: Sequence[int], mode: GLMapMode | str | None = None, ) -> ArrayInt: """Compute local numbering from global numbering. Not collective. Parameters ---------- indices Indices with a global numbering. mode Flag indicating what to do with indices that have no local value, defaults to ``"mask"``. Returns ------- ArrayInt Indices with a local numbering. See Also -------- petsc.ISGlobalToLocalMappingApply """ cdef PetscGLMapMode cmode = PETSC_IS_GTOLM_MASK if mode is not None: cmode = mode cdef PetscInt n = 0, *idx = NULL indices = iarray_i(indices, &n, &idx) cdef PetscInt nout = n, *idxout = NULL if cmode != PETSC_IS_GTOLM_MASK: CHKERR( ISGlobalToLocalMappingApply( self.lgm, cmode, n, idx, &nout, NULL) ) result = oarray_i(empty_i(nout), &nout, &idxout) CHKERR( ISGlobalToLocalMappingApply( self.lgm, cmode, n, idx, &nout, idxout) ) return result def applyBlockInverse( self, indices: Sequence[int], mode: GLMapMode | str | None = None, ) -> ArrayInt: """Compute blocked local numbering from blocked global numbering. Not collective. Parameters ---------- indices Indices with a global block numbering. mode Flag indicating what to do with indices that have no local value, defaults to ``"mask"``. Returns ------- ArrayInt Indices with a local block numbering. See Also -------- petsc.ISGlobalToLocalMappingApplyBlock """ cdef PetscGLMapMode cmode = PETSC_IS_GTOLM_MASK if mode is not None: cmode = mode cdef PetscInt n = 0, *idx = NULL indices = iarray_i(indices, &n, &idx) cdef PetscInt nout = n, *idxout = NULL if cmode != PETSC_IS_GTOLM_MASK: CHKERR( ISGlobalToLocalMappingApply( self.lgm, cmode, n, idx, &nout, NULL) ) result = oarray_i(empty_i(nout), &nout, &idxout) CHKERR( ISGlobalToLocalMappingApplyBlock( self.lgm, cmode, n, idx, &nout, idxout) ) return result # property size: """The local size. Not collective. See Also -------- LGMap.getSize """ def __get__(self) -> int: return self.getSize() property block_size: """The block size. Not collective. See Also -------- LGMap.getBlockSize """ def __get__(self) -> int: return self.getBlockSize() property indices: """The global indices for each local point in the mapping. Not collective. See Also -------- LGMap.getIndices, petsc.ISLocalToGlobalMappingGetIndices """ def __get__(self) -> ArrayInt: return self.getIndices() property block_indices: """The global indices for each local block in the mapping. Not collective. See Also -------- LGMap.getBlockIndices, petsc.ISLocalToGlobalMappingGetBlockIndices """ def __get__(self) -> ArrayInt: return self.getBlockIndices() property info: """Mapping describing indices shared with neighboring processes. Collective. See Also -------- LGMap.getInfo, petsc.ISLocalToGlobalMappingGetInfo """ def __get__(self) -> dict[int, ArrayInt]: return self.getInfo() property block_info: """Mapping describing block indices shared with neighboring processes. Collective. See Also -------- LGMap.getBlockInfo, petsc.ISLocalToGlobalMappingGetBlockInfo """ def __get__(self) -> dict[int, ArrayInt]: return self.getBlockInfo() # -------------------------------------------------------------------- del ISType del GLMapMode del LGMapType # -------------------------------------------------------------------- ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/src/petsc4py/PETSc/KSP.pyx0000644000175000017500000020453614567251135017060 0ustar00balaybalay# -------------------------------------------------------------------- class KSPType(object): """KSP Type. The available types are: `RICHARDSON` The preconditioned Richardson iterative method `petsc.KSPRICHARDSON`. `CHEBYSHEV` The preconditioned Chebyshev iterative method. `petsc.KSPCHEBYSHEV`. `CG` The Preconditioned Conjugate Gradient (PCG) iterative method. `petsc.KSPCG` `GROPPCG` A pipelined conjugate gradient method (Gropp). `petsc.KSPGROPPCG` `PIPECG` A pipelined conjugate gradient method. `petsc.KSPPIPECG` `PIPECGRR` Pipelined Conjugate Gradients with Residual Replacement. `petsc.KSPPIPECGRR` `PIPELCG` Deep pipelined (length l) Conjugate Gradient method. `petsc.KSPPIPELCG` `PIPEPRCG` Pipelined predict-and-recompute conjugate gradient method. `petsc.KSPPIPEPRCG` `PIPECG2` Pipelined conjugate gradient method with a single non-blocking reduction per two iterations. `petsc.KSPPIPECG2` `CGNE` Applies the preconditioned conjugate gradient method to the normal equations without explicitly forming AᵀA. `petsc.KSPCGNE` `NASH` Conjugate gradient method subject to a constraint on the solution norm. `petsc.KSPNASH` `STCG` Conjugate gradient method subject to a constraint on the solution norm. `petsc.KSPSTCG` `GLTR` Conjugate gradient method subject to a constraint on the solution norm. `petsc.KSPGLTR` `FCG` Flexible Conjugate Gradient method (FCG). Unlike most KSP methods this allows the preconditioner to be nonlinear. `petsc.KSPFCG` `PIPEFCG` Pipelined, Flexible Conjugate Gradient method. `petsc.KSPPIPEFCG` `GMRES` Generalized Minimal Residual method with restart. `petsc.KSPGMRES` `PIPEFGMRES` Pipelined (1-stage) Flexible Generalized Minimal Residual method. `petsc.KSPPIPEFGMRES` `FGMRES` Implements the Flexible Generalized Minimal Residual method. `petsc.KSPFGMRES` `LGMRES` Augments the standard Generalized Minimal Residual method approximation space with approximations to the error from previous restart cycles. `petsc.KSPLGMRES` `DGMRES` Deflated Generalized Minimal Residual method. In this implementation, the adaptive strategy allows to switch to the deflated GMRES when the stagnation occurs. `petsc.KSPDGMRES` `PGMRES` Pipelined Generalized Minimal Residual method. `petsc.KSPPGMRES` `TCQMR` A variant of Quasi Minimal Residual (QMR). `petsc.KSPTCQMR` `BCGS` Stabilized version of Biconjugate Gradient (BiCGStab) method. `petsc.KSPBCGS` `IBCGS` Improved Stabilized version of BiConjugate Gradient (IBiCGStab) method in an alternative form to have only a single global reduction operation instead of the usual 3 (or 4). `petsc.KSPIBCGS` `QMRCGS` Quasi- Minimal Residual variant of the Bi-CGStab algorithm (QMRCGStab) method. `petsc.KSPQMRCGS` `FBCGS` Flexible Stabilized version of BiConjugate Gradient (BiCGStab) method. `petsc.KSPFBCGS` `FBCGSR` A mathematically equivalent variant of flexible stabilized BiConjugate Gradient (BiCGStab). `petsc.KSPFBCGSR` `BCGSL` Variant of the L-step stabilized BiConjugate Gradient (BiCGStab(L)) algorithm. Uses "L-step" Minimal Residual (MR) polynomials. The variation concerns cases when some parameters are negative due to round-off. `petsc.KSPBCGSL` `PIPEBCGS` Pipelined stabilized BiConjugate Gradient (BiCGStab) method. `petsc.KSPPIPEBCGS` `CGS` Conjugate Gradient Squared method. `petsc.KSPCGS` `TFQMR` A Transpose Tree Quasi- Minimal Residual (QMR). `petsc.KSPCR` `CR` (Preconditioned) Conjugate Residuals (CR) method. `petsc.KSPCR` `PIPECR` Pipelined Conjugate Residual (CR) method. `petsc.KSPPIPECR` `LSQR` Least squares solver. `petsc.KSPLSQR` `PREONLY` Applies ONLY the preconditioner exactly once. This may be used in inner iterations, where it is desired to allow multiple iterations as well as the "0-iteration" case. It is commonly used with the direct solver preconditioners like PCLU and PCCHOLESKY. There is an alias of KSPNONE. `petsc.KSPPREONLY` `NONE` No solver ``KSPNONE`` `QCG` Conjugate Gradient (CG) method subject to a constraint on the solution norm. `petsc.KSPQCG` `BICG` Implements the Biconjugate gradient method (BiCG). Similar to running the conjugate gradient on the normal equations. `petsc.KSPBICG` `MINRES` Minimum Residual (MINRES) method. `petsc.KSPMINRES` `SYMMLQ` Symmetric LQ method (SymmLQ). Uses LQ decomposition (lower trapezoidal). `petsc.KSPSYMMLQ` `LCD` Left Conjugate Direction (LCD) method. `petsc.KSPLCD` `PYTHON` Python shell solver. Call Python function to implement solver. ``KSPPYTHON`` `GCR` Preconditioned flexible Generalized Conjugate Residual (GCR) method. `petsc.KSPGCR` `PIPEGCR` Pipelined Generalized Conjugate Residual method. `petsc.KSPPIPEGCR` `TSIRM` Two-Stage Iteration with least-squares Residual Minimization method. `petsc.KSPTSIRM` `CGLS` Conjugate Gradient method for Least-Squares problems. Supports non-square (rectangular) matrices. `petsc.KSPCGLS` `FETIDP` Dual-Primal (DP) Finite Element Tearing and Interconnect (FETI) method. `petsc.KSPFETIDP` `HPDDM` Interface with the HPDDM library. This KSP may be used to further select methods that are currently not implemented natively in PETSc, e.g., GCRODR, a recycled Krylov method which is similar to KSPLGMRES. `petsc.KSPHPDDM` Notes ----- `KSP Type `__ `KSP Type table `__ `Pieplined KSP methods `__ `Flexible KSP methods `__ See Also -------- petsc_options, petsc.KSP """ RICHARDSON = S_(KSPRICHARDSON) CHEBYSHEV = S_(KSPCHEBYSHEV) CG = S_(KSPCG) GROPPCG = S_(KSPGROPPCG) PIPECG = S_(KSPPIPECG) PIPECGRR = S_(KSPPIPECGRR) PIPELCG = S_(KSPPIPELCG) PIPEPRCG = S_(KSPPIPEPRCG) PIPECG2 = S_(KSPPIPECG2) CGNE = S_(KSPCGNE) NASH = S_(KSPNASH) STCG = S_(KSPSTCG) GLTR = S_(KSPGLTR) FCG = S_(KSPFCG) PIPEFCG = S_(KSPPIPEFCG) GMRES = S_(KSPGMRES) PIPEFGMRES = S_(KSPPIPEFGMRES) FGMRES = S_(KSPFGMRES) LGMRES = S_(KSPLGMRES) DGMRES = S_(KSPDGMRES) PGMRES = S_(KSPPGMRES) TCQMR = S_(KSPTCQMR) BCGS = S_(KSPBCGS) IBCGS = S_(KSPIBCGS) QMRCGS = S_(KSPQMRCGS) FBCGS = S_(KSPFBCGS) FBCGSR = S_(KSPFBCGSR) BCGSL = S_(KSPBCGSL) PIPEBCGS = S_(KSPPIPEBCGS) CGS = S_(KSPCGS) TFQMR = S_(KSPTFQMR) CR = S_(KSPCR) PIPECR = S_(KSPPIPECR) LSQR = S_(KSPLSQR) PREONLY = S_(KSPPREONLY) NONE = S_(KSPNONE) QCG = S_(KSPQCG) BICG = S_(KSPBICG) MINRES = S_(KSPMINRES) SYMMLQ = S_(KSPSYMMLQ) LCD = S_(KSPLCD) PYTHON = S_(KSPPYTHON) GCR = S_(KSPGCR) PIPEGCR = S_(KSPPIPEGCR) TSIRM = S_(KSPTSIRM) CGLS = S_(KSPCGLS) FETIDP = S_(KSPFETIDP) HPDDM = S_(KSPHPDDM) class KSPNormType(object): """KSP norm type. The available norm types are: `NONE` Skips computing the norm, this should generally only be used if you are using the Krylov method as a smoother with a fixed small number of iterations. Implicitly sets `petsc.KSPConvergedSkip` as KSP convergence test. Note that certain algorithms such as `Type.GMRES` ALWAYS require the norm calculation, for these methods the norms are still computed, they are just not used in the convergence test. `PRECONDITIONED` The default for left preconditioned solves, uses the l₂ norm of the preconditioned residual P⁻¹(b - Ax). `UNPRECONDITIONED` Uses the l₂ norm of the true b - Ax residual. `NATURAL` Supported by `Type.CG`, `Type.CR`, `Type.CGNE`, `Type.CGS`. """ # native NORM_DEFAULT = KSP_NORM_DEFAULT NORM_NONE = KSP_NORM_NONE NORM_PRECONDITIONED = KSP_NORM_PRECONDITIONED NORM_UNPRECONDITIONED = KSP_NORM_UNPRECONDITIONED NORM_NATURAL = KSP_NORM_NATURAL # aliases DEFAULT = NORM_DEFAULT NONE = NO = NORM_NONE PRECONDITIONED = NORM_PRECONDITIONED UNPRECONDITIONED = NORM_UNPRECONDITIONED NATURAL = NORM_NATURAL class KSPConvergedReason(object): """KSP Converged Reason. `CONVERGED_ITERATING` Still iterating `ITERATING` Still iterating `CONVERGED_RTOL_NORMAL` Undocumented. `CONVERGED_ATOL_NORMAL` Undocumented. `CONVERGED_RTOL` ∥r∥ <= rtolnorm(b) or rtolnorm(b - Ax₀) `CONVERGED_ATOL` ∥r∥ <= atol `CONVERGED_ITS` Used by the `Type.PREONLY` solver after the single iteration of the preconditioner is applied. Also used when the `petsc.KSPConvergedSkip` convergence test routine is set in KSP. `CONVERGED_NEG_CURVE` Undocumented. `CONVERGED_STEP_LENGTH` Undocumented. `CONVERGED_HAPPY_BREAKDOWN` Undocumented. `DIVERGED_NULL` Undocumented. `DIVERGED_MAX_IT` Ran out of iterations before any convergence criteria was reached. `DIVERGED_DTOL` norm(r) >= dtol*norm(b) `DIVERGED_BREAKDOWN` A breakdown in the Krylov method was detected so the method could not continue to enlarge the Krylov space. Could be due to a singular matrix or preconditioner. In KSPHPDDM, this is also returned when some search directions within a block are colinear. `DIVERGED_BREAKDOWN_BICG` A breakdown in the KSPBICG method was detected so the method could not continue to enlarge the Krylov space. `DIVERGED_NONSYMMETRIC` It appears the operator or preconditioner is not symmetric and this Krylov method (`Type.CG`, `Type.MINRES`, `Type.CR`) requires symmetry. `DIVERGED_INDEFINITE_PC` It appears the preconditioner is indefinite (has both positive and negative eigenvalues) and this Krylov method (`Type.CG`) requires it to be positive definite. `DIVERGED_NANORINF` Undocumented. `DIVERGED_INDEFINITE_MAT` Undocumented. `DIVERGED_PCSETUP_FAILED` It was not possible to build or use the requested preconditioner. This is usually due to a zero pivot in a factorization. It can also result from a failure in a subpreconditioner inside a nested preconditioner such as `PC.Type.FIELDSPLIT`. See Also -------- `petsc.KSPConvergedReason` """ #iterating CONVERGED_ITERATING = KSP_CONVERGED_ITERATING ITERATING = KSP_CONVERGED_ITERATING # converged CONVERGED_RTOL_NORMAL = KSP_CONVERGED_RTOL_NORMAL CONVERGED_ATOL_NORMAL = KSP_CONVERGED_ATOL_NORMAL CONVERGED_RTOL = KSP_CONVERGED_RTOL CONVERGED_ATOL = KSP_CONVERGED_ATOL CONVERGED_ITS = KSP_CONVERGED_ITS CONVERGED_NEG_CURVE = KSP_CONVERGED_NEG_CURVE CONVERGED_STEP_LENGTH = KSP_CONVERGED_STEP_LENGTH CONVERGED_HAPPY_BREAKDOWN = KSP_CONVERGED_HAPPY_BREAKDOWN # diverged DIVERGED_NULL = KSP_DIVERGED_NULL DIVERGED_MAX_IT = KSP_DIVERGED_MAX_IT DIVERGED_DTOL = KSP_DIVERGED_DTOL DIVERGED_BREAKDOWN = KSP_DIVERGED_BREAKDOWN DIVERGED_BREAKDOWN_BICG = KSP_DIVERGED_BREAKDOWN_BICG DIVERGED_NONSYMMETRIC = KSP_DIVERGED_NONSYMMETRIC DIVERGED_INDEFINITE_PC = KSP_DIVERGED_INDEFINITE_PC DIVERGED_NANORINF = KSP_DIVERGED_NANORINF DIVERGED_INDEFINITE_MAT = KSP_DIVERGED_INDEFINITE_MAT DIVERGED_PCSETUP_FAILED = KSP_DIVERGED_PC_FAILED class KSPHPDDMType(object): """The *HPDDM* Krylov solver type.""" GMRES = KSP_HPDDM_TYPE_GMRES BGMRES = KSP_HPDDM_TYPE_BGMRES CG = KSP_HPDDM_TYPE_CG BCG = KSP_HPDDM_TYPE_BCG GCRODR = KSP_HPDDM_TYPE_GCRODR BGCRODR = KSP_HPDDM_TYPE_BGCRODR BFBCG = KSP_HPDDM_TYPE_BFBCG PREONLY = KSP_HPDDM_TYPE_PREONLY # -------------------------------------------------------------------- cdef class KSP(Object): """Abstract PETSc object that manages all Krylov methods. This is the object that manages the linear solves in PETSc (even those such as direct solvers that do no use Krylov accelerators). Notes ----- When a direct solver is used, but no Krylov solver is used, the KSP object is still used but with a `Type.PREONLY`, meaning that only application of the preconditioner is used as the linear solver. See Also -------- create, setType, SNES, TS, PC, Type.CG, Type.GMRES, petsc.KSP """ Type = KSPType NormType = KSPNormType ConvergedReason = KSPConvergedReason HPDDMType = KSPHPDDMType # --- xxx --- def __cinit__(self): self.obj = &self.ksp self.ksp = NULL def __call__(self, Vec b, Vec x = None) -> Vec: """Solve linear system. Collective. Parameters ---------- b Right hand side vector. x Solution vector. Notes ----- Shortcut for `solve`, which returns the solution vector. See Also -------- solve, petsc_options, petsc.KSPSolve """ if x is None: # XXX do this better x = self.getOperators()[0].createVecLeft() self.solve(b, x) return x # --- xxx --- def view(self, Viewer viewer=None) -> None: """Print the KSP data structure. Collective. Parameters ---------- viewer Viewer used to display the KSP. See Also -------- petsc.KSPView """ cdef PetscViewer vwr = NULL if viewer is not None: vwr = viewer.vwr CHKERR( KSPView(self.ksp, vwr) ) def destroy(self) -> Self: """Destroy KSP context. Collective. See Also -------- petsc.KSPDestroy """ CHKERR( KSPDestroy(&self.ksp) ) return self def create(self, comm: Comm | None = None) -> Self: """Create the KSP context. Collective. See Also -------- petsc.KSPCreate """ cdef MPI_Comm ccomm = def_Comm(comm, PETSC_COMM_DEFAULT) cdef PetscKSP newksp = NULL CHKERR( KSPCreate(ccomm, &newksp) ) CHKERR( PetscCLEAR(self.obj) ); self.ksp = newksp return self def setType(self, ksp_type: Type | str) -> None: """Build the `KSP` data structure for a particular `Type`. Logically collective. Parameters ---------- ksp_type KSP Type object Notes ----- See `Type` for available methods (for instance, `Type.CG` or `Type.GMRES`). Normally, it is best to use the `setFromOptions` command and then set the KSP type from the options database rather than by using this routine. Using the options database provides the user with maximum flexibility in evaluating the many different Krylov methods. This method is provided for those situations where it is necessary to set the iterative solver independently of the command line or options database. This might be the case, for example, when the choice of iterative solver changes during the execution of the program, and the user's application is taking responsibility for choosing the appropriate method. In other words, this routine is not for beginners. See Also -------- petsc.KSPSetType """ cdef PetscKSPType cval = NULL ksp_type = str2bytes(ksp_type, &cval) CHKERR( KSPSetType(self.ksp, cval) ) def getType(self) -> str: """Return the KSP type as a string from the `KSP` object. Not collective. See Also -------- petsc.KSPGetType """ cdef PetscKSPType cval = NULL CHKERR( KSPGetType(self.ksp, &cval) ) return bytes2str(cval) def setOptionsPrefix(self, prefix: str) -> None: """Set the prefix used for all `KSP` options in the database. Logically collective. Parameters ---------- prefix The options prefix. Notes ----- A hyphen (-) must NOT be given at the beginning of the prefix name. The first character of all runtime options is AUTOMATICALLY the hyphen. For example, to distinguish between the runtime options for two different `KSP` contexts, one could call ``` KSPSetOptionsPrefix(ksp1, "sys1_") KSPSetOptionsPrefix(ksp2, "sys2_") ``` This would enable use of different options for each system, such as ``` -sys1_ksp_type gmres -sys1_ksp_rtol 1.e-3 -sys2_ksp_type bcgs -sys2_ksp_rtol 1.e-4 ``` See Also -------- petsc_options, petsc.KSPSetOptionsPrefix """ cdef const char *cval = NULL prefix = str2bytes(prefix, &cval) CHKERR( KSPSetOptionsPrefix(self.ksp, cval) ) def getOptionsPrefix(self) -> str: """Return the prefix used for all `KSP` options in the database. Not collective. See Also -------- petsc.KSPGetOptionsPrefix """ cdef const char *cval = NULL CHKERR( KSPGetOptionsPrefix(self.ksp, &cval) ) return bytes2str(cval) def appendOptionsPrefix(self, prefix: str) -> None: """Append to prefix used for all `KSP` options in the database. Logically collective. Parameters ---------- prefix The options prefix to append. Notes ----- A hyphen (-) must NOT be given at the beginning of the prefix name. The first character of all runtime options is AUTOMATICALLY the hyphen. See Also -------- petsc.KSPAppendOptionsPrefix """ cdef const char *cval = NULL prefix = str2bytes(prefix, &cval) CHKERR( KSPAppendOptionsPrefix(self.ksp, cval) ) def setFromOptions(self) -> None: """Set `KSP` options from the options database. Collective. This routine must be called before `setUp` if the user is to be allowed to set the Krylov type. See Also -------- petsc_options, petsc.KSPSetFromOptions """ CHKERR( KSPSetFromOptions(self.ksp) ) # --- application context --- def setAppCtx(self, appctx: Any) -> None: """Set the optional user-defined context for the linear solver. Not collective. Parameters ---------- appctx The user defined context Notes ----- The user context is a way for users to attach any information to the `KSP` that they may need later when interacting with the solver. See Also -------- getAppCtx """ self.set_attr('__appctx__', appctx) def getAppCtx(self) -> Any: """Return the user-defined context for the linear solver. Not collective. See Also -------- setAppCtx """ return self.get_attr('__appctx__') # --- discretization space --- def getDM(self) -> DM: """Return the `DM` that may be used by some preconditioners. Not collective. See Also -------- PETSc.KSP, DM, petsc.KSPGetDM """ cdef PetscDM newdm = NULL CHKERR( KSPGetDM(self.ksp, &newdm) ) cdef DM dm = subtype_DM(newdm)() dm.dm = newdm CHKERR( PetscINCREF(dm.obj) ) return dm def setDM(self, DM dm) -> None: """Set the `DM` that may be used by some preconditioners. Logically collective. Parameters ---------- dm The `DM` object, cannot be `None`. Notes ----- If this is used then the `KSP` will attempt to use the `DM` to create the matrix and use the routine set with `DM.setKSPComputeOperators`. Use ``setDMActive(False)`` to instead use the matrix you have provided with `setOperators`. A `DM` can only be used for solving one problem at a time because information about the problem is stored on the `DM`, even when not using interfaces like `DM.setKSPComputeOperators`. Use `DM.clone` to get a distinct `DM` when solving different problems using the same function space. See Also -------- PETSc.KSP, DM, DM.setKSPComputeOperators, setOperators, DM.clone petsc.KSPSetDM """ CHKERR( KSPSetDM(self.ksp, dm.dm) ) def setDMActive(self, flag: bool) -> None: """`DM` should be used to generate system matrix & RHS vector. Logically collective. Parameters ---------- flag Whether to use the `DM`. Notes ----- By default `setDM` sets the `DM` as active, call ``setDMActive(False)`` after ``setDM(dm)`` to not have the `KSP` object use the `DM` to generate the matrices. See Also -------- PETSc.KSP, DM, setDM, petsc.KSPSetDMActive """ cdef PetscBool cflag = asBool(flag) CHKERR( KSPSetDMActive(self.ksp, cflag) ) # --- operators and preconditioner --- def setComputeRHS( self, rhs: KSPRHSFunction, args: tuple[Any, ...] | None = None, kargs: dict[str, Any] | None = None ) -> None: """Set routine to compute the right-hand side of the linear system. Logically collective. Parameters ---------- rhs Function which computes the right-hand side. args Positional arguments for callback function ``rhs``. kargs Keyword arguments for callback function ``rhs``. Notes ----- The routine you provide will be called each time you call `solve` to prepare the new right-hand side for that solve. See Also -------- PETSc.KSP, solve, petsc.KSPSetComputeRHS """ if args is None: args = () if kargs is None: kargs = {} context = (rhs, args, kargs) self.set_attr('__rhs__', context) CHKERR( KSPSetComputeRHS(self.ksp, KSP_ComputeRHS, context) ) def setComputeOperators( self, operators: KSPOperatorsFunction, args: tuple[Any, ...] | None = None, kargs: dict[str, Any] | None = None ) -> None: """Set routine to compute the linear operators. Logically collective. Parameters ---------- operators Function which computes the operators. args Positional arguments for callback function ``operators``. kargs Keyword arguments for callback function ``operators``. Notes ----- The user provided function `operators` will be called automatically at the very next call to `solve`. It will NOT be called at future `solve` calls unless either `setComputeOperators` or `setOperators` is called before that `solve` is called. This allows the same system to be solved several times with different right-hand side functions, but is a confusing API since one might expect it to be called for each `solve`. To reuse the same preconditioner for the next `solve` and not compute a new one based on the most recently computed matrix call `petsc.KSPSetReusePreconditioner`. See Also -------- PETSc.KSP, solve, setOperators, petsc.KSPSetComputeOperators petsc.KSPSetReusePreconditioner """ if args is None: args = () if kargs is None: kargs = {} context = (operators, args, kargs) self.set_attr('__operators__', context) CHKERR( KSPSetComputeOperators(self.ksp, KSP_ComputeOps, context) ) def setOperators(self, Mat A=None, Mat P=None) -> None: """Set matrix associated with the linear system. Collective. Set the matrix associated with the linear system and a (possibly) different one from which the preconditioner will be built. Parameters ---------- A Matrix that defines the linear system. P Matrix to be used in constructing the preconditioner, usually the same as ``A``. Notes ----- If you know the operator ``A`` has a null space you can use `Mat.setNullSpace` and `Mat.setTransposeNullSpace` to supply the null space to ``A`` and the `KSP` solvers will automatically use that null space as needed during the solution process. All future calls to `setOperators` must use the same size matrices! Passing `None` for ``A`` or ``P`` removes the matrix that is currently used. See Also -------- PETSc.KSP, solve, setComputeOperators, petsc.KSPSetOperators """ cdef PetscMat amat=NULL if A is not None: amat = A.mat cdef PetscMat pmat=amat if P is not None: pmat = P.mat CHKERR( KSPSetOperators(self.ksp, amat, pmat) ) def getOperators(self) -> tuple[Mat, Mat]: """Return the matrix associated with the linear system. Collective. Return the matrix associated with the linear system and a (possibly) different one used to construct the preconditioner. Returns ------- A : Mat Matrix that defines the linear system. P : Mat Matrix to be used in constructing the preconditioner, usually the same as ``A``. See Also -------- PETSc.KSP, solve, setOperators, petsc.KSPGetOperators """ cdef Mat A = Mat(), P = Mat() CHKERR( KSPGetOperators(self.ksp, &A.mat, &P.mat) ) CHKERR( PetscINCREF(A.obj) ) CHKERR( PetscINCREF(P.obj) ) return (A, P) def setPC(self, PC pc) -> None: """Set the preconditioner. Collective. Set the preconditioner to be used to calculate the application of the preconditioner on a vector. Parameters ---------- pc The preconditioner object See Also -------- PETSc.KSP, getPC, petsc.KSPSetPC """ CHKERR( KSPSetPC(self.ksp, pc.pc) ) def getPC(self) -> PC: """Return the preconditioner. Not collective. See Also -------- PETSc.KSP, setPC, petsc.KSPGetPC """ cdef PC pc = PC() CHKERR( KSPGetPC(self.ksp, &pc.pc) ) CHKERR( PetscINCREF(pc.obj) ) return pc # --- tolerances and convergence --- def setTolerances( self, rtol: float | None = None, atol: float | None = None, divtol: float | None = None, max_it: int | None = None ) -> None: """Set various tolerances used by the KSP convergence testers. Logically collective. Set the relative, absolute, divergence, and maximum iteration tolerances used by the default KSP convergence testers. Parameters ---------- rtol The relative convergence tolerance, relative decrease in the (possibly preconditioned) residual norm. atol The absolute convergence tolerance absolute size of the (possibly preconditioned) residual norm. dtol The divergence tolerance, amount (possibly preconditioned) residual norm can increase before `petsc.KSPConvergedDefault` concludes that the method is diverging. max_it Maximum number of iterations to use. Notes ----- Use `None` to retain the default value of any of the tolerances. See Also -------- petsc_options, getTolerances, setConvergenceTest petsc.KSPSetTolerances, petsc.KSPConvergedDefault """ cdef PetscReal crtol, catol, cdivtol crtol = catol = cdivtol = PETSC_DEFAULT; if rtol is not None: crtol = asReal(rtol) if atol is not None: catol = asReal(atol) if divtol is not None: cdivtol = asReal(divtol) cdef PetscInt cmaxits = PETSC_DEFAULT if max_it is not None: cmaxits = asInt(max_it) CHKERR( KSPSetTolerances(self.ksp, crtol, catol, cdivtol, cmaxits) ) def getTolerances(self) -> tuple[float, float, float, int]: """Return various tolerances used by the KSP convergence tests. Not collective. Return the relative, absolute, divergence, and maximum iteration tolerances used by the default KSP convergence tests. Returns ------- rtol : float The relative convergence tolerance atol : float The absolute convergence tolerance dtol : float The divergence tolerance maxits : int Maximum number of iterations See Also -------- setTolerances, petsc.KSPGetTolerances """ cdef PetscReal crtol=0, catol=0, cdivtol=0 cdef PetscInt cmaxits=0 CHKERR( KSPGetTolerances(self.ksp, &crtol, &catol, &cdivtol, &cmaxits) ) return (toReal(crtol), toReal(catol), toReal(cdivtol), toInt(cmaxits)) def setConvergenceTest( self, converged: KSPConvergenceTestFunction, args: tuple[Any, ...] | None = None, kargs: dict[str, Any] | None = None ) -> None: """Set the function to be used to determine convergence. Logically collective. Parameters ---------- converged Callback which computes the convergence. args Positional arguments for callback function. kargs Keyword arguments for callback function. Notes ----- Must be called after the KSP type has been set so put this after a call to `setType`, or `setFromOptions`. The default convergence test, `petsc.KSPConvergedDefault`, aborts if the residual grows to more than 10000 times the initial residual. The default is a combination of relative and absolute tolerances. The residual value that is tested may be an approximation; routines that need exact values should compute them. In the default PETSc convergence test, the precise values of reason are macros such as ``KSP_CONVERGED_RTOL``, which are defined in ``petsch``. See Also -------- setTolerances, getConvergenceTest, petsc.KSPSetConvergenceTest petsc.KSPConvergedDefault """ cdef PetscKSPNormType normtype = KSP_NORM_NONE cdef void* cctx = NULL if converged is not None: CHKERR( KSPSetConvergenceTest( self.ksp, KSP_Converged, NULL, NULL) ) if args is None: args = () if kargs is None: kargs = {} self.set_attr('__converged__', (converged, args, kargs)) else: CHKERR( KSPGetNormType(self.ksp, &normtype) ) if normtype != KSP_NORM_NONE: CHKERR( KSPConvergedDefaultCreate(&cctx) ) CHKERR( KSPSetConvergenceTest( self.ksp, KSPConvergedDefault, cctx, KSPConvergedDefaultDestroy) ) else: CHKERR( KSPSetConvergenceTest( self.ksp, KSPConvergedSkip, NULL, NULL) ) self.set_attr('__converged__', None) def getConvergenceTest(self) -> KSPConvergenceTestFunction: """Return the function to be used to determine convergence. Logically collective. See Also -------- setTolerances, setConvergenceTest, petsc.KSPGetConvergenceTest petsc.KSPConvergedDefault """ return self.get_attr('__converged__') def callConvergenceTest(self, its: int, rnorm: float) -> None: """Call the convergence test callback. Parameters ---------- its Number of iterations. rnorm The residual norm. Notes ----- This functionality is implemented in petsc4py. """ cdef PetscInt ival = asInt(its) cdef PetscReal rval = asReal(rnorm) cdef PetscKSPConvergedReason reason = KSP_CONVERGED_ITERATING CHKERR( KSPConvergenceTestCall(self.ksp, ival, rval, &reason) ) return reason def setConvergenceHistory( self, length: int | None = None, reset: bool = False ) -> None: """Set the array used to hold the residual history. Not collective. If set, this array will contain the residual norms computed at each iteration of the solver. Parameters ---------- length Length of array to store history in. reset `True` indicates the history counter is reset to zero for each new linear solve. Notes ----- If ``length`` is not provided or `None` then a default array of length 10000 is allocated. If the array is not long enough then once the iterations is longer than the array length `solve` stops recording the history. See Also -------- getConvergenceHistory, petsc.KSPSetResidualHistory """ cdef PetscReal *data = NULL cdef PetscInt size = 10000 cdef PetscBool flag = PETSC_FALSE if length is True: pass elif length is not None: size = asInt(length) if size < 0: size = 10000 if reset: flag = PETSC_TRUE cdef object hist = oarray_r(empty_r(size), NULL, &data) self.set_attr('__history__', hist) CHKERR( KSPSetResidualHistory(self.ksp, data, size, flag) ) def getConvergenceHistory(self) -> ArrayReal: """Return array containing the residual history. Not collective. See Also -------- setConvergenceHistory, petsc.KSPGetResidualHistory """ cdef const PetscReal *data = NULL cdef PetscInt size = 0 CHKERR( KSPGetResidualHistory(self.ksp, &data, &size) ) return array_r(size, data) def logConvergenceHistory(self, rnorm: float) -> None: """Add residual to convergence history. Logically collective. Parameters ---------- rnorm Residual norm to be added to convergence history. """ cdef PetscReal rval = asReal(rnorm) CHKERR( KSPLogResidualHistory(self.ksp, rval) ) # --- monitoring --- def setMonitor(self, monitor: KSPMonitorFunction, args: tuple[Any, ...] | None = None, kargs: dict[str, Any] | None = None ) -> None: """Set additional function to monitor the residual. Logically collective. Set an ADDITIONAL function to be called at every iteration to monitor the residual/error etc. Parameters ---------- monitor Callback which monitors the convergence. args Positional arguments for callback function. kargs Keyword arguments for callback function. Notes ----- The default is to do nothing. To print the residual, or preconditioned residual if ``setNormType(NORM_PRECONDITIONED)`` was called, use `monitor` as the monitoring routine, with a `PETSc.Viewer.ASCII` as the context. Several different monitoring routines may be set by calling `setMonitor` multiple times; all will be called in the order in which they were set. See Also -------- petsc_options, getMonitor, monitor, monitorCancel, petsc.KSPMonitorSet """ if monitor is None: return cdef object monitorlist = self.get_attr('__monitor__') if monitorlist is None: monitorlist = [] self.set_attr('__monitor__', monitorlist) CHKERR( KSPMonitorSet(self.ksp, KSP_Monitor, NULL, NULL) ) if args is None: args = () if kargs is None: kargs = {} monitorlist.append((monitor, args, kargs)) def getMonitor(self) -> KSPMonitorFunction: """Return function used to monitor the residual. Not collective. See Also -------- petsc_options, setMonitor, monitor, monitorCancel petsc.KSPGetMonitorContext """ return self.get_attr('__monitor__') def monitorCancel(self) -> None: """Clear all monitors for a `KSP` object. Logically collective. See Also -------- petsc_options, getMonitor, setMonitor, monitor, petsc.KSPMonitorCancel """ CHKERR( KSPMonitorCancel(self.ksp) ) self.set_attr('__monitor__', None) cancelMonitor = monitorCancel def monitor(self, its: int, rnorm: float) -> None: """Run the user provided monitor routines, if they exist. Collective. Notes ----- This routine is called by the `KSP` implementations. It does not typically need to be called by the user. See Also -------- setMonitor, petsc.KSPMonitor """ cdef PetscInt ival = asInt(its) cdef PetscReal rval = asReal(rnorm) CHKERR( KSPMonitor(self.ksp, ival, rval) ) # --- customization --- def setPCSide(self, side: PC.Side) -> None: """Set the preconditioning side. Logically collective. Parameters ---------- side The preconditioning side (see `PC.Side`). Notes ----- Left preconditioning is used by default for most Krylov methods except `Type.FGMRES` which only supports right preconditioning. For methods changing the side of the preconditioner changes the norm type that is used, see `setNormType`. Symmetric preconditioning is currently available only for the `Type.QCG` method. Note, however, that symmetric preconditioning can be emulated by using either right or left preconditioning and a pre or post processing step. Setting the PC side often affects the default norm type. See `setNormType` for details. See Also -------- PC.Side, petsc_options, getPCSide, setNormType, getNormType petsc.KSPSetPCSide """ CHKERR( KSPSetPCSide(self.ksp, side) ) def getPCSide(self) -> PC.Side: """Return the preconditioning side. Not collective. See Also -------- petsc_options, setPCSide, setNormType, getNormType, petsc.KSPGetPCSide """ cdef PetscPCSide side = PC_LEFT CHKERR( KSPGetPCSide(self.ksp, &side) ) return side def setNormType(self, normtype: NormType) -> None: """Set the norm that is used for convergence testing. Parameters ---------- normtype The norm type to use (see `NormType`). Notes ----- Not all combinations of preconditioner side (see `setPCSide`) and norm type are supported by all Krylov methods. If only one is set, PETSc tries to automatically change the other to find a compatible pair. If no such combination is supported, PETSc will generate an error. See Also -------- NormType, petsc_options, setUp, solve, destroy, setPCSide, getPCSide NormType, petsc.KSPSetNormType, petsc.KSPConvergedSkip petsc.KSPSetCheckNormIteration """ CHKERR( KSPSetNormType(self.ksp, normtype) ) def getNormType(self) -> NormType: """Return the norm that is used for convergence testing. Not collective. See Also -------- NormType, setNormType, petsc.KSPGetNormType, petsc.KSPConvergedSkip """ cdef PetscKSPNormType normtype = KSP_NORM_NONE CHKERR( KSPGetNormType(self.ksp, &normtype) ) return normtype def setComputeEigenvalues(self, flag: bool) -> None: """Set a flag to compute eigenvalues. Set a flag so that the extreme eigenvalues values will be calculated via a Lanczos or Arnoldi process as the linear system is solved. Parameters ---------- flag Boolean whether to compute eigenvalues (or not). Notes ----- Currently this option is not valid for all iterative methods. See Also -------- getComputeEigenvalues, petsc.KSPSetComputeEigenvalues """ cdef PetscBool compute = asBool(flag) CHKERR( KSPSetComputeEigenvalues(self.ksp, compute) ) def getComputeEigenvalues(self) -> bool: """Return flag indicating whether eigenvalues will be calculated. Not collective. Return the flag indicating that the extreme eigenvalues values will be calculated via a Lanczos or Arnoldi process as the linear system is solved. See Also -------- setComputeEigenvalues, petsc.KSPSetComputeEigenvalues """ cdef PetscBool flag = PETSC_FALSE CHKERR( KSPGetComputeEigenvalues(self.ksp, &flag) ) return toBool(flag) def setComputeSingularValues(self, flag: bool) -> None: """Set flag to calculate singular values. Logically collective. Set a flag so that the extreme singular values will be calculated via a Lanczos or Arnoldi process as the linear system is solved. Parameters ---------- flag Boolean whether to compute singular values (or not). Notes ----- Currently this option is not valid for all iterative methods. See Also -------- getComputeSingularValues, petsc.KSPSetComputeSingularValues """ cdef PetscBool compute = asBool(flag) CHKERR( KSPSetComputeSingularValues(self.ksp, compute) ) def getComputeSingularValues(self) -> bool: """Return flag indicating whether singular values will be calculated. Return the flag indicating whether the extreme singular values will be calculated via a Lanczos or Arnoldi process as the linear system is solved. See Also -------- setComputeSingularValues, petsc.KSPGetComputeSingularValues """ cdef PetscBool flag = PETSC_FALSE CHKERR( KSPGetComputeSingularValues(self.ksp, &flag) ) return toBool(flag) # --- initial guess --- def setInitialGuessNonzero(self, flag: bool) -> None: """Tell the iterative solver that the initial guess is nonzero. Logically collective. Otherwise KSP assumes the initial guess is to be zero (and thus zeros it out before solving). Parameters ---------- flag `True` indicates the guess is non-zero, `False` indicates the guess is zero. See Also -------- petsc.KSPSetInitialGuessNonzero """ cdef PetscBool guess_nonzero = asBool(flag) CHKERR( KSPSetInitialGuessNonzero(self.ksp, guess_nonzero) ) def getInitialGuessNonzero(self) -> bool: """Determine whether the KSP solver uses a zero initial guess. Not collective. See Also -------- petsc.KSPGetInitialGuessNonzero """ cdef PetscBool flag = PETSC_FALSE CHKERR( KSPGetInitialGuessNonzero(self.ksp, &flag) ) return toBool(flag) def setInitialGuessKnoll(self, flag: bool) -> None: """Tell solver to use `PC.apply` to compute the initial guess. Logically collective. This is the Knoll trick. Parameters ---------- flag `True` uses Knoll trick. See Also -------- petsc.KSPSetInitialGuessKnoll """ cdef PetscBool guess_knoll = asBool(flag) CHKERR( KSPSetInitialGuessKnoll(self.ksp, guess_knoll) ) def getInitialGuessKnoll(self) -> bool: """Determine whether the KSP solver is using the Knoll trick. This uses the Knoll trick; using `PC.apply` to compute the initial guess. See Also -------- petsc.KSPGetInitialGuessKnoll """ cdef PetscBool flag = PETSC_FALSE CHKERR( KSPGetInitialGuessKnoll(self.ksp, &flag) ) return toBool(flag) def setUseFischerGuess(self, model: int, size: int) -> None: """Use the Paul Fischer algorithm to compute initial guesses. Use the Paul Fischer algorithm or its variants to compute initial guesses for a set of solves with related right hand sides. Parameters ---------- model Use model ``1``, model ``2``, model ``3``, any other number to turn it off. size Size of subspace used to generate initial guess. See Also -------- petsc.KSPSetUseFischerGuess """ cdef PetscInt ival1 = asInt(model) cdef PetscInt ival2 = asInt(size) CHKERR( KSPSetUseFischerGuess(self.ksp, ival1, ival2) ) # --- solving --- def setUp(self) -> None: """Set up internal data structures for an iterative solver. Collective. See Also -------- petsc.KSPSetUp """ CHKERR( KSPSetUp(self.ksp) ) def reset(self) -> None: """Resets a KSP context. Collective. Resets a KSP context to the ``kspsetupcalled = 0`` state and removes any allocated Vecs and Mats. See Also -------- petsc.KSPReset """ CHKERR( KSPReset(self.ksp) ) def setUpOnBlocks(self) -> None: """Set up the preconditioner for each block in a block method. Collective. Methods include: block Jacobi, block Gauss-Seidel, and overlapping Schwarz methods. See Also -------- petsc.KSPSetUpOnBlocks """ CHKERR( KSPSetUpOnBlocks(self.ksp) ) def solve(self, Vec b, Vec x) -> None: """Solve the linear system. Collective. Parameters ---------- b Right hand side vector. x Solution vector. Notes ----- If one uses `setDM` then ``x`` or ``b`` need not be passed. Use `getSolution` to access the solution in this case. The operator is specified with `setOperators`. `solve` will normally return without generating an error regardless of whether the linear system was solved or if constructing the preconditioner failed. Call `getConvergedReason` to determine if the solver converged or failed and why. The option ``-ksp_error_if_not_converged`` or function `setErrorIfNotConverged` will cause `solve` to error as soon as an error occurs in the linear solver. In inner solves, ``DIVERGED_MAX_IT`` is not treated as an error because when using nested solvers it may be fine that inner solvers in the preconditioner do not converge during the solution process. The number of iterations can be obtained from `its`. If you provide a matrix that has a `Mat.setNullSpace` and `Mat.setTransposeNullSpace` this will use that information to solve singular systems in the least squares sense with a norm minimizing solution. Ax = b where b = bₚ + bₜ where bₜ is not in the range of A (and hence by the fundamental theorem of linear algebra is in the nullspace(Aᵀ), see `Mat.setNullSpace`. KSP first removes bₜ producing the linear system Ax = bₚ (which has multiple solutions) and solves this to find the ∥x∥ minimizing solution (and hence it finds the solution x orthogonal to the nullspace(A). The algorithm is simply in each iteration of the Krylov method we remove the nullspace(A) from the search direction thus the solution which is a linear combination of the search directions has no component in the nullspace(A). We recommend always using `Type.GMRES` for such singular systems. If nullspace(A) = nullspace(Aᵀ) (note symmetric matrices always satisfy this property) then both left and right preconditioning will work If nullspace(A) != nullspace(Aᵀ) then left preconditioning will work but right preconditioning may not work (or it may). If using a direct method (e.g., via the KSP solver `Type.PREONLY` and a preconditioner such as `PC.Type.LU` or `PC.Type.ILU`, then its=1. See `setTolerances` for more details. **Understanding Convergence** The routines `setMonitor` and `computeEigenvalues` provide information on additional options to monitor convergence and print eigenvalue information. See Also -------- create, setUp, destroy, setTolerances, is_converged, solveTranspose, its Mat.setNullSpace, Mat.setTransposeNullSpace, Type, setErrorIfNotConverged petsc_options, petsc.KSPSolve """ cdef PetscVec b_vec = NULL cdef PetscVec x_vec = NULL if b is not None: b_vec = b.vec if x is not None: x_vec = x.vec CHKERR( KSPSolve(self.ksp, b_vec, x_vec) ) def solveTranspose(self, Vec b, Vec x) -> None: """Solve the transpose of a linear system. Collective. Parameters ---------- b Right hand side vector. x Solution vector. Notes ----- For complex numbers this solve the non-Hermitian transpose system. See Also -------- solve, petsc.KSPSolveTranspose """ CHKERR( KSPSolveTranspose(self.ksp, b.vec, x.vec) ) def matSolve(self, Mat B, Mat X) -> None: """Solve a linear system with multiple right-hand sides. These are stored as a `Mat.Type.DENSE`. Unlike `solve`, ``B`` and ``X`` must be different matrices. Parameters ---------- B Block of right-hand sides. X Block of solutions. See Also -------- solve, petsc.KSPMatSolve """ CHKERR( KSPMatSolve(self.ksp, B.mat, X.mat) ) def matSolveTranspose(self, Mat B, Mat X) -> None: """Solve the transpose of a linear system with multiple RHS. Parameters ---------- B Block of right-hand sides. X Block of solutions. See Also -------- solveTranspose, petsc.KSPMatSolve """ CHKERR( KSPMatSolveTranspose(self.ksp, B.mat, X.mat) ) def setIterationNumber(self, its: int) -> None: """Use `its` property.""" cdef PetscInt ival = asInt(its) CHKERR( KSPSetIterationNumber(self.ksp, ival) ) def getIterationNumber(self) -> int: """Use `its` property.""" cdef PetscInt ival = 0 CHKERR( KSPGetIterationNumber(self.ksp, &ival) ) return toInt(ival) def setResidualNorm(self, rnorm: float) -> None: """Use `norm` property.""" cdef PetscReal rval = asReal(rnorm) CHKERR( KSPSetResidualNorm(self.ksp, rval) ) def getResidualNorm(self) -> float: """Use `norm` property.""" cdef PetscReal rval = 0 CHKERR( KSPGetResidualNorm(self.ksp, &rval) ) return toReal(rval) def setConvergedReason(self, reason: KSP.ConvergedReason) -> None: """Use `reason` property.""" cdef PetscKSPConvergedReason val = reason CHKERR( KSPSetConvergedReason(self.ksp, val) ) def getConvergedReason(self) -> KSP.ConvergedReason: """Use `reason` property.""" cdef PetscKSPConvergedReason reason = KSP_CONVERGED_ITERATING CHKERR( KSPGetConvergedReason(self.ksp, &reason) ) return reason def setHPDDMType(self, hpddm_type: HPDDMType) -> None: """Set the Krylov solver type. Collective. Parameters ---------- hpddm_type The type of Krylov solver to use. See Also -------- petsc.KSPHPDDMSetType """ cdef PetscKSPHPDDMType ctype = hpddm_type CHKERR( KSPHPDDMSetType(self.ksp, ctype) ) def getHPDDMType(self) -> HPDDMType: """Return the Krylov solver type. See Also -------- petsc.KSPHPDDMGetType """ cdef PetscKSPHPDDMType cval = KSP_HPDDM_TYPE_GMRES CHKERR( KSPHPDDMGetType(self.ksp, &cval) ) return cval def setErrorIfNotConverged(self, flag: bool) -> None: """Cause `solve` to generate an error if not converged. Logically collective. Parameters ---------- flag `True` enables this behavior. See Also -------- petsc.KSPSetErrorIfNotConverged """ cdef PetscBool ernc = asBool(flag) CHKERR( KSPSetErrorIfNotConverged(self.ksp, ernc) ) def getErrorIfNotConverged(self) -> bool: """Return the flag indicating the solver will error if divergent. Not collective. See Also -------- petsc.KSPGetErrorIfNotConverged """ cdef PetscBool flag = PETSC_FALSE CHKERR( KSPGetErrorIfNotConverged(self.ksp, &flag) ) return toBool(flag) def getRhs(self) -> Vec: """Return the right-hand side vector for the linear system. Not collective. See Also -------- petsc.KSPGetRhs """ cdef Vec vec = Vec() CHKERR( KSPGetRhs(self.ksp, &vec.vec) ) CHKERR( PetscINCREF(vec.obj) ) return vec def getSolution(self) -> Vec: """Return the solution for the linear system to be solved. Note that this may not be the solution that is stored during the iterative process. See Also -------- petsc.KSPGetSolution """ cdef Vec vec = Vec() CHKERR( KSPGetSolution(self.ksp, &vec.vec) ) CHKERR( PetscINCREF(vec.obj) ) return vec def getWorkVecs( self, right: int | None = None, left: int | None = None ) -> tuple[list[Vec], list[Vec]] | list[Vec] | None: """Create working vectors. Parameters ---------- right Number of right hand vectors to allocate. left Number of left hand vectors to allocate. Returns ------- R : list of Vec List of correctly allocated right hand vectors. L : list of Vec List of correctly allocated left hand vectors. """ cdef bint R = right is not None cdef bint L = left is not None cdef PetscInt i=0, nr=0, nl=0 cdef PetscVec *vr=NULL, *vl=NULL if R: nr = asInt(right) if L: nl = asInt(left) cdef object vecsr = [] if R else None cdef object vecsl = [] if L else None CHKERR( KSPCreateVecs(self.ksp, nr, &vr, nl, &vr) ) try: for i from 0 <= i < nr: vecsr.append(ref_Vec(vr[i])) for i from 0 <= i < nl: vecsl.append(ref_Vec(vl[i])) finally: if nr > 0 and vr != NULL: VecDestroyVecs(nr, &vr) # XXX errors? if nl > 0 and vl !=NULL: VecDestroyVecs(nl, &vl) # XXX errors? # if R and L: return (vecsr, vecsl) elif R: return vecsr elif L: return vecsl else: return None def buildSolution(self, Vec x=None) -> Vec: """Return the solution vector. Parameters ---------- x Optional vector to store the solution. See Also -------- buildResidual, petsc.KSPBuildSolution """ if x is None: x = Vec() if x.vec == NULL: CHKERR( KSPGetSolution(self.ksp, &x.vec) ) CHKERR( VecDuplicate(x.vec, &x.vec) ) CHKERR( KSPBuildSolution(self.ksp, x.vec, NULL) ) return x def buildResidual(self, Vec r=None) -> Vec: """Return the residual of the linear system. Parameters ---------- r Optional vector to use for the result. See Also -------- buildSolution, petsc.KSPBuildResidual """ if r is None: r = Vec() if r.vec == NULL: CHKERR( KSPGetRhs(self.ksp, &r.vec) ) CHKERR( VecDuplicate(r.vec, &r.vec) ) CHKERR( KSPBuildResidual(self.ksp , NULL, r.vec, &r.vec) ) return r def computeEigenvalues(self) -> ArrayComplex: """Compute the extreme eigenvalues for the preconditioned operator. See Also -------- petsc.KSPComputeEigenvalues """ cdef PetscInt its = 0 cdef PetscInt neig = 0 cdef PetscReal *rdata = NULL cdef PetscReal *idata = NULL CHKERR( KSPGetIterationNumber(self.ksp, &its) ) cdef ndarray r = oarray_r(empty_r(its), NULL, &rdata) cdef ndarray i = oarray_r(empty_r(its), NULL, &idata) CHKERR( KSPComputeEigenvalues(self.ksp, its, rdata, idata, &neig) ) eigen = empty_c(neig) eigen.real = r[:neig] eigen.imag = i[:neig] return eigen def computeExtremeSingularValues(self) -> tuple[float, float]: """Compute the extreme singular values for the preconditioned operator. Returns ------- smax : float The maximum singular value. smin : float The minimum singular value. See Also -------- petsc.KSPComputeExtremeSingularValues """ cdef PetscReal smax = 0 cdef PetscReal smin = 0 CHKERR( KSPComputeExtremeSingularValues(self.ksp, &smax, &smin) ) return toReal(smax), toReal(smin) # --- GMRES --- def setGMRESRestart(self, restart: int) -> None: """Set number of iterations at which KSP restarts. Suitable KSPs are: KSPGMRES, KSPFGMRES and KSPLGMRES. Parameters ---------- restart Integer restart value. See Also -------- petsc.KSPGMRESSetRestart """ cdef PetscInt ival = asInt(restart) CHKERR( KSPGMRESSetRestart(self.ksp, ival) ) # --- Python --- def createPython( self, context: Any = None, comm: Comm | None = None ) -> Self: """Create a linear solver of Python type. Collective. Parameters ---------- context An instance of the Python class implementing the required methods. comm MPI communicator, defaults to `Sys.getDefaultComm`. See Also -------- petsc_python_ksp, setType, setPythonContext, Type.PYTHON """ cdef MPI_Comm ccomm = def_Comm(comm, PETSC_COMM_DEFAULT) cdef PetscKSP newksp = NULL CHKERR( KSPCreate(ccomm, &newksp) ) CHKERR( PetscCLEAR(self.obj) ); self.ksp = newksp CHKERR( KSPSetType(self.ksp, KSPPYTHON) ) CHKERR( KSPPythonSetContext(self.ksp, context) ) return self def setPythonContext(self, context: Any | None = None) -> None: """Set the instance of the class implementing Python methods. Not collective. See Also -------- petsc_python_ksp, getPythonContext """ CHKERR( KSPPythonSetContext(self.ksp, context) ) def getPythonContext(self) -> Any: """Return the instance of the class implementing Python methods. Not collective. See Also -------- petsc_python_ksp, setPythonContext """ cdef void *context = NULL CHKERR( KSPPythonGetContext(self.ksp, &context) ) if context == NULL: return None else: return context def setPythonType(self, py_type: str) -> None: """Set the fully qualified Python name of the class to be used. Collective. See Also -------- petsc_python_ksp, setPythonContext, getPythonType petsc.KSPPythonSetType """ cdef const char *cval = NULL py_type = str2bytes(py_type, &cval) CHKERR( KSPPythonSetType(self.ksp, cval) ) def getPythonType(self) -> str: """Return the fully qualified Python name of the class used by the solver. Not collective. See Also -------- petsc_python_ksp, setPythonContext, setPythonType petsc.KSPPythonGetType """ cdef const char *cval = NULL CHKERR( KSPPythonGetType(self.ksp, &cval) ) return bytes2str(cval) # --- application context --- property appctx: """The solver application context.""" def __get__(self) -> Any: return self.getAppCtx() def __set__(self, value): self.setAppCtx(value) # --- discretization space --- property dm: """The solver `DM`.""" def __get__(self) -> DM: return self.getDM() def __set__(self, value): self.setDM(value) # --- vectors --- property vec_sol: """The solution vector.""" def __get__(self) -> Vec: return self.getSolution() property vec_rhs: """The right-hand side vector.""" def __get__(self) -> Vec: return self.getRhs() # --- operators --- property mat_op: """The system matrix operator.""" def __get__(self) -> Mat: return self.getOperators()[0] property mat_pc: """The preconditioner operator.""" def __get__(self) -> Mat: return self.getOperators()[1] # --- initial guess --- property guess_nonzero: """Whether guess is non-zero.""" def __get__(self) -> bool: return self.getInitialGuessNonzero() def __set__(self, value): self.setInitialGuessNonzero(value) property guess_knoll: """Whether solver uses Knoll trick.""" def __get__(self) -> bool: return self.getInitialGuessKnoll() def __set__(self, value): self.setInitialGuessKnoll(value) # --- preconditioner --- property pc: """The `PC` of the solver.""" def __get__(self) -> PC: return self.getPC() property pc_side: """The side on which preconditioning is performed.""" def __get__(self) -> PC.Side: return self.getPCSide() def __set__(self, value): self.setPCSide(value) property norm_type: """The norm used by the solver.""" def __get__(self) -> NormType: return self.getNormType() def __set__(self, value): self.setNormType(value) # --- tolerances --- property rtol: """The relative tolerance of the solver.""" def __get__(self) -> float: return self.getTolerances()[0] def __set__(self, value): self.setTolerances(rtol=value) property atol: """The absolute tolerance of the solver.""" def __get__(self) -> float: return self.getTolerances()[1] def __set__(self, value): self.setTolerances(atol=value) property divtol: """The divergence tolerance of the solver.""" def __get__(self) -> float: return self.getTolerances()[2] def __set__(self, value): self.setTolerances(divtol=value) property max_it: """The maximum number of iteration the solver may take.""" def __get__(self) -> int: return self.getTolerances()[3] def __set__(self, value): self.setTolerances(max_it=value) # --- iteration --- property its: """The current number of iterations the solver has taken.""" def __get__(self) -> int: return self.getIterationNumber() def __set__(self, value): self.setIterationNumber(value) property norm: """The norm of the residual at the current iteration.""" def __get__(self) -> float: return self.getResidualNorm() def __set__(self, value): self.setResidualNorm(value) property history: """The convergence history of the solver.""" def __get__(self) -> ndarray: return self.getConvergenceHistory() # --- convergence --- property reason: """The converged reason.""" def __get__(self) -> KSP.ConvergedReason: return self.getConvergedReason() def __set__(self, value): self.setConvergedReason(value) property is_iterating: """Boolean indicating if the solver has not converged yet.""" def __get__(self) -> bool: return self.reason == 0 property is_converged: """Boolean indicating if the solver has converged.""" def __get__(self) -> bool: return self.reason > 0 property is_diverged: """Boolean indicating if the solver has failed.""" def __get__(self) -> bool: return self.reason < 0 # -------------------------------------------------------------------- del KSPType del KSPNormType del KSPConvergedReason del KSPHPDDMType # -------------------------------------------------------------------- ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/src/petsc4py/PETSc/Log.pyx0000644000175000017500000003572714567251135017150 0ustar00balaybalay# -------------------------------------------------------------------- cdef object functools = None import functools # -------------------------------------------------------------------- cdef class Log: """Logging support.""" @classmethod def Stage(cls, name): if not name: raise ValueError("empty name") cdef const char *cname = NULL name = str2bytes(name, &cname) cdef PetscLogStage stageid = -1 cdef LogStage stage = get_LogStage(name) if stage is not None: return stage CHKERR( PetscLogStageFindId(cname, &stageid) ) if stageid == -1: CHKERR( PetscLogStageRegister(cname, &stageid) ) stage = reg_LogStage(name, stageid) return stage @classmethod def Class(cls, name): if not name: raise ValueError("empty name") cdef const char *cname = NULL name = str2bytes(name, &cname) cdef PetscLogClass classid = -1 cdef LogClass klass = get_LogClass(name) if klass is not None: return klass CHKERR( PetscLogClassFindId(cname, &classid) ) if classid == -1: CHKERR( PetscLogClassRegister(cname, &classid) ) klass = reg_LogClass(name, classid) return klass @classmethod def Event(cls, name, klass=None): if not name: raise ValueError("empty name") cdef const char *cname = NULL name = str2bytes(name, &cname) cdef PetscLogClass classid = PETSC_OBJECT_CLASSID cdef PetscLogEvent eventid = -1 if klass is not None: classid = klass cdef LogEvent event = get_LogEvent(name) if event is not None: return event CHKERR( PetscLogEventFindId(cname, &eventid) ) if eventid == -1: CHKERR( PetscLogEventRegister(cname, classid, &eventid) ) event = reg_LogEvent(name, eventid) return event @classmethod def begin(cls): """Turn on logging of objects and events. Collective. See Also -------- petsc.PetscLogDefaultBegin """ CHKERR( PetscLogDefaultBegin() ) @classmethod def view(cls, Viewer viewer=None) -> None: """Print the log. Collective. Parameters ---------- viewer A `Viewer` instance or `None` for the default viewer. See Also -------- petsc_options, petsc.PetscLogView """ cdef PetscViewer vwr = NULL if viewer is not None: vwr = viewer.vwr if vwr == NULL: vwr = PETSC_VIEWER_STDOUT_WORLD CHKERR( PetscLogView(vwr) ) @classmethod def logFlops(cls, flops: float) -> None: """Add floating point operations to the current event. Not collective. Parameters ---------- flops The number of flops to log. See Also -------- petsc.PetscLogFlops """ cdef PetscLogDouble cflops=flops CHKERR( PetscLogFlops(cflops) ) @classmethod def addFlops(cls, flops: float) -> None: """Add floating point operations to the current event. Not collective. Parameters ---------- flops The number of flops to log. Notes ----- This method exists for backward compatibility. See Also -------- logFlops, petsc.PetscLogFlops """ cdef PetscLogDouble cflops=flops CHKERR( PetscLogFlops(cflops) ) @classmethod def getFlops(cls) -> float: """Return the number of flops used on this processor since the program began. Not collective. Returns ------- float Number of floating point operations. See Also -------- petsc.PetscGetFlops """ cdef PetscLogDouble cflops=0 CHKERR( PetscGetFlops(&cflops) ) return cflops @classmethod def getTime(cls) -> float: """Return the current time of day in seconds. Collective. Returns ------- wctime : float Current time. See Also -------- petsc.PetscTime """ cdef PetscLogDouble wctime=0 CHKERR( PetscTime(&wctime) ) return wctime @classmethod def getCPUTime(cls) -> float: """Return the CPU time.""" cdef PetscLogDouble cputime=0 CHKERR( PetscGetCPUTime(&cputime) ) return cputime @classmethod def EventDecorator(cls, name=None, klass=None): """Decorate a function with a `PETSc` event.""" def decorator(func): @functools.wraps(func) def wrapped_func(*args, **kwargs): if name: name_ = name else: name_ = ".".join([func.__module__, getattr(func, "__qualname__", func.__name__)]) with cls.Event(name_, klass): return func(*args, **kwargs) return wrapped_func return decorator @classmethod def isActive(cls) -> bool: """Return whether logging is currently in progress. Not collective. See Also -------- petsc.PetscLogIsActive """ cdef PetscBool flag = PETSC_FALSE CHKERR( PetscLogIsActive(&flag) ) return toBool(flag) # -------------------------------------------------------------------- cdef class LogStage: """Logging support for different stages.""" cdef readonly PetscLogStage id def __cinit__(self): self.id = 0 def __int__(self): return self.id def __enter__(self): self.push() return self def __exit__(self, *exc): self.pop() # def push(self) -> None: """Push a stage on the logging stack. Logically collective. See Also -------- LogStage.pop, petsc.PetscLogStagePush """ CHKERR( PetscLogStagePush(self.id) ) def pop(self) -> None: """Pop a stage from the logging stack. Logically collective. See Also -------- LogStage.push, petsc.PetscLogStagePop """ self # unused CHKERR( PetscLogStagePop() ) # def getName(self): cdef const char *cval = NULL CHKERR( PetscLogStageFindName(self.id, &cval) ) return bytes2str(cval) property name: def __get__(self): return self.getName() def __set__(self, value): self; value; # unused raise TypeError("readonly attribute") # def activate(self) -> None: """Activate the stage. Logically collective. See Also -------- petsc.PetscLogStageSetActive """ CHKERR( PetscLogStageSetActive(self.id, PETSC_TRUE) ) def deactivate(self) -> None: """Deactivate the stage. Logically collective. See Also -------- petsc.PetscLogStageSetActive """ CHKERR( PetscLogStageSetActive(self.id, PETSC_FALSE) ) def getActive(self) -> bool: """Check if the stage is activated. Not collective. See Also -------- petsc.PetscLogStageGetActive """ cdef PetscBool flag = PETSC_FALSE CHKERR( PetscLogStageGetActive(self.id, &flag) ) return toBool(flag) def setActive(self, flag: bool) -> None: """Activate or deactivate the current stage. Logically collective. See Also -------- petsc.PetscLogStageSetActive """ cdef PetscBool tval = PETSC_FALSE if flag: tval = PETSC_TRUE CHKERR( PetscLogStageSetActive(self.id, tval) ) property active: def __get__(self): return self.getActive() def __set__(self, value): self.setActive(value) # def getVisible(self) -> bool: """Return whether the stage is visible. Not collective. See Also -------- LogStage.setVisible, petsc.PetscLogStageSetVisible """ cdef PetscBool flag = PETSC_FALSE CHKERR( PetscLogStageGetVisible(self.id, &flag) ) return toBool(flag) def setVisible(self, flag: bool) -> None: """Set the visibility of the stage. Logically collective. Parameters ---------- flag `True` to make the stage visible, `False` otherwise. See Also -------- LogStage.getVisible, petsc.PetscLogStageSetVisible """ cdef PetscBool tval = PETSC_FALSE if flag: tval = PETSC_TRUE CHKERR( PetscLogStageSetVisible(self.id, tval) ) property visible: def __get__(self): return self.getVisible() def __set__(self, value): self.setVisible(value) cdef dict stage_registry = { } cdef LogStage get_LogStage(object name): return stage_registry.get(name) cdef LogStage reg_LogStage(object name, PetscLogStage stageid): cdef LogStage stage = LogStage() stage.id = stageid stage_registry[name] = stage return stage # -------------------------------------------------------------------- cdef class LogClass: cdef readonly PetscLogClass id def __cinit__(self): self.id = PETSC_OBJECT_CLASSID def __int__(self): return self.id # def getName(self): cdef const char *cval = NULL CHKERR( PetscLogClassFindName(self.id, &cval) ) return bytes2str(cval) property name: def __get__(self): return self.getName() def __set__(self, value): self; value; # unused raise TypeError("readonly attribute") # def activate(self): CHKERR( PetscLogClassActivate(self.id) ) def deactivate(self): CHKERR( PetscLogClassDeactivate(self.id) ) def getActive(self): self # unused raise NotImplementedError def setActive(self, flag): if flag: CHKERR( PetscLogClassActivate(self.id) ) else: CHKERR( PetscLogClassDeactivate(self.id) ) property active: def __get__(self): return self.getActive() def __set__(self, value): self.setActive(value) cdef dict class_registry = { } cdef LogClass get_LogClass(object name): return class_registry.get(name) cdef LogClass reg_LogClass(object name, PetscLogClass classid): cdef LogClass klass = LogClass() klass.id = classid class_registry[name] = klass return klass # -------------------------------------------------------------------- cdef class LogEvent: cdef readonly PetscLogEvent id def __cinit__(self): self.id = 0 def __int__(self): return self.id def __enter__(self): self.begin() return self def __exit__(self, *exc): self.end() def begin(self, *objs) -> None: """Log the beginning of a user event. Collective. Parameters ---------- *objs objects associated with the event See Also -------- petsc.PetscLogEventBegin """ cdef PetscObject o[4] event_args2objs(objs, o) CHKERR( PetscLogEventBegin(self.id, o[0], o[1], o[2], o[3]) ) def end(self, *objs) -> None: """Log the end of a user event. Collective. Parameters ---------- *objs Objects associated with the event. See Also -------- petsc.PetscLogEventEnd """ cdef PetscObject o[4] event_args2objs(objs, o) CHKERR( PetscLogEventEnd(self.id, o[0], o[1], o[2], o[3]) ) # def getName(self): cdef const char *cval = NULL CHKERR( PetscLogEventFindName(self.id, &cval) ) return bytes2str(cval) property name: def __get__(self): return self.getName() def __set__(self, value): self; value; # unused raise TypeError("readonly attribute") # def activate(self) -> None: """Indicate that the event should be logged. Logically collective. See Also -------- petsc.PetscLogEventActivate """ CHKERR( PetscLogEventActivate(self.id) ) def deactivate(self) -> None: """Indicate that the event should not be logged. Logically collective. See Also -------- petsc.PetscLogEventDeactivate """ CHKERR( PetscLogEventDeactivate(self.id) ) def getActive(self): self # unused raise NotImplementedError def setActive(self, flag: bool) -> None: """Indicate whether or not the event should be logged. Logically collective. Parameters ---------- flag Activate or deactivate the event. See Also -------- petsc.PetscLogEventDeactivate, petsc.PetscLogEventActivate """ if flag: CHKERR( PetscLogEventActivate(self.id) ) else: CHKERR( PetscLogEventDeactivate(self.id) ) property active: def __get__(self): return self.getActive() def __set__(self, value): self.setActive(value) def getActiveAll(self): self # unused raise NotImplementedError def setActiveAll(self, flag: bool) -> None: """Turn on logging of all events. Logically collective. Parameters ---------- flag Activate (if `True`) or deactivate (if `False`) the logging of all events. See Also -------- petsc.PetscLogEventSetActiveAll """ cdef PetscBool tval = PETSC_FALSE if flag: tval = PETSC_TRUE CHKERR( PetscLogEventSetActiveAll(self.id, tval) ) property active_all: def __get__(self): self.getActiveAll() def __set__(self, value): self.setActiveAll(value) # def getPerfInfo(self, stage: int | None = None) -> dict: """Get the performance information about the given event in the given event. Not collective. Parameters ---------- stage The stage number. Returns ------- info : dict This structure is filled with the performance information. See Also -------- petsc.PetscLogEventGetPerfInfo """ cdef PetscEventPerfInfo info cdef PetscInt cstage = PETSC_DETERMINE if stage is not None: cstage = asInt(stage) CHKERR( PetscLogEventGetPerfInfo(cstage, self.id, &info) ) return info cdef dict event_registry = { } cdef LogEvent get_LogEvent(object name): return event_registry.get(name) cdef LogEvent reg_LogEvent(object name, PetscLogEvent eventid): cdef LogEvent event = LogEvent() event.id = eventid event_registry[name] = event return event # -------------------------------------------------------------------- ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/src/petsc4py/PETSc/Mat.pyx0000644000175000017500000050337214567251135017144 0ustar00balaybalay# -------------------------------------------------------------------- class MatType(object): """Matrix type. See Also -------- petsc.MatType """ SAME = S_(MATSAME) MAIJ = S_(MATMAIJ) SEQMAIJ = S_(MATSEQMAIJ) MPIMAIJ = S_(MATMPIMAIJ) KAIJ = S_(MATKAIJ) SEQKAIJ = S_(MATSEQKAIJ) MPIKAIJ = S_(MATMPIKAIJ) IS = S_(MATIS) AIJ = S_(MATAIJ) SEQAIJ = S_(MATSEQAIJ) MPIAIJ = S_(MATMPIAIJ) AIJCRL = S_(MATAIJCRL) SEQAIJCRL = S_(MATSEQAIJCRL) MPIAIJCRL = S_(MATMPIAIJCRL) AIJCUSPARSE = S_(MATAIJCUSPARSE) SEQAIJCUSPARSE = S_(MATSEQAIJCUSPARSE) MPIAIJCUSPARSE = S_(MATMPIAIJCUSPARSE) AIJVIENNACL = S_(MATAIJVIENNACL) SEQAIJVIENNACL = S_(MATSEQAIJVIENNACL) MPIAIJVIENNACL = S_(MATMPIAIJVIENNACL) AIJPERM = S_(MATAIJPERM) SEQAIJPERM = S_(MATSEQAIJPERM) MPIAIJPERM = S_(MATMPIAIJPERM) AIJSELL = S_(MATAIJSELL) SEQAIJSELL = S_(MATSEQAIJSELL) MPIAIJSELL = S_(MATMPIAIJSELL) AIJMKL = S_(MATAIJMKL) SEQAIJMKL = S_(MATSEQAIJMKL) MPIAIJMKL = S_(MATMPIAIJMKL) BAIJMKL = S_(MATBAIJMKL) SEQBAIJMKL = S_(MATSEQBAIJMKL) MPIBAIJMKL = S_(MATMPIBAIJMKL) SHELL = S_(MATSHELL) DENSE = S_(MATDENSE) DENSECUDA = S_(MATDENSECUDA) SEQDENSE = S_(MATSEQDENSE) SEQDENSECUDA = S_(MATSEQDENSECUDA) MPIDENSE = S_(MATMPIDENSE) MPIDENSECUDA = S_(MATMPIDENSECUDA) ELEMENTAL = S_(MATELEMENTAL) BAIJ = S_(MATBAIJ) SEQBAIJ = S_(MATSEQBAIJ) MPIBAIJ = S_(MATMPIBAIJ) MPIADJ = S_(MATMPIADJ) SBAIJ = S_(MATSBAIJ) SEQSBAIJ = S_(MATSEQSBAIJ) MPISBAIJ = S_(MATMPISBAIJ) MFFD = S_(MATMFFD) NORMAL = S_(MATNORMAL) NORMALHERMITIAN = S_(MATNORMALHERMITIAN) LRC = S_(MATLRC) SCATTER = S_(MATSCATTER) BLOCKMAT = S_(MATBLOCKMAT) COMPOSITE = S_(MATCOMPOSITE) FFT = S_(MATFFT) FFTW = S_(MATFFTW) SEQCUFFT = S_(MATSEQCUFFT) TRANSPOSE = S_(MATTRANSPOSEVIRTUAL) HERMITIANTRANSPOSE = S_(MATHERMITIANTRANSPOSEVIRTUAL) SCHURCOMPLEMENT = S_(MATSCHURCOMPLEMENT) PYTHON = S_(MATPYTHON) HYPRE = S_(MATHYPRE) HYPRESTRUCT = S_(MATHYPRESTRUCT) HYPRESSTRUCT = S_(MATHYPRESSTRUCT) SUBMATRIX = S_(MATSUBMATRIX) LOCALREF = S_(MATLOCALREF) NEST = S_(MATNEST) PREALLOCATOR = S_(MATPREALLOCATOR) SELL = S_(MATSELL) SEQSELL = S_(MATSEQSELL) MPISELL = S_(MATMPISELL) DUMMY = S_(MATDUMMY) LMVM = S_(MATLMVM) LMVMDFP = S_(MATLMVMDFP) LMVMBFGS = S_(MATLMVMBFGS) LMVMSR1 = S_(MATLMVMSR1) LMVMBROYDEN = S_(MATLMVMBROYDEN) LMVMBADBROYDEN = S_(MATLMVMBADBROYDEN) LMVMSYMBROYDEN = S_(MATLMVMSYMBROYDEN) LMVMSYMBADBROYDEN = S_(MATLMVMSYMBADBROYDEN) LMVMDIAGBBROYDEN = S_(MATLMVMDIAGBROYDEN) CONSTANTDIAGONAL = S_(MATCONSTANTDIAGONAL) DIAGONAL = S_(MATDIAGONAL) H2OPUS = S_(MATH2OPUS) class MatOption(object): """Matrix option. See Also -------- petsc.MatOption """ OPTION_MIN = MAT_OPTION_MIN UNUSED_NONZERO_LOCATION_ERR = MAT_UNUSED_NONZERO_LOCATION_ERR ROW_ORIENTED = MAT_ROW_ORIENTED SYMMETRIC = MAT_SYMMETRIC STRUCTURALLY_SYMMETRIC = MAT_STRUCTURALLY_SYMMETRIC FORCE_DIAGONAL_ENTRIES = MAT_FORCE_DIAGONAL_ENTRIES IGNORE_OFF_PROC_ENTRIES = MAT_IGNORE_OFF_PROC_ENTRIES USE_HASH_TABLE = MAT_USE_HASH_TABLE KEEP_NONZERO_PATTERN = MAT_KEEP_NONZERO_PATTERN IGNORE_ZERO_ENTRIES = MAT_IGNORE_ZERO_ENTRIES USE_INODES = MAT_USE_INODES HERMITIAN = MAT_HERMITIAN SYMMETRY_ETERNAL = MAT_SYMMETRY_ETERNAL NEW_NONZERO_LOCATION_ERR = MAT_NEW_NONZERO_LOCATION_ERR IGNORE_LOWER_TRIANGULAR = MAT_IGNORE_LOWER_TRIANGULAR ERROR_LOWER_TRIANGULAR = MAT_ERROR_LOWER_TRIANGULAR GETROW_UPPERTRIANGULAR = MAT_GETROW_UPPERTRIANGULAR SPD = MAT_SPD NO_OFF_PROC_ZERO_ROWS = MAT_NO_OFF_PROC_ZERO_ROWS NO_OFF_PROC_ENTRIES = MAT_NO_OFF_PROC_ENTRIES NEW_NONZERO_LOCATIONS = MAT_NEW_NONZERO_LOCATIONS NEW_NONZERO_ALLOCATION_ERR = MAT_NEW_NONZERO_ALLOCATION_ERR SUBSET_OFF_PROC_ENTRIES = MAT_SUBSET_OFF_PROC_ENTRIES SUBMAT_SINGLEIS = MAT_SUBMAT_SINGLEIS STRUCTURE_ONLY = MAT_STRUCTURE_ONLY SORTED_FULL = MAT_SORTED_FULL OPTION_MAX = MAT_OPTION_MAX class MatAssemblyType(object): """Matrix assembly type. See Also -------- petsc.MatAssemblyType """ # native FINAL_ASSEMBLY = MAT_FINAL_ASSEMBLY FLUSH_ASSEMBLY = MAT_FLUSH_ASSEMBLY # aliases FINAL = FINAL_ASSEMBLY FLUSH = FLUSH_ASSEMBLY class MatInfoType(object): """Matrix info type.""" LOCAL = MAT_LOCAL GLOBAL_MAX = MAT_GLOBAL_MAX GLOBAL_SUM = MAT_GLOBAL_SUM class MatStructure(object): """Matrix modification structure. See Also -------- petsc.MatStructure """ # native SAME_NONZERO_PATTERN = MAT_SAME_NONZERO_PATTERN DIFFERENT_NONZERO_PATTERN = MAT_DIFFERENT_NONZERO_PATTERN SUBSET_NONZERO_PATTERN = MAT_SUBSET_NONZERO_PATTERN UNKNOWN_NONZERO_PATTERN = MAT_UNKNOWN_NONZERO_PATTERN # aliases SAME = SAME_NZ = SAME_NONZERO_PATTERN SUBSET = SUBSET_NZ = SUBSET_NONZERO_PATTERN DIFFERENT = DIFFERENT_NZ = DIFFERENT_NONZERO_PATTERN UNKNOWN = UNKNOWN_NZ = UNKNOWN_NONZERO_PATTERN class MatDuplicateOption(object): """Matrix duplicate option. See Also -------- petsc.MatDuplicateOption """ DO_NOT_COPY_VALUES = MAT_DO_NOT_COPY_VALUES COPY_VALUES = MAT_COPY_VALUES SHARE_NONZERO_PATTERN = MAT_SHARE_NONZERO_PATTERN class MatOrderingType(object): """Factored matrix ordering type. See Also -------- petsc.MatOrderingType """ NATURAL = S_(MATORDERINGNATURAL) ND = S_(MATORDERINGND) OWD = S_(MATORDERING1WD) RCM = S_(MATORDERINGRCM) QMD = S_(MATORDERINGQMD) ROWLENGTH = S_(MATORDERINGROWLENGTH) WBM = S_(MATORDERINGWBM) SPECTRAL = S_(MATORDERINGSPECTRAL) AMD = S_(MATORDERINGAMD) METISND = S_(MATORDERINGMETISND) class MatSolverType(object): """Factored matrix solver type. See Also -------- petsc.MatSolverType """ SUPERLU = S_(MATSOLVERSUPERLU) SUPERLU_DIST = S_(MATSOLVERSUPERLU_DIST) STRUMPACK = S_(MATSOLVERSTRUMPACK) UMFPACK = S_(MATSOLVERUMFPACK) CHOLMOD = S_(MATSOLVERCHOLMOD) KLU = S_(MATSOLVERKLU) ELEMENTAL = S_(MATSOLVERELEMENTAL) SCALAPACK = S_(MATSOLVERSCALAPACK) ESSL = S_(MATSOLVERESSL) LUSOL = S_(MATSOLVERLUSOL) MUMPS = S_(MATSOLVERMUMPS) MKL_PARDISO = S_(MATSOLVERMKL_PARDISO) MKL_CPARDISO = S_(MATSOLVERMKL_CPARDISO) PASTIX = S_(MATSOLVERPASTIX) MATLAB = S_(MATSOLVERMATLAB) PETSC = S_(MATSOLVERPETSC) BAS = S_(MATSOLVERBAS) CUSPARSE = S_(MATSOLVERCUSPARSE) CUDA = S_(MATSOLVERCUDA) SPQR = S_(MATSOLVERSPQR) class MatFactorShiftType(object): """Factored matrix shift type. See Also -------- petsc.MatFactorShiftType """ # native NONE = MAT_SHIFT_NONE NONZERO = MAT_SHIFT_NONZERO POSITIVE_DEFINITE = MAT_SHIFT_POSITIVE_DEFINITE INBLOCKS = MAT_SHIFT_INBLOCKS # aliases NZ = MAT_SHIFT_NONZERO PD = MAT_SHIFT_POSITIVE_DEFINITE class MatSORType(object): """Matrix SOR type. See Also -------- petsc.MatSORType """ FORWARD_SWEEP = SOR_FORWARD_SWEEP BACKWARD_SWEEP = SOR_BACKWARD_SWEEP SYMMETRY_SWEEP = SOR_SYMMETRIC_SWEEP LOCAL_FORWARD_SWEEP = SOR_LOCAL_FORWARD_SWEEP LOCAL_BACKWARD_SWEEP = SOR_LOCAL_BACKWARD_SWEEP LOCAL_SYMMETRIC_SWEEP = SOR_LOCAL_SYMMETRIC_SWEEP ZERO_INITIAL_GUESS = SOR_ZERO_INITIAL_GUESS EISENSTAT = SOR_EISENSTAT APPLY_UPPER = SOR_APPLY_UPPER APPLY_LOWER = SOR_APPLY_LOWER @cython.internal cdef class MatStencil: """Associate structured grid coordinates with matrix indices. See Also -------- petsc.MatStencil """ cdef PetscMatStencil stencil property i: "First logical grid coordinate." def __get__(self) -> int: return toInt(self.stencil.i) def __set__(self, value: int) -> None: self.stencil.i = asInt(value) property j: "Second logical grid coordinate." def __get__(self) -> int: return toInt(self.stencil.j) def __set__(self, value: int) -> None: self.stencil.j = asInt(value) property k: "Third logical grid coordinate." def __get__(self) -> int: return toInt(self.stencil.k) def __set__(self, value: int) -> None: self.stencil.k = asInt(value) property c: "Field component." def __get__(self) -> int: return toInt(self.stencil.c) def __set__(self, value: int) -> None: self.stencil.c = asInt(value) property index: "Logical grid coordinates ``(i, j, k)``." def __get__(self) -> tuple[int, int, int]: cdef PetscMatStencil *s = &self.stencil return toInt(s.i), toInt(s.j), toInt(s.k) def __set__(self, value: Sequence[int]) -> None: cdef PetscMatStencil *s = &self.stencil s.i = s.j = s.k = 0 asDims(value, &s.i, &s.j, &s.k) property field: "Field component." def __get__(self) -> int: cdef PetscMatStencil *s = &self.stencil return toInt(s.c) def __set__(self, value: int) -> None: cdef PetscMatStencil *s = &self.stencil s.c = asInt(value) # -------------------------------------------------------------------- cdef class Mat(Object): """Matrix object. Mat is described in the `PETSc manual `. See Also -------- petsc.Mat """ Type = MatType Option = MatOption AssemblyType = MatAssemblyType InfoType = MatInfoType Structure = MatStructure DuplicateOption = MatDuplicateOption OrderingType = MatOrderingType SolverType = MatSolverType FactorShiftType = MatFactorShiftType SORType = MatSORType # def __cinit__(self): self.obj = &self.mat self.mat = NULL # unary operations def __pos__(self): return mat_pos(self) def __neg__(self): return mat_neg(self) # inplace binary operations def __iadd__(self, other): return mat_iadd(self, other) def __isub__(self, other): return mat_isub(self, other) def __imul__(self, other): return mat_imul(self, other) def __idiv__(self, other): return mat_idiv(self, other) def __itruediv__(self, other): return mat_idiv(self, other) # binary operations def __add__(self, other): return mat_add(self, other) def __radd__(self, other): return mat_radd(self, other) def __sub__(self, other): return mat_sub(self, other) def __rsub__(self, other): return mat_rsub(self, other) def __mul__(self, other): return mat_mul(self, other) def __rmul__(self, other): return mat_rmul(self, other) def __div__(self, other): return mat_div(self, other) def __rdiv__(self, other): return mat_rdiv(self, other) def __truediv__(self, other): return mat_div(self, other) def __rtruediv__(self, other): return mat_rdiv(self, other) def __matmul__(self, other): return mat_matmul(self, other) # def __getitem__(self, ij): return mat_getitem(self, ij) def __setitem__(self, ij, v): mat_setitem(self, ij, v) def __call__(self, x, y=None): if y is None: y = self.createVecLeft() self.mult(x, y) return y # def view(self, Viewer viewer=None) -> None: """View the matrix. Collective. Parameters ---------- viewer A `Viewer` instance or `None` for the default viewer. Notes ----- Viewers with type `Viewer.Type.ASCII` are only recommended for small matrices on small numbers of processes. Larger matrices should use a binary format like `Viewer.Type.BINARY`. See Also -------- load, Viewer, petsc.MatView """ cdef PetscViewer vwr = NULL if viewer is not None: vwr = viewer.vwr CHKERR( MatView(self.mat, vwr) ) def destroy(self) -> Self: """Destroy the matrix. Collective. See Also -------- create, petsc.MatDestroy """ CHKERR( MatDestroy(&self.mat) ) return self def create(self, comm: Comm | None = None) -> Self: """Create the matrix. Collective. Once created, the user should call `setType` or `setFromOptions` before using the matrix. Alternatively, specific creation routines such as `createAIJ` or `createBAIJ` can be used. Parameters ---------- comm MPI communicator, defaults to `Sys.getDefaultComm`. See Also -------- destroy, petsc.MatCreate """ cdef MPI_Comm ccomm = def_Comm(comm, PETSC_COMM_DEFAULT) cdef PetscMat newmat = NULL CHKERR( MatCreate(ccomm, &newmat) ) CHKERR( PetscCLEAR(self.obj) ); self.mat = newmat return self def setType(self, mat_type: Type | str) -> None: """Set the matrix type. Collective. Parameters ---------- mat_type The matrix type. See Also -------- create, getType, petsc.MatSetType """ cdef PetscMatType cval = NULL mat_type = str2bytes(mat_type, &cval) CHKERR( MatSetType(self.mat, cval) ) def setSizes( self, size: MatSizeSpec, bsize: MatBlockSizeSpec | None = None, ) -> None: """Set the local, global and block sizes. Collective. Parameters ---------- size Matrix size. bsize Matrix block size. If `None`, a block size of ``1`` is set. Examples -------- Create a `Mat` with ``n`` rows and columns and the same local and global sizes. >>> mat = PETSc.Mat().create() >>> mat.setFromOptions() >>> mat.setSizes(n) Create a `Mat` with ``nr`` rows, ``nc`` columns and the same local and global sizes. >>> mat = PETSc.Mat().create() >>> mat.setFromOptions() >>> mat.setSizes([nr, nc]) Create a `Mat` with ``nrl`` local rows, ``nrg`` global rows, ``ncl`` local columns and ``ncg`` global columns. >>> mat = PETSc.Mat().create() >>> mat.setFromOptions() >>> mat.setSizes([[nrl, nrg], [ncl, ncg]]) See Also -------- setBlockSize, setBlockSizes, petsc.MatSetSizes, petsc.MatSetBlockSize petsc.MatSetBlockSizes """ cdef PetscInt rbs = 0, cbs = 0, m = 0, n = 0, M = 0, N = 0 Mat_Sizes(size, bsize, &rbs, &cbs, &m, &n, &M, &N) CHKERR( MatSetSizes(self.mat, m, n, M, N) ) if rbs != PETSC_DECIDE: if cbs != PETSC_DECIDE: CHKERR( MatSetBlockSizes(self.mat, rbs, cbs) ) else: CHKERR( MatSetBlockSize(self.mat, rbs) ) def setBlockSize(self, bsize: int) -> None: """Set the matrix block size (same for rows and columns). Logically collective. Parameters ---------- bsize Block size. See Also -------- setBlockSizes, setSizes, petsc.MatSetBlockSize """ cdef PetscInt bs = asInt(bsize) CHKERR( MatSetBlockSize(self.mat, bs) ) def setBlockSizes(self, row_bsize: int, col_bsize: int) -> None: """Set the row and column block sizes. Logically collective. Parameters ---------- row_bsize Row block size. col_bsize Column block size. See Also -------- setBlockSize, setSizes, petsc.MatSetBlockSizes """ cdef PetscInt rbs = asInt(row_bsize) cdef PetscInt cbs = asInt(col_bsize) CHKERR( MatSetBlockSizes(self.mat, rbs, cbs) ) def setVecType(self, vec_type: Vec.Type | str) -> None: """Set the vector type. Collective. Parameters ---------- vec_type Vector type used when creating vectors with `createVecs`. See Also -------- getVecType, petsc.MatSetVecType """ cdef PetscVecType cval = NULL vec_type = str2bytes(vec_type, &cval) CHKERR( MatSetVecType(self.mat, cval) ) def getVecType(self) -> str: """Return the vector type used by the matrix. Not collective. See Also -------- setVecType, petsc.MatGetVecType """ cdef PetscVecType cval = NULL CHKERR( MatGetVecType(self.mat, &cval) ) return bytes2str(cval) def setNestVecType(self, vec_type: Vec.Type | str) -> None: """Set the vector type for a `Type.NEST` matrix. Collective. Parameters ---------- vec_type Vector type used when creating vectors with `createVecs`. See Also -------- getVecType, petsc.MatNestSetVecType """ cdef PetscVecType cval = NULL vec_type = str2bytes(vec_type, &cval) CHKERR( MatNestSetVecType(self.mat, cval) ) # def createAIJ( self, size: MatSizeSpec, bsize: MatBlockSizeSpec | None = None, nnz: NNZSpec | None = None, csr: CSRIndicesSpec | None = None, comm: Comm | None = None, ) -> Self: """Create a sparse `Type.AIJ` matrix, optionally preallocating. Collective. To preallocate the matrix the user can either pass ``nnz`` or ``csr`` describing the sparsity. If neither is set then preallocation will not occur. Consult the `PETSc manual ` for more information. Parameters ---------- size Matrix size. bsize Matrix block size. If `None`, a block size of ``1`` is set. nnz Optional non-zeros preallocation pattern. csr Optional compressed sparse row layout information. If provided, it takes precedence on ``nnz``. comm MPI communicator, defaults to `Sys.getDefaultComm`. See Also -------- setSizes, createBAIJ, petsc.MATAIJ, petsc.MATSEQAIJ, petsc.MATMPIAIJ petsc.MatCreateAIJ, petsc.MatSeqAIJSetPreallocation petsc.MatSeqAIJSetPreallocationCSR """ # create matrix cdef PetscMat newmat = NULL Mat_Create(MATAIJ, comm, size, bsize, &newmat) CHKERR( PetscCLEAR(self.obj) ); self.mat = newmat # preallocate matrix Mat_AllocAIJ(self.mat, nnz, csr) return self def createBAIJ( self, size: MatSizeSpec, bsize: MatBlockSizeSpec, nnz: NNZSpec | None = None, csr: CSRIndicesSpec | None = None, comm: Comm | None = None, ) -> Self: """Create a sparse blocked `Type.BAIJ` matrix, optionally preallocating. Collective. To preallocate the matrix the user can either pass ``nnz`` or ``csr`` describing the sparsity. If neither is set then preallocation will not occur. Consult the `PETSc manual ` for more information. Parameters ---------- size Matrix size. bsize Matrix block size. nnz Optional non-zeros preallocation pattern for block rows. csr Optional block-compressed sparse row layout information. If provided, it takes precedence on ``nnz``. comm MPI communicator, defaults to `Sys.getDefaultComm`. See Also -------- setSizes, createAIJ, petsc.MATBAIJ, petsc.MATSEQBAIJ petsc.MATMPIBAIJ, petsc.MatCreateBAIJ """ # create matrix cdef PetscMat newmat = NULL Mat_Create(MATBAIJ, comm, size, bsize, &newmat) CHKERR( PetscCLEAR(self.obj) ); self.mat = newmat # preallocate matrix Mat_AllocAIJ(self.mat, nnz, csr) return self def createSBAIJ( self, size: MatSizeSpec, bsize: int, nnz: NNZSpec | None = None, csr: CSRIndicesSpec | None = None, comm: Comm | None = None, ) -> Self: """Create a sparse `Type.SBAIJ` matrix in symmetric block format. Collective. To preallocate the matrix the user can either pass ``nnz`` or ``csr`` describing the sparsity. If neither is set then preallocation will not occur. Consult the `PETSc manual ` for more information. Parameters ---------- size Matrix size. bsize Matrix block size. nnz Optional upper-triangular (including diagonal) non-zeros preallocation pattern for block rows. csr Optional block-compressed sparse row layout information. If provided, it takes precedence on ``nnz``. comm MPI communicator, defaults to `Sys.getDefaultComm`. See Also -------- createAIJ, createBAIJ, petsc.MatCreateSBAIJ """ # create matrix cdef PetscMat newmat = NULL Mat_Create(MATSBAIJ, comm, size, bsize, &newmat) CHKERR( PetscCLEAR(self.obj) ); self.mat = newmat # preallocate matrix Mat_AllocAIJ(self.mat, nnz, csr) return self def createAIJCRL( self, size: MatSizeSpec, bsize: MatBlockSizeSpec | None = None, nnz: NNZSpec | None = None, csr: CSRIndicesSpec | None = None, comm: Comm | None = None, ) -> Self: """Create a sparse `Type.AIJCRL` matrix. Collective. This is similar to `Type.AIJ` matrices but stores some additional information that improves vectorization for the matrix-vector product. To preallocate the matrix the user can either pass ``nnz`` or ``csr`` describing the sparsity. If neither is set then preallocation will not occur. Consult the `PETSc manual ` for more information. Parameters ---------- size Matrix size. bsize Matrix block size. If `None`, a block size of ``1`` is set. nnz Optional non-zeros preallocation pattern. csr Optional compressed sparse row layout information. If provided, it takes precedence on ``nnz``. comm MPI communicator, defaults to `Sys.getDefaultComm`. See Also -------- createAIJ, createBAIJ, petsc.MatCreateSeqAIJCRL petsc.MatCreateMPIAIJCRL """ # create matrix cdef PetscMat newmat = NULL Mat_Create(MATAIJCRL, comm, size, bsize, &newmat) CHKERR( PetscCLEAR(self.obj) ); self.mat = newmat # preallocate matrix Mat_AllocAIJ(self.mat, nnz, csr) return self def setPreallocationNNZ(self, nnz: NNZSpec) -> Self: """Preallocate memory for the matrix with a non-zero pattern. Collective. Correct preallocation can result in a dramatic reduction in matrix assembly time. Parameters ---------- nnz The number of non-zeros per row for the local portion of the matrix, or a 2-tuple for the on-process and off-process part of the matrix. See Also -------- setPreallocationCSR, createAIJ, petsc.MatSeqAIJSetPreallocation petsc.MatMPIAIJSetPreallocation """ cdef PetscBool done = PETSC_FALSE CHKERR( MatIsPreallocated(self.mat, &done) ) # if done: raise Error(PETSC_ERR_ORDER) Mat_AllocAIJ_NNZ(self.mat, nnz) return self def setPreallocationCSR(self, csr: CSRIndicesSpec) -> Self: """Preallocate memory for the matrix with a CSR layout. Collective. Correct preallocation can result in a dramatic reduction in matrix assembly time. Parameters ---------- csr Local matrix data in compressed sparse row layout format. Notes ----- Must use the block-compressed form with `Type.BAIJ` and `Type.SBAIJ`. See Also -------- setPreallocationNNZ, createAIJ, createBAIJ, createSBAIJ petsc.MatSeqAIJSetPreallocationCSR petsc.MatMPIAIJSetPreallocationCSR petsc.MatSeqBAIJSetPreallocationCSR petsc.MatMPIBAIJSetPreallocationCSR petsc.MatSeqSBAIJSetPreallocationCSR petsc.MatMPISBAIJSetPreallocationCSR """ cdef PetscBool done = PETSC_FALSE CHKERR( MatIsPreallocated(self.mat, &done) ) # if done: raise Error(PETSC_ERR_ORDER) Mat_AllocAIJ_CSR(self.mat, csr) return self def createAIJWithArrays( self, size: MatSizeSpec, csr: CSRSpec | tuple[CSRSpec, CSRSpec], bsize: MatBlockSizeSpec | None = None, comm: Comm | None = None, ) -> Self: """Create a sparse `Type.AIJ` matrix with data in CSR format. Collective. Parameters ---------- size Matrix size. csr Local matrix data in compressed sparse row format. bsize Matrix block size. If `None`, a block size of ``1`` is set. comm MPI communicator, defaults to `Sys.getDefaultComm`. Notes ----- For `Type.SEQAIJ` matrices, the ``csr`` data is not copied. For `Type.MPIAIJ` matrices, the ``csr`` data is not copied only in the case it represents on-process and off-process information. See Also -------- createAIJ, petsc.MatCreateSeqAIJWithArrays petsc.MatCreateMPIAIJWithArrays, petsc.MatCreateMPIAIJWithSplitArrays """ # communicator cdef MPI_Comm ccomm = def_Comm(comm, PETSC_COMM_DEFAULT) # sizes and block sizes cdef PetscInt rbs = 0, cbs = 0, m = 0, n = 0, M = 0, N = 0 Mat_Sizes(size, bsize, &rbs, &cbs, &m, &n, &M, &N) if rbs == PETSC_DECIDE: rbs = 1 if cbs == PETSC_DECIDE: cbs = rbs Sys_Layout(ccomm, rbs, &m, &M) Sys_Layout(ccomm, cbs, &n, &N) # unpack CSR argument cdef object pi, pj, pv, poi, poj, pov try: (pi, pj, pv), (poi, poj, pov) = csr except (TypeError, ValueError): pi, pj, pv = csr poi = poj = pov = None # rows, cols, and values cdef PetscInt ni=0, noi=0, *i=NULL, *oi=NULL cdef PetscInt nj=0, noj=0, *j=NULL, *oj=NULL pi = iarray_i(pi, &ni, &i) # Row pointers (diagonal) pj = iarray_i(pj, &nj, &j) # Column indices (diagonal) if ni != m+1: raise ValueError( "A matrix with %d rows requires a row pointer of length %d (given: %d)" % (toInt(m), toInt(m+1), toInt(ni))) if poi is not None and poj is not None: poi = iarray_i(poi, &noi, &oi) # Row pointers (off-diagonal) poj = iarray_i(poj, &noj, &oj) # Column indices (off-diagonal) cdef PetscInt nv=0, nov=0 cdef PetscScalar *v=NULL, *ov=NULL pv = iarray_s(pv, &nv, &v) # Non-zero values (diagonal) if nj != nv: raise ValueError( "Given %d column indices but %d non-zero values" % (toInt(nj), toInt(nv))) if pov is not None: pov = iarray_s(pov, &nov, &ov) # Non-zero values (off-diagonal) # create matrix cdef PetscMat newmat = NULL if comm_size(ccomm) == 1: CHKERR( MatCreateSeqAIJWithArrays( ccomm, m, n, i, j, v, &newmat) ) csr = (pi, pj, pv) else: # if off-diagonal components are provided then SplitArrays can be # used (and not cause a copy). if oi != NULL and oj != NULL and ov != NULL: CHKERR( MatCreateMPIAIJWithSplitArrays( ccomm, m, n, M, N, i, j, v, oi, oj, ov, &newmat) ) csr = ((pi, pj, pv), (poi, poj, pov)) else: CHKERR( MatCreateMPIAIJWithArrays( ccomm, m, n, M, N, i, j, v, &newmat) ) csr = None CHKERR( PetscCLEAR(self.obj) ); self.mat = newmat self.set_attr('__csr__', csr) return self # def createDense( self, size: MatSizeSpec, bsize: MatBlockSizeSpec | None = None, array: Sequence[Scalar] | None = None, comm: Comm | None = None ) -> Self: """Create a `Type.DENSE` matrix. Collective. Parameters ---------- size Matrix size. bsize Matrix block size. If `None`, a block size of ``1`` is set. array Optional matrix data. If `None`, memory is internally allocated. comm MPI communicator, defaults to `Sys.getDefaultComm`. See Also -------- createDenseCUDA, petsc.MATDENSE, petsc.MatCreateDense """ # create matrix cdef PetscMat newmat = NULL Mat_Create(MATDENSE, comm, size, bsize, &newmat) CHKERR( PetscCLEAR(self.obj) ); self.mat = newmat # preallocate matrix if array is not None: array = Mat_AllocDense(self.mat, array) self.set_attr('__array__', array) return self def createDenseCUDA( self, size: MatSizeSpec, bsize: MatBlockSizeSpec | None = None, array: Sequence[Scalar] | None = None, cudahandle: int | None = None, comm: Comm | None = None, ) -> Self: """Create a `Type.DENSECUDA` matrix with optional host and device data. Collective. Parameters ---------- size Matrix size. bsize Matrix block size. If `None`, a block size of ``1`` is set. array Host data. Will be lazily allocated if `None`. cudahandle Address of the array on the GPU. Will be lazily allocated if `None`. If ``cudahandle`` is provided, ``array`` will be ignored. comm MPI communicator, defaults to `Sys.getDefaultComm`. See Also -------- createDense, petsc.MatCreateDenseCUDA """ # create matrix cdef PetscMat newmat = NULL # communicator cdef MPI_Comm ccomm = def_Comm(comm, PETSC_COMM_DEFAULT) # sizes and block sizes cdef PetscInt rbs = 0, cbs = 0, m = 0, n = 0, M = 0, N = 0 # FIXME handle the case of array not None? if cudahandle is not None: Mat_Sizes(size, None, &rbs, &cbs, &m, &n, &M, &N) if rbs == PETSC_DECIDE: rbs = 1 if cbs == PETSC_DECIDE: cbs = rbs Sys_Layout(ccomm, rbs, &m, &M) Sys_Layout(ccomm, cbs, &n, &N) # create matrix and set sizes CHKERR( MatCreateDenseCUDA(ccomm, m, n, M, N, (cudahandle), &newmat) ) # Does block size make sense for MATDENSE? CHKERR( MatSetBlockSizes(newmat, rbs, cbs) ) else: Mat_Create(MATDENSECUDA, comm, size, bsize, &newmat) if array is not None: array = Mat_AllocDense(self.mat, array) self.set_attr('__array__', array) CHKERR( PetscCLEAR(self.obj) ); self.mat = newmat return self def setPreallocationDense(self, array: Sequence[Scalar]) -> Self: """Set the array used for storing matrix elements for a dense matrix. Collective. Parameters ---------- array Array that will be used to store matrix data. See Also -------- petsc.MatSeqDenseSetPreallocation, petsc.MatMPIDenseSetPreallocation """ cdef PetscBool done = PETSC_FALSE CHKERR( MatIsPreallocated(self.mat, &done) ) # if done: raise Error(PETSC_ERR_ORDER) array = Mat_AllocDense(self.mat, array) self.set_attr('__array__', array) return self # def createScatter(self, Scatter scatter, comm: Comm | None = None) -> Self: """Create a `Type.SCATTER` matrix from a vector scatter. Collective. Parameters ---------- scatter Vector scatter. comm MPI communicator, defaults to `Sys.getDefaultComm`. See Also -------- petsc.MATSCATTER, petsc.MatCreateScatter """ if comm is None: comm = scatter.getComm() cdef MPI_Comm ccomm = def_Comm(comm, PETSC_COMM_DEFAULT) cdef PetscMat newmat = NULL CHKERR( MatCreateScatter(ccomm, scatter.sct, &newmat) ) CHKERR( PetscCLEAR(self.obj) ); self.mat = newmat return self def createNormal(self, Mat mat) -> Self: """Create a `Type.NORMAL` matrix representing AᵀA. Collective. Parameters ---------- mat The (possibly rectangular) matrix A. Notes ----- The product AᵀA is never actually formed. Instead A and Aᵀ are used during `mult` and various other matrix operations. See Also -------- petsc.MATNORMAL, petsc.MatCreateNormal """ cdef PetscMat newmat = NULL CHKERR( MatCreateNormal(mat.mat, &newmat) ) CHKERR( PetscCLEAR(self.obj) ); self.mat = newmat return self def createTranspose(self, Mat mat) -> Self: """Create a `Type.TRANSPOSE` matrix that behaves like Aᵀ. Collective. Parameters ---------- mat Matrix A to represent the transpose of. Notes ----- The transpose is never actually formed. Instead `multTranspose` is called whenever the matrix-vector product is computed. See Also -------- createNormal, petsc.MatCreateTranspose """ cdef PetscMat newmat = NULL CHKERR( MatCreateTranspose(mat.mat, &newmat) ) CHKERR( PetscCLEAR(self.obj) ); self.mat = newmat return self def createNormalHermitian(self, Mat mat) -> Self: """Create a `Type.NORMALHERMITIAN` matrix representing (A*)ᵀA. Collective. Parameters ---------- mat The (possibly rectangular) matrix A. Notes ----- The product (A*)ᵀA is never actually formed. See Also -------- createHermitianTranspose, petsc.MATNORMAL, petsc.MATNORMALHERMITIAN petsc.MatCreateNormalHermitian """ cdef PetscMat newmat = NULL CHKERR( MatCreateNormalHermitian(mat.mat, &newmat) ) CHKERR( PetscCLEAR(self.obj) ); self.mat = newmat return self def createHermitianTranspose(self, Mat mat) -> Self: """Create a `Type.HERMITIANTRANSPOSE` matrix that behaves like (A*)ᵀ. Collective. Parameters ---------- mat Matrix A to represent the hermitian transpose of. Notes ----- The Hermitian transpose is never actually formed. See Also -------- createNormal, createNormalHermitian petsc.MATHERMITIANTRANSPOSEVIRTUAL, petsc.MatCreateHermitianTranspose """ cdef PetscMat newmat = NULL CHKERR( MatCreateHermitianTranspose(mat.mat, &newmat) ) CHKERR( PetscCLEAR(self.obj) ); self.mat = newmat return self def createLRC(self, Mat A, Mat U, Vec c, Mat V) -> Self: """Create a low-rank correction `Type.LRC` matrix representing A + UCVᵀ. Collective. Parameters ---------- A Sparse matrix, can be `None`. U, V Dense rectangular matrices. c Vector containing the diagonal of C, can be `None`. Notes ----- The matrix A + UCVᵀ is never actually formed. C is a diagonal matrix (represented as a vector) of order k, where k is the number of columns of both U and V. If A is `None` then the new object behaves like a low-rank matrix UCVᵀ. Use the same matrix for ``V`` and ``U`` (or ``V=None``) for a symmetric low-rank correction, A + UCUᵀ. If ``c`` is `None` then the low-rank correction is just U*Vᵀ. If a sequential ``c`` vector is used for a parallel matrix, PETSc assumes that the values of the vector are consistently set across processors. See Also -------- petsc.MATLRC, petsc.MatCreateLRC """ cdef PetscMat Amat = NULL cdef PetscMat Umat = U.mat cdef PetscVec cvec = NULL cdef PetscMat Vmat = NULL cdef PetscMat newmat = NULL if A is not None: Amat = A.mat if c is not None: cvec = c.vec if V is not None: Vmat = V.mat CHKERR( MatCreateLRC(Amat, Umat, cvec, Vmat, &newmat) ) CHKERR( PetscCLEAR(self.obj) ); self.mat = newmat return self def createSubMatrixVirtual(self, Mat A, IS isrow, IS iscol=None) -> Self: """Create a `Type.SUBMATRIX` matrix that acts as a submatrix. Collective. Parameters ---------- A Matrix to extract submatrix from. isrow Rows present in the submatrix. iscol Columns present in the submatrix, defaults to ``isrow``. See Also -------- petsc.MatCreateSubMatrixVirtual """ if iscol is None: iscol = isrow cdef PetscMat newmat = NULL CHKERR( MatCreateSubMatrixVirtual(A.mat, isrow.iset, iscol.iset, &newmat) ) CHKERR( PetscCLEAR(self.obj) ); self.mat = newmat return self def createNest( self, mats: Sequence[Sequence[Mat]], isrows: Sequence[IS] | None = None, iscols: Sequence[IS] | None = None, comm: Comm | None = None, ) -> Self: """Create a `Type.NEST` matrix containing multiple submatrices. Collective. Parameters ---------- mats Iterable of matrix block rows with size ``len(isrows)``. Each matrix block row must be of size ``len(iscols)``. Empty submatrices can be set with `None`. isrows Index set for each nested row block, defaults to contiguous ordering. iscols Index set for each nested column block, defaults to contiguous ordering. comm MPI communicator, defaults to `Sys.getDefaultComm`. See Also -------- petsc.MatCreateNest, petsc.MATNEST """ cdef object mat mats = [list(mat) for mat in mats] if isrows: isrows = list(isrows) assert len(isrows) == len(mats) else: isrows = None if iscols: iscols = list(iscols) assert len(iscols) == len(mats[0]) else: iscols = None cdef MPI_Comm ccomm = def_Comm(comm, PETSC_COMM_DEFAULT) cdef Py_ssize_t i, mr = len(mats) cdef Py_ssize_t j, mc = len(mats[0]) cdef PetscInt nr = mr cdef PetscInt nc = mc cdef PetscMat *cmats = NULL cdef PetscIS *cisrows = NULL cdef PetscIS *ciscols = NULL cdef object tmp1, tmp2, tmp3 tmp1 = oarray_p(empty_p(nr*nc), NULL, &cmats) for i from 0 <= i < mr: for j from 0 <= j < mc: mat = mats[i][j] cmats[i*mc+j] = (mat).mat if mat is not None else NULL if isrows is not None: tmp2 = oarray_p(empty_p(nr), NULL, &cisrows) for i from 0 <= i < mr: cisrows[i] = (isrows[i]).iset if iscols is not None: tmp3 = oarray_p(empty_p(nc), NULL, &ciscols) for j from 0 <= j < mc: ciscols[j] = (iscols[j]).iset cdef PetscMat newmat = NULL CHKERR( MatCreateNest(ccomm, nr, cisrows, nc, ciscols, cmats, &newmat) ) CHKERR( PetscCLEAR(self.obj) ); self.mat = newmat return self def createH2OpusFromMat( self, Mat A, coordinates: Sequence[Scalar] | None = None, dist: bool | None = None, eta: float | None = None, leafsize: int | None = None, maxrank: int | None = None, bs: int | None = None, rtol: float | None = None, ) -> Self: """Create a hierarchical `Type.H2OPUS` matrix sampling from a provided operator. Parameters ---------- A Matrix to be sampled. coordinates Coordinates of the points. dist Whether or not coordinates are distributed, defaults to `False`. eta Admissibility condition tolerance, defaults to `DECIDE`. leafsize Leaf size in cluster tree, defaults to `DECIDE`. maxrank Maximum rank permitted, defaults to `DECIDE`. bs Maximum number of samples to take concurrently, defaults to `DECIDE`. rtol Relative tolerance for construction, defaults to `DECIDE`. Notes ----- See `petsc.MatCreateH2OpusFromMat` for the appropriate database options. See Also -------- petsc_options, petsc.MatCreateH2OpusFromMat """ cdef PetscInt cdim = 1 cdef PetscReal *coords = NULL cdef PetscBool cdist = PETSC_FALSE cdef PetscReal peta = PETSC_DECIDE cdef PetscInt lsize = PETSC_DECIDE cdef PetscInt maxr = PETSC_DECIDE cdef PetscInt pbs = PETSC_DECIDE cdef PetscReal tol = PETSC_DECIDE cdef ndarray xyz cdef PetscInt nvtx cdef PetscInt rl = 0, cl = 0 if dist is not None: cdist = asBool(dist) if eta is not None: peta = asReal(eta) if leafsize is not None: lsize = asInt(leafsize) if maxrank is not None: maxr = asInt(maxrank) if bs is not None: pbs = asInt(bs) if rtol is not None: tol = asReal(rtol) if coordinates is not None: xyz = iarray(coordinates, NPY_PETSC_REAL) if PyArray_ISFORTRAN(xyz): xyz = PyArray_Copy(xyz) if PyArray_NDIM(xyz) != 2: raise ValueError( ("coordinates must have two dimensions: " "coordinates.ndim=%d") % (PyArray_NDIM(xyz)) ) nvtx = PyArray_DIM(xyz, 0) CHKERR( MatGetLocalSize(A.mat, &rl, &cl) ) if cl != rl: raise ValueError("Not for rectangular matrices") if nvtx < rl: raise ValueError( ("coordinates size must be at least %d" % rl )) cdim = PyArray_DIM(xyz, 1) coords = PyArray_DATA(xyz) cdef PetscMat newmat = NULL CHKERR( MatCreateH2OpusFromMat(A.mat, cdim, coords, cdist, peta, lsize, maxr, pbs, tol, &newmat) ) CHKERR( PetscCLEAR(self.obj) ); self.mat = newmat return self def createIS( self, size: MatSizeSpec, LGMap lgmapr = None, LGMap lgmapc = None, comm: Comm | None = None, ) -> Self: """Create a `Type.IS` matrix representing globally unassembled operators. Collective. Parameters ---------- size Matrix size. lgmapr Optional local-to-global mapping for the rows. If `None`, the local row space matches the global row space. lgmapc Optional local-to-global mapping for the columns. If `None`, the local column space matches the global column space. comm MPI communicator, defaults to `Sys.getDefaultComm`. See Also -------- petsc.MATIS """ # communicator and sizes if comm is None and lgmapr is not None: comm = lgmapr.getComm() if comm is None and lgmapc is not None: comm = lgmapc.getComm() cdef PetscLGMap lgmr = NULL cdef PetscLGMap lgmc = NULL cdef MPI_Comm ccomm = def_Comm(comm, PETSC_COMM_DEFAULT) cdef PetscInt rbs = 0, cbs = 0, m = 0, n = 0, M = 0, N = 0 Mat_Sizes(size, None, &rbs, &cbs, &m, &n, &M, &N) Sys_Layout(ccomm, rbs, &m, &M) Sys_Layout(ccomm, cbs, &n, &N) # create matrix cdef PetscMat newmat = NULL cdef PetscInt bs = 1 if rbs == cbs: bs = rbs if lgmapr is not None: lgmr = lgmapr.lgm if lgmapc is not None: lgmc = lgmapc.lgm CHKERR( MatCreateIS(ccomm, bs, m, n, M, N, lgmr, lgmc, &newmat) ) CHKERR( PetscCLEAR(self.obj) ); self.mat = newmat return self def createConstantDiagonal( self, size: MatSizeSpec, diag: float, comm: Comm | None = None, ) -> Self: """Create a diagonal matrix of type `Type.CONSTANTDIAGONAL`. Collective. Parameters ---------- size Matrix size. diag The diagonal value. comm MPI communicator, defaults to `Sys.getDefaultComm`. See Also -------- createDiagonal """ cdef MPI_Comm ccomm = def_Comm(comm, PETSC_COMM_DEFAULT) cdef PetscInt rbs = 0, cbs = 0, m = 0, n = 0, M = 0, N = 0 Mat_Sizes(size, None, &rbs, &cbs, &m, &n, &M, &N) Sys_Layout(ccomm, rbs, &m, &M) Sys_Layout(ccomm, cbs, &n, &N) cdef PetscMat newmat = NULL CHKERR( MatCreateConstantDiagonal(ccomm, m, n, M, N, diag, &newmat) ) CHKERR( PetscCLEAR(self.obj) ); self.mat = newmat return self def createDiagonal( self, Vec diag, ) -> Self: """Create a diagonal matrix of type `Type.DIAGONAL`. Collective. Parameters ---------- diag The vector holding diagonal values. See Also -------- createConstantDiagonal """ cdef PetscVec dvec = diag.vec cdef PetscMat newmat = NULL CHKERR( MatCreateDiagonal(dvec, &newmat) ) CHKERR( PetscCLEAR(self.obj) ); self.mat = newmat return self def createPython(self, size: MatSizeSpec, context: Any = None, comm: Comm | None = None) -> Self: """Create a `Type.PYTHON` matrix. Collective. Parameters ---------- size Matrix size. context An instance of the Python class implementing the required methods. comm MPI communicator, defaults to `Sys.getDefaultComm`. See Also -------- petsc_python_mat, setType, setPythonContext, Type.PYTHON """ # communicator and sizes cdef MPI_Comm ccomm = def_Comm(comm, PETSC_COMM_DEFAULT) cdef PetscInt rbs = 0, cbs = 0, m = 0, n = 0, M = 0, N = 0 Mat_Sizes(size, None, &rbs, &cbs, &m, &n, &M, &N) Sys_Layout(ccomm, rbs, &m, &M) Sys_Layout(ccomm, cbs, &n, &N) # create matrix # FIXME: propagate block sizes? cdef PetscMat newmat = NULL CHKERR( MatCreate(ccomm, &newmat) ) CHKERR( PetscCLEAR(self.obj) ); self.mat = newmat CHKERR( MatSetSizes(self.mat, m, n, M, N) ) CHKERR( MatSetType(self.mat, MATPYTHON) ) CHKERR( MatPythonSetContext(self.mat, context) ) return self def setPythonContext(self, context: Any) -> None: """Set the instance of the class implementing the required Python methods. Not collective. See Also -------- petsc_python_mat, getPythonContext """ CHKERR( MatPythonSetContext(self.mat, context) ) def getPythonContext(self) -> Any: """Return the instance of the class implementing the required Python methods. Not collective. See Also -------- petsc_python_mat, setPythonContext """ cdef void *context = NULL CHKERR( MatPythonGetContext(self.mat, &context) ) if context == NULL: return None else: return context def setPythonType(self, py_type: str) -> None: """Set the fully qualified Python name of the class to be used. Collective. See Also -------- petsc_python_mat, setPythonContext, getPythonType petsc.MatPythonSetType """ cdef const char *cval = NULL py_type = str2bytes(py_type, &cval) CHKERR( MatPythonSetType(self.mat, cval) ) def getPythonType(self) -> str: """Return the fully qualified Python name of the class used by the matrix. Not collective. See Also -------- petsc_python_mat, setPythonContext, setPythonType petsc.MatPythonGetType """ cdef const char *cval = NULL CHKERR( MatPythonGetType(self.mat, &cval) ) return bytes2str(cval) # def setOptionsPrefix(self, prefix: str) -> None: """Set the prefix used for searching for options in the database. Logically collective. See Also -------- petsc_options, getOptionsPrefix, petsc.MatSetOptionsPrefix """ cdef const char *cval = NULL prefix = str2bytes(prefix, &cval) CHKERR( MatSetOptionsPrefix(self.mat, cval) ) def getOptionsPrefix(self) -> str: """Return the prefix used for searching for options in the database. Not collective. See Also -------- petsc_options, setOptionsPrefix, petsc.MatGetOptionsPrefix """ cdef const char *cval = NULL CHKERR( MatGetOptionsPrefix(self.mat, &cval) ) return bytes2str(cval) def appendOptionsPrefix(self, prefix: str) -> None: """Append to the prefix used for searching for options in the database. Logically collective. See Also -------- petsc_options, setOptionsPrefix, petsc.MatAppendOptionsPrefix """ cdef const char *cval = NULL prefix = str2bytes(prefix, &cval) CHKERR( MatAppendOptionsPrefix(self.mat, cval) ) def setFromOptions(self) -> None: """Configure the matrix from the options database. Collective. See Also -------- petsc_options, petsc.MatSetFromOptions """ CHKERR( MatSetFromOptions(self.mat) ) def setUp(self) -> None: """Set up the internal data structures for using the matrix. Collective. See Also -------- petsc.MatSetUp """ CHKERR( MatSetUp(self.mat) ) return self def setOption(self, option: Option, flag: bool) -> None: """Set option. Collective. See Also -------- getOption, petsc.MatSetOption """ CHKERR( MatSetOption(self.mat, option, flag) ) def getOption(self, option: Option) -> bool: """Return the option value. Not collective. See Also -------- setOption, petsc.MatGetOption """ cdef PetscBool flag = PETSC_FALSE CHKERR( MatGetOption(self.mat, option, &flag) ) return toBool(flag) def getType(self) -> str: """Return the type of the matrix. Not collective. See Also -------- setType, Type, petsc.MatGetType """ cdef PetscMatType cval = NULL CHKERR( MatGetType(self.mat, &cval) ) return bytes2str(cval) def getSize(self) -> tuple[int, int]: """Return the global number of rows and columns. Not collective. See Also -------- getLocalSize, getSizes, petsc.MatGetSize """ cdef PetscInt M = 0, N = 0 CHKERR( MatGetSize(self.mat, &M, &N) ) return (toInt(M), toInt(N)) def getLocalSize(self) -> tuple[int, int]: """Return the local number of rows and columns. Not collective. See Also -------- getSize, petsc.MatGetLocalSize """ cdef PetscInt m = 0, n = 0 CHKERR( MatGetLocalSize(self.mat, &m, &n) ) return (toInt(m), toInt(n)) def getSizes(self) -> tuple[LayoutSizeSpec, LayoutSizeSpec]: """Return the tuple of matrix layouts. Not collective. See Also -------- getLocalSize, getSize """ cdef PetscInt m = 0, n = 0 cdef PetscInt M = 0, N = 0 CHKERR( MatGetLocalSize(self.mat, &m, &n) ) CHKERR( MatGetSize(self.mat, &M, &N) ) return ((toInt(m), toInt(M)), (toInt(n), toInt(N))) def getBlockSize(self) -> int: """Return the matrix block size. Not collective. See Also -------- getBlockSize, petsc.MatGetBlockSize """ cdef PetscInt bs = 0 CHKERR( MatGetBlockSize(self.mat, &bs) ) return toInt(bs) def getBlockSizes(self) -> tuple[int, int]: """Return the row and column block sizes. Not collective. See Also -------- getBlockSize, petsc.MatGetBlockSizes """ cdef PetscInt rbs = 0, cbs = 0 CHKERR( MatGetBlockSizes(self.mat, &rbs, &cbs) ) return (toInt(rbs), toInt(cbs)) def getOwnershipRange(self) -> tuple[int, int]: """Return the locally owned range of rows. Not collective. See Also -------- getOwnershipRanges, getOwnershipRangeColumn, petsc.MatGetOwnershipRange """ cdef PetscInt ival1 = 0, ival2 = 0 CHKERR( MatGetOwnershipRange(self.mat, &ival1, &ival2) ) return (toInt(ival1), toInt(ival2)) def getOwnershipRanges(self) -> ArrayInt: """Return the range of rows owned by each process. Not collective. The returned array is the result of exclusive scan of the local sizes. See Also -------- getOwnershipRange, petsc.MatGetOwnershipRanges """ cdef const PetscInt *rowrng = NULL CHKERR( MatGetOwnershipRanges(self.mat, &rowrng) ) cdef MPI_Comm comm = MPI_COMM_NULL CHKERR( PetscObjectGetComm(self.mat, &comm) ) cdef int size = -1 CHKERR( MPI_Comm_size(comm, &size) ) return array_i(size+1, rowrng) def getOwnershipRangeColumn(self) -> tuple[int, int]: """Return the locally owned range of columns. Not collective. See Also -------- getOwnershipRangesColumn, getOwnershipRange petsc.MatGetOwnershipRangeColumn """ cdef PetscInt ival1 = 0, ival2 = 0 CHKERR( MatGetOwnershipRangeColumn(self.mat, &ival1, &ival2) ) return (toInt(ival1), toInt(ival2)) def getOwnershipRangesColumn(self) -> ArrayInt: """Return the range of columns owned by each process. Not collective. See Also -------- getOwnershipRangeColumn, petsc.MatGetOwnershipRangesColumn """ cdef const PetscInt *colrng = NULL CHKERR( MatGetOwnershipRangesColumn(self.mat, &colrng) ) cdef MPI_Comm comm = MPI_COMM_NULL CHKERR( PetscObjectGetComm(self.mat, &comm) ) cdef int size = -1 CHKERR( MPI_Comm_size(comm, &size) ) return array_i(size+1, colrng) def getOwnershipIS(self) -> tuple[IS, IS]: """Return the ranges of rows and columns owned by each process as index sets. Not collective. See Also -------- getOwnershipRanges, getOwnershipRangesColumn, petsc.MatGetOwnershipIS """ cdef IS rows = IS() cdef IS cols = IS() CHKERR( MatGetOwnershipIS(self.mat, &rows.iset, &cols.iset) ) return (rows, cols) def getInfo(self, info: InfoType = None) -> dict[str, float]: """Return summary information. Collective. Parameters ---------- info If `None`, it uses `InfoType.GLOBAL_SUM`. See Also -------- petsc.MatInfo, petsc.MatGetInfo """ cdef PetscMatInfoType itype = infotype(info) cdef PetscMatInfo cinfo CHKERR( MatGetInfo(self.mat, itype, &cinfo) ) return cinfo def duplicate(self, copy: bool = False) -> Mat: """Return a clone of the matrix. Collective. Parameters ---------- copy If `True`, it also copies the values. See Also -------- petsc.MatDuplicate """ cdef PetscMatDuplicateOption flag = MAT_DO_NOT_COPY_VALUES if copy: flag = MAT_COPY_VALUES if copy > MAT_COPY_VALUES: flag = MAT_SHARE_NONZERO_PATTERN cdef Mat mat = type(self)() CHKERR( MatDuplicate(self.mat, flag, &mat.mat) ) return mat def copy(self, Mat result=None, structure: Structure | None = None) -> Mat: """Return a copy of the matrix. Collective. Parameters ---------- result Optional return matrix. If `None`, it is internally created. structure The copy structure. Only relevant if ``result`` is not `None`. See Also -------- petsc.MatCopy, petsc.MatDuplicate """ cdef PetscMatDuplicateOption copy = MAT_COPY_VALUES cdef PetscMatStructure mstr = matstructure(structure) if result is None: result = type(self)() if result.mat == NULL: CHKERR( MatDuplicate(self.mat, copy, &result.mat) ) else: CHKERR( MatCopy(self.mat, result.mat, mstr) ) return result def load(self, Viewer viewer) -> Self: """Load a matrix. Collective. See Also -------- petsc.MatLoad """ cdef MPI_Comm comm = MPI_COMM_NULL cdef PetscObject obj = (viewer.vwr) if self.mat == NULL: CHKERR( PetscObjectGetComm(obj, &comm) ) CHKERR( MatCreate(comm, &self.mat) ) CHKERR( MatLoad(self.mat, viewer.vwr) ) return self def convert(self, mat_type: Type | str = None, Mat out=None) -> Mat: """Convert the matrix type. Collective. Parameters ---------- mat_type The type of the new matrix. If `None` uses `Type.SAME`. out Optional return matrix. If `None`, inplace conversion is performed. Otherwise, the matrix is reused. See Also -------- petsc.MatConvert """ cdef PetscMatType mtype = MATSAME cdef PetscMatReuse reuse = MAT_INITIAL_MATRIX mat_type = str2bytes(mat_type, &mtype) if mtype == NULL: mtype = MATSAME if out is None: out = self if out.mat == self.mat: reuse = MAT_INPLACE_MATRIX elif out.mat == NULL: reuse = MAT_INITIAL_MATRIX else: reuse = MAT_REUSE_MATRIX CHKERR( MatConvert(self.mat, mtype, reuse, &out.mat) ) return out def transpose(self, Mat out=None) -> Mat: """Return the transposed matrix. Collective. Parameters ---------- out Optional return matrix. If `None`, inplace transposition is performed. Otherwise, the matrix is reused. See Also -------- petsc.MatTranspose """ cdef PetscMatReuse reuse = MAT_INITIAL_MATRIX if out is None: out = self if out.mat == self.mat: reuse = MAT_INPLACE_MATRIX elif out.mat == NULL: reuse = MAT_INITIAL_MATRIX else: reuse = MAT_REUSE_MATRIX CHKERR( MatTranspose(self.mat, reuse, &out.mat) ) return out def setTransposePrecursor(self, Mat out) -> None: """Set transpose precursor. See Also -------- petsc.MatTransposeSetPrecursor """ CHKERR( MatTransposeSetPrecursor(self.mat, out.mat) ) def hermitianTranspose(self, Mat out=None) -> Mat: """Return the transposed Hermitian matrix. Collective. Parameters ---------- out Optional return matrix. If `None`, inplace transposition is performed. Otherwise, the matrix is reused. See Also -------- petsc.MatHermitianTranspose """ cdef PetscMatReuse reuse = MAT_INITIAL_MATRIX if out is None: out = self if out.mat == self.mat: reuse = MAT_INPLACE_MATRIX elif out.mat == NULL: reuse = MAT_INITIAL_MATRIX else: reuse = MAT_REUSE_MATRIX CHKERR( MatHermitianTranspose(self.mat, reuse, &out.mat) ) return out def realPart(self, Mat out=None) -> Mat: """Return the real part of the matrix. Collective. Parameters ---------- out Optional return matrix. If `None`, the operation is performed in-place. Otherwise, the operation is performed on ``out``. See Also -------- imagPart, conjugate, petsc.MatRealPart """ if out is None: out = self elif out.mat == NULL: CHKERR( MatDuplicate(self.mat, MAT_COPY_VALUES, &out.mat) ) CHKERR( MatRealPart(out.mat) ) return out def imagPart(self, Mat out=None) -> Mat: """Return the imaginary part of the matrix. Collective. Parameters ---------- out Optional return matrix. If `None`, the operation is performed in-place. Otherwise, the operation is performed on ``out``. See Also -------- realPart, conjugate, petsc.MatImaginaryPart """ if out is None: out = self elif out.mat == NULL: CHKERR( MatDuplicate(self.mat, MAT_COPY_VALUES, &out.mat) ) CHKERR( MatImaginaryPart(out.mat) ) return out def conjugate(self, Mat out=None) -> Mat: """Return the conjugate matrix. Collective. Parameters ---------- out Optional return matrix. If `None`, the operation is performed in-place. Otherwise, the operation is performed on ``out``. See Also -------- realPart, imagPart, petsc.MatConjugate """ if out is None: out = self elif out.mat == NULL: CHKERR( MatDuplicate(self.mat, MAT_COPY_VALUES, &out.mat) ) CHKERR( MatConjugate(out.mat) ) return out def permute(self, IS row, IS col) -> Mat: """Return the permuted matrix. Collective. Parameters ---------- row Row permutation. col Column permutation. See Also -------- petsc.MatPermute """ cdef Mat mat = Mat() CHKERR( MatPermute(self.mat, row.iset, col.iset, &mat.mat) ) return mat def equal(self, Mat mat) -> bool: """Return the result of matrix comparison. Collective. See Also -------- petsc.MatEqual """ cdef PetscBool flag = PETSC_FALSE CHKERR( MatEqual(self.mat, mat.mat, &flag) ) return toBool(flag) def isTranspose(self, Mat mat=None, tol: float = 0) -> bool: """Return the result of matrix comparison with transposition. Collective. Parameters ---------- mat Matrix to compare against. Uses ``self`` if `None`. tol Tolerance for comparison. See Also -------- petsc.MatIsTranspose """ if mat is None: mat = self cdef PetscReal rval = asReal(tol) cdef PetscBool flag = PETSC_FALSE CHKERR( MatIsTranspose(self.mat, mat.mat, rval, &flag) ) return toBool(flag) def isSymmetric(self, tol: float = 0) -> bool: """Return the boolean indicating if the matrix is symmetric. Collective. Parameters ---------- tol Tolerance for comparison. See Also -------- petsc.MatIsSymmetric """ cdef PetscReal rval = asReal(tol) cdef PetscBool flag = PETSC_FALSE CHKERR( MatIsSymmetric(self.mat, rval, &flag) ) return toBool(flag) def isSymmetricKnown(self) -> tuple[bool, bool]: """Return the 2-tuple indicating if the matrix is known to be symmetric. Not collective. See Also -------- petsc.MatIsSymmetricKnown """ cdef PetscBool flag1 = PETSC_FALSE cdef PetscBool flag2 = PETSC_FALSE CHKERR( MatIsSymmetricKnown(self.mat, &flag1, &flag2) ) return (toBool(flag1), toBool(flag2)) def isHermitian(self, tol: float = 0) -> bool: """Return the boolean indicating if the matrix is Hermitian. Collective. Parameters ---------- tol Tolerance for comparison. See Also -------- petsc.MatIsHermitian """ cdef PetscReal rval = asReal(tol) cdef PetscBool flag = PETSC_FALSE CHKERR( MatIsHermitian(self.mat, rval, &flag) ) return toBool(flag) def isHermitianKnown(self) -> tuple[bool, bool]: """Return the 2-tuple indicating if the matrix is known to be Hermitian. Not collective. See Also -------- petsc.MatIsHermitianKnown """ cdef PetscBool flag1 = PETSC_FALSE cdef PetscBool flag2 = PETSC_FALSE CHKERR( MatIsHermitianKnown(self.mat, &flag1, &flag2) ) return (toBool(flag1), toBool(flag2)) def isStructurallySymmetric(self) -> bool: """Return the boolean indicating if the matrix is structurally symmetric.""" cdef PetscBool flag = PETSC_FALSE CHKERR( MatIsStructurallySymmetric(self.mat, &flag) ) return toBool(flag) def zeroEntries(self) -> None: """Zero the entries of the matrix. Collective. See Also -------- petsc.MatZeroEntries """ CHKERR( MatZeroEntries(self.mat) ) def getValue(self, row, col) -> Scalar: """Return the value in the (row,col) position. Not collective. See Also -------- petsc.MatGetValues """ cdef PetscInt ival1 = asInt(row) cdef PetscInt ival2 = asInt(col) cdef PetscScalar sval = 0 CHKERR( MatGetValues(self.mat, 1, &ival1, 1, &ival2, &sval) ) return toScalar(sval) def getValues(self, rows: Sequence[int], cols: Sequence[int], values: ArrayScalar = None) -> ArrayScalar: """Return the values in the ``zip(rows,cols)`` positions. Not collective. Parameters ---------- rows Row indices. cols Column indices. values Optional array where to store the values. See Also -------- petsc.MatGetValues """ return matgetvalues(self.mat, rows, cols, values) def getValuesCSR(self) -> tuple[ArrayInt, ArrayInt, ArrayScalar]: """Return the CSR representation of the local part of the matrix. Not collective. See Also -------- petsc.MatGetRow """ # row ownership cdef PetscInt rstart=0, rend=0, nrows=0 CHKERR( MatGetOwnershipRange(self.mat, &rstart, &rend) ) nrows = rend - rstart # first pass: row pointer array cdef PetscInt *AI = NULL cdef ndarray ai = oarray_i(empty_i(nrows+1), NULL, &AI) cdef PetscInt irow=0, ncols=0 AI[0] = 0 for irow from 0 <= irow < nrows: CHKERR( MatGetRow(self.mat, irow+rstart, &ncols, NULL, NULL) ) AI[irow+1] = AI[irow] + ncols CHKERR( MatRestoreRow(self.mat, irow+rstart, &ncols, NULL, NULL) ) # second pass: column indices and values cdef PetscInt *AJ = NULL cdef ndarray aj = oarray_i(empty_i(AI[nrows]), NULL, &AJ) cdef PetscScalar *AV = NULL cdef ndarray av = oarray_s(empty_s(AI[nrows]), NULL, &AV) cdef const PetscInt *cols = NULL cdef const PetscScalar *vals = NULL for irow from 0 <= irow < nrows: CHKERR( MatGetRow(self.mat, irow+rstart, &ncols, &cols, &vals) ) CHKERR( PetscMemcpy(AJ+AI[irow], cols, ncols*sizeof(PetscInt)) ) CHKERR( PetscMemcpy(AV+AI[irow], vals, ncols*sizeof(PetscScalar)) ) CHKERR( MatRestoreRow(self.mat, irow+rstart, &ncols, &cols, &vals) ) # return (ai, aj, av) def getRow(self, row: int) -> tuple[ArrayInt, ArrayScalar]: """Return the column indices and values for the requested row. Not collective. See Also -------- petsc.MatGetRow """ cdef PetscInt irow = asInt(row) cdef PetscInt ncols = 0 cdef const PetscInt *icols=NULL cdef const PetscScalar *svals=NULL CHKERR( MatGetRow(self.mat, irow, &ncols, &icols, &svals) ) cdef object cols = array_i(ncols, icols) cdef object vals = array_s(ncols, svals) CHKERR( MatRestoreRow(self.mat, irow, &ncols, &icols, &svals) ) return (cols, vals) def getRowIJ(self, symmetric: bool = False, compressed: bool = False) -> tuple[ArrayInt, ArrayInt]: """Return the CSR representation of the local sparsity pattern. Collective. Parameters ---------- symmetric If `True`, return the symmetrized graph. compressed If `True`, return the compressed graph. See Also -------- petsc.MatGetRowIJ """ cdef PetscInt shift=0 cdef PetscBool symm=symmetric cdef PetscBool bcmp=compressed cdef PetscInt n=0 cdef const PetscInt *ia=NULL cdef const PetscInt *ja=NULL cdef PetscBool done=PETSC_FALSE CHKERR( MatGetRowIJ(self.mat, shift, symm, bcmp, &n, &ia, &ja, &done) ) cdef object ai=None, aj=None if done != PETSC_FALSE: ai = array_i( n+1, ia) if done != PETSC_FALSE: aj = array_i(ia[n], ja) CHKERR( MatRestoreRowIJ(self.mat, shift, symm, bcmp, &n, &ia, &ja, &done) ) return (ai, aj) def getColumnIJ(self, symmetric: bool = False, compressed: bool = False) -> tuple[ArrayInt, ArrayInt]: """Return the CSC representation of the local sparsity pattern. Collective. Parameters ---------- symmetric If `True`, return the symmetrized graph. compressed If `True`, return the compressed graph. See Also -------- petsc.MatGetRowIJ """ cdef PetscInt shift=0 cdef PetscBool symm=symmetric, bcmp=compressed cdef PetscInt n=0 cdef const PetscInt *ia=NULL cdef const PetscInt *ja=NULL cdef PetscBool done=PETSC_FALSE CHKERR( MatGetColumnIJ(self.mat, shift, symm, bcmp, &n, &ia, &ja, &done) ) cdef object ai=None, aj=None if done != PETSC_FALSE: ai = array_i( n+1, ia) if done != PETSC_FALSE: aj = array_i(ia[n], ja) CHKERR( MatRestoreColumnIJ(self.mat, shift, symm, bcmp, &n, &ia, &ja, &done) ) return (ai, aj) def setValue( self, row: int, col: int, value: Scalar, addv: InsertModeSpec = None, ) -> None: """Set a value to the ``(row, col)`` entry of the matrix. Not collective. Parameters ---------- row Row index. col Column index. value The scalar value. addv Insertion mode. See Also -------- petsc.MatSetValues """ cdef PetscInt ival1 = asInt(row) cdef PetscInt ival2 = asInt(col) cdef PetscScalar sval = asScalar(value) cdef PetscInsertMode caddv = insertmode(addv) CHKERR( MatSetValues(self.mat, 1, &ival1, 1, &ival2, &sval, caddv) ) def setValues( self, rows: Sequence[int], cols: Sequence[int], values: Sequence[Scalar], addv: InsertModeSpec = None, ) -> None: """Set values to the rows ⊗ cols entries of the matrix. Not collective. Parameters ---------- rows Row indices. cols Column indices. values The scalar values. A sequence of length at least ``len(rows) * len(cols)``. addv Insertion mode. See Also -------- petsc.MatSetValues """ matsetvalues(self.mat, rows, cols, values, addv, 0, 0) def setValuesRCV(self, R, C, V, addv=None) -> None: """Undocumented.""" matsetvalues_rcv(self.mat, R, C, V, addv, 0, 0) def setValuesIJV( self, I: Sequence[int], J: Sequence[int], V: Sequence[Scalar], addv: InsertModeSpec = None, rowmap: Sequence[int] = None, ) -> None: """Set a subset of values stored in CSR format. Not collective. Parameters ---------- I Row pointers. J Column indices. V The scalar values. addv Insertion mode. rowmap Optional iterable indicating which row to insert. See Also -------- petsc.MatSetValues """ matsetvalues_ijv(self.mat, I, J, V, addv, rowmap, 0, 0) def setValuesCSR( self, I: Sequence[int], J: Sequence[int], V: Sequence[Scalar], addv: InsertModeSpec = None, ) -> None: """Set values stored in CSR format. Not collective. Parameters ---------- I Row pointers. J Column indices. V The scalar values. addv Insertion mode. See Also -------- petsc.MatSetValues """ matsetvalues_csr(self.mat, I, J, V, addv, 0, 0) def setValuesBlocked( self, rows: Sequence[int], cols: Sequence[int], values: Sequence[Scalar], addv: InsertModeSpec = None, ) -> None: """Set values to the rows ⊗ col block entries of the matrix. Not collective. Parameters ---------- rows Block row indices. cols Block column indices. values The scalar values. A sequence of length at least ``len(rows) * len(cols) * bs * bs``, where ``bs`` is the block size of the matrix. addv Insertion mode. See Also -------- petsc.MatSetValuesBlocked """ matsetvalues(self.mat, rows, cols, values, addv, 1, 0) def setValuesBlockedRCV(self, R, C, V, addv=None) -> None: """Undocumented.""" matsetvalues_rcv(self.mat, R, C, V, addv, 1, 0) def setValuesBlockedIJV( self, I: Sequence[int], J: Sequence[int], V: Sequence[Scalar], addv: InsertModeSpec = None, rowmap: Sequence[int] = None, ) -> None: """Set a subset of values stored in block CSR format. Not collective. Parameters ---------- I Block row pointers. J Block column indices. V The scalar values. addv Insertion mode. rowmap Optional iterable indicating which block row to insert. See Also -------- petsc.MatSetValuesBlocked """ matsetvalues_ijv(self.mat, I, J, V, addv, rowmap, 1, 0) def setValuesBlockedCSR( self, I: Sequence[int], J: Sequence[int], V: Sequence[Scalar], addv: InsertModeSpec = None, ) -> None: """Set values stored in block CSR format. Not collective. Parameters ---------- I Block row pointers. J Block column indices. V The scalar values. addv Insertion mode. See Also -------- petsc.MatSetValuesBlocked """ matsetvalues_csr(self.mat, I, J, V, addv, 1, 0) def setLGMap(self, LGMap rmap, LGMap cmap=None) -> None: """Set the local-to-global mappings. Collective. Parameters ---------- rmap Row mapping. cmap Column mapping. If `None`, ``cmap = rmap``. See Also -------- getLGMap, petsc.MatSetLocalToGlobalMapping """ if cmap is None: cmap = rmap CHKERR( MatSetLocalToGlobalMapping(self.mat, rmap.lgm, cmap.lgm) ) def getLGMap(self) -> tuple[LGMap, LGMap]: """Return the local-to-global mappings. Not collective. See Also -------- setLGMap, petsc.MatGetLocalToGlobalMapping """ cdef LGMap cmap = LGMap() cdef LGMap rmap = LGMap() CHKERR( MatGetLocalToGlobalMapping(self.mat, &rmap.lgm, &cmap.lgm) ) CHKERR( PetscINCREF(cmap.obj) ) CHKERR( PetscINCREF(rmap.obj) ) return (rmap, cmap) def setValueLocal( self, row: int, col: int, value: Scalar, addv: InsertModeSpec = None, ) -> None: """Set a value to the ``(row, col)`` entry of the matrix in local ordering. Not collective. Parameters ---------- row Local row index. col Local column index. value The scalar value. addv Insertion mode. See Also -------- petsc.MatSetValuesLocal """ cdef PetscInt ival1 = asInt(row) cdef PetscInt ival2 = asInt(col) cdef PetscScalar sval = asScalar(value) cdef PetscInsertMode caddv = insertmode(addv) CHKERR( MatSetValuesLocal( self.mat, 1, &ival1, 1, &ival2, &sval, caddv) ) def setValuesLocal( self, rows: Sequence[int], cols: Sequence[int], values: Sequence[Scalar], addv: InsertModeSpec = None, ) -> None: """Set values to the rows ⊗ col entries of the matrix in local ordering. Not collective. Parameters ---------- rows Local row indices. cols Local column indices. values The scalar values. A sequence of length at least ``len(rows) * len(cols)``. addv Insertion mode. See Also -------- petsc.MatSetValuesLocal """ matsetvalues(self.mat, rows, cols, values, addv, 0, 1) def setValuesLocalRCV(self, R, C, V, addv=None) -> None: """Undocumented.""" matsetvalues_rcv(self.mat, R, C, V, addv, 0, 1) def setValuesLocalIJV( self, I: Sequence[int], J: Sequence[int], V: Sequence[Scalar], addv: InsertModeSpec = None, rowmap: Sequence[int] = None, ) -> None: """Set a subset of values stored in CSR format. Not collective. Parameters ---------- I Row pointers. J Local column indices. V The scalar values. addv Insertion mode. rowmap Optional iterable indicating which row to insert. See Also -------- petsc.MatSetValuesLocal """ matsetvalues_ijv(self.mat, I, J, V, addv, rowmap, 0, 1) def setValuesLocalCSR( self, I: Sequence[int], J: Sequence[int], V: Sequence[Scalar], addv: InsertModeSpec = None, ) -> None: """Set values stored in CSR format. Not collective. Parameters ---------- I Row pointers. J Local column indices. V The scalar values. addv Insertion mode. See Also -------- petsc.MatSetValuesLocal """ matsetvalues_csr(self.mat, I, J, V, addv, 0, 1) def setValuesBlockedLocal( self, rows: Sequence[int], cols: Sequence[int], values: Sequence[Scalar], addv: InsertModeSpec = None, ) -> None: """Set values to the rows ⊗ col block entries of the matrix in local ordering. Not collective. Parameters ---------- rows Local block row indices. cols Local block column indices. values The scalar values. A sequence of length at least ``len(rows) * len(cols) * bs * bs``, where ``bs`` is the block size of the matrix. addv Insertion mode. See Also -------- petsc.MatSetValuesBlockedLocal """ matsetvalues(self.mat, rows, cols, values, addv, 1, 1) def setValuesBlockedLocalRCV(self, R, C, V, addv=None) -> None: """Undocumented.""" matsetvalues_rcv(self.mat, R, C, V, addv, 1, 1) def setValuesBlockedLocalIJV( self, I: Sequence[int], J: Sequence[int], V: Sequence[Scalar], addv: InsertModeSpec = None, rowmap: Sequence[int] = None, ) -> None: """Set a subset of values stored in block CSR format. Not collective. Parameters ---------- I Block row pointers. J Local block column indices. V The scalar values. addv Insertion mode. rowmap Optional iterable indicating which block row to insert. See Also -------- petsc.MatSetValuesBlockedLocal """ matsetvalues_ijv(self.mat, I, J, V, addv, rowmap, 1, 1) def setValuesBlockedLocalCSR( self, I: Sequence[int], J: Sequence[int], V: Sequence[Scalar], addv: InsertModeSpec = None, ) -> None: """Set values stored in block CSR format. Not collective. Parameters ---------- I Block row pointers. J Local block column indices. V The scalar values. addv Insertion mode. See Also -------- petsc.MatSetValuesBlockedLocal """ matsetvalues_csr(self.mat, I, J, V, addv, 1, 1) # Stencil = MatStencil def setStencil(self, dims: DimsSpec, starts: DimsSpec | None = None, dof: int = 1) -> None: """Set matrix stencil. Not collective. See Also -------- petsc.MatSetStencil """ cdef PetscInt ndim, ndof cdef PetscInt cdims[3], cstarts[3] cdims[0] = cdims[1] = cdims[2] = 1 cstarts[0] = cstarts[1] = cstarts[2] = 0 ndim = asDims(dims, &cdims[0], &cdims[1], &cdims[2]) ndof = asInt(dof) if starts is not None: asDims(dims, &cstarts[0], &cstarts[1], &cstarts[2]) CHKERR( MatSetStencil(self.mat, ndim, cdims, cstarts, ndof) ) def setValueStencil( self, MatStencil row: Stencil, MatStencil col: Stencil, value: Sequence[Scalar], addv: InsertModeSpec = None, ) -> None: """Set a value to row and col stencil. Not collective. Parameters ---------- row Row stencil. col Column stencil. value The scalar values. addv Insertion mode. See Also -------- petsc.MatSetValuesStencil """ cdef MatStencil r = row, c = col cdef PetscInsertMode im = insertmode(addv) matsetvaluestencil(self.mat, r, c, value, im, 0) def setValueStagStencil(self, row, col, value, addv=None) -> None: """Not implemented.""" raise NotImplementedError def setValueBlockedStencil( self, row: Stencil, col: Stencil, value: Sequence[Scalar], addv: InsertModeSpec = None, ) -> None: """Set a block of values to row and col stencil. Not collective. Parameters ---------- row Row stencil. col Column stencil. value The scalar values. addv Insertion mode. See Also -------- petsc.MatSetValuesBlockedStencil """ cdef MatStencil r = row, c = col cdef PetscInsertMode im = insertmode(addv) matsetvaluestencil(self.mat, r, c, value, im, 1) def setValueBlockedStagStencil(self, row, col, value, addv=None) -> None: """Not implemented.""" raise NotImplementedError def zeroRows(self, rows: IS | Sequence[int], diag: Scalar = 1, Vec x=None, Vec b=None) -> None: """Zero selected rows of the matrix. Collective. Parameters ---------- rows Row indices to be zeroed. diag Scalar value to be inserted into the diagonal. x Optional solution vector to be modified for zeroed rows. b Optional right-hand side vector to be modified. It will be adjusted with provided solution entries. See Also -------- zeroRowsLocal, petsc.MatZeroRows, petsc.MatZeroRowsIS """ cdef PetscInt ni=0, *i=NULL cdef PetscScalar sval = asScalar(diag) cdef PetscVec xvec=NULL, bvec=NULL if x is not None: xvec = x.vec if b is not None: bvec = b.vec if isinstance(rows, IS): CHKERR( MatZeroRowsIS(self.mat, (rows).iset, sval, xvec, bvec) ) else: rows = iarray_i(rows, &ni, &i) CHKERR( MatZeroRows(self.mat, ni, i, sval, xvec, bvec) ) def zeroRowsLocal(self, rows: IS | Sequence[int], diag: Scalar = 1, Vec x=None, Vec b=None) -> None: """Zero selected rows of the matrix in local ordering. Collective. Parameters ---------- rows Local row indices to be zeroed. diag Scalar value to be inserted into the diagonal. x Optional solution vector to be modified for zeroed rows. b Optional right-hand side vector to be modified. It will be adjusted with provided solution entries. See Also -------- zeroRows, petsc.MatZeroRowsLocal, petsc.MatZeroRowsLocalIS """ cdef PetscInt ni=0, *i=NULL cdef PetscScalar sval = asScalar(diag) cdef PetscVec xvec=NULL, bvec=NULL if x is not None: xvec = x.vec if b is not None: bvec = b.vec if isinstance(rows, IS): CHKERR( MatZeroRowsLocalIS(self.mat, (rows).iset, sval, xvec, bvec) ) else: rows = iarray_i(rows, &ni, &i) CHKERR( MatZeroRowsLocal(self.mat, ni, i, sval, xvec, bvec) ) def zeroRowsColumns(self, rows: IS | Sequence[int], diag: Scalar = 1, Vec x=None, Vec b=None) -> None: """Zero selected rows and columns of the matrix. Collective. Parameters ---------- rows Row/column indices to be zeroed. diag Scalar value to be inserted into the diagonal. x Optional solution vector to be modified for zeroed rows. b Optional right-hand side vector to be modified. It will be adjusted with provided solution entries. See Also -------- zeroRowsColumnsLocal, zeroRows, petsc.MatZeroRowsColumns petsc.MatZeroRowsColumnsIS """ cdef PetscInt ni=0, *i=NULL cdef PetscScalar sval = asScalar(diag) cdef PetscVec xvec=NULL, bvec=NULL if x is not None: xvec = x.vec if b is not None: bvec = b.vec if isinstance(rows, IS): CHKERR( MatZeroRowsColumnsIS(self.mat, (rows).iset, sval, xvec, bvec) ) else: rows = iarray_i(rows, &ni, &i) CHKERR( MatZeroRowsColumns(self.mat, ni, i, sval, xvec, bvec) ) def zeroRowsColumnsLocal(self, rows: IS | Sequence[int], diag: Scalar = 1, Vec x=None, Vec b=None) -> None: """Zero selected rows and columns of the matrix in local ordering. Collective. Parameters ---------- rows Local row/column indices to be zeroed. diag Scalar value to be inserted into the diagonal. x Optional solution vector to be modified for zeroed rows. b Optional right-hand side vector to be modified. It will be adjusted with provided solution entries. See Also -------- zeroRowsLocal, zeroRowsColumns, petsc.MatZeroRowsColumnsLocal petsc.MatZeroRowsColumnsLocalIS """ cdef PetscInt ni=0, *i=NULL cdef PetscScalar sval = asScalar(diag) cdef PetscVec xvec=NULL, bvec=NULL if x is not None: xvec = x.vec if b is not None: bvec = b.vec if isinstance(rows, IS): CHKERR( MatZeroRowsColumnsLocalIS(self.mat, (rows).iset, sval, xvec, bvec) ) else: rows = iarray_i(rows, &ni, &i) CHKERR( MatZeroRowsColumnsLocal(self.mat, ni, i, sval, xvec, bvec) ) def zeroRowsColumnsStencil(self, rows: Sequence[Stencil], diag: Scalar = 1, Vec x=None, Vec b=None) -> None: """Zero selected rows and columns of the matrix. Collective. Parameters ---------- rows Iterable of stencil rows and columns. diag Scalar value to be inserted into the diagonal. x Optional solution vector to be modified for zeroed rows. b Optional right-hand side vector to be modified. It will be adjusted with provided solution entries. See Also -------- zeroRowsLocal, zeroRowsColumns, petsc.MatZeroRowsColumnsStencil """ cdef PetscScalar sval = asScalar(diag) cdef PetscInt nrows = asInt(len(rows)) cdef PetscMatStencil st cdef MatStencil r cdef PetscMatStencil *crows = NULL CHKERR( PetscMalloc((nrows+1)*sizeof(st), &crows) ) for i in range(nrows): r = rows[i] crows[i] = r.stencil cdef PetscVec xvec = NULL, bvec = NULL if x is not None: xvec = x.vec if b is not None: bvec = b.vec CHKERR( MatZeroRowsColumnsStencil(self.mat, nrows, crows, sval, xvec, bvec) ) CHKERR( PetscFree( crows ) ) def storeValues(self) -> None: """Stash a copy of the matrix values. Collective. See Also -------- retrieveValues, petsc.MatStoreValues """ CHKERR( MatStoreValues(self.mat) ) def retrieveValues(self) -> None: """Retrieve a copy of the matrix values previously stored with `storeValues`. Collective. See Also -------- storeValues, petsc.MatRetrieveValues """ CHKERR( MatRetrieveValues(self.mat) ) def assemblyBegin(self, assembly: MatAssemblySpec = None) -> None: """Begin an assembling stage of the matrix. Collective. Parameters ---------- assembly The assembly type. See Also -------- assemblyEnd, assemble, petsc.MatAssemblyBegin """ cdef PetscMatAssemblyType flag = assemblytype(assembly) CHKERR( MatAssemblyBegin(self.mat, flag) ) def assemblyEnd(self, assembly: MatAssemblySpec = None) -> None: """Complete an assembling stage of the matrix initiated with `assemblyBegin`. Collective. Parameters ---------- assembly The assembly type. See Also -------- assemblyBegin, assemble, petsc.MatAssemblyEnd """ cdef PetscMatAssemblyType flag = assemblytype(assembly) CHKERR( MatAssemblyEnd(self.mat, flag) ) def assemble(self, assembly: MatAssemblySpec = None) -> None: """Assemble the matrix. Collective. Parameters ---------- assembly The assembly type. See Also -------- assemblyBegin, assemblyEnd """ cdef PetscMatAssemblyType flag = assemblytype(assembly) CHKERR( MatAssemblyBegin(self.mat, flag) ) CHKERR( MatAssemblyEnd(self.mat, flag) ) def isAssembled(self) -> bool: """The boolean flag indicating if the matrix is assembled. Not collective. See Also -------- assemble, petsc.MatAssembled """ cdef PetscBool flag = PETSC_FALSE CHKERR( MatAssembled(self.mat, &flag) ) return toBool(flag) def findZeroRows(self) -> IS: """Return the index set of empty rows. Collective. See Also -------- petsc.MatFindZeroRows """ cdef IS zerorows = IS() CHKERR( MatFindZeroRows(self.mat, &zerorows.iset) ) return zerorows def createVecs( self, side: Literal['r', 'R', 'right', 'Right', 'RIGHT', 'l', 'L', 'left', 'Left', 'LEFT'] | None = None, ) -> Vec | tuple[Vec, Vec]: """Return vectors that can be used in matrix vector products. Collective. Parameters ---------- side If `None` returns a 2-tuple of vectors ``(right, left)``. Otherwise it just return a left or right vector. Notes ----- ``right`` vectors are vectors in the column space of the matrix. ``left`` vectors are vectors in the row space of the matrix. See Also -------- createVecLeft, createVecRight, petsc.MatCreateVecs """ cdef Vec vecr, vecl if side is None: vecr = Vec(); vecl = Vec(); CHKERR( MatCreateVecs(self.mat, &vecr.vec, &vecl.vec) ) return (vecr, vecl) elif side in ('r', 'R', 'right', 'Right', 'RIGHT'): vecr = Vec() CHKERR( MatCreateVecs(self.mat, &vecr.vec, NULL) ) return vecr elif side in ('l', 'L', 'left', 'Left', 'LEFT'): vecl = Vec() CHKERR( MatCreateVecs(self.mat, NULL, &vecl.vec) ) return vecl else: raise ValueError("side '%r' not understood" % side) def createVecRight(self) -> Vec: """Return a right vector, a vector that the matrix can be multiplied against. Collective. See Also -------- createVecs, createVecLeft, petsc.MatCreateVecs """ cdef Vec vecr = Vec() CHKERR( MatCreateVecs(self.mat, &vecr.vec, NULL) ) return vecr def createVecLeft(self) -> Vec: """Return a left vector, a vector that the matrix vector product can be stored in. Collective. See Also -------- createVecs, createVecRight, petsc.MatCreateVecs """ cdef Vec vecl = Vec() CHKERR( MatCreateVecs(self.mat, NULL, &vecl.vec) ) return vecl getVecs = createVecs getVecRight = createVecRight getVecLeft = createVecLeft # def getColumnVector(self, column: int, Vec result=None) -> Vec: """Return the columnᵗʰ column vector of the matrix. Collective. Parameters ---------- column Column index. result Optional vector to store the result. See Also -------- petsc.MatGetColumnVector """ cdef PetscInt ival = asInt(column) if result is None: result = Vec() if result.vec == NULL: CHKERR( MatCreateVecs(self.mat, NULL, &result.vec) ) CHKERR( MatGetColumnVector(self.mat, result.vec, ival) ) return result def getRedundantMatrix(self, nsubcomm: int, subcomm: Comm | None = None, Mat out=None) -> Mat: """Return redundant matrices on subcommunicators. Parameters ---------- nsubcomm The number of subcommunicators. subcomm Communicator split or `None` for the null communicator. out Optional resultant matrix. When `None`, a new matrix is created, and ``MAT_INITIAL_MATRIX`` is used. When not `None`, the matrix is reused with ``MAT_REUSE_MATRIX``. See Also -------- petsc.MatCreateRedundantMatrix """ cdef PetscInt _nsubcomm = asInt(nsubcomm) cdef MPI_Comm _subcomm = MPI_COMM_NULL if subcomm: _subcomm = def_Comm(subcomm, PETSC_COMM_DEFAULT) cdef PetscMatReuse reuse = MAT_INITIAL_MATRIX if out is None: out = Mat() if out.mat != NULL: reuse = MAT_REUSE_MATRIX CHKERR( MatCreateRedundantMatrix(self.mat, _nsubcomm, _subcomm, reuse, &out.mat)) return out def getDiagonal(self, Vec result=None) -> Vec: """Return the diagonal of the matrix. Collective. Parameters ---------- result Optional vector to store the result. See Also -------- setDiagonal, petsc.MatGetDiagonal """ if result is None: result = Vec() if result.vec == NULL: CHKERR( MatCreateVecs(self.mat, NULL, &result.vec) ) CHKERR( MatGetDiagonal(self.mat, result.vec) ) return result def getRowSum(self, Vec result=None) -> Vec: """Return the row-sum vector. Collective. Parameters ---------- result Optional vector to store the result. See Also -------- petsc.MatGetRowSum """ if result is None: result = Vec() if result.vec == NULL: CHKERR( MatCreateVecs(self.mat, NULL, &result.vec) ) CHKERR( MatGetRowSum(self.mat, result.vec) ) return result def setDiagonal(self, Vec diag, addv: InsertModeSpec = None) -> None: """Set the diagonal values of the matrix. Collective. Parameters ---------- diag Vector storing diagonal values. addv Insertion mode. See Also -------- getDiagonal, petsc.MatDiagonalSet """ cdef PetscInsertMode caddv = insertmode(addv) CHKERR( MatDiagonalSet(self.mat, diag.vec, caddv) ) def diagonalScale(self, Vec L=None, Vec R=None) -> None: """Perform left and/or right diagonal scaling of the matrix. Collective. Parameters ---------- L Optional left scaling vector. R Optional right scaling vector. See Also -------- petsc.MatDiagonalScale """ cdef PetscVec vecl=NULL, vecr=NULL if L is not None: vecl = L.vec if R is not None: vecr = R.vec CHKERR( MatDiagonalScale(self.mat, vecl, vecr) ) def invertBlockDiagonal(self) -> ArrayScalar: """Return the inverse of the block-diagonal entries. Collective. See Also -------- petsc.MatInvertBlockDiagonal """ cdef PetscInt bs = 0, m = 0 cdef const PetscScalar *cibdiag = NULL CHKERR( MatGetBlockSize(self.mat, &bs) ) CHKERR( MatGetLocalSize(self.mat, &m, NULL) ) CHKERR( MatInvertBlockDiagonal(self.mat, &cibdiag) ) cdef ndarray ibdiag = array_s(m*bs, cibdiag) ibdiag.shape = (toInt(m//bs), toInt(bs), toInt(bs)) return ibdiag.transpose(0, 2, 1) # null space def setNullSpace(self, NullSpace nsp) -> None: """Set the nullspace. Collective. See Also -------- getNullSpace, petsc.MatSetNullSpace """ CHKERR( MatSetNullSpace(self.mat, nsp.nsp) ) def getNullSpace(self) -> NullSpace: """Return the nullspace. Not collective. See Also -------- setNullSpace, petsc.MatGetNullSpace """ cdef NullSpace nsp = NullSpace() CHKERR( MatGetNullSpace(self.mat, &nsp.nsp) ) CHKERR( PetscINCREF(nsp.obj) ) return nsp def setTransposeNullSpace(self, NullSpace nsp) -> None: """Set the transpose nullspace. Collective. See Also -------- setNullSpace, getTransposeNullSpace, petsc.MatSetTransposeNullSpace """ CHKERR( MatSetTransposeNullSpace(self.mat, nsp.nsp) ) def getTransposeNullSpace(self) -> NullSpace: """Return the transpose nullspace. Not collective. See Also -------- getNullSpace, setTransposeNullSpace, petsc.MatGetTransposeNullSpace """ cdef NullSpace nsp = NullSpace() CHKERR( MatGetTransposeNullSpace(self.mat, &nsp.nsp) ) CHKERR( PetscINCREF(nsp.obj) ) return nsp def setNearNullSpace(self, NullSpace nsp) -> None: """Set the near-nullspace. Collective. See Also -------- setNullSpace, getNearNullSpace, petsc.MatSetNearNullSpace """ CHKERR( MatSetNearNullSpace(self.mat, nsp.nsp) ) def getNearNullSpace(self) -> NullSpace: """Return the near-nullspace. Not collective. See Also -------- getNullSpace, setNearNullSpace, petsc.MatSetNearNullSpace """ cdef NullSpace nsp = NullSpace() CHKERR( MatGetNearNullSpace(self.mat, &nsp.nsp) ) CHKERR( PetscINCREF(nsp.obj) ) return nsp # matrix-vector product def mult(self, Vec x, Vec y) -> None: """Perform the matrix vector product y = A @ x. Collective. Parameters ---------- x The input vector. y The output vector. See Also -------- petsc.MatMult """ CHKERR( MatMult(self.mat, x.vec, y.vec) ) def multAdd(self, Vec x, Vec v, Vec y) -> None: """Perform the matrix vector product with addition y = A @ x + v. Collective. Parameters ---------- x The input vector for the matrix-vector product. v The input vector to be added to. y The output vector. See Also -------- petsc.MatMultAdd """ CHKERR( MatMultAdd(self.mat, x.vec, v.vec, y.vec) ) def multTranspose(self, Vec x, Vec y) -> None: """Perform the transposed matrix vector product y = A^T @ x. Collective. Parameters ---------- x The input vector. y The output vector. See Also -------- petsc.MatMultTranspose """ CHKERR( MatMultTranspose(self.mat, x.vec, y.vec) ) def multTransposeAdd(self, Vec x, Vec v, Vec y) -> None: """Perform the transposed matrix vector product with addition y = A^T @ x + v. Collective. Parameters ---------- x The input vector for the transposed matrix-vector product. v The input vector to be added to. y The output vector. See Also -------- petsc.MatMultTransposeAdd """ CHKERR( MatMultTransposeAdd(self.mat, x.vec, v.vec, y.vec) ) def multHermitian(self, Vec x, Vec y) -> None: """Perform the Hermitian matrix vector product y = A^H @ x. Collective. Parameters ---------- x The input vector for the Hermitian matrix-vector product. y The output vector. See Also -------- petsc.MatMultHermitianTranspose """ CHKERR( MatMultHermitian(self.mat, x.vec, y.vec) ) def multHermitianAdd(self, Vec x, Vec v, Vec y) -> None: """Perform the Hermitian matrix vector product with addition y = A^H @ x + v. Collective. Parameters ---------- x The input vector for the Hermitian matrix-vector product. v The input vector to be added to. y The output vector. See Also -------- petsc.MatMultHermitianTransposeAdd """ CHKERR( MatMultHermitianAdd(self.mat, x.vec, v.vec, y.vec) ) # SOR def SOR( self, Vec b, Vec x, omega:float = 1.0, sortype:SORType | None = None, shift:float = 0.0, its:int = 1, lits:int = 1, ) -> None: """Compute relaxation (SOR, Gauss-Seidel) sweeps. Neighborwise collective. See Also -------- petsc.MatSOR """ cdef PetscReal comega = asReal(omega) cdef PetscMatSORType csortype = SOR_LOCAL_SYMMETRIC_SWEEP if sortype is not None: csortype = asInt(sortype) cdef PetscReal cshift = asReal(shift) cdef PetscInt cits = asInt(its) cdef PetscInt clits = asInt(lits) CHKERR( MatSOR(self.mat, b.vec, comega, csortype, cshift, cits, clits, x.vec) ) # def getDiagonalBlock(self) -> Mat: """Return the part of the matrix associated with the on-process coupling. Not collective. See Also -------- petsc.MatGetDiagonalBlock """ cdef Mat submat = Mat() CHKERR( MatGetDiagonalBlock(self.mat, &submat.mat) ) CHKERR( PetscINCREF(submat.obj) ) return submat def increaseOverlap(self, IS iset, overlap: int = 1) -> None: """Increase the overlap of a index set. Collective. See Also -------- petsc.MatIncreaseOverlap """ cdef PetscInt ival = asInt(overlap) CHKERR( MatIncreaseOverlap(self.mat, 1, &iset.iset, ival) ) def createSubMatrix(self, IS isrow, IS iscol=None, Mat submat=None) -> Mat: """Return a submatrix. Collective. Parameters ---------- isrow Row index set. iscol Column index set. If `None`, ``iscol = isrow``. submat Optional resultant matrix. When `None`, a new matrix is created, and ``MAT_INITIAL_MATRIX`` is used. When not `None`, the matrix is reused with ``MAT_REUSE_MATRIX``. See Also -------- petsc.MatCreateSubMatrix """ cdef PetscMatReuse reuse = MAT_INITIAL_MATRIX cdef PetscIS ciscol = NULL if iscol is not None: ciscol = iscol.iset if submat is None: submat = Mat() if submat.mat != NULL: reuse = MAT_REUSE_MATRIX CHKERR( MatCreateSubMatrix(self.mat, isrow.iset, ciscol, reuse, &submat.mat) ) return submat def createSubMatrices( self, isrows: IS | Sequence[IS], iscols: IS | Sequence[IS] = None, submats: Mat | Sequence[Mat] = None, ) -> Sequence[Mat]: """Return several sequential submatrices. Collective. Parameters ---------- isrows Row index sets. iscols Column index sets. If `None`, ``iscols = isrows``. submats Optional resultant matrices. When `None`, new matrices are created, and ``MAT_INITIAL_MATRIX`` is used. When not `None`, the matrices are reused with ``MAT_REUSE_MATRIX``. See Also -------- petsc.MatCreateSubMatrices """ if iscols is None: iscols = isrows isrows = [isrows] if isinstance(isrows, IS) else list(isrows) iscols = [iscols] if isinstance(iscols, IS) else list(iscols) assert len(isrows) == len(iscols) cdef Py_ssize_t i, n = len(isrows) cdef PetscMatReuse reuse = MAT_INITIAL_MATRIX cdef PetscIS *cisrows = NULL cdef PetscIS *ciscols = NULL cdef PetscMat *cmats = NULL cdef object tmp1, tmp2 cdef Mat mat tmp1 = oarray_p(empty_p(n), NULL, &cisrows) for i from 0 <= i < n: cisrows[i] = (isrows[i]).iset tmp2 = oarray_p(empty_p(n), NULL, &ciscols) for i from 0 <= i < n: ciscols[i] = (iscols[i]).iset if submats is not None: reuse = MAT_REUSE_MATRIX submats = list(submats) assert len(submats) == len(isrows) CHKERR( PetscMalloc((n+1)*sizeof(PetscMat), &cmats) ) for i from 0 <= i < n: cmats[i] = (submats[i]).mat CHKERR( MatCreateSubMatrices(self.mat, n, cisrows, ciscols, reuse, &cmats) ) for i from 0 <= i < n: CHKERR( PetscINCREF(&cmats[i]) ) if reuse == MAT_INITIAL_MATRIX: submats = [None] * n for i from 0 <= i < n: submats[i] = mat = Mat() mat.mat = cmats[i] CHKERR( MatDestroyMatrices(n, &cmats) ) return submats # def getLocalSubMatrix(self, IS isrow, IS iscol, Mat submat=None) -> Mat: """Return a reference to a submatrix specified in local numbering. Collective. Parameters ---------- isrow Row index set. iscol Column index set. submat Optional resultant matrix. When `None`, a new matrix is created. When not `None`, the matrix is first destroyed and then recreated. See Also -------- restoreLocalSubMatrix, petsc.MatGetLocalSubMatrix """ if submat is None: submat = Mat() else: CHKERR( MatDestroy(&submat.mat) ) CHKERR( MatGetLocalSubMatrix(self.mat, isrow.iset, iscol.iset, &submat.mat) ) return submat def restoreLocalSubMatrix(self, IS isrow, IS iscol, Mat submat): """Restore a reference to a submatrix obtained with `getLocalSubMatrix`. Collective. Parameters ---------- isrow Row index set. iscol Column index set. submat The submatrix. See Also -------- getLocalSubMatrix, petsc.MatRestoreLocalSubMatrix """ CHKERR( MatRestoreLocalSubMatrix(self.mat, isrow.iset, iscol.iset, &submat.mat) ) # def norm( self, norm_type: NormTypeSpec = None, ) -> float | tuple[float, float]: """Compute the requested matrix norm. Collective. A 2-tuple is returned if `NormType.NORM_1_AND_2` is specified. See Also -------- petsc.MatNorm, petsc.NormType """ cdef PetscNormType norm_1_2 = PETSC_NORM_1_AND_2 cdef PetscNormType ntype = PETSC_NORM_FROBENIUS if norm_type is not None: ntype = norm_type cdef PetscReal rval[2] CHKERR( MatNorm(self.mat, ntype, rval) ) if ntype != norm_1_2: return toReal(rval[0]) else: return (toReal(rval[0]), toReal(rval[1])) def scale(self, alpha: Scalar) -> None: """Scale the matrix. Collective. See Also -------- petsc.MatScale """ cdef PetscScalar sval = asScalar(alpha) CHKERR( MatScale(self.mat, sval) ) def shift(self, alpha: Scalar) -> None: """Shift the matrix. Collective. See Also -------- petsc.MatShift """ cdef PetscScalar sval = asScalar(alpha) CHKERR( MatShift(self.mat, sval) ) def chop(self, tol: float) -> None: """Set entries smallest of tol (in absolute values) to zero. Collective. See Also -------- petsc.MatFilter """ cdef PetscReal rval = asReal(tol) CHKERR( MatFilter(self.mat, rval, PETSC_FALSE, PETSC_FALSE) ) def setRandom(self, Random random=None) -> None: """Set random values in the matrix. Collective. Parameters ---------- random The random number generator object or `None` for the default. See Also -------- petsc.MatSetRandom """ cdef PetscRandom rnd = NULL if random is not None: rnd = random.rnd CHKERR( MatSetRandom(self.mat, rnd) ) def axpy(self, alpha: Scalar, Mat X, structure: Structure = None) -> None: """Perform the matrix summation ``self`` + = ɑ·X. Collective. Parameters ---------- alpha The scalar. X The matrix to be added. structure The structure of the operation. See Also -------- petsc.MatAXPY """ cdef PetscScalar sval = asScalar(alpha) cdef PetscMatStructure flag = matstructure(structure) CHKERR( MatAXPY(self.mat, sval, X.mat, flag) ) def aypx(self, alpha: Scalar, Mat X, structure: Structure = None) -> None: """Perform the matrix summation ``self`` = ɑ·``self`` + X. Collective. Parameters ---------- alpha The scalar. X The matrix to be added. structure The structure of the operation. See Also -------- petsc.MatAYPX """ cdef PetscScalar sval = asScalar(alpha) cdef PetscMatStructure flag = matstructure(structure) CHKERR( MatAYPX(self.mat, sval, X.mat, flag) ) # matrix-matrix product def matMult( self, Mat mat, Mat result=None, fill: float | None = None ) -> Mat: """Perform matrix-matrix multiplication C=AB. Neighborwise collective. Parameters ---------- mat The right hand matrix B. result The optional resultant matrix C. When `None`, a new matrix is created, and ``MAT_INITIAL_MATRIX`` is used. When C is not `None`, the matrix is reused with ``MAT_REUSE_MATRIX``. fill Expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use `None` if you do not have a good estimate. If the result is a dense matrix this is irrelevant. Returns ------- result : Mat The resultant product matrix C. Notes ----- To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value actually needed. See Also -------- petsc.MatMatMult, petsc.MatReuse """ cdef PetscMatReuse reuse = MAT_INITIAL_MATRIX cdef PetscReal rval = 2 if result is None: result = Mat() elif result.mat != NULL: reuse = MAT_REUSE_MATRIX if fill is not None: rval = asReal(fill) CHKERR( MatMatMult(self.mat, mat.mat, reuse, rval, &result.mat) ) return result def matTransposeMult( self, Mat mat, Mat result=None, fill: float | None = None ): """Perform matrix-matrix multiplication C=ABᵀ. Neighborwise collective. Parameters ---------- mat The right hand matrix B. result The optional resultant matrix C. When `None`, a new matrix is created, and ``MAT_INITIAL_MATRIX`` is used. When C is not `None`, the matrix is reused with ``MAT_REUSE_MATRIX``. fill Expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use `None` if you do not have a good estimate. If the result is a dense matrix this is irrelevant. Returns ------- result : Mat The resultant product matrix C. Notes ----- To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value actually needed. See Also -------- petsc.MatMatTransposeMult, petsc.MatReuse """ cdef PetscMatReuse reuse = MAT_INITIAL_MATRIX cdef PetscReal rval = 2 if result is None: result = Mat() elif result.mat != NULL: reuse = MAT_REUSE_MATRIX if fill is not None: rval = asReal(fill) CHKERR( MatMatTransposeMult(self.mat, mat.mat, reuse, rval, &result.mat) ) return result def transposeMatMult( self, Mat mat, Mat result=None, fill: float | None = None ): """Perform matrix-matrix multiplication C=AᵀB. Neighborwise collective. Parameters ---------- mat The right hand matrix B. result The optional resultant matrix C. When `None`, a new matrix is created, and ``MAT_INITIAL_MATRIX`` is used. When C is not `None`, the matrix is reused with ``MAT_REUSE_MATRIX``. fill Expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use `None` if you do not have a good estimate. If the result is a dense matrix this is irrelevant. Returns ------- result : Mat The resultant product matrix C. Notes ----- To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value actually needed. See Also -------- petsc.MatTransposeMatMult, petsc.MatReuse """ cdef PetscMatReuse reuse = MAT_INITIAL_MATRIX cdef PetscReal rval = 2 if result is None: result = Mat() elif result.mat != NULL: reuse = MAT_REUSE_MATRIX if fill is not None: rval = asReal(fill) CHKERR( MatTransposeMatMult(self.mat, mat.mat, reuse, rval, &result.mat) ) return result def ptap( self, Mat P, Mat result=None, fill: float | None = None ) -> Mat: """Creates the matrix product C = PᵀAP. Neighborwise collective. Parameters ---------- P The matrix P. result The optional resultant matrix C. When `None`, a new matrix is created, and ``MAT_INITIAL_MATRIX`` is used. When C is not `None`, the matrix is reused with ``MAT_REUSE_MATRIX``. fill Expected fill as ratio of nnz(C)/(nnz(A) + nnz(P)), use `None` if you do not have a good estimate. If the result is a dense matrix this is irrelevant. Returns ------- result : Mat The resultant product matrix C. Notes ----- To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value actually needed. An alternative approach to this function is to use `petsc.MatProductCreate` and set the desired options before the computation is done. See Also -------- petsc.MatPtAP, petsc.MatReuse """ cdef PetscMatReuse reuse = MAT_INITIAL_MATRIX cdef PetscReal cfill = PETSC_DEFAULT if result is None: result = Mat() elif result.mat != NULL: reuse = MAT_REUSE_MATRIX if fill is not None: cfill = asReal(fill) CHKERR( MatPtAP(self.mat, P.mat, reuse, cfill, &result.mat) ) return result def rart( self, Mat R, Mat result=None, fill: float | None = None ) -> Mat: """Create the matrix product C = RARᵀ. Neighborwise collective. Parameters ---------- R The projection matrix. result The optional resultant matrix C. When `None`, a new matrix is created, and ``MAT_INITIAL_MATRIX`` is used. When C is not `None`, the matrix is reused with ``MAT_REUSE_MATRIX``. fill Expected fill as ratio of nnz(C)/nnz(A), use `None` if you do not have a good estimate. If the result is a dense matrix this is irrelevant. Returns ------- result : Mat The resultant product matrix C. Notes ----- To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value actually needed. See Also -------- petsc.MatRARt, petsc.MatReuse """ cdef PetscMatReuse reuse = MAT_INITIAL_MATRIX cdef PetscReal cfill = PETSC_DEFAULT if result is None: result = Mat() elif result.mat != NULL: reuse = MAT_REUSE_MATRIX if fill is not None: cfill = asReal(fill) CHKERR( MatRARt(self.mat, R.mat, reuse, cfill, &result.mat) ) return result def matMatMult( self, Mat B, Mat C, Mat result=None, fill: float | None = None ) -> Mat: """Perform matrix-matrix-matrix multiplication D=ABC. Neighborwise collective. Parameters ---------- B The middle matrix B. C The right hand matrix C. result The optional resultant matrix D. When `None`, a new matrix is created, and ``MAT_INITIAL_MATRIX`` is used. When D is not `None`, the matrix is reused with ``MAT_REUSE_MATRIX``. fill Expected fill as ratio of nnz(C)/nnz(A), use `None` if you do not have a good estimate. If the result is a dense matrix this is irrelevant. Returns ------- result : Mat The resultant product matrix D. See Also -------- petsc.MatMatMatMult, petsc.MatReuse """ cdef PetscMatReuse reuse = MAT_INITIAL_MATRIX cdef PetscReal cfill = PETSC_DEFAULT if result is None: result = Mat() elif result.mat != NULL: reuse = MAT_REUSE_MATRIX if fill is not None: cfill = asReal(fill) CHKERR( MatMatMatMult(self.mat, B.mat, C.mat, reuse, cfill, &result.mat) ) return result def kron( self, Mat mat, Mat result=None ) -> Mat: """Compute C, the Kronecker product of A and B. Parameters ---------- mat The right hand matrix B. result The optional resultant matrix. When `None`, a new matrix is created, and ``MAT_INITIAL_MATRIX`` is used. When it is not `None`, the matrix is reused with ``MAT_REUSE_MATRIX``. Returns ------- result : Mat The resultant matrix C, the Kronecker product of A and B. See Also -------- petsc.MatSeqAIJKron, petsc.MatReuse """ cdef PetscMatReuse reuse = MAT_INITIAL_MATRIX if result is None: result = Mat() elif result.mat != NULL: reuse = MAT_REUSE_MATRIX CHKERR( MatSeqAIJKron(self.mat, mat.mat, reuse, &result.mat) ) return result def bindToCPU(self, flg: bool) -> None: """Mark a matrix to temporarily stay on the CPU. Once marked, perform computations on the CPU. Parameters ---------- flg Bind to the CPU if `True`. See Also -------- petsc.MatBindToCPU """ cdef PetscBool bindFlg = asBool(flg) CHKERR( MatBindToCPU(self.mat, bindFlg) ) def boundToCPU(self) -> bool: """Query if a matrix is bound to the CPU. See Also -------- petsc.MatBoundToCPU """ cdef PetscBool flg = PETSC_TRUE CHKERR( MatBoundToCPU(self.mat, &flg) ) return toBool(flg) # XXX factorization def getOrdering(self, ord_type: OrderingType) -> tuple[IS, IS]: """Return a reordering for a matrix to improve a LU factorization. Collective. Parameters ---------- ord_type The type of reordering. Returns ------- rp : IS The row permutation indices. cp : IS The column permutation indices. See Also -------- petsc.MatGetOrdering """ cdef PetscMatOrderingType cval = NULL ord_type = str2bytes(ord_type, &cval) cdef IS rp = IS(), cp = IS() CHKERR( MatGetOrdering(self.mat, cval, &rp.iset, &cp.iset) ) return (rp, cp) def reorderForNonzeroDiagonal( self, IS isrow, IS iscol, atol: float = 0 ) -> None: """Change a matrix ordering to remove zeros from the diagonal. Collective. Parameters ---------- isrow The row reordering. iscol The column reordering. atol The absolute tolerance. Values along the diagonal whose absolute value are smaller than this tolerance are moved off the diagonal. See Also -------- getOrdering, petsc.MatReorderForNonzeroDiagonal """ cdef PetscReal rval = asReal(atol) cdef PetscIS rp = isrow.iset, cp = iscol.iset CHKERR( MatReorderForNonzeroDiagonal(self.mat, rval, rp, cp) ) def factorLU( self, IS isrow, IS iscol, options: dict[str, Any] | None = None, ) -> None: """Perform an in-place LU factorization. Collective. Parameters ---------- isrow The row permutation. iscol The column permutation. options An optional dictionary of options for the factorization. These include ``fill``, the expected fill as a ratio of the original fill and ``dtcol``, the pivot tolerance where ``0`` indicates no pivot and ``1`` indicates full column pivoting. See Also -------- petsc.MatLUFactor """ cdef PetscMatFactorInfo info matfactorinfo(PETSC_FALSE, PETSC_FALSE, options, &info) CHKERR( MatLUFactor(self.mat, isrow.iset, iscol.iset, &info) ) def factorSymbolicLU(self, Mat mat, IS isrow, IS iscol, options=None) -> None: """Not implemented.""" raise NotImplementedError def factorNumericLU(self, Mat mat, options=None) -> None: """Not implemented.""" raise NotImplementedError def factorILU( self, IS isrow, IS iscol, options: dict[str, Any] | None = None, ) -> None: """Perform an in-place ILU factorization. Collective. Parameters ---------- isrow The row permutation. iscol The column permutation. options An optional dictionary of options for the factorization. These include ``levels``, the number of levels of fill, ``fill``, the expected fill as a ratio of the original fill, and ``dtcol``, the pivot tolerance where ``0`` indicates no pivot and ``1`` indicates full column pivoting. See Also -------- petsc.MatILUFactor """ cdef PetscMatFactorInfo info matfactorinfo(PETSC_TRUE, PETSC_FALSE, options, &info) CHKERR( MatILUFactor(self.mat, isrow.iset, iscol.iset, &info) ) def factorSymbolicILU(self, IS isrow, IS iscol, options=None) -> None: """Not implemented.""" raise NotImplementedError def factorCholesky( self, IS isperm, options: dict[str, Any] | None = None, ) -> None: """Perform an in-place Cholesky factorization. Collective. Parameters ---------- isperm The row and column permutations. options An optional dictionary of options for the factorization. These include ``fill``, the expected fill as a ratio of the original fill. See Also -------- factorLU, petsc.MatCholeskyFactor """ cdef PetscMatFactorInfo info matfactorinfo(PETSC_FALSE, PETSC_TRUE, options, &info) CHKERR( MatCholeskyFactor(self.mat, isperm.iset, &info) ) def factorSymbolicCholesky(self, IS isperm, options=None) -> None: """Not implemented.""" raise NotImplementedError def factorNumericCholesky(self, Mat mat, options=None) -> None: """Not implemented.""" raise NotImplementedError def factorICC( self, IS isperm, options: dict[str, Any] | None = None, ) -> None: """Perform an in-place an incomplete Cholesky factorization. Collective. Parameters ---------- isperm The row and column permutations options An optional dictionary of options for the factorization. These include ``fill``, the expected fill as a ratio of the original fill. See Also -------- factorILU, petsc.MatICCFactor """ cdef PetscMatFactorInfo info matfactorinfo(PETSC_TRUE, PETSC_TRUE, options, &info) CHKERR( MatICCFactor(self.mat, isperm.iset, &info) ) def factorSymbolicICC(self, IS isperm, options=None) -> None: """Not implemented.""" raise NotImplementedError def getInertia(self) -> tuple[int, int, int]: """Return the inertia from a factored matrix. Collective. The matrix must have been factored by calling `factorCholesky`. Returns ------- n : int The number of negative eigenvalues. z : int The number of zero eigenvalues. p : int The number of positive eigenvalues. See Also -------- petsc.MatGetInertia """ cdef PetscInt ival1 = 0, ival2 = 0, ival3 = 0 CHKERR( MatGetInertia(self.mat, &ival1, &ival2, &ival3) ) return (toInt(ival1), toInt(ival2), toInt(ival3)) def setUnfactored(self) -> None: """Set a factored matrix to be treated as unfactored. Logically collective. See Also -------- petsc.MatSetUnfactored """ CHKERR( MatSetUnfactored(self.mat) ) # IS def fixISLocalEmpty(self, fix: bool) -> None: """Compress out zero local rows from the local matrices. Collective. Parameters ---------- fix When `True`, new local matrices and local to global maps are generated during the final assembly process. See Also -------- petsc.MatISFixLocalEmpty """ cdef PetscBool cfix = asBool(fix) CHKERR( MatISFixLocalEmpty(self.mat, cfix) ) def getISLocalMat(self) -> Mat: """Return the local matrix stored inside a `Type.IS` matrix. See Also -------- petsc.MatISGetLocalMat """ cdef Mat local = Mat() CHKERR( MatISGetLocalMat(self.mat, &local.mat) ) CHKERR( PetscINCREF(local.obj) ) return local def restoreISLocalMat(self, Mat local not None) -> None: """Restore the local matrix obtained with `getISLocalMat`. Parameters ---------- local The local matrix. See Also -------- petsc.MatISRestoreLocalMat """ CHKERR( MatISRestoreLocalMat(self.mat, &local.mat) ) def setISLocalMat(self, Mat local not None) -> None: """Set the local matrix stored inside a `Type.IS`. Parameters ---------- local The local matrix. See Also -------- petsc.MatISSetLocalMat """ CHKERR( MatISSetLocalMat(self.mat, local.mat) ) def setISPreallocation( self, nnz: Sequence[int], onnz: Sequence[int], ) -> Self: """Preallocate memory for a `Type.IS` parallel matrix. Parameters ---------- nnz The sequence whose length corresponds to the number of local rows and values which represent the number of nonzeros in the various rows of the *diagonal* of the local submatrix. onnz: The sequence whose length corresponds to the number of local rows and values which represent the number of nonzeros in the various rows of the *off-diagonal* of the local submatrix. See Also -------- petsc.MatISSetPreallocation """ cdef PetscInt *cnnz = NULL cdef PetscInt *connz = NULL nnz = iarray_i(nnz, NULL, &cnnz) onnz = iarray_i(onnz, NULL, &connz) CHKERR( MatISSetPreallocation(self.mat, 0, cnnz, 0, connz) ) return self # LRC def getLRCMats(self) -> tuple[Mat, Mat, Vec, Mat]: """Return the constituents of a `Type.LRC` matrix. Not collective. Returns ------- A : Mat The ``A`` matrix. U : Mat The first dense rectangular matrix. c : Vec The sequential vector containing the diagonal of ``C``. V : Mat The second dense rectangular matrix. See Also -------- petsc.MatLRCGetMats """ cdef Mat A = Mat() cdef Mat U = Mat() cdef Vec c = Vec() cdef Mat V = Mat() CHKERR( MatLRCGetMats(self.mat, &A.mat, &U.mat, &c.vec, &V.mat) ) CHKERR( PetscINCREF(A.obj) ) CHKERR( PetscINCREF(U.obj) ) CHKERR( PetscINCREF(c.obj) ) CHKERR( PetscINCREF(V.obj) ) return (A, U, c, V) def setLRCMats(self, Mat A, Mat U, Vec c=None, Mat V=None): """Set the constituents of a `Type.LRC` matrix. Logically collective. Parameters ---------- A : Mat The ``A`` matrix, or `None` to omit ``A``. U : Mat The first dense rectangular matrix. c : Vec The sequential vector containing the diagonal of ``C``, or `None` for all ones. V : Mat The second dense rectangular matrix, or `None` for a copy of ``U``. See Also -------- petsc.MatLRCSetMats """ cdef PetscMat Amat = A.mat if A is not None else NULL cdef PetscVec cvec = c.vec if c is not None else NULL cdef PetscMat Vmat = V.mat if V is not None else NULL CHKERR( MatLRCSetMats(self.mat, Amat, U.mat, cvec, Vmat) ) # H2Opus def H2OpusOrthogonalize(self) -> Self: """Orthogonalize the basis tree of a hierarchical matrix. See Also -------- petsc.MatH2OpusOrthogonalize """ CHKERR( MatH2OpusOrthogonalize(self.mat) ) return self def H2OpusCompress(self, tol: float): """Compress a hierarchical matrix. Parameters ---------- tol The absolute truncation threshold. See Also -------- petsc.MatH2OpusCompress """ cdef PetscReal _tol = asReal(tol) CHKERR( MatH2OpusCompress(self.mat, _tol) ) return self def H2OpusLowRankUpdate(self, Mat U, Mat V=None, s: float = 1.0): """Perform a low-rank update of the form ``self`` += sUVᵀ. Parameters ---------- U The dense low-rank update matrix. V The dense low-rank update matrix. If `None`, ``V = U``. s The scaling factor. See Also -------- petsc.MatH2OpusLowRankUpdate """ cdef PetscScalar _s = asScalar(s) cdef PetscMat vmat = NULL if V is not None: vmat = V.mat CHKERR( MatH2OpusLowRankUpdate(self.mat, U.mat, vmat, _s) ) return self # MUMPS def setMumpsIcntl(self, icntl: int, ival: int) -> None: """Set a MUMPS parameter, ``ICNTL[icntl] = ival``. Logically collective. Parameters ---------- icntl The index of the MUMPS parameter array. ival The value to set. See Also -------- petsc_options, petsc.MatMumpsSetIcntl """ cdef PetscInt _icntl = asInt(icntl) cdef PetscInt _ival = asInt(ival) CHKERR( MatMumpsSetIcntl(self.mat, _icntl, _ival) ); def getMumpsIcntl(self, icntl: int) -> int: """Return the MUMPS parameter, ``ICNTL[icntl]``. Logically collective. See Also -------- petsc_options, petsc.MatMumpsGetIcntl """ cdef PetscInt _icntl = asInt(icntl) cdef PetscInt ival = 0 CHKERR( MatMumpsGetIcntl(self.mat, _icntl, &ival) ); return toInt(ival) def setMumpsCntl(self, icntl: int, val: float): """Set a MUMPS parameter, ``CNTL[icntl] = val``. Logically collective. Parameters ---------- icntl The index of the MUMPS parameter array. val The value to set. See Also -------- petsc_options, petsc.MatMumpsSetCntl """ cdef PetscInt _icntl = asInt(icntl) cdef PetscReal _val = asReal(val) CHKERR( MatMumpsSetCntl(self.mat, _icntl, _val) ); def getMumpsCntl(self, icntl: int) -> float: """Return the MUMPS parameter, ``CNTL[icntl]``. Logically collective. See Also -------- petsc_options, petsc.MatMumpsGetCntl """ cdef PetscInt _icntl = asInt(icntl) cdef PetscReal val = 0 CHKERR( MatMumpsGetCntl(self.mat, _icntl, &val) ); return toReal(val) def getMumpsInfo(self, icntl: int) -> int: """Return the MUMPS parameter, ``INFO[icntl]``. Logically collective. Parameters ---------- icntl The index of the MUMPS INFO array. See Also -------- petsc.MatMumpsGetInfo """ cdef PetscInt _icntl = asInt(icntl) cdef PetscInt ival = 0 CHKERR( MatMumpsGetInfo(self.mat, _icntl, &ival) ); return toInt(ival) def getMumpsInfog(self, icntl: int) -> int: """Return the MUMPS parameter, ``INFOG[icntl]``. Logically collective. Parameters ---------- icntl The index of the MUMPS INFOG array. See Also -------- petsc.MatMumpsGetInfog """ cdef PetscInt _icntl = asInt(icntl) cdef PetscInt ival = 0 CHKERR( MatMumpsGetInfog(self.mat, _icntl, &ival) ); return toInt(ival) def getMumpsRinfo(self, icntl: int) -> float: """Return the MUMPS parameter, ``RINFO[icntl]``. Logically collective. Parameters ---------- icntl The index of the MUMPS RINFO array. See Also -------- petsc.MatMumpsGetRinfo """ cdef PetscInt _icntl = asInt(icntl) cdef PetscReal val = 0 CHKERR( MatMumpsGetRinfo(self.mat, _icntl, &val) ); return toReal(val) def getMumpsRinfog(self, icntl: int) -> float: """Return the MUMPS parameter, ``RINFOG[icntl]``. Logically collective. Parameters ---------- icntl The index of the MUMPS RINFOG array. See Also -------- petsc.MatMumpsGetRinfog """ cdef PetscInt _icntl = asInt(icntl) cdef PetscReal val = 0 CHKERR( MatMumpsGetRinfog(self.mat, _icntl, &val) ); return toReal(val) # solve def solveForward(self, Vec b, Vec x) -> None: """Solve Lx = b, given a factored matrix A = LU. Neighborwise collective. Parameters ---------- b The right-hand side vector. x The output solution vector. See Also -------- petsc.MatForwardSolve """ CHKERR( MatForwardSolve(self.mat, b.vec, x.vec) ) def solveBackward(self, Vec b, Vec x) -> None: """Solve Ux=b, given a factored matrix A=LU. Neighborwise collective. Parameters ---------- b The right-hand side vector. x The output solution vector. See Also -------- petsc.MatBackwardSolve """ CHKERR( MatBackwardSolve(self.mat, b.vec, x.vec) ) def solve(self, Vec b, Vec x) -> None: """Solve Ax=b, given a factored matrix. Neighborwise collective. The vectors ``b`` and ``x`` cannot be the same. Most users should employ the `KSP` interface for linear solvers instead of working directly with matrix algebra routines. Parameters ---------- b The right-hand side vector. x The output solution vector, must be different than ``b``. See Also -------- KSP.create, solveTranspose, petsc.MatSolve """ CHKERR(MatSolve(self.mat, b.vec, x.vec) ) def solveTranspose(self, Vec b, Vec x) -> None: """Solve Aᵀx=b, given a factored matrix. Neighborwise collective. The vectors ``b`` and ``x`` cannot be the same. Parameters ---------- b The right-hand side vector. x The output solution vector, must be different than ``b``. See Also -------- KSP.create, petsc.MatSolve, petsc.MatSolveTranspose """ CHKERR( MatSolveTranspose(self.mat, b.vec, x.vec) ) def solveAdd(self, Vec b, Vec y, Vec x) -> None: """Solve x=y+A⁻¹b, given a factored matrix. Neighborwise collective. The vectors ``b`` and ``x`` cannot be the same. Parameters ---------- b The right-hand side vector. y The vector to be added x The output solution vector, must be different than ``b``. See Also -------- KSP.create, petsc.MatSolve, petsc.MatSolveAdd """ CHKERR( MatSolveAdd(self.mat, b.vec, y.vec, x.vec) ) def solveTransposeAdd(self, Vec b, Vec y, Vec x) -> None: """Solve x=y+A⁻ᵀb, given a factored matrix. Neighborwise collective. The vectors ``b`` and ``x`` cannot be the same. Parameters ---------- b The right-hand side vector. y The vector to be added x The output solution vector, must be different than ``b``. See Also -------- KSP.create, petsc.MatSolve, petsc.MatSolveTransposeAdd """ CHKERR( MatSolveTransposeAdd(self.mat, b.vec, y.vec, x.vec) ) def matSolve(self, Mat B, Mat X) -> None: """Solve AX=B, given a factored matrix A. Neighborwise collective. Parameters ---------- B The right-hand side matrix of type `Type.DENSE`. Can be of type `Type.AIJ` if using MUMPS. X The output solution matrix, must be different than ``B``. See Also -------- KSP.create, petsc.MatMatSolve """ CHKERR( MatMatSolve(self.mat, B.mat, X.mat) ) # dense matrices def setDenseLDA(self, lda: int) -> None: """Set the leading dimension of the array used by the dense matrix. Not collective. Parameters ---------- lda The leading dimension. See Also -------- petsc.MatDenseSetLDA """ cdef PetscInt _ilda = asInt(lda) CHKERR( MatDenseSetLDA(self.mat, _ilda) ) def getDenseLDA(self) -> int: """Return the leading dimension of the array used by the dense matrix. Not collective. See Also -------- petsc.MatDenseGetLDA """ cdef PetscInt lda=0 CHKERR( MatDenseGetLDA(self.mat, &lda) ) return toInt(lda) def getDenseArray(self, readonly: bool = False) -> ArrayScalar: """Return the array where the data is stored. Not collective. Parameters ---------- readonly Enable to obtain a read only array. See Also -------- petsc.MatDenseGetArrayRead, petsc.MatDenseGetArray """ cdef PetscInt m=0, N=0, lda=0 cdef PetscScalar *data = NULL CHKERR( MatGetLocalSize(self.mat, &m, NULL) ) CHKERR( MatGetSize(self.mat, NULL, &N) ) CHKERR( MatDenseGetLDA(self.mat, &lda) ) if readonly: CHKERR( MatDenseGetArrayRead(self.mat, &data) ) else: CHKERR( MatDenseGetArray(self.mat, &data) ) cdef int typenum = NPY_PETSC_SCALAR cdef int itemsize = sizeof(PetscScalar) cdef int flags = NPY_ARRAY_FARRAY cdef npy_intp dims[2], strides[2] dims[0] = m; strides[0] = sizeof(PetscScalar); dims[1] = N; strides[1] = (lda*sizeof(PetscScalar)); array = PyArray_New(ndarray, 2, dims, typenum, strides, data, itemsize, flags, NULL) if readonly: CHKERR( MatDenseRestoreArrayRead(self.mat, &data) ) else: CHKERR( MatDenseRestoreArray(self.mat, &data) ) return array def getDenseLocalMatrix(self) -> Mat: """Return the local part of the dense matrix. Not collective. See Also -------- petsc.MatDenseGetLocalMatrix """ cdef Mat mat = type(self)() CHKERR( MatDenseGetLocalMatrix(self.mat, &mat.mat) ) CHKERR( PetscINCREF(mat.obj) ) return mat def getDenseColumnVec(self, i: int, mode: AccessModeSpec = 'rw') -> Vec: """Return the iᵗʰ column vector of the dense matrix. Collective. Parameters ---------- i The column index to access. mode The access type of the returned array See Also -------- restoreDenseColumnVec, petsc.MatDenseGetColumnVec petsc.MatDenseGetColumnVecRead, petsc.MatDenseGetColumnVecWrite """ if mode is None: mode = 'rw' if mode not in ['rw', 'r', 'w']: raise ValueError("Invalid mode: expected 'rw', 'r', or 'w'") cdef Vec v = Vec() cdef PetscInt _i = asInt(i) if mode == 'rw': CHKERR( MatDenseGetColumnVec(self.mat, _i, &v.vec) ) elif mode == 'r': CHKERR( MatDenseGetColumnVecRead(self.mat, _i, &v.vec) ) else: CHKERR( MatDenseGetColumnVecWrite(self.mat, _i, &v.vec) ) CHKERR( PetscINCREF(v.obj) ) return v def restoreDenseColumnVec(self, i: int, mode: AccessModeSpec = 'rw') -> None: """Restore the iᵗʰ column vector of the dense matrix. Collective. Parameters ---------- i The column index to be restored. mode The access type of the restored array See Also -------- getDenseColumnVec, petsc.MatDenseRestoreColumnVec petsc.MatDenseRestoreColumnVecRead, petsc.MatDenseRestoreColumnVecWrite """ cdef PetscInt _i = asInt(i) if mode == 'rw': CHKERR( MatDenseRestoreColumnVec(self.mat, _i, NULL) ) elif mode == 'r': CHKERR( MatDenseRestoreColumnVecRead(self.mat, _i, NULL) ) else: CHKERR( MatDenseRestoreColumnVecWrite(self.mat, _i, NULL) ) # Nest def getNestSize(self) -> tuple[int, int]: """Return the number of rows and columns of the matrix. Not collective. See Also -------- petsc.MatNestGetSize """ cdef PetscInt nrows, ncols CHKERR( MatNestGetSize(self.mat, &nrows, &ncols) ) return toInt(nrows), toInt(ncols) def getNestISs(self) -> tuple[list[IS], list[IS]]: """Return the index sets representing the row and column spaces. Not collective. See Also -------- petsc.MatNestGetISs """ cdef PetscInt i, nrows =0, ncols = 0 cdef PetscIS *cisrows = NULL cdef PetscIS *ciscols = NULL CHKERR( MatNestGetSize(self.mat, &nrows, &ncols) ) cdef object tmpr = oarray_p(empty_p(nrows), NULL, &cisrows) cdef object tmpc = oarray_p(empty_p(ncols), NULL, &ciscols) CHKERR( MatNestGetISs(self.mat, cisrows, ciscols) ) cdef object isetsrows = [ref_IS(cisrows[i]) for i from 0 <= i < nrows] cdef object isetscols = [ref_IS(ciscols[i]) for i from 0 <= i < ncols] return isetsrows, isetscols def getNestLocalISs(self) -> tuple[list[IS], list[IS]]: """Return the local index sets representing the row and column spaces. Not collective. See Also -------- petsc.MatNestGetLocalISs """ cdef PetscInt i, nrows =0, ncols = 0 cdef PetscIS *cisrows = NULL cdef PetscIS *ciscols = NULL CHKERR( MatNestGetSize(self.mat, &nrows, &ncols) ) cdef object tmpr = oarray_p(empty_p(nrows), NULL, &cisrows) cdef object tmpc = oarray_p(empty_p(ncols), NULL, &ciscols) CHKERR( MatNestGetLocalISs(self.mat, cisrows, ciscols) ) cdef object isetsrows = [ref_IS(cisrows[i]) for i from 0 <= i < nrows] cdef object isetscols = [ref_IS(ciscols[i]) for i from 0 <= i < ncols] return isetsrows, isetscols def getNestSubMatrix(self, i: int, j: int) -> Mat: """Return a single submatrix. Not collective. Parameters ---------- i The first index of the matrix within the nesting. j The second index of the matrix within the nesting. See Also -------- petsc.MatNestGetSubMat """ cdef Mat submat = Mat() cdef PetscInt idxm = asInt(i) cdef PetscInt jdxm = asInt(j) CHKERR( MatNestGetSubMat(self.mat, idxm, jdxm, &submat.mat) ) CHKERR( PetscINCREF(submat.obj) ) return submat # DM def getDM(self) -> DM: """Return the DM defining the data layout of the matrix. Not collective. See Also -------- petsc.MatGetDM """ cdef PetscDM newdm = NULL CHKERR( MatGetDM(self.mat, &newdm) ) cdef DM dm = subtype_DM(newdm)() dm.dm = newdm CHKERR( PetscINCREF(dm.obj) ) return dm def setDM(self, DM dm) -> None: """Set the DM defining the data layout of the matrix. Not collective. Parameters ---------- dm The `DM`. See Also -------- petsc.MatSetDM """ CHKERR( MatSetDM(self.mat, dm.dm) ) # backward compatibility PtAP = ptap # property sizes: """Matrix local and global sizes.""" def __get__(self) -> tuple[tuple[int, int], tuple[int, int]]: return self.getSizes() def __set__(self, value): self.setSizes(value) property size: """Matrix global size.""" def __get__(self) -> tuple[int, int]: return self.getSize() property local_size: """Matrix local size.""" def __get__(self) -> int: return self.getLocalSize() property block_size: """Matrix block size.""" def __get__(self) -> int: return self.getBlockSize() property block_sizes: """Matrix row and column block sizes.""" def __get__(self) -> tuple[int, int]: return self.getBlockSizes() property owner_range: """Matrix local row range.""" def __get__(self) -> tuple[int, int]: return self.getOwnershipRange() property owner_ranges: """Matrix row ranges.""" def __get__(self) -> ArrayInt: return self.getOwnershipRanges() # property assembled: """The boolean flag indicating if the matrix is assembled.""" def __get__(self) -> bool: return self.isAssembled() property symmetric: """The boolean flag indicating if the matrix is symmetric.""" def __get__(self) -> bool: return self.isSymmetric() property hermitian: """The boolean flag indicating if the matrix is Hermitian.""" def __get__(self) -> bool: return self.isHermitian() property structsymm: """The boolean flag indicating if the matrix is structurally symmetric.""" def __get__(self) -> bool: return self.isStructurallySymmetric() # TODO Stream def __dlpack__(self, stream=-1): return self.toDLPack('rw') def __dlpack_device__(self): (dltype, devId, _, _, _) = mat_get_dlpack_ctx(self) return (dltype, devId) def toDLPack(self, mode: AccessModeSpec = 'rw') -> Any: """Return a DLPack `PyCapsule` wrapping the vector data.""" if mode is None: mode = 'rw' if mode is None: mode = 'rw' if mode not in ['rw', 'r', 'w']: raise ValueError("Invalid mode: expected 'rw', 'r', or 'w'") cdef int64_t ndim = 0 (device_type, device_id, ndim, shape, strides) = mat_get_dlpack_ctx(self) hostmem = (device_type == kDLCPU) cdef DLManagedTensor* dlm_tensor = malloc(sizeof(DLManagedTensor)) cdef DLTensor* dl_tensor = &dlm_tensor.dl_tensor cdef PetscScalar *a = NULL cdef int64_t* shape_strides = NULL dl_tensor.byte_offset = 0 # DLPack does not currently play well with our get/restore model # Call restore right-away and hope that the consumer will do the right thing # and not modify memory requested with read access # By restoring now, we guarantee the sanity of the ObjectState if mode == 'w': if hostmem: CHKERR( MatDenseGetArrayWrite(self.mat, &a) ) CHKERR( MatDenseRestoreArrayWrite(self.mat, NULL) ) else: CHKERR( MatDenseCUDAGetArrayWrite(self.mat, &a) ) CHKERR( MatDenseCUDARestoreArrayWrite(self.mat, NULL) ) elif mode == 'r': if hostmem: CHKERR( MatDenseGetArrayRead(self.mat, &a) ) CHKERR( MatDenseRestoreArrayRead(self.mat, NULL) ) else: CHKERR( MatDenseCUDAGetArrayRead(self.mat, &a) ) CHKERR( MatDenseCUDARestoreArrayRead(self.mat, NULL) ) else: if hostmem: CHKERR( MatDenseGetArray(self.mat, &a) ) CHKERR( MatDenseRestoreArray(self.mat, NULL) ) else: CHKERR( MatDenseCUDAGetArray(self.mat, &a) ) CHKERR( MatDenseCUDARestoreArray(self.mat, NULL) ) dl_tensor.data = a cdef DLContext* ctx = &dl_tensor.ctx ctx.device_type = device_type ctx.device_id = device_id shape_strides = malloc(sizeof(int64_t)*2*ndim) for i in range(ndim): shape_strides[i] = shape[i] for i in range(ndim): shape_strides[i+ndim] = strides[i] dl_tensor.ndim = ndim dl_tensor.shape = shape_strides dl_tensor.strides = shape_strides + ndim cdef DLDataType* dtype = &dl_tensor.dtype dtype.code = DLDataTypeCode.kDLFloat if sizeof(PetscScalar) == 8: dtype.bits = 64 elif sizeof(PetscScalar) == 4: dtype.bits = 32 else: raise ValueError('Unsupported PetscScalar type') dtype.lanes = 1 dlm_tensor.manager_ctx = self.mat CHKERR( PetscObjectReference(self.mat) ) dlm_tensor.manager_deleter = manager_deleter dlm_tensor.del_obj = PetscDEALLOC return PyCapsule_New(dlm_tensor, 'dltensor', pycapsule_deleter) # -------------------------------------------------------------------- cdef class NullSpace(Object): """Nullspace object. See Also -------- petsc.MatNullSpace """ # def __cinit__(self): self.obj = &self.nsp self.nsp = NULL def __call__(self, vec): self.remove(vec) # def view(self, Viewer viewer=None) -> None: """View the null space. Collective. Parameters ---------- viewer A `Viewer` instance or `None` for the default viewer. See Also -------- Viewer, petsc.MatNullSpaceView """ cdef PetscViewer vwr = NULL if viewer is not None: vwr = viewer.vwr CHKERR( MatNullSpaceView(self.nsp, vwr) ) def destroy(self) -> Self: """Destroy the null space. Collective. See Also -------- create, petsc.MatNullSpaceDestroy """ CHKERR( MatNullSpaceDestroy(&self.nsp) ) return self def create( self, constant: bool = False, vectors: Sequence[Vec] = (), comm=None ) -> Self: """Create the null space. Collective. Parameters ---------- constant A flag to indicate the null space contains the constant vector. vectors The sequence of vectors that span the null space. comm MPI communicator, defaults to `Sys.getDefaultComm`. See Also -------- destroy, petsc.MatNullSpaceCreate """ cdef MPI_Comm ccomm = def_Comm(comm, PETSC_COMM_DEFAULT) cdef PetscBool has_const = PETSC_FALSE if constant: has_const = PETSC_TRUE cdef PetscInt i = 0, nv = len(vectors) cdef PetscVec *v = NULL cdef object tmp2 = oarray_p(empty_p(nv), NULL, &v) for i from 0 <= i < nv: v[i] = ((vectors[i])).vec cdef PetscNullSpace newnsp = NULL CHKERR( MatNullSpaceCreate(ccomm, has_const, nv, v, &newnsp) ) CHKERR( PetscCLEAR(self.obj) ); self.nsp = newnsp return self def createRigidBody(self, Vec coords) -> Self: """Create rigid body modes from coordinates. Collective. Parameters ---------- coords The block coordinates of each node. Requires the block size to have been set. See Also -------- petsc.MatNullSpaceCreateRigidBody """ cdef PetscNullSpace newnsp = NULL CHKERR( MatNullSpaceCreateRigidBody(coords.vec, &newnsp) ) CHKERR( PetscCLEAR(self.obj) ); self.nsp = newnsp return self def setFunction( self, function: MatNullFunction, args: tuple[Any, ...] | None = None, kargs: dict[str, Any] | None = None, ) -> None: """Set the callback to remove the nullspace. Logically collective. Parameters ---------- function The callback. args Positional arguments for the callback. kargs Keyword arguments for the callback. See Also -------- getFunction, petsc.MatNullSpaceSetFunction """ if function is not None: CHKERR( MatNullSpaceSetFunction( self.nsp, NullSpace_Function, NULL) ) if args is None: args = () if kargs is None: kargs = {} self.set_attr('__function__', (function, args, kargs)) else: CHKERR( MatNullSpaceSetFunction(self.nsp, NULL, NULL) ) self.set_attr('__function__', None) # def hasConstant(self) -> bool: """Return whether the null space contains the constant. Not collective. See Also -------- petsc.MatNullSpaceGetVecs """ cdef PetscBool flag = PETSC_FALSE CHKERR( MatNullSpaceGetVecs(self.nsp, &flag, NULL, NULL) ) return toBool(flag) def getVecs(self) -> list[Vec]: """Return the vectors defining the null space. Not collective. See Also -------- petsc.MatNullSpaceGetVecs """ cdef PetscInt i = 0, nv = 0 cdef const PetscVec *v = NULL CHKERR( MatNullSpaceGetVecs(self.nsp, NULL, &nv, &v) ) cdef Vec vec = None cdef list vectors = [] for i from 0 <= i < nv: vec = Vec() vec.vec = v[i] CHKERR( PetscINCREF(vec.obj) ) vectors.append(vec) return vectors def getFunction(self) -> MatNullFunction: """Return the callback to remove the nullspace. Not collective. See Also -------- setFunction """ return self.get_attr('__function__') # def remove(self, Vec vec) -> None: """Remove all components of a null space from a vector. Collective. Parameters ---------- vec The vector from which the null space is removed. See Also -------- petsc.MatNullSpaceRemove """ CHKERR( MatNullSpaceRemove(self.nsp, vec.vec) ) def test(self, Mat mat) -> bool: """Return if the claimed null space is valid for a matrix. Collective. Parameters ---------- mat The matrix to check. See Also -------- petsc.MatNullSpaceTest """ cdef PetscBool flag = PETSC_FALSE CHKERR( MatNullSpaceTest(self.nsp, mat.mat, &flag) ) return toBool(flag) # -------------------------------------------------------------------- del MatType del MatOption del MatAssemblyType del MatInfoType del MatStructure del MatDuplicateOption del MatOrderingType del MatSolverType del MatFactorShiftType del MatSORType # -------------------------------------------------------------------- ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/src/petsc4py/PETSc/MatPartitioning.pyx0000644000175000017500000001030614567251135021522 0ustar00balaybalay# -------------------------------------------------------------------- class MatPartitioningType(object): PARTITIONINGCURRENT = S_(MATPARTITIONINGCURRENT) PARTITIONINGAVERAGE = S_(MATPARTITIONINGAVERAGE) PARTITIONINGSQUARE = S_(MATPARTITIONINGSQUARE) PARTITIONINGPARMETIS = S_(MATPARTITIONINGPARMETIS) PARTITIONINGCHACO = S_(MATPARTITIONINGCHACO) PARTITIONINGPARTY = S_(MATPARTITIONINGPARTY) PARTITIONINGPTSCOTCH = S_(MATPARTITIONINGPTSCOTCH) PARTITIONINGHIERARCH = S_(MATPARTITIONINGHIERARCH) # -------------------------------------------------------------------- cdef class MatPartitioning(Object): """Object for managing the partitioning of a matrix or graph.""" Type = MatPartitioningType def __cinit__(self): self.obj = &self.part self.part = NULL def __call__(self): return self.getValue() def view(self, Viewer viewer=None) -> None: """View the partitioning data structure. Collective. Parameters ---------- viewer A `Viewer` to display the graph. See Also -------- petsc.MatPartitioningView """ assert self.obj != NULL cdef PetscViewer vwr = NULL if viewer is not None: vwr = viewer.vwr CHKERR( MatPartitioningView(self.part, vwr) ) def destroy(self) -> Self: """Destroy the partitioning context. Collective. See Also -------- create, petsc.MatPartitioningDestroy """ CHKERR( MatPartitioningDestroy(&self.part) ) return self def create(self, comm: Comm | None = None) -> Self: """Create a partitioning context. Collective. Parameters ---------- comm MPI communicator, defaults to `Sys.getDefaultComm`. See Also -------- destroy, petsc.MatPartitioningCreate """ cdef MPI_Comm ccomm = def_Comm(comm, PETSC_COMM_DEFAULT) CHKERR( MatPartitioningCreate(ccomm, &self.part) ) return self def setType(self, matpartitioning_type: Type | str) -> None: """Set the type of the partitioner to use. Collective. Parameters ---------- matpartitioning_type The partitioner type. See Also -------- getType, petsc.MatPartitioningSetType """ cdef PetscMatPartitioningType cval = NULL matpartitioning_type = str2bytes(matpartitioning_type, &cval) CHKERR( MatPartitioningSetType(self.part, cval) ) def getType(self) -> str: """Return the partitioning method. Not collective. See Also -------- setType, petsc.MatPartitioningGetType """ cdef PetscMatPartitioningType cval = NULL CHKERR( MatPartitioningGetType(self.part, &cval) ) return bytes2str(cval) def setFromOptions(self) -> None: """Set parameters in the partitioner from the options database. Collective. See Also -------- petsc_options, petsc.MatPartitioningSetFromOptions """ CHKERR( MatPartitioningSetFromOptions(self.part) ) def setAdjacency(self, Mat adj) -> None: """Set the adjacency graph (matrix) of the thing to be partitioned. Collective. Parameters ---------- adj The adjacency matrix, this can be any `Mat.Type` but the natural representation is `Mat.Type.MPIADJ`. See Also -------- petsc.MatPartitioningSetAdjacency """ CHKERR( MatPartitioningSetAdjacency(self.part, adj.mat) ) def apply(self, IS partitioning) -> None: """Return a partitioning for the graph represented by a sparse matrix. Collective. For each local node this tells the processor number that that node is assigned to. See Also -------- petsc.MatPartitioningApply """ CHKERR( MatPartitioningApply(self.part, &partitioning.iset) ) # -------------------------------------------------------------------- del MatPartitioningType # -------------------------------------------------------------------- ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/src/petsc4py/PETSc/Object.pyx0000644000175000017500000002077514567251135017632 0ustar00balaybalay# -------------------------------------------------------------------- cdef class Object: # --- special methods --- def __cinit__(self): self.oval = NULL self.obj = &self.oval def __dealloc__(self): CHKERR( PetscDEALLOC(&self.obj[0]) ) self.obj = NULL def __richcmp__(self, other, int op): if not isinstance(self, Object): return NotImplemented if not isinstance(other, Object): return NotImplemented cdef Object s = self, o = other if op == 2: return (s.obj[0] == o.obj[0]) elif op == 3: return (s.obj[0] != o.obj[0]) else: raise TypeError("only '==' and '!='") def __bool__(self): return self.obj[0] != NULL def __copy__(self): cdef Object obj = type(self)() cdef PetscObject o = self.obj[0] if o != NULL: CHKERR( PetscObjectReference(o) ) obj.obj[0] = o return obj def __deepcopy__(self, dict memo): cdef object obj_copy = None try: obj_copy = self.copy except AttributeError: raise NotImplementedError memo # unused return obj_copy() # --- attribute management --- cdef object get_attr(self, char name[]): return PetscGetPyObj(self.obj[0], name) cdef object set_attr(self, char name[], object attr): return PetscSetPyObj(self.obj[0], name, attr) cdef object get_dict(self): return PetscGetPyDict(self.obj[0], True) # def view(self, Viewer viewer=None): cdef PetscViewer vwr = NULL if viewer is not None: vwr = viewer.vwr CHKERR( PetscObjectView(self.obj[0], vwr) ) def destroy(self): CHKERR( PetscObjectDestroy(&self.obj[0]) ) return self def getType(self): cdef const char *cval = NULL CHKERR( PetscObjectGetType(self.obj[0], &cval) ) return bytes2str(cval) # def setOptionsPrefix(self, prefix): cdef const char *cval = NULL prefix = str2bytes(prefix, &cval) CHKERR( PetscObjectSetOptionsPrefix(self.obj[0], cval) ) def getOptionsPrefix(self): cdef const char *cval = NULL CHKERR( PetscObjectGetOptionsPrefix(self.obj[0], &cval) ) return bytes2str(cval) def appendOptionsPrefix(self, prefix): cdef const char *cval = NULL prefix = str2bytes(prefix, &cval) CHKERR( PetscObjectAppendOptionsPrefix(self.obj[0], cval) ) def setFromOptions(self): CHKERR( PetscObjectSetFromOptions(self.obj[0]) ) def viewFromOptions(self, name, Object prefix=None): cdef PetscObject pobj = NULL cdef const char *cval = NULL pobj = prefix.obj[0] if prefix is not None else NULL name = str2bytes(name, &cval) CHKERR( PetscObjectViewFromOptions(self.obj[0], pobj, cval) ) # def getComm(self): cdef Comm comm = Comm() CHKERR( PetscObjectGetComm(self.obj[0], &comm.comm) ) return comm def getName(self): cdef const char *cval = NULL CHKERR( PetscObjectGetName(self.obj[0], &cval) ) return bytes2str(cval) def setName(self, name): cdef const char *cval = NULL name = str2bytes(name, &cval) CHKERR( PetscObjectSetName(self.obj[0], cval) ) def getClassId(self): cdef PetscClassId classid = 0 CHKERR( PetscObjectGetClassId(self.obj[0], &classid) ) return classid def getClassName(self): cdef const char *cval = NULL CHKERR( PetscObjectGetClassName(self.obj[0], &cval) ) return bytes2str(cval) def getRefCount(self): if self.obj[0] == NULL: return 0 cdef PetscInt refcnt = 0 CHKERR( PetscObjectGetReference(self.obj[0], &refcnt) ) return toInt(refcnt) # --- general support --- def compose(self, name, Object obj or None): cdef const char *cval = NULL cdef PetscObject cobj = NULL name = str2bytes(name, &cval) if obj is not None: cobj = obj.obj[0] CHKERR( PetscObjectCompose(self.obj[0], cval, cobj) ) def query(self, name): cdef const char *cval = NULL cdef PetscObject cobj = NULL name = str2bytes(name, &cval) CHKERR( PetscObjectQuery(self.obj[0], cval, &cobj) ) if cobj == NULL: return None cdef Object obj = subtype_Object(cobj)() obj.obj[0] = cobj CHKERR( PetscINCREF(obj.obj) ) return obj def incRef(self): cdef PetscObject obj = self.obj[0] cdef PetscInt refct = 0 if obj != NULL: CHKERR( PetscObjectReference(obj) ) CHKERR( PetscObjectGetReference(obj, &refct) ) return (refct) def decRef(self): cdef PetscObject obj = self.obj[0] cdef PetscInt refct = 0 if obj != NULL: CHKERR( PetscObjectGetReference(obj, &refct) ) CHKERR( PetscObjectDereference(obj) ) if refct == 1: self.obj[0] = NULL refct -= 1 return (refct) def getAttr(self, name): cdef const char *cval = NULL name = str2bytes(name, &cval) return self.get_attr(cval) def setAttr(self, name, attr): cdef const char *cval = NULL name = str2bytes(name, &cval) self.set_attr(cval, attr) def getDict(self): return self.get_dict() # --- state manipulation --- def stateIncrease(self): PetscINCSTATE(self.obj) def stateGet(self): cdef PetscObjectState state = 0 CHKERR( PetscObjectStateGet(self.obj[0], &state) ) return toInt(state) def stateSet(self, state): cdef PetscObjectState cstate = asInt(state) CHKERR( PetscObjectStateSet(self.obj[0], cstate) ) # --- tab level --- def incrementTabLevel(self, tab, Object parent=None): cdef PetscInt ctab = asInt(tab) cdef PetscObject cobj = NULL if parent is None else parent.obj[0] CHKERR( PetscObjectIncrementTabLevel(self.obj[0], cobj, ctab) ) def setTabLevel(self, level): cdef PetscInt clevel = asInt(level) CHKERR( PetscObjectSetTabLevel(self.obj[0], clevel) ) def getTabLevel(self): cdef PetscInt clevel = 0 CHKERR( PetscObjectGetTabLevel(self.obj[0], &clevel) ) return toInt(clevel) # --- properties --- property type: def __get__(self): return self.getType() def __set__(self, value): self.setType(value) property prefix: def __get__(self): return self.getOptionsPrefix() def __set__(self, value): self.setOptionsPrefix(value) property comm: def __get__(self): return self.getComm() property name: def __get__(self): return self.getName() def __set__(self, value): self.setName(value) property classid: def __get__(self): return self.getClassId() property klass: def __get__(self): return self.getClassName() property refcount: def __get__(self): return self.getRefCount() # --- ctypes support --- property handle: def __get__(self): cdef PetscObject obj = self.obj[0] return PyLong_FromVoidPtr(obj) # --- Fortran support --- property fortran: def __get__(self): cdef PetscObject obj = self.obj[0] return Object_toFortran(obj) # -------------------------------------------------------------------- include "cyclicgc.pxi" cdef dict type_registry = { 0 : None } __type_registry__ = type_registry cdef int PyPetscType_Register(int classid, type cls) except -1: global type_registry cdef object key = classid cdef object value = cls cdef const char *dummy = NULL if key not in type_registry: type_registry[key] = cls reg_LogClass(str2bytes(cls.__name__, &dummy), classid) TypeEnableGC(cls) else: value = type_registry[key] if cls is not value: raise ValueError( "key: %d, cannot register: %s, " \ "already registered: %s" % (key, cls, value)) return 0 cdef type PyPetscType_Lookup(int classid): global type_registry cdef object key = classid cdef type cls = Object try: cls = type_registry[key] except KeyError: cls = Object return cls # -------------------------------------------------------------------- ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/src/petsc4py/PETSc/Options.pyx0000644000175000017500000001006314567251135020044 0ustar00balaybalay# -------------------------------------------------------------------- cdef class Options: cdef PetscOptions opt cdef object _prefix def __init__(self, prefix=None): self.opt = NULL self.prefix = prefix def __dealloc__(self): if self.opt == NULL: return CHKERR( PetscOptionsDestroy(&self.opt) ) def __contains__(self, item): return self.hasName(item) def __getitem__(self, item): return self.getString(item) def __setitem__(self, item, value): self.setValue(item, value) def __delitem__(self, item): self.delValue(item) property prefix: def __get__(self): return self._prefix def __set__(self, prefix): self._prefix = getprefix(prefix) def __del__(self): self._prefix = None # def create(self): if self.opt != NULL: return CHKERR( PetscOptionsCreate(&self.opt) ) return self def destroy(self): if self.opt == NULL: return CHKERR( PetscOptionsDestroy(&self.opt) ) return self def clear(self): if self.opt == NULL: return CHKERR( PetscOptionsClear(self.opt) ) return self def view(self, Viewer viewer=None): cdef PetscViewer vwr = NULL if viewer is not None: vwr = viewer.vwr CHKERR( PetscOptionsView(self.opt, vwr) ) def prefixPush(self, prefix): prefix = getprefix(prefix) cdef const char *cprefix = NULL prefix = str2bytes(prefix, &cprefix) CHKERR( PetscOptionsPrefixPush(self.opt, cprefix) ) def prefixPop(self): CHKERR( PetscOptionsPrefixPop(self.opt) ) # def hasName(self, name): cdef const char *pr = NULL cdef const char *nm = NULL tmp = getpair(self.prefix, name, &pr, &nm) cdef PetscBool flag = PETSC_FALSE CHKERR( PetscOptionsHasName(self.opt, pr, nm, &flag) ) return toBool(flag) def setValue(self, name, value): cdef const char *pr = NULL cdef const char *nm = NULL tmp = getpair(self.prefix, name, &pr, &nm) if pr == NULL: option = bytes2str(nm) else: option = '-%s%s' % (bytes2str(pr), bytes2str(&nm[1])) if type(value) is bool: value = str(value).lower() elif value is not None : value = str(value) cdef const char *key = NULL cdef const char *val = NULL option = str2bytes(option, &key) value = str2bytes(value, &val) CHKERR( PetscOptionsSetValue(self.opt, key, val) ) def delValue(self, name): cdef const char *pr = NULL cdef const char *nm = NULL tmp = getpair(self.prefix, name, &pr, &nm) if pr == NULL: option = bytes2str(nm) else: option = '-%s%s' % (bytes2str(pr), bytes2str(&nm[1])) cdef const char *key = NULL option = str2bytes(option, &key) CHKERR( PetscOptionsClearValue(self.opt, key) ) # def getBool(self, name, default=None): return getopt(self.opt, OPT_BOOL, self.prefix, name, default) def getInt(self, name, default=None): return getopt(self.opt, OPT_INT, self.prefix, name, default) def getReal(self, name, default=None): return getopt(self.opt, OPT_REAL, self.prefix, name, default) def getScalar(self, name, default=None): return getopt(self.opt, OPT_SCALAR, self.prefix, name, default) def getString(self, name, default=None): return getopt(self.opt, OPT_STRING, self.prefix, name, default) # def insertString(self, string): cdef const char *cstring = NULL string = str2bytes(string, &cstring) CHKERR( PetscOptionsInsertString(self.opt, cstring) ) def getAll(self): cdef char *allopts = NULL CHKERR( PetscOptionsGetAll(self.opt, &allopts) ) options = bytes2str(allopts) CHKERR( PetscFree(allopts) ) return parseopt(options, self.prefix) # -------------------------------------------------------------------- ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/src/petsc4py/PETSc/PC.pyx0000644000175000017500000023110014567251135016710 0ustar00balaybalay# -------------------------------------------------------------------- class PCType(object): """The preconditioner method.""" NONE = S_(PCNONE) JACOBI = S_(PCJACOBI) SOR = S_(PCSOR) LU = S_(PCLU) QR = S_(PCQR) SHELL = S_(PCSHELL) BJACOBI = S_(PCBJACOBI) VPBJACOBI = S_(PCVPBJACOBI) MG = S_(PCMG) EISENSTAT = S_(PCEISENSTAT) ILU = S_(PCILU) ICC = S_(PCICC) ASM = S_(PCASM) GASM = S_(PCGASM) KSP = S_(PCKSP) COMPOSITE = S_(PCCOMPOSITE) REDUNDANT = S_(PCREDUNDANT) SPAI = S_(PCSPAI) NN = S_(PCNN) CHOLESKY = S_(PCCHOLESKY) PBJACOBI = S_(PCPBJACOBI) MAT = S_(PCMAT) HYPRE = S_(PCHYPRE) PARMS = S_(PCPARMS) FIELDSPLIT = S_(PCFIELDSPLIT) TFS = S_(PCTFS) ML = S_(PCML) GALERKIN = S_(PCGALERKIN) EXOTIC = S_(PCEXOTIC) CP = S_(PCCP) BFBT = S_(PCBFBT) LSC = S_(PCLSC) PYTHON = S_(PCPYTHON) PFMG = S_(PCPFMG) SYSPFMG = S_(PCSYSPFMG) REDISTRIBUTE = S_(PCREDISTRIBUTE) SVD = S_(PCSVD) GAMG = S_(PCGAMG) CHOWILUVIENNACL = S_(PCCHOWILUVIENNACL) ROWSCALINGVIENNACL = S_(PCROWSCALINGVIENNACL) SAVIENNACL = S_(PCSAVIENNACL) BDDC = S_(PCBDDC) KACZMARZ = S_(PCKACZMARZ) TELESCOPE = S_(PCTELESCOPE) PATCH = S_(PCPATCH) LMVM = S_(PCLMVM) HMG = S_(PCHMG) DEFLATION = S_(PCDEFLATION) HPDDM = S_(PCHPDDM) H2OPUS = S_(PCH2OPUS) class PCSide(object): """The manner in which the preconditioner is applied.""" # native LEFT = PC_LEFT RIGHT = PC_RIGHT SYMMETRIC = PC_SYMMETRIC # aliases L = LEFT R = RIGHT S = SYMMETRIC class PCASMType(object): """The *ASM* subtype.""" NONE = PC_ASM_NONE BASIC = PC_ASM_BASIC RESTRICT = PC_ASM_RESTRICT INTERPOLATE = PC_ASM_INTERPOLATE class PCGASMType(object): """The *GASM* subtype.""" NONE = PC_GASM_NONE BASIC = PC_GASM_BASIC RESTRICT = PC_GASM_RESTRICT INTERPOLATE = PC_GASM_INTERPOLATE class PCMGType(object): """The *MG* subtype.""" MULTIPLICATIVE = PC_MG_MULTIPLICATIVE ADDITIVE = PC_MG_ADDITIVE FULL = PC_MG_FULL KASKADE = PC_MG_KASKADE class PCMGCycleType(object): """The *MG* cycle type.""" V = PC_MG_CYCLE_V W = PC_MG_CYCLE_W class PCGAMGType(object): """The *GAMG* subtype.""" AGG = S_(PCGAMGAGG) GEO = S_(PCGAMGGEO) CLASSICAL = S_(PCGAMGCLASSICAL) class PCCompositeType(object): """The composite type.""" ADDITIVE = PC_COMPOSITE_ADDITIVE MULTIPLICATIVE = PC_COMPOSITE_MULTIPLICATIVE SYMMETRIC_MULTIPLICATIVE = PC_COMPOSITE_SYMMETRIC_MULTIPLICATIVE SPECIAL = PC_COMPOSITE_SPECIAL SCHUR = PC_COMPOSITE_SCHUR class PCFieldSplitSchurPreType(object): """The field split Schur subtype.""" SELF = PC_FIELDSPLIT_SCHUR_PRE_SELF SELFP = PC_FIELDSPLIT_SCHUR_PRE_SELFP A11 = PC_FIELDSPLIT_SCHUR_PRE_A11 USER = PC_FIELDSPLIT_SCHUR_PRE_USER FULL = PC_FIELDSPLIT_SCHUR_PRE_FULL class PCFieldSplitSchurFactType(object): """The field split Schur factorization type.""" DIAG = PC_FIELDSPLIT_SCHUR_FACT_DIAG LOWER = PC_FIELDSPLIT_SCHUR_FACT_LOWER UPPER = PC_FIELDSPLIT_SCHUR_FACT_UPPER FULL = PC_FIELDSPLIT_SCHUR_FACT_FULL class PCPatchConstructType(object): """The patch construction type.""" STAR = PC_PATCH_STAR VANKA = PC_PATCH_VANKA PARDECOMP = PC_PATCH_PARDECOMP USER = PC_PATCH_USER PYTHON = PC_PATCH_PYTHON class PCHPDDMCoarseCorrectionType(object): """The *HPDDM* coarse correction type.""" DEFLATED = PC_HPDDM_COARSE_CORRECTION_DEFLATED ADDITIVE = PC_HPDDM_COARSE_CORRECTION_ADDITIVE BALANCED = PC_HPDDM_COARSE_CORRECTION_BALANCED class PCDeflationSpaceType(object): """The deflation space subtype.""" HAAR = PC_DEFLATION_SPACE_HAAR DB2 = PC_DEFLATION_SPACE_DB2 DB4 = PC_DEFLATION_SPACE_DB4 DB8 = PC_DEFLATION_SPACE_DB8 DB16 = PC_DEFLATION_SPACE_DB16 BIORTH22 = PC_DEFLATION_SPACE_BIORTH22 MEYER = PC_DEFLATION_SPACE_MEYER AGGREGATION = PC_DEFLATION_SPACE_AGGREGATION USER = PC_DEFLATION_SPACE_USER class PCFailedReason(object): """The reason the preconditioner has failed.""" SETUP_ERROR = PC_SETUP_ERROR NOERROR = PC_NOERROR FACTOR_STRUCT_ZEROPIVOT = PC_FACTOR_STRUCT_ZEROPIVOT FACTOR_NUMERIC_ZEROPIVOT = PC_FACTOR_NUMERIC_ZEROPIVOT FACTOR_OUTMEMORY = PC_FACTOR_OUTMEMORY FACTOR_OTHER = PC_FACTOR_OTHER SUBPC_ERROR = PC_SUBPC_ERROR # -------------------------------------------------------------------- cdef class PC(Object): """Preconditioners. `PC` is described in the `PETSc manual `. Calling the `PC` with a vector as an argument will `apply` the preconditioner as shown in the example below. Examples -------- >>> from petsc4py import PETSc >>> v = PETSc.Vec().createWithArray([1,2]) >>> m = PETSc.Mat().createDense(2,array=[[1,0],[0,1]]) >>> pc = PETSc.PC().create() >>> pc.setOperators(m) >>> u = pc(v) # Vec u is created internally, can also be passed as second argument See Also -------- petsc.PC """ Type = PCType Side = PCSide ASMType = PCASMType GASMType = PCGASMType MGType = PCMGType MGCycleType = PCMGCycleType GAMGType = PCGAMGType CompositeType = PCCompositeType FieldSplitSchurFactType = PCFieldSplitSchurFactType FieldSplitSchurPreType = PCFieldSplitSchurPreType PatchConstructType = PCPatchConstructType HPDDMCoarseCorrectionType = PCHPDDMCoarseCorrectionType DeflationSpaceType = PCDeflationSpaceType FailedReason = PCFailedReason # Backward compatibility SchurFactType = PCFieldSplitSchurFactType SchurPreType = PCFieldSplitSchurPreType # --- xxx --- def __cinit__(self): self.obj = &self.pc self.pc = NULL def __call__(self, x, y=None): if y is None: # XXX do this better y = self.getOperators()[0].createVecLeft() self.apply(x, y) return y # --- xxx --- def view(self, Viewer viewer=None) -> None: """View the `PC` object. Collective. Parameters ---------- viewer The visualization context. See Also -------- petsc.PCView """ cdef PetscViewer vwr = NULL if viewer is not None: vwr = viewer.vwr CHKERR( PCView(self.pc, vwr) ) def destroy(self) -> Self: """Destroy the `PC` that was created with `create`. Collective. See Also -------- petsc.PCDestroy """ CHKERR( PCDestroy(&self.pc) ) self.pc = NULL return self def create(self, comm: Comm | None = None) -> Self: """Create an empty `PC`. Collective. The default preconditioner for sparse matrices is `ILU` or `ICC` with 0 fill on one process and block Jacobi (`BJACOBI`) with `ILU` or `ICC` in parallel. For dense matrices it is always `None`. Parameters ---------- comm MPI communicator, defaults to `Sys.getDefaultComm`. See Also -------- destroy, petsc.PCCreate """ cdef MPI_Comm ccomm = def_Comm(comm, PETSC_COMM_DEFAULT) cdef PetscPC newpc = NULL CHKERR( PCCreate(ccomm, &newpc) ) CHKERR( PetscCLEAR(self.obj) ); self.pc = newpc return self def setType(self, pc_type: Type | str) -> None: """Set the preconditioner type. Collective. Parameters ---------- pc_type The preconditioner type. See Also -------- petsc_options, getType, petsc.TSSetType """ cdef PetscPCType cval = NULL pc_type = str2bytes(pc_type, &cval) CHKERR( PCSetType(self.pc, cval) ) def getType(self) -> str: """Return the preconditioner type. Not collective. See Also -------- setType, petsc.PCGetType """ cdef PetscPCType cval = NULL CHKERR( PCGetType(self.pc, &cval) ) return bytes2str(cval) def setOptionsPrefix(self, prefix: str) -> None: """Set the prefix used for all the `PC` options. Logically collective. Parameters ---------- prefix The prefix to prepend to all option names. See Also -------- petsc_options, petsc.PCSetOptionsPrefix """ cdef const char *cval = NULL prefix = str2bytes(prefix, &cval) CHKERR( PCSetOptionsPrefix(self.pc, cval) ) def getOptionsPrefix(self) -> str: """Return the prefix used for all the `PC` options. Not collective. See Also -------- petsc_options, petsc.PCGetOptionsPrefix """ cdef const char *cval = NULL CHKERR( PCGetOptionsPrefix(self.pc, &cval) ) return bytes2str(cval) def appendOptionsPrefix(self, prefix: str) -> None: """Append to the prefix used for all the `PC` options. Logically collective. Parameters ---------- prefix The prefix to append to the current prefix. See Also -------- petsc_options, petsc.PCAppendOptionsPrefix """ cdef const char *cval = NULL prefix = str2bytes(prefix, &cval) CHKERR( PCAppendOptionsPrefix(self.pc, cval) ) def setFromOptions(self) -> None: """Set various `PC` parameters from user options. Collective. See Also -------- petsc_options, petsc.PCSetFromOptions """ CHKERR( PCSetFromOptions(self.pc) ) def setOperators(self, Mat A=None, Mat P=None) -> None: """Set the matrices associated with the linear system. Logically collective. Passing `None` for ``A`` or ``P`` removes the matrix that is currently used. PETSc does not reset the matrix entries of either ``A`` or ``P`` to zero after a linear solve; the user is completely responsible for matrix assembly. See `Mat.zeroEntries` to zero all elements of a matrix. Parameters ---------- A the matrix which defines the linear system P the matrix to be used in constructing the preconditioner, usually the same as ``A`` See Also -------- petsc.PCSetOperators """ cdef PetscMat amat=NULL if A is not None: amat = A.mat cdef PetscMat pmat=amat if P is not None: pmat = P.mat CHKERR( PCSetOperators(self.pc, amat, pmat) ) def getOperators(self) -> tuple[Mat,Mat]: """Return the matrices associated with a linear system. Not collective. See Also -------- setOperators, petsc.PCGetOperators """ cdef Mat A = Mat(), P = Mat() CHKERR( PCGetOperators(self.pc, &A.mat, &P.mat) ) CHKERR( PetscINCREF(A.obj) ) CHKERR( PetscINCREF(P.obj) ) return (A, P) def setUseAmat(self, flag: bool) -> None: """Set to indicate to apply `PC` to ``A`` and not ``P``. Logically collective. Sets a flag to indicate that when the preconditioner needs to apply (part of) the operator during the preconditioning process, it applies to ``A`` provided to `TS.setRHSJacobian`, `TS.setIJacobian`, `SNES.setJacobian`, `KSP.setOperators` or `PC.setOperators` not the ``P``. Parameters ---------- flag Set True to use ``A`` and False to use ``P``. See Also -------- setOperators, petsc.PCSetUseAmat """ cdef PetscBool cflag = PETSC_FALSE if flag: cflag = PETSC_TRUE CHKERR( PCSetUseAmat(self.pc, cflag) ) def getUseAmat(self): """Return the flag to indicate if `PC` is applied to ``A`` or ``P``. Logically collective. Returns ------- flag : bool True if ``A`` is used and False if ``P``. See Also -------- setUseAmat, petsc.PCGetUseAmat """ cdef PetscBool cflag = PETSC_FALSE CHKERR( PCGetUseAmat(self.pc, &cflag) ) return toBool(cflag) def setReusePreconditioner(self, flag: bool) -> None: """Set to indicate the preconditioner is to be reused. Logically collective. Normally if the ``A`` matrix inside a `PC` changes, the `PC` automatically updates itself using information from the changed matrix. Enable this option prevents this. Parameters ---------- flag Set to `True` to use the reuse the current preconditioner and `False` to recompute on changes to the matrix. See Also -------- setOperators, petsc.PCSetReusePreconditioner """ cdef PetscBool cflag = PETSC_FALSE if flag: cflag = PETSC_TRUE CHKERR( PCSetReusePreconditioner(self.pc, cflag) ) def setFailedReason(self, reason: FailedReason | str) -> None: """Set the reason the `PC` terminated. Logically collective. Parameters ---------- reason the reason the `PC` terminated See Also -------- petsc.PCSetFailedReason """ cdef PetscPCFailedReason val = reason CHKERR( PCSetFailedReason(self.pc, val) ) def getFailedReason(self) -> FailedReason: """Return the reason the `PC` terminated. Logically collective. This is the maximum reason over all ranks in the `PC` communicator. See Also -------- petsc.PCGetFailedReason """ cdef PetscPCFailedReason reason = PC_NOERROR CHKERR( PCGetFailedReason(self.pc, &reason) ) return reason def getFailedReasonRank(self) -> FailedReason: """Return the reason the `PC` terminated on this rank. Not collective. Different ranks may have different reasons. See Also -------- getFailedReason, petsc.PCGetFailedReasonRank """ cdef PetscPCFailedReason reason = PC_NOERROR CHKERR( PCGetFailedReasonRank(self.pc, &reason) ) return reason def setUp(self) -> None: """Set up the internal data structures for the `PC`. Collective. See Also -------- petsc.PCSetUp """ CHKERR( PCSetUp(self.pc) ) def reset(self) -> None: """Reset the `PC`, removing any allocated vectors and matrices. Collective. See Also -------- petsc.PCReset """ CHKERR( PCReset(self.pc) ) def setUpOnBlocks(self) -> None: """Set up the `PC` for each block. Collective. For nested preconditioners such as `BJACOBI`, `setUp` is not called on each sub-`KSP` when `setUp` is called on the outer `PC`. This routine ensures it is called. See Also -------- setUp, petsc.PCSetUpOnBlocks """ CHKERR( PCSetUpOnBlocks(self.pc) ) def apply(self, Vec x, Vec y) -> None: """Apply the `PC` to a vector. Collective. Parameters ---------- x The input vector. y The output vector, cannot be the same as ``x``. See Also -------- petsc.PCApply """ CHKERR( PCApply(self.pc, x.vec, y.vec) ) def matApply(self, Mat x, Mat y) -> None: """Apply the `PC` to many vectors stored as `Mat.Type.DENSE`. Collective. Parameters ---------- x The input matrix. y The output matrix, cannot be the same as ``x``. See Also -------- petsc.PCMatApply, petsc.PCApply """ CHKERR( PCMatApply(self.pc, x.mat, y.mat) ) def applyTranspose(self, Vec x, Vec y) -> None: """Apply the transpose of the `PC` to a vector. Collective. For complex numbers this applies the non-Hermitian transpose. Parameters ---------- x The input vector. y The output vector, cannot be the same as ``x``. See Also -------- petsc.PCApply """ CHKERR( PCApplyTranspose(self.pc, x.vec, y.vec) ) def applySymmetricLeft(self, Vec x, Vec y) -> None: """Apply the left part of a symmetric `PC` to a vector. Collective. Parameters ---------- x The input vector. y The output vector, cannot be the same as ``x``. See Also -------- petsc.PCApplySymmetricLeft """ CHKERR( PCApplySymmetricLeft(self.pc, x.vec, y.vec) ) def applySymmetricRight(self, Vec x, Vec y) -> None: """Apply the right part of a symmetric `PC` to a vector. Collective. Parameters ---------- x The input vector. y The output vector, cannot be the same as ``x``. See Also -------- petsc.PCApplySymmetricRight """ CHKERR( PCApplySymmetricRight(self.pc, x.vec, y.vec) ) # --- discretization space --- def getDM(self) -> DM: """Return the `DM` associated with the `PC`. Not collective. See Also -------- petsc.PCGetDM """ cdef PetscDM newdm = NULL CHKERR( PCGetDM(self.pc, &newdm) ) cdef DM dm = subtype_DM(newdm)() dm.dm = newdm CHKERR( PetscINCREF(dm.obj) ) return dm def setDM(self, DM dm) -> None: """Set the `DM` that may be used by some preconditioners. Logically collective. Parameters ---------- dm The `DM` object. See Also -------- petsc.PCSetDM """ CHKERR( PCSetDM(self.pc, dm.dm) ) def setCoordinates(self, coordinates: Sequence[Sequence[float]]) -> None: """Set the coordinates for the nodes on the local process. Collective. Parameters ---------- coordinates The two dimensional coordinate array. See Also -------- petsc.PCSetCoordinates """ cdef ndarray xyz = iarray(coordinates, NPY_PETSC_REAL) if PyArray_ISFORTRAN(xyz): xyz = PyArray_Copy(xyz) if PyArray_NDIM(xyz) != 2: raise ValueError( ("coordinates must have two dimensions: " "coordinates.ndim=%d") % (PyArray_NDIM(xyz)) ) cdef PetscInt nvtx = PyArray_DIM(xyz, 0) cdef PetscInt ndim = PyArray_DIM(xyz, 1) cdef PetscReal *coords = PyArray_DATA(xyz) CHKERR( PCSetCoordinates(self.pc, ndim, nvtx, coords) ) # --- Python --- def createPython(self, context: Any = None, comm: Comm | None = None) -> Self: """Create a preconditioner of Python type. Collective. Parameters ---------- context An instance of the Python class implementing the required methods. comm MPI communicator, defaults to `Sys.getDefaultComm`. See Also -------- petsc_python_pc, setType, setPythonContext, PC.Type.PYTHON """ cdef MPI_Comm ccomm = def_Comm(comm, PETSC_COMM_DEFAULT) cdef PetscPC newpc = NULL CHKERR( PCCreate(ccomm, &newpc) ) CHKERR( PetscCLEAR(self.obj) ); self.pc = newpc CHKERR( PCSetType(self.pc, PCPYTHON) ) CHKERR( PCPythonSetContext(self.pc, context) ) return self def setPythonContext(self, context: Any) -> None: """Set the instance of the class implementing the required Python methods. Not collective. See Also -------- petsc_python_pc, getPythonContext """ CHKERR( PCPythonSetContext(self.pc, context) ) def getPythonContext(self) -> Any: """Return the instance of the class implementing the required Python methods. Not collective. See Also -------- petsc_python_pc, setPythonContext """ cdef void *context = NULL CHKERR( PCPythonGetContext(self.pc, &context) ) if context == NULL: return None else: return context def setPythonType(self, py_type: str) -> None: """Set the fully qualified Python name of the class to be used. Collective. See Also -------- petsc_python_pc, setPythonContext, getPythonType, petsc.PCPythonSetType """ cdef const char *cval = NULL py_type = str2bytes(py_type, &cval) CHKERR( PCPythonSetType(self.pc, cval) ) def getPythonType(self) -> str: """Return the fully qualified Python name of the class used by the preconditioner. Not collective. See Also -------- petsc_python_pc, setPythonContext, setPythonType, petsc.PCPythonGetType """ cdef const char *cval = NULL CHKERR( PCPythonGetType(self.pc, &cval) ) return bytes2str(cval) # --- ASM --- def setASMType(self, asmtype: ASMType) -> None: """Set the type of restriction and interpolation. Logically collective. Parameters ---------- asmtype The type of ASM you wish to use. See Also -------- petsc.PCASMSetType """ cdef PetscPCASMType cval = asmtype CHKERR( PCASMSetType(self.pc, cval) ) def setASMOverlap(self, overlap: int) -> None: """Set the overlap between a pair of subdomains. Logically collective. Parameters ---------- overlap The amount of overlap between subdomains. See Also -------- petsc.PCASMSetOverlap """ cdef PetscInt ival = asInt(overlap) CHKERR( PCASMSetOverlap(self.pc, ival) ) def setASMLocalSubdomains( self, nsd: int, is_: Sequence[IS] | None = None, is_local: Sequence[IS] | None = None) -> None: """Set the local subdomains. Collective. Parameters ---------- nsd The number of subdomains for this process. is\_ Defines the subdomains for this process or `None` to determine internally. is_local Defines the local part of the subdomains for this process, only used for `PC.ASMType.RESTRICT`. See Also -------- setASMTotalSubdomains, petsc.PCASMSetLocalSubdomains """ cdef PetscInt n = asInt(nsd) cdef PetscInt i = 0 cdef PetscIS *isets = NULL cdef PetscIS *isets_local = NULL if is_ is not None: assert len(is_) == nsd CHKERR( PetscMalloc(n*sizeof(PetscIS), &isets) ) for i in range(n): isets[i] = (is_[i]).iset if is_local is not None: assert len(is_local) == nsd CHKERR( PetscMalloc(n*sizeof(PetscIS), &isets_local) ) for i in range(n): isets_local[i] = (is_local[i]).iset CHKERR( PCASMSetLocalSubdomains(self.pc, n, isets, isets_local) ) CHKERR( PetscFree(isets) ) CHKERR( PetscFree(isets_local) ) def setASMTotalSubdomains( self, nsd: int, is_: Sequence[IS] | None=None, is_local: Sequence[IS] | None=None) -> None: """Set the subdomains for all processes. Collective. Parameters ---------- nsd The number of subdomains for all processes. is\_ Defines the subdomains for all processes or `None` to determine internally. is_local Defines the local part of the subdomains for this process, only used for `PC.ASMType.RESTRICT`. See Also -------- setASMLocalSubdomains, petsc.PCASMSetTotalSubdomains """ cdef PetscInt n = asInt(nsd) cdef PetscInt i = 0 cdef PetscIS *isets = NULL cdef PetscIS *isets_local = NULL if is_ is not None: assert len(is_) == nsd CHKERR( PetscMalloc(n*sizeof(PetscIS), &isets) ) for i in range(n): isets[i] = (is_[i]).iset if is_local is not None: assert len(is_local) == nsd CHKERR( PetscMalloc(n*sizeof(PetscIS), &isets_local) ) for i in range(n): isets_local[i] = (is_local[i]).iset CHKERR( PCASMSetTotalSubdomains(self.pc, n, isets, isets_local) ) CHKERR( PetscFree(isets) ) CHKERR( PetscFree(isets_local) ) def getASMSubKSP(self) -> list[KSP]: """Return the local `KSP` object for all blocks on this process. Not collective. See Also -------- petsc.PCASMGetSubKSP """ cdef PetscInt i = 0, n = 0 cdef PetscKSP *p = NULL CHKERR( PCASMGetSubKSP(self.pc, &n, NULL, &p) ) return [ref_KSP(p[i]) for i from 0 <= i None: """Set to sort subdomain indices. Logically collective. Parameters ---------- dosort Set to `True` to sort indices See Also -------- petsc.PCASMSetSortIndices """ cdef PetscBool cdosort = asBool(dosort) CHKERR( PCASMSetSortIndices(self.pc, cdosort) ) # --- GASM --- def setGASMType(self, gasmtype: GASMType) -> None: """Set the type of restriction and interpolation. Logically collective. Parameters ---------- gasmtype The type of `GASM`. See Also -------- petsc.PCGASMSetType """ cdef PetscPCGASMType cval = gasmtype CHKERR( PCGASMSetType(self.pc, cval) ) def setGASMOverlap(self, overlap: int) -> None: """Set the overlap between a pair of subdomains. Logically collective. Parameters ---------- overlap The amount of overlap between subdomains. See Also -------- petsc.PCGASMSetOverlap """ cdef PetscInt ival = asInt(overlap) CHKERR( PCGASMSetOverlap(self.pc, ival) ) # --- GAMG --- def setGAMGType(self, gamgtype: GAMGType | str) -> None: """Set the type of algorithm. Collective. Parameters ---------- gamgtype The type of `GAMG` See Also -------- petsc.PCGAMGSetType """ cdef PetscPCGAMGType cval = NULL gamgtype = str2bytes(gamgtype, &cval) CHKERR( PCGAMGSetType(self.pc, cval) ) def setGAMGLevels(self, levels: int) -> None: """Set the maximum number of levels. Not collective. Parameters ---------- levels The maximum number of levels to use. See Also -------- petsc.PCGAMGSetNlevels """ cdef PetscInt ival = asInt(levels) CHKERR( PCGAMGSetNlevels(self.pc, ival) ) def setGAMGSmooths(self, smooths: int) -> None: """Set the number of smoothing steps used on all levels. Logically collective. Parameters ---------- smooths The maximum number of smooths. See Also -------- petsc.PCGAMGSetNSmooths """ cdef PetscInt ival = asInt(smooths) CHKERR( PCGAMGSetNSmooths(self.pc, ival) ) # --- Hypre --- def getHYPREType(self) -> str: """Return the `Type.HYPRE` type. See Also -------- petsc.PCHYPREGetType """ cdef PetscPCHYPREType cval = NULL CHKERR( PCHYPREGetType(self.pc, &cval) ) return bytes2str(cval) def setHYPREType(self, hypretype: str): """Set the `Type.HYPRE` type. Parameters ---------- hypretype The name of the type, one of ``"euclid"``, ``"pilut"``, ``"parasails"``, ``"boomeramg"``, ``"ams"``, ``"ads"`` See Also -------- petsc.PCHYPRESetType """ cdef PetscPCHYPREType cval = NULL hypretype = str2bytes(hypretype, &cval) CHKERR( PCHYPRESetType(self.pc, cval) ) def setHYPREDiscreteCurl(self, Mat mat) -> None: """Set the discrete curl matrix. Collective. Parameters ---------- mat The discrete curl. See Also -------- petsc.PCHYPRESetDiscreteCurl """ CHKERR( PCHYPRESetDiscreteCurl(self.pc, mat.mat) ) def setHYPREDiscreteGradient(self, Mat mat) -> None: """Set the discrete gradient matrix. Collective. Parameters ---------- mat The discrete gradient. See Also -------- petsc.PCHYPRESetDiscreteGradient """ CHKERR( PCHYPRESetDiscreteGradient(self.pc, mat.mat) ) def setHYPRESetAlphaPoissonMatrix(self, Mat mat) -> None: """Set the vector Poisson matrix. Collective. Parameters ---------- mat The vector Poisson matrix. See Also -------- petsc.PCHYPRESetAlphaPoissonMatrix """ CHKERR( PCHYPRESetAlphaPoissonMatrix(self.pc, mat.mat) ) def setHYPRESetBetaPoissonMatrix(self, Mat mat=None) -> None: """Set the Posson matrix. Collective. Parameters ---------- mat The Poisson matrix or `None` to turn off. See Also -------- petsc.PCHYPRESetBetaPoissonMatrix """ cdef PetscMat pmat = NULL if mat is not None: pmat = mat.mat CHKERR( PCHYPRESetBetaPoissonMatrix(self.pc, pmat) ) def setHYPRESetInterpolations(self, dim: int, Mat RT_Pi_Full=None, RT_Pi=None, Mat ND_Pi_Full=None, ND_Pi=None) -> None: """Set the interpolation matrices. Collective. Parameters ---------- dim The dimension of the problem. RT_Pi_Full The Raviart-Thomas interpolation matrix or `None` to omit. RT_Pi The xyz components of the Raviart-Thomas interpolation matrix, or `None` to omit. ND_Pi_Full The Nedelec interpolation matrix or `None` to omit. ND_Pi The xyz components of the Nedelec interpolation matrix, or `None` to omit. See Also -------- petsc.PCHYPRESetInterpolations """ cdef PetscMat RT_full_mat = NULL if RT_Pi_Full is not None: RT_full_mat = RT_Pi_Full.mat cdef PetscMat ND_full_mat = NULL if ND_Pi_Full is not None: ND_full_mat = ND_Pi_Full.mat cdef PetscInt idim = asInt(dim) cdef PetscMat *RT_Pi_mat = NULL if RT_Pi is not None: PetscMalloc(dim*sizeof(PetscMat), &RT_Pi_mat) assert len(RT_Pi) == dim for i in range(dim): RT_Pi_mat[i] = (RT_Pi[i]).mat cdef PetscMat *ND_Pi_mat = NULL if ND_Pi is not None: PetscMalloc(dim*sizeof(PetscMat), &ND_Pi_mat) assert len(ND_Pi) == dim for i in range(dim): ND_Pi_mat[dim] = (ND_Pi[i]).mat CHKERR (PCHYPRESetInterpolations(self.pc, idim, RT_full_mat, RT_Pi_mat, ND_full_mat, ND_Pi_mat)) CHKERR (PetscFree(RT_Pi_mat)) CHKERR (PetscFree(ND_Pi_mat)) def setHYPRESetEdgeConstantVectors(self, Vec ozz, Vec zoz, Vec zzo=None) -> None: """Set the representation of the constant vector fields in the edge element basis. Collective. Parameters ---------- ozz A vector representing ``[1,0,0]`` or ``[1,0]`` in 2D. zoz A vector representing ``[0,1,0]`` or ``[0,1]`` in 2D. zzo A vector representing ``[0,0,1]`` or `None` in 2D. See Also -------- petsc.PCHYPRESetEdgeConstantVectors """ cdef PetscVec zzo_vec = NULL if zzo is not None: zzo_vec = zzo.vec CHKERR( PCHYPRESetEdgeConstantVectors(self.pc, ozz.vec, zoz.vec, zzo_vec) ) def setHYPREAMSSetInteriorNodes(self, Vec interior) -> None: """Set the list of interior nodes to a zero conductivity region. Collective. Parameters ---------- interior A vector where a value of 1.0 indicates an interior node. See Also -------- petsc.PCHYPREAMSSetInteriorNodes """ CHKERR(PCHYPREAMSSetInteriorNodes(self.pc, interior.vec)) # --- Factor --- def setFactorSolverType(self, solver: Mat.SolverType | str) -> None: """Set the solver package used to perform the factorization. Logically collective. Parameters ---------- solver The solver package used to factorize. See Also -------- petsc.PCFactorSetMatSolverType """ cdef PetscMatSolverType cval = NULL solver = str2bytes(solver, &cval) CHKERR( PCFactorSetMatSolverType(self.pc, cval) ) def getFactorSolverType(self) -> str: """Return the solver package used to perform the factorization. Not collective. See Also -------- petsc.PCFactorGetMatSolverType """ cdef PetscMatSolverType cval = NULL CHKERR( PCFactorGetMatSolverType(self.pc, &cval) ) return bytes2str(cval) def setFactorSetUpSolverType(self) -> None: """Set up the factorization solver. This can be called after `KSP.setOperators` or `PC.setOperators`, causes `petsc.MatGetFactor` to be called so then one may set the options for that particular factorization object. See Also -------- petsc_options, petsc.PCFactorSetUpMatSolverType """ CHKERR( PCFactorSetUpMatSolverType(self.pc) ) def setFactorOrdering( self, ord_type: str | None = None, nzdiag: float | None = None, reuse: bool | None = None) -> None: """Set options for the matrix factorization reordering. Logically collective. Parameters ---------- ord_type The name of the matrix ordering or `None` to leave unchanged. nzdiag Threshold to consider diagonal entries in the matrix as zero. reuse Enable to reuse the ordering of a factored matrix. See Also -------- petsc.PCFactorSetMatOrderingType petsc.PCFactorReorderForNonzeroDiagonal, petsc.PCFactorSetReuseOrdering """ cdef PetscMatOrderingType cval = NULL if ord_type is not None: ord_type = str2bytes(ord_type, &cval) CHKERR( PCFactorSetMatOrderingType(self.pc, cval) ) cdef PetscReal rval = 0 if nzdiag is not None: rval = asReal(nzdiag) CHKERR( PCFactorReorderForNonzeroDiagonal(self.pc, rval) ) cdef PetscBool bval = PETSC_FALSE if reuse is not None: bval = PETSC_TRUE if reuse else PETSC_FALSE CHKERR( PCFactorSetReuseOrdering(self.pc, bval) ) def setFactorPivot( self, zeropivot: float | None = None, inblocks: bool | None = None) -> None: """Set options for matrix factorization pivoting. Logically collective. Parameters ---------- zeropivot The size at which smaller pivots are treated as zero. inblocks Enable to allow pivoting while factoring in blocks. See Also -------- petsc.PCFactorSetZeroPivot, petsc.PCFactorSetPivotInBlocks """ cdef PetscReal rval = 0 if zeropivot is not None: rval = asReal(zeropivot) CHKERR( PCFactorSetZeroPivot(self.pc, rval) ) cdef PetscBool bval = PETSC_FALSE if inblocks is not None: bval = PETSC_TRUE if inblocks else PETSC_FALSE CHKERR( PCFactorSetPivotInBlocks(self.pc, bval) ) def setFactorShift( self, shift_type: Mat.FactorShiftType | None = None, amount: float | None = None) -> None: """Set options for shifting diagonal entries of a matrix. Parameters ---------- shift_type The type of shift, or `None` to leave unchanged. amount The amount of shift. Specify `DEFAULT` to determine internally or `None` to leave unchanged. See Also -------- petsc.PCFactorSetShiftType, petsc.PCFactorSetShiftAmount """ cdef PetscMatFactorShiftType cval = MAT_SHIFT_NONE if shift_type is not None: cval = matfactorshifttype(shift_type) CHKERR( PCFactorSetShiftType(self.pc, cval) ) cdef PetscReal rval = 0 if amount is not None: rval = asReal(amount) CHKERR( PCFactorSetShiftAmount(self.pc, rval) ) def setFactorLevels(self, levels: int) -> None: """Set the number of levels of fill. Logically collective. Parameters ---------- levels The number of levels to fill. See Also -------- petsc.PCFactorSetLevels """ cdef PetscInt ival = asInt(levels) CHKERR( PCFactorSetLevels(self.pc, ival) ) def getFactorMatrix(self) -> Mat: """Return the factored matrix. Not collective. See Also -------- petsc.PCFactorGetMatrix """ cdef Mat mat = Mat() CHKERR( PCFactorGetMatrix(self.pc, &mat.mat) ) CHKERR( PetscINCREF(mat.obj) ) return mat # --- FieldSplit --- def setFieldSplitType(self, ctype: CompositeType) -> None: """Set the type of composition of a field split preconditioner. Collective. Parameters ---------- ctype The type of composition. See Also -------- petsc.PCFieldSplitSetType """ cdef PetscPCCompositeType cval = ctype CHKERR( PCFieldSplitSetType(self.pc, cval) ) def setFieldSplitIS(self, *fields: Tuple[str, IS]) -> None: """Set the elements for the field split by `IS`. Logically collective. Solve options for this split will be available under the prefix ``-fieldsplit_SPLITNAME_*``. Parameters ---------- fields A sequence of tuples containing the split name and the `IS` that defines the elements in the split. See Also -------- petsc_options, petsc.PCFieldSplitSetIS """ cdef object name = None cdef IS field = None cdef const char *cname = NULL for name, field in fields: name = str2bytes(name, &cname) CHKERR( PCFieldSplitSetIS(self.pc, cname, field.iset) ) def setFieldSplitFields(self, bsize: int, *fields: Tuple[str, Sequence[int]]) -> None: """Sets the elements for the field split. Parameters ---------- bsize The block size fields A sequence of tuples containing the split name and a sequence of integers that define the elements in the split. See Also -------- petsc.PCFieldSplitSetBlockSize, petsc.PCFieldSplitSetFields """ cdef PetscInt bs = asInt(bsize) CHKERR( PCFieldSplitSetBlockSize(self.pc, bs) ) cdef object name = None cdef object field = None cdef const char *cname = NULL cdef PetscInt nfields = 0, *ifields = NULL for name, field in fields: name = str2bytes(name, &cname) field = iarray_i(field, &nfields, &ifields) CHKERR( PCFieldSplitSetFields(self.pc, cname, nfields, ifields, ifields) ) def getFieldSplitSubKSP(self) -> list[KSP]: """Return the `KSP` for all splits. See Also -------- petsc.PCFieldSplitGetSubKSP """ cdef PetscInt i = 0, n = 0 cdef PetscKSP *p = NULL cdef object subksp = None try: CHKERR( PCFieldSplitGetSubKSP(self.pc, &n, &p) ) subksp = [ref_KSP(p[i]) for i from 0 <= i list[KSP]: """Return the `KSP` for the Schur complement based splits. See Also -------- petsc.PCFieldSplitSchurGetSubKSP, petsc.PCFieldSplitGetSubKSP """ cdef PetscInt i = 0, n = 0 cdef PetscKSP *p = NULL cdef object subksp = None try: CHKERR( PCFieldSplitSchurGetSubKSP(self.pc, &n, &p) ) subksp = [ref_KSP(p[i]) for i from 0 <= i None: """Set the type of approximate block factorization. Collective. Parameters ---------- ctype The type indicating which blocks to retain. See Also -------- petsc.PCFieldSplitSetSchurFactType """ cdef PetscPCFieldSplitSchurFactType cval = ctype CHKERR( PCFieldSplitSetSchurFactType(self.pc, cval) ) def setFieldSplitSchurPreType( self, ptype: FieldSplitSchurPreType, Mat pre=None) -> None: """Set from what operator the `PC` is constructed. Collective. Parameters ---------- ptype The type of matrix to use for preconditioning the Schur complement. pre The optional matrix to use for preconditioning. See Also -------- petsc.PCFieldSplitSetSchurPre """ cdef PetscPCFieldSplitSchurPreType pval = ptype cdef PetscMat pmat = NULL if pre is not None: pmat = pre.mat CHKERR( PCFieldSplitSetSchurPre(self.pc, pval, pmat) ) # --- COMPOSITE --- def setCompositeType(self, ctype: CompositeType) -> None: """Set the type of composite preconditioner. Logically collective. Parameters ---------- ctype The type of composition. See Also -------- petsc.PCCompositeSetType """ cdef PetscPCCompositeType cval = ctype CHKERR( PCCompositeSetType(self.pc, cval) ) def getCompositePC(self, n: int) -> None: """Return a component of the composite `PC`. Not collective. Parameters ---------- n The index of the `PC` in the composition. See Also -------- petsc.PCCompositeGetPC """ cdef PC pc = PC() cdef cn = asInt(n) CHKERR( PCCompositeGetPC(self.pc, cn, &pc.pc) ) CHKERR( PetscINCREF(pc.obj) ) return pc def addCompositePCType(self, pc_type: Type | str) -> None: """Add a `PC` of the given type to the composite `PC`. Collective. Parameters ---------- pc_type The type of the preconditioner to add. See Also -------- petsc.PCCompositeAddPCType """ cdef PetscPCType cval = NULL pc_type = str2bytes(pc_type, &cval) CHKERR( PCCompositeAddPCType(self.pc, cval) ) # --- KSP --- def getKSP(self): """Return the `KSP` if the `PC` is `Type.KSP`. Not collective. See Also -------- petsc.PCKSPGetKSP """ cdef KSP ksp = KSP() CHKERR( PCKSPGetKSP(self.pc, &ksp.ksp) ) CHKERR( PetscINCREF(ksp.obj) ) return ksp # --- MG --- def getMGType(self) -> MGType: """Return the form of multigrid. Logically collective. See Also -------- petsc.PCMGGetType """ cdef PetscPCMGType cval = PC_MG_ADDITIVE CHKERR( PCMGGetType(self.pc, &cval) ) return cval def setMGType(self, mgtype: MGType): """Set the form of multigrid. Logically collective. See Also -------- petsc.PCMGSetType """ cdef PetscPCMGType cval = mgtype CHKERR( PCMGSetType(self.pc, cval) ) def getMGLevels(self) -> int: """Return the number of `MG` levels. Not collective. See Also -------- petsc.PCMGGetLevels """ cdef PetscInt levels = 0 CHKERR( PCMGGetLevels(self.pc, &levels) ) return toInt(levels) def setMGLevels(self, levels: int) -> None: """Set the number of `MG` levels. Parameters ---------- levels The number of levels See Also -------- petsc.PCMGSetLevels """ cdef PetscInt clevels = asInt(levels) CHKERR( PCMGSetLevels(self.pc, clevels, NULL) ) def getMGCoarseSolve(self) -> KSP: """Return the `KSP` used on the coarse grid. Not collective. See Also -------- petsc.PCMGGetCoarseSolve """ cdef KSP ksp = KSP() CHKERR( PCMGGetCoarseSolve(self.pc, &ksp.ksp) ) CHKERR( PetscINCREF(ksp.obj) ) return ksp def setMGInterpolation(self, level, Mat mat) -> None: """Set the interpolation operator for the given level. Logically collective. Parameters ---------- level The level where interpolation is defined from ``level-1`` to ``level``. mat The interpolation operator See Also -------- petsc.PCMGSetInterpolation """ cdef PetscInt clevel = asInt(level) CHKERR( PCMGSetInterpolation(self.pc, clevel, mat.mat) ) def getMGInterpolation(self, level: int) -> Mat: """Return the interpolation operator for the given level. Logically collective. Parameters ---------- level The level where interpolation is defined from ``level-1`` to ``level``. See Also -------- petsc.PCMGGetInterpolation """ cdef PetscInt clevel = asInt(level) cdef Mat interpolation = Mat() CHKERR( PCMGGetInterpolation(self.pc, clevel, &interpolation.mat) ) CHKERR( PetscINCREF(interpolation.obj) ) return interpolation def setMGRestriction(self, level: int, Mat mat) -> None: """Set the restriction operator for the given level. Logically collective. Parameters ---------- level The level where restriction is defined from ``level`` to ``level-1``. mat The restriction operator See Also -------- petsc.PCMGSetRestriction """ cdef PetscInt clevel = asInt(level) CHKERR( PCMGSetRestriction(self.pc, clevel, mat.mat) ) def getMGRestriction(self, level: int) -> Mat: """Return the restriction operator for the given level. Logically collective. Parameters ---------- level The level where restriction is defined from ``level`` to ``level-1``. See Also -------- petsc.PCMGGetRestriction """ cdef PetscInt clevel = asInt(level) cdef Mat restriction = Mat() CHKERR( PCMGGetRestriction(self.pc, clevel, &restriction.mat) ) CHKERR( PetscINCREF(restriction.obj) ) return restriction def setMGRScale(self, level: int, Vec rscale) -> None: """Set the pointwise scaling for the restriction operator on the given level. Logically collective. Parameters ---------- level The level where restriction is defined from ``level`` to ``level-1``. rscale The scaling vector. See Also -------- petsc.PCMGSetRScale """ cdef PetscInt clevel = asInt(level) CHKERR( PCMGSetRScale(self.pc, clevel, rscale.vec) ) def getMGRScale(self, level: int) -> Vec: """Return the pointwise scaling for the restriction operator on the given level. Logically collective. Parameters ---------- level The level where restriction is defined from ``level`` to ``level-1``. See Also -------- petsc.PCMGGetRScale """ cdef PetscInt clevel = asInt(level) cdef Vec rscale = Vec() CHKERR( PCMGGetRScale(self.pc, clevel, &rscale.vec) ) CHKERR( PetscINCREF(rscale.obj) ) return rscale def getMGSmoother(self, level: int) -> KSP: """Return the `KSP` to be used as a smoother. Not collective. Parameters ---------- level The level of the smoother. See Also -------- getMGSmootherDown, getMGSmootherUp, petsc.PCMGGetSmoother """ cdef PetscInt clevel = asInt(level) cdef KSP ksp = KSP() CHKERR( PCMGGetSmoother(self.pc, clevel, &ksp.ksp) ) CHKERR( PetscINCREF(ksp.obj) ) return ksp def getMGSmootherDown(self, level: int) -> KSP: """Return the `KSP` to be used as a smoother before coarse grid correction. Not collective. Parameters ---------- level The level of the smoother. See Also -------- getMGSmoother, getMGSmootherUp, petsc.PCMGGetSmootherDown """ cdef PetscInt clevel = asInt(level) cdef KSP ksp = KSP() CHKERR( PCMGGetSmootherDown(self.pc, clevel, &ksp.ksp) ) CHKERR( PetscINCREF(ksp.obj) ) return ksp def getMGSmootherUp(self, level: int) -> KSP: """Return the `KSP` to be used as a smoother after coarse grid correction. Not collective. Parameters ---------- level The level of the smoother. See Also -------- getMGSmootherDown, getMGSmoother, petsc.PCMGGetSmootherUp """ cdef PetscInt clevel = asInt(level) cdef KSP ksp = KSP() CHKERR( PCMGGetSmootherUp(self.pc, clevel, &ksp.ksp) ) CHKERR( PetscINCREF(ksp.obj) ) return ksp def setMGCycleType(self, cycle_type: MGCycleType) -> None: """Set the type of cycles. Parameters ---------- cycle_type The type of multigrid cycles to use. See Also -------- setMGCycleTypeOnLevel, petsc.PCMGSetCycleType """ cdef PetscPCMGCycleType ctype = cycle_type CHKERR( PCMGSetCycleType(self.pc, ctype) ) def setMGCycleTypeOnLevel(self, level: int, cycle_type: MGCycleType) -> None: """Set the type of cycle on the given level. Logically collective. Parameters ---------- level The level on which to set the cycle type. cycle_type The type of multigrid cycles to use. See Also -------- setMGCycleType, petsc.PCMGSetCycleTypeOnLevel """ cdef PetscInt clevel = asInt(level) cdef PetscPCMGCycleType ctype = cycle_type CHKERR( PCMGSetCycleTypeOnLevel(self.pc, clevel, ctype) ) def setMGRhs(self, level: int, Vec rhs) -> None: """Set the vector where the right-hand side is stored. Logically collective. If not provided, one will be set internally. Will be cleaned up in `destroy`. Parameters ---------- level The level on which to set the right-hand side. rhs The vector where the right-hand side is stored. See Also -------- petsc.PCMGSetRhs """ cdef PetscInt clevel = asInt(level) CHKERR( PCMGSetRhs(self.pc, clevel, rhs.vec) ) def setMGX(self, level: int, Vec x) -> None: """Set the vector where the solution is stored. Logically collective. If not provided, one will be set internally. Will be cleaned up in `destroy`. Parameters ---------- level The level on which to set the solution. x The vector where the solution is stored. See Also -------- petsc.PCMGSetX """ cdef PetscInt clevel = asInt(level) CHKERR( PCMGSetX(self.pc, clevel, x.vec) ) def setMGR(self, level: int, Vec r) -> None: """Set the vector where the residual is stored. Logically collective. If not provided, one will be set internally. Will be cleaned up in `destroy`. Parameters ---------- level The level on which to set the residual. r The vector where the residual is stored. See Also -------- petsc.PCMGSetR """ cdef PetscInt clevel = asInt(level) CHKERR( PCMGSetR(self.pc, clevel, r.vec) ) # --- BDDC --- def setBDDCDivergenceMat(self, Mat div, trans: bool = False, IS l2l=None) -> None: """Set the linear operator representing ∫ div(u)•p dx. Collective. Parameters ---------- div The matrix in `Mat.Type.IS` format. trans If `True`, the pressure/velocity is in the trial/test space respectively. If `False` the pressure/velocity is in the test/trial space. l2l Optional `IS` describing the local to local map for velocities. See Also -------- petsc.PCBDDCSetDivergenceMat """ cdef PetscBool ptrans = trans cdef PetscIS pl2l = NULL if l2l is not None: pl2l = l2l.iset CHKERR( PCBDDCSetDivergenceMat(self.pc, div.mat, ptrans, pl2l) ) def setBDDCDiscreteGradient( self, Mat G, order: int = 1, field: int = 1, gord: bool = True, conforming: bool = True) -> None: """Set the discrete gradient. Collective. Parameters ---------- G The discrete gradient matrix in `Mat.Type.AIJ` format. order The order of the Nedelec space. field The field number of the Nedelec degrees of freedom. This is not used if no fields have been specified. gord Enable to use global ordering in the rows of ``G``. conforming Enable if the mesh is conforming. See Also -------- petsc.PCBDDCSetDiscreteGradient """ cdef PetscInt porder = asInt(order) cdef PetscInt pfield = asInt(field) cdef PetscBool pgord = gord cdef PetscBool pconforming = conforming CHKERR( PCBDDCSetDiscreteGradient(self.pc, G.mat, porder, pfield, pgord, pconforming) ) def setBDDCChangeOfBasisMat(self, Mat T, interior: bool = False) -> None: """Set a user defined change of basis for degrees of freedom. Collective. Parameters ---------- T The matrix representing the change of basis. interior Enable to indicate the change of basis affects interior degrees of freedom. See Also -------- petsc.PCBDDCSetChangeOfBasisMat """ cdef PetscBool pinterior = interior CHKERR( PCBDDCSetChangeOfBasisMat(self.pc, T.mat, pinterior) ) def setBDDCPrimalVerticesIS(self, IS primv) -> None: """Set additional user defined primal vertices. Collective. Parameters ---------- primv The `IS` of primal vertices in global numbering. See Also -------- petsc.PCBDDCSetPrimalVerticesIS """ CHKERR( PCBDDCSetPrimalVerticesIS(self.pc, primv.iset) ) def setBDDCPrimalVerticesLocalIS(self, IS primv) -> None: """Set additional user defined primal vertices. Collective. Parameters ---------- primv The `IS` of primal vertices in local numbering. See Also -------- petsc.PCBDDCSetPrimalVerticesLocalIS """ CHKERR( PCBDDCSetPrimalVerticesLocalIS(self.pc, primv.iset) ) def setBDDCCoarseningRatio(self, cratio: int) -> None: """Set the coarsening ratio used in the multilevel version. Logically collective. Parameters ---------- cratio The coarsening ratio at the coarse level See Also -------- petsc.PCBDDCSetCoarseningRatio """ cdef PetscInt pcratio = asInt(cratio) CHKERR( PCBDDCSetCoarseningRatio(self.pc, pcratio) ) def setBDDCLevels(self, levels: int) -> None: """Set the maximum number of additional levels allowed. Logically collective. Parameters ---------- levels The maximum number of levels. See Also -------- petsc.PCBDDCSetLevels """ cdef PetscInt plevels = asInt(levels) CHKERR( PCBDDCSetLevels(self.pc, plevels) ) def setBDDCDirichletBoundaries(self, IS bndr) -> None: """Set the `IS` defining Dirichlet boundaries for the global problem. Collective. Parameters ---------- bndr The parallel `IS` defining Dirichlet boundaries. See Also -------- petsc.PCBDDCSetDirichletBoundaries """ CHKERR( PCBDDCSetDirichletBoundaries(self.pc, bndr.iset) ) def setBDDCDirichletBoundariesLocal(self, IS bndr) -> None: """Set the `IS` defining Dirichlet boundaries in local ordering. Collective. Parameters ---------- bndr The parallel `IS` defining Dirichlet boundaries in local ordering. See Also -------- setBDDCDirichletBoundaries, petsc.PCBDDCSetDirichletBoundariesLocal """ CHKERR( PCBDDCSetDirichletBoundariesLocal(self.pc, bndr.iset) ) def setBDDCNeumannBoundaries(self, IS bndr) -> None: """Set the `IS` defining Neumann boundaries for the global problem. Collective. Parameters ---------- bndr The parallel `IS` defining Neumann boundaries. See Also -------- petsc.PCBDDCSetNeumannBoundaries """ CHKERR( PCBDDCSetNeumannBoundaries(self.pc, bndr.iset) ) def setBDDCNeumannBoundariesLocal(self, IS bndr) -> None: """Set the `IS` defining Neumann boundaries in local ordering. Collective. Parameters ---------- bndr The parallel `IS` defining Neumann boundaries in local ordering. See Also -------- setBDDCNeumannBoundaries, petsc.PCBDDCSetNeumannBoundariesLocal """ CHKERR( PCBDDCSetNeumannBoundariesLocal(self.pc, bndr.iset) ) def setBDDCDofsSplitting(self, isfields: IS | Sequence[IS]) -> None: """Set the index set(s) defining fields of the global matrix. Collective. Parameters ---------- isfields The sequence of `IS` describing the fields in global ordering. See Also -------- petsc.PCBDDCSetDofsSplitting """ isfields = [isfields] if isinstance(isfields, IS) else list(isfields) cdef Py_ssize_t i, n = len(isfields) cdef PetscIS *cisfields = NULL cdef object tmp tmp = oarray_p(empty_p(n), NULL, &cisfields) for i from 0 <= i < n: cisfields[i] = (isfields[i]).iset CHKERR( PCBDDCSetDofsSplitting(self.pc, n, cisfields) ) def setBDDCDofsSplittingLocal(self, isfields: IS | Sequence[IS]): """Set the index set(s) defining fields of the local subdomain matrix. Collective. Not all nodes need to be listed. Unlisted nodes will belong to the complement field. Parameters ---------- isfields The sequence of `IS` describing the fields in local ordering. See Also -------- petsc.PCBDDCSetDofsSplittingLocal """ isfields = [isfields] if isinstance(isfields, IS) else list(isfields) cdef Py_ssize_t i, n = len(isfields) cdef PetscIS *cisfields = NULL cdef object tmp tmp = oarray_p(empty_p(n), NULL, &cisfields) for i from 0 <= i < n: cisfields[i] = (isfields[i]).iset CHKERR( PCBDDCSetDofsSplittingLocal(self.pc, n, cisfields) ) # --- Patch --- def setPatchCellNumbering(self, Section sec not None): CHKERR( PCPatchSetCellNumbering(self.pc, sec.sec) ) def setPatchDiscretisationInfo(self, dms, bs, cellNodeMaps, subspaceOffsets, ghostBcNodes, globalBcNodes): cdef PetscInt numSubSpaces = 0 cdef PetscInt numGhostBcs = 0, numGlobalBcs = 0 cdef PetscInt *nodesPerCell = NULL cdef const PetscInt **ccellNodeMaps = NULL cdef PetscDM *cdms = NULL cdef PetscInt *cbs = NULL cdef PetscInt *csubspaceOffsets = NULL cdef PetscInt *cghostBcNodes = NULL cdef PetscInt *cglobalBcNodes = NULL cdef PetscInt i = 0 bs = iarray_i(bs, &numSubSpaces, &cbs) ghostBcNodes = iarray_i(ghostBcNodes, &numGhostBcs, &cghostBcNodes) globalBcNodes = iarray_i(globalBcNodes, &numGlobalBcs, &cglobalBcNodes) subspaceOffsets = iarray_i(subspaceOffsets, NULL, &csubspaceOffsets) CHKERR( PetscMalloc(numSubSpaces*sizeof(PetscInt), &nodesPerCell) ) CHKERR( PetscMalloc(numSubSpaces*sizeof(PetscDM), &cdms) ) CHKERR( PetscMalloc(numSubSpaces*sizeof(PetscInt*), &ccellNodeMaps) ) for i in range(numSubSpaces): cdms[i] = (dms[i]).dm _, nodes = asarray(cellNodeMaps[i]).shape cellNodeMaps[i] = iarray_i(cellNodeMaps[i], NULL, &(ccellNodeMaps[i])) nodesPerCell[i] = asInt(nodes) # TODO: refactor on the PETSc side to take ISes? CHKERR( PCPatchSetDiscretisationInfo(self.pc, numSubSpaces, cdms, cbs, nodesPerCell, ccellNodeMaps, csubspaceOffsets, numGhostBcs, cghostBcNodes, numGlobalBcs, cglobalBcNodes) ) CHKERR( PetscFree(nodesPerCell) ) CHKERR( PetscFree(cdms) ) CHKERR( PetscFree(ccellNodeMaps) ) def setPatchComputeOperator(self, operator, args=None, kargs=None): if args is None: args = () if kargs is None: kargs = {} context = (operator, args, kargs) self.set_attr("__patch_compute_operator__", context) CHKERR( PCPatchSetComputeOperator(self.pc, PCPatch_ComputeOperator, context) ) def setPatchComputeOperatorInteriorFacets(self, operator, args=None, kargs=None): if args is None: args = () if kargs is None: kargs = {} context = (operator, args, kargs) self.set_attr("__patch_compute_operator_interior_facets__", context) CHKERR( PCPatchSetComputeOperatorInteriorFacets(self.pc, PCPatch_ComputeOperatorInteriorFacets, context) ) def setPatchComputeFunction(self, function, args=None, kargs=None): if args is None: args = () if kargs is None: kargs = {} context = (function, args, kargs) self.set_attr("__patch_compute_function__", context) CHKERR( PCPatchSetComputeFunction(self.pc, PCPatch_ComputeFunction, context) ) def setPatchComputeFunctionInteriorFacets(self, function, args=None, kargs=None): if args is None: args = () if kargs is None: kargs = {} context = (function, args, kargs) self.set_attr("__patch_compute_function_interior_facets__", context) CHKERR( PCPatchSetComputeFunction(self.pc, PCPatch_ComputeFunctionInteriorFacets, context) ) def setPatchConstructType(self, typ, operator=None, args=None, kargs=None): if args is None: args = () if kargs is None: kargs = {} if typ in {PC.PatchConstructType.PYTHON, PC.PatchConstructType.USER} and operator is None: raise ValueError("Must provide operator for USER or PYTHON type") if operator is not None: context = (operator, args, kargs) else: context = None self.set_attr("__patch_construction_operator__", context) CHKERR( PCPatchSetConstructType(self.pc, typ, PCPatch_UserConstructOperator, context) ) # --- HPDDM --- def setHPDDMAuxiliaryMat(self, IS uis, Mat uaux) -> None: """Set the auxiliary matrix used by the preconditioner. Parameters ---------- uis The `IS` of the local auxiliary matrix uaux The auxiliary sequential matrix See Also -------- petsc.PCHPDDMSetAuxiliaryMat """ CHKERR( PCHPDDMSetAuxiliaryMat(self.pc, uis.iset, uaux.mat, NULL, NULL) ) def setHPDDMRHSMat(self, Mat B) -> None: """Set the right-hand side matrix of the preconditioner. Parameters ---------- B The right-hand side sequential matrix. See Also -------- petsc.PCHPDDMSetRHSMat """ CHKERR( PCHPDDMSetRHSMat(self.pc, B.mat) ) def setHPDDMHasNeumannMat(self, has: bool) -> None: """Set to indicate that the `Mat` passed to the `PC` is the local Neumann matrix. Parameters ---------- has Enable to indicate the matrix is the local Neumann matrix. See Also -------- petsc.PCHPDDMHasNeumannMat """ cdef PetscBool phas = has CHKERR( PCHPDDMHasNeumannMat(self.pc, phas) ) def setHPDDMCoarseCorrectionType(self, correction_type: HPDDMCoarseCorrectionType) -> None: """Set the coarse correction type. Collective. Parameters ---------- correction_type The type of coarse correction to apply. See Also -------- petsc.PCHPDDMSetCoarseCorrectionType """ cdef PetscPCHPDDMCoarseCorrectionType ctype = correction_type CHKERR( PCHPDDMSetCoarseCorrectionType(self.pc, ctype) ) def getHPDDMCoarseCorrectionType(self) -> HPDDMCoarseCorrectionType: """Return the coarse correction type. See Also -------- petsc.PCHPDDMGetCoarseCorrectionType """ cdef PetscPCHPDDMCoarseCorrectionType cval = PC_HPDDM_COARSE_CORRECTION_DEFLATED CHKERR( PCHPDDMGetCoarseCorrectionType(self.pc, &cval) ) return cval def getHPDDMSTShareSubKSP(self) -> bool: """Return true if the `KSP` in SLEPc ``ST`` and the subdomain solver is shared. See Also -------- petsc.PCHPDDMGetSTShareSubKSP """ cdef PetscBool cval = PETSC_FALSE CHKERR( PCHPDDMGetSTShareSubKSP(self.pc, &cval) ) return toBool(cval) def setHPDDMDeflationMat(self, IS uis, Mat U): """Set the deflation space used to assemble a coarse operator. Parameters ---------- uis The `IS` of the local deflation matrix. U The deflation sequential matrix of type `Mat.Type.DENSE`. See Also -------- petsc.PCHPDDMSetDeflationMat """ CHKERR( PCHPDDMSetDeflationMat(self.pc, uis.iset, U.mat) ) # --- SPAI --- def setSPAIEpsilon(self, val: float) -> None: """Set the tolerance for the preconditioner. Parameters ---------- val The tolerance, defaults to ``0.4``. See Also -------- petsc.PCSPAISetEpsilon """ cdef PetscReal cval = asReal(val) CHKERR( PCSPAISetEpsilon(self.pc, cval) ) def setSPAINBSteps(self, nbsteps: int) -> None: """Set the maximum number of improvement steps per row. Parameters ---------- nbsteps The number of steps, defaults to ``5``. See Also -------- petsc.PCSPAISetNBSteps """ cdef PetscInt cval = asInt(nbsteps) CHKERR( PCSPAISetNBSteps(self.pc, cval) ) def setSPAIMax(self, maxval: int) -> None: """Set the size of working buffers in the preconditioner. Parameters ---------- maxval Number of entries in the work arrays to be allocated, defaults to ``5000``. See Also -------- petsc.PCSPAISetMax """ cdef PetscInt cval = asInt(maxval) CHKERR( PCSPAISetMax(self.pc, cval) ) def setSPAIMaxNew(self, maxval: int) -> None: """Set the maximum number of new non-zero candidates per step. Parameters ---------- maxval Number of entries allowed, defaults to ``5``. See Also -------- petsc.PCSPAISetMaxNew """ cdef PetscInt cval = asInt(maxval) CHKERR( PCSPAISetMaxNew(self.pc, cval) ) def setSPAIBlockSize(self, n: int) -> None: """Set the block size of the preconditioner. Parameters ---------- n The block size, defaults to ``1``. See Also -------- petsc.PCSPAISetBlockSize """ cdef PetscInt cval = asInt(n) CHKERR( PCSPAISetBlockSize(self.pc, cval) ) def setSPAICacheSize(self, size: int) -> None: """Set the cache size. Parameters ---------- size The size of the cache, defaults to ``5``. See Also -------- petsc.PCSPAISetCacheSize """ cdef PetscInt cval = asInt(size) CHKERR( PCSPAISetCacheSize(self.pc, cval) ) def setSPAIVerbose(self, level: int) -> None: """Set the verbosity level. Parameters ---------- level The level of verbosity, defaults to ``1``. See Also -------- petsc.PCSPAISetVerbose """ cdef PetscInt cval = asInt(level) CHKERR( PCSPAISetVerbose(self.pc, cval) ) def setSPAISp(self, sym: int) -> None: """Set to specify a symmetric sparsity pattern. Parameters ---------- sym Enable to indicate the matrix is symmetric. See Also -------- petsc.PCSPAISetSp """ cdef PetscInt cval = asInt(sym) CHKERR( PCSPAISetSp(self.pc, cval) ) # --- DEFLATION --- def setDeflationInitOnly(self, flg: bool) -> None: """Set to only perform the initialization. Logically collective. Sets initial guess to the solution on the deflation space but does not apply the deflation preconditioner. The additional preconditioner is still applied. Parameters ---------- flg Enable to only initialize the preconditioner. See Also -------- petsc.PCDeflationSetInitOnly """ cdef PetscBool cflg = asBool(flg) CHKERR( PCDeflationSetInitOnly(self.pc, cflg) ) def setDeflationLevels(self, levels: int) -> None: """Set the maximum level of deflation nesting. Logically collective. Parameters ---------- levels The maximum deflation level. See Also -------- petsc.PCDeflationSetLevels """ cdef PetscInt clevels = asInt(levels) CHKERR( PCDeflationSetLevels(self.pc, clevels) ) def setDeflationReductionFactor(self, red: int) -> None: """Set the reduction factor for the preconditioner. Logically collective. Parameters ---------- red The reduction factor or ``DEFAULT``. See Also -------- petsc.PCDeflationSetReductionFactor """ cdef PetscInt cred = asInt(red) CHKERR( PCDeflationSetReductionFactor(self.pc, cred) ) def setDeflationCorrectionFactor(self, fact: float) -> None: """Set the coarse problem correction factor. Logically collective. Parameters ---------- fact The correction factor. See Also -------- petsc.PCDeflationSetCorrectionFactor """ cdef PetscScalar cfact = asScalar(fact) CHKERR( PCDeflationSetCorrectionFactor(self.pc, fact) ) def setDeflationSpaceToCompute(self, space_type: DeflationSpaceType, size: int) -> None: """Set the deflation space type. Logically collective. Parameters ---------- space_type The deflation space type. size The size of the space to compute See Also -------- petsc.PCDeflationSetSpaceToCompute """ cdef PetscInt csize = asInt(size) cdef PetscPCDeflationSpaceType ctype = space_type CHKERR( PCDeflationSetSpaceToCompute(self.pc, space_type, csize) ) def setDeflationSpace(self, Mat W, transpose: bool) -> None: """Set the deflation space matrix or its (Hermitian) transpose. Logically collective. Parameters ---------- W The deflation matrix. transpose Enable to indicate that ``W`` is an explicit transpose of the deflation matrix. See Also -------- petsc.PCDeflationSetSpace """ cdef PetscBool ctranspose = asBool(transpose) CHKERR( PCDeflationSetSpace(self.pc, W.mat, ctranspose) ) def setDeflationProjectionNullSpaceMat(self, Mat mat) -> None: """Set the projection null space matrix. Collective. Parameters ---------- mat The projection null space matrix. See Also -------- petsc.PCDeflationSetProjectionNullSpaceMat """ CHKERR( PCDeflationSetProjectionNullSpaceMat(self.pc, mat.mat) ) def setDeflationCoarseMat(self, Mat mat) -> None: """Set the coarse problem matrix. Collective. Parameters ---------- mat The coarse problem matrix. See Also -------- petsc.PCDeflationSetCoarseMat """ CHKERR( PCDeflationSetCoarseMat(self.pc, mat.mat) ) def getDeflationCoarseKSP(self) -> KSP: """Return the coarse problem `KSP`. Not collective. See Also -------- petsc.PCDeflationGetCoarseKSP """ cdef KSP ksp = KSP() CHKERR( PCDeflationGetCoarseKSP(self.pc, &ksp.ksp) ) CHKERR( PetscINCREF(ksp.obj) ) return ksp def getDeflationPC(self) -> PC: """Return the additional preconditioner. See Also -------- petsc.PCDeflationGetPC """ cdef PC apc = PC() CHKERR( PCDeflationGetPC(self.pc, &apc.pc) ) CHKERR( PetscINCREF(apc.obj) ) return apc # -------------------------------------------------------------------- del PCType del PCSide del PCASMType del PCGASMType del PCMGType del PCMGCycleType del PCGAMGType del PCCompositeType del PCFieldSplitSchurPreType del PCFieldSplitSchurFactType del PCPatchConstructType del PCHPDDMCoarseCorrectionType del PCDeflationSpaceType del PCFailedReason # -------------------------------------------------------------------- ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/src/petsc4py/PETSc/PETSc.pyx0000644000175000017500000005026714567251135017341 0ustar00balaybalay# -------------------------------------------------------------------- cdef extern from * nogil: """ #include "lib-petsc/compat.h" #include "lib-petsc/custom.h" /* Silence Clang warnings in Cython-generated C code */ #if defined(__clang__) #pragma clang diagnostic ignored "-Wextra-semi-stmt" #pragma clang diagnostic ignored "-Wparentheses-equality" #pragma clang diagnostic ignored "-Wunreachable-code-fallthrough" #pragma clang diagnostic ignored "-Woverlength-strings" #pragma clang diagnostic ignored "-Wunreachable-code" #pragma clang diagnostic ignored "-Wundef" #elif defined(__GNUC__) || defined(__GNUG__) #pragma GCC diagnostic ignored "-Wstrict-aliasing" #pragma GCC diagnostic ignored "-Wtype-limits" #endif """ # -------------------------------------------------------------------- cdef extern from * nogil: ctypedef ssize_t Py_intptr_t ctypedef size_t Py_uintptr_t # -------------------------------------------------------------------- cdef inline object bytes2str(const char p[]): if p == NULL: return None cdef bytes s = p if isinstance(s, str): return s else: return s.decode() cdef inline object str2bytes(object s, const char *p[]): if s is None: p[0] = NULL return None if not isinstance(s, bytes): s = s.encode() p[0] = (s) return s cdef inline object S_(const char p[]): if p == NULL: return None cdef object s = p return s if isinstance(s, str) else s.decode() # -------------------------------------------------------------------- # Vile hack for raising a exception and not contaminating traceback cdef extern from *: void PyErr_SetObject(object, object) void *PyExc_RuntimeError # SETERR Support # -------------- cdef object PetscError = PyExc_RuntimeError cdef inline int SETERR(PetscErrorCode ierr) except -1 nogil: if (PetscError) != NULL: with gil: PyErr_SetObject(PetscError, ierr) else: with gil: PyErr_SetObject(PyExc_RuntimeError, ierr) return 0 cdef inline PetscErrorCode CHKERR(PetscErrorCode ierr) except PETSC_ERR_PYTHON nogil: if ierr == PETSC_SUCCESS: return ierr # no error if ierr == PETSC_ERR_PYTHON: return ierr # error in python code SETERR(ierr) return PETSC_ERR_PYTHON # SETERRMPI Support # ----------------- cdef extern from * nogil: enum: MPI_SUCCESS = 0 enum: MPI_MAX_ERROR_STRING int MPI_Error_string(int, char[], int*) PetscErrorCode PetscSNPrintf(char[], size_t, const char[], ...) PetscErrorCode PetscERROR(MPI_Comm, char[], PetscErrorCode, int, char[], char[]) cdef inline int SETERRMPI(int ierr) except -1 nogil: cdef char mpi_err_str[MPI_MAX_ERROR_STRING] cdef int result_len = sizeof(mpi_err_str) memset(mpi_err_str, 0, result_len) MPI_Error_string(ierr, mpi_err_str, &result_len); result_len cdef char error_str[MPI_MAX_ERROR_STRING+64] PetscSNPrintf(error_str, sizeof(error_str), b"MPI Error %s %d", mpi_err_str, ierr) PetscERROR(PETSC_COMM_SELF, "Unknown Python Function", PETSC_ERR_MPI, PETSC_ERROR_INITIAL, "%s", error_str) SETERR(PETSC_ERR_MPI) return ierr cdef inline PetscErrorCode CHKERRMPI(int ierr) except PETSC_ERR_PYTHON nogil: if ierr == MPI_SUCCESS: return PETSC_SUCCESS SETERRMPI(ierr) return PETSC_ERR_PYTHON # -------------------------------------------------------------------- # PETSc support # ------------- cdef extern from * nogil: ctypedef long PetscInt ctypedef double PetscReal ctypedef double PetscScalar cdef extern from "": object PyPetscScalar_FromPetscScalar(PetscScalar) PetscScalar PyPetscScalar_AsPetscScalar(object) except? -1.0 cdef extern from "": int PyPetscBuffer_FillInfo(Py_buffer*,void*,PetscInt,char,int,int) except -1 void PyPetscBuffer_Release(Py_buffer*) cdef inline object toBool(PetscBool value): return True if value else False cdef inline PetscBool asBool(object value) except? 0: return PETSC_TRUE if value else PETSC_FALSE cdef inline object toInt(PetscInt value): return value cdef inline PetscInt asInt(object value) except? -1: return value cdef inline object toReal(PetscReal value): return value cdef inline PetscReal asReal(object value) except? -1: return value cdef inline object toScalar(PetscScalar value): return PyPetscScalar_FromPetscScalar(value) cdef inline PetscScalar asScalar(object value) except? -1.0: return PyPetscScalar_AsPetscScalar(value) # -------------------------------------------------------------------- # NumPy support # ------------- include "arraynpy.pxi" import_array() IntType = PyArray_TypeObjectFromType(NPY_PETSC_INT) RealType = PyArray_TypeObjectFromType(NPY_PETSC_REAL) ScalarType = PyArray_TypeObjectFromType(NPY_PETSC_SCALAR) ComplexType = PyArray_TypeObjectFromType(NPY_PETSC_COMPLEX) include "dlpack.pxi" # -------------------------------------------------------------------- include "typing.pxi" include "petscdef.pxi" include "petscmem.pxi" include "petscopt.pxi" include "petscmpi.pxi" include "petscsys.pxi" include "petsclog.pxi" include "petscobj.pxi" include "petscvwr.pxi" include "petscrand.pxi" include "petscdevice.pxi" include "petsclayout.pxi" include "petscis.pxi" include "petscsf.pxi" include "petscvec.pxi" include "petscdt.pxi" include "petscfe.pxi" include "petscsct.pxi" include "petscsec.pxi" include "petscmat.pxi" include "petscmatpartitioning.pxi" include "petscpc.pxi" include "petscksp.pxi" include "petscsnes.pxi" include "petscts.pxi" include "petsctao.pxi" include "petscao.pxi" include "petscdm.pxi" include "petscds.pxi" include "petscdmda.pxi" include "petscdmplex.pxi" include "petscdmstag.pxi" include "petscdmcomposite.pxi" include "petscdmshell.pxi" include "petscdmlabel.pxi" include "petscdmswarm.pxi" include "petscpartitioner.pxi" include "petscspace.pxi" include "petscdmutils.pxi" include "petscpyappctx.pxi" # -------------------------------------------------------------------- __doc__ = """ Portable, Extensible Toolkit for Scientific Computation. """ include "Const.pyx" include "Error.pyx" include "Options.pyx" include "Sys.pyx" include "Log.pyx" include "Comm.pyx" include "Object.pyx" include "Viewer.pyx" include "Random.pyx" include "Device.pyx" include "IS.pyx" include "SF.pyx" include "Vec.pyx" include "DT.pyx" include "FE.pyx" include "Scatter.pyx" include "Section.pyx" include "Mat.pyx" include "MatPartitioning.pyx" include "PC.pyx" include "KSP.pyx" include "SNES.pyx" include "TS.pyx" include "TAO.pyx" include "AO.pyx" include "DM.pyx" include "DS.pyx" include "DMDA.pyx" include "DMPlex.pyx" include "DMStag.pyx" include "DMComposite.pyx" include "DMShell.pyx" include "DMLabel.pyx" include "DMSwarm.pyx" include "Partitioner.pyx" include "Space.pyx" include "DMUtils.pyx" # -------------------------------------------------------------------- include "CAPI.pyx" include "libpetsc4py.pyx" # -------------------------------------------------------------------- cdef extern from "Python.h": int Py_IsInitialized() nogil int PyList_Insert(object,Py_ssize_t,object) except -1 int PyList_Append(object,object) except -1 cdef extern from * nogil: PetscErrorCode PetscTBEH(MPI_Comm,int,char*,char*,int,PetscErrorType,char*,void*) cdef object tracebacklist = [] cdef PetscErrorCode traceback( MPI_Comm comm, int line, const char *cfunc, const char *cfile, PetscErrorCode n, PetscErrorType p, const char *mess, void *ctx, ) except (-1) with gil: cdef PetscLogDouble mem=0 cdef PetscLogDouble rss=0 cdef const char *text=NULL global tracebacklist cdef object tbl = tracebacklist cdef object fun = bytes2str(cfunc) cdef object fnm = bytes2str(cfile) cdef object m = "%s() at %s:%d" % (fun, fnm, line) PyList_Insert(tbl, 0, m) if p != PETSC_ERROR_INITIAL: return n # del tbl[1:] # clear any previous stuff if n == PETSC_ERR_MEM: # special case PetscMallocGetCurrentUsage(&mem) PetscMemoryGetCurrentUsage(&rss) m = ( "Out of memory. " "Allocated: %d, " "Used by process: %d" ) % (mem, rss) PyList_Append(tbl, m) else: PetscErrorMessage(n, &text, NULL) if text != NULL: PyList_Append(tbl, bytes2str(text)) if mess != NULL: PyList_Append(tbl, bytes2str(mess)) comm # unused ctx # unused return n cdef PetscErrorCode PetscPythonErrorHandler( MPI_Comm comm, int line, const char *cfunc, const char *cfile, PetscErrorCode n, PetscErrorType p, const char *mess, void *ctx, ) except (-1) nogil: global tracebacklist if (tracebacklist) != NULL and Py_IsInitialized(): return traceback(comm, line, cfunc, cfile, n, p, mess, ctx) else: return PetscTBEH(comm, line, cfunc, cfile, n, p, mess, ctx) # -------------------------------------------------------------------- cdef extern from "" nogil: void* malloc(size_t) void* realloc (void*,size_t) void free(void*) cdef extern from "" nogil: ctypedef struct va_list: pass cdef extern from "" nogil: void* memset(void*,int,size_t) void* memcpy(void*,void*,size_t) char* strdup(char*) cdef extern from "" nogil: ctypedef struct FILE FILE *stderr int fprintf(FILE *, char *, ...) cdef extern from "Python.h": int Py_AtExit(void (*)() noexcept nogil) void PySys_WriteStderr(char*,...) cdef extern from * nogil: """ #include "lib-petsc/initpkg.h" """ PetscErrorCode PetscInitializePackageAll() cdef int PyPetsc_Argc = 0 cdef char** PyPetsc_Argv = NULL cdef int getinitargs(object args, int *argc, char **argv[]) except -1: # allocate command line arguments cdef int i, c = 0 cdef char **v = NULL if args is None: args = [] args = [str(a).encode() for a in args] args = [a for a in args if a] c = len(args) v = malloc((c+1)*sizeof(char*)) if v == NULL: raise MemoryError memset(v, 0, (c+1)*sizeof(char*)) try: for 0 <= i < c: v[i] = strdup(args[i]) if v[i] == NULL: raise MemoryError except: delinitargs(&c, &v); raise argc[0] = c; argv[0] = v return 0 cdef void delinitargs(int *argc, char **argv[]) noexcept nogil: # dallocate command line arguments cdef int i, c = argc[0] cdef char** v = argv[0] argc[0] = 0; argv[0] = NULL; if c >= 0 and v != NULL: for 0 <= i < c: if v[i] != NULL: free(v[i]) free(v) cdef void finalize() noexcept nogil: cdef int ierr = 0 # deallocate command line arguments global PyPetsc_Argc, PyPetsc_Argv global PetscVFPrintf, prevfprintf delinitargs(&PyPetsc_Argc, &PyPetsc_Argv) # manage PETSc finalization if not (PetscInitializeCalled): return if (PetscFinalizeCalled): return # stop stdout/stderr redirect if (prevfprintf != NULL): PetscVFPrintf = prevfprintf prevfprintf = NULL # deinstall Python error handler ierr = PetscPopErrorHandler() if ierr != 0: fprintf(stderr, "PetscPopErrorHandler() failed " "[error code: %d]\n", ierr) # finalize PETSc ierr = PetscFinalize() if ierr != 0: fprintf(stderr, "PetscFinalize() failed " "[error code: %d]\n", ierr) # and we are done, see you later !! # -------------------------------------------------------------------- cdef extern from *: PetscErrorCode (*PetscVFPrintf)(FILE*,const char*,va_list) except PETSC_ERR_PYTHON nogil cdef PetscErrorCode (*prevfprintf)(FILE*,const char*,va_list) except PETSC_ERR_PYTHON nogil prevfprintf = NULL cdef PetscErrorCode PetscVFPrintf_PythonStdStream( FILE *fd, const char fmt[], va_list ap, ) except PETSC_ERR_PYTHON with gil: import sys cdef char cstring[8192] cdef size_t stringlen = sizeof(cstring) cdef size_t final_pos if (fd == PETSC_STDOUT) and not (sys.stdout == sys.__stdout__): CHKERR( PetscVSNPrintf(&cstring[0], stringlen, fmt, &final_pos,ap)) if final_pos > 0 and cstring[final_pos-1] == '\x00': final_pos -= 1 ustring = cstring[:final_pos].decode('UTF-8') sys.stdout.write(ustring) elif (fd == PETSC_STDERR) and not (sys.stderr == sys.__stderr__): CHKERR( PetscVSNPrintf(&cstring[0], stringlen, fmt, &final_pos,ap)) if final_pos > 0 and cstring[final_pos-1] == '\x00': final_pos -= 1 ustring = cstring[:final_pos].decode('UTF-8') sys.stderr.write(ustring) else: CHKERR( PetscVFPrintfDefault(fd, fmt, ap) ) return PETSC_SUCCESS cdef int _push_vfprintf( PetscErrorCode (*vfprintf)(FILE*, const char*, va_list) except PETSC_ERR_PYTHON nogil, ) except -1: global PetscVFPrintf, prevfprintf assert prevfprintf == NULL prevfprintf = PetscVFPrintf PetscVFPrintf = vfprintf cdef int _pop_vfprintf() except -1: global PetscVFPrintf, prevfprintf assert prevfprintf != NULL PetscVFPrintf = prevfprintf prevfprintf == NULL cdef int initialize(object args, object comm) except -1: if (PetscInitializeCalled): return 1 if (PetscFinalizeCalled): return 0 # allocate command line arguments global PyPetsc_Argc, PyPetsc_Argv getinitargs(args, &PyPetsc_Argc, &PyPetsc_Argv) # communicator global PETSC_COMM_WORLD PETSC_COMM_WORLD = def_Comm(comm, PETSC_COMM_WORLD) # initialize PETSc CHKERR( PetscInitialize(&PyPetsc_Argc, &PyPetsc_Argv, NULL, NULL) ) # install Python error handler cdef PetscErrorHandlerFunction handler = NULL handler = PetscPythonErrorHandler CHKERR( PetscPushErrorHandler(handler, NULL) ) # redirect PETSc std streams import sys if (sys.stdout != sys.__stdout__) or (sys.stderr != sys.__stderr__): _push_vfprintf(&PetscVFPrintf_PythonStdStream) # register finalization function if Py_AtExit(finalize) < 0: PySys_WriteStderr(b"warning: could not register %s with Py_AtExit()", b"PetscFinalize()") return 1 # and we are done, enjoy !! cdef extern from * nogil: PetscClassId PETSC_OBJECT_CLASSID "PETSC_OBJECT_CLASSID" PetscClassId PETSC_VIEWER_CLASSID "PETSC_VIEWER_CLASSID" PetscClassId PETSC_RANDOM_CLASSID "PETSC_RANDOM_CLASSID" PetscClassId PETSC_IS_CLASSID "IS_CLASSID" PetscClassId PETSC_LGMAP_CLASSID "IS_LTOGM_CLASSID" PetscClassId PETSC_SF_CLASSID "PETSCSF_CLASSID" PetscClassId PETSC_VEC_CLASSID "VEC_CLASSID" PetscClassId PETSC_SECTION_CLASSID "PETSC_SECTION_CLASSID" PetscClassId PETSC_MAT_CLASSID "MAT_CLASSID" PetscClassId PETSC_MAT_PARTITIONING_CLASSID "MAT_PARTITIONING_CLASSID" PetscClassId PETSC_NULLSPACE_CLASSID "MAT_NULLSPACE_CLASSID" PetscClassId PETSC_PC_CLASSID "PC_CLASSID" PetscClassId PETSC_KSP_CLASSID "KSP_CLASSID" PetscClassId PETSC_SNES_CLASSID "SNES_CLASSID" PetscClassId PETSC_TS_CLASSID "TS_CLASSID" PetscClassId PETSC_TAO_CLASSID "TAO_CLASSID" PetscClassId PETSC_AO_CLASSID "AO_CLASSID" PetscClassId PETSC_DM_CLASSID "DM_CLASSID" PetscClassId PETSC_DS_CLASSID "PETSCDS_CLASSID" PetscClassId PETSC_PARTITIONER_CLASSID "PETSCPARTITIONER_CLASSID" PetscClassId PETSC_FE_CLASSID "PETSCFE_CLASSID" PetscClassId PETSC_DMLABEL_CLASSID "DMLABEL_CLASSID" PetscClassId PETSC_SPACE_CLASSID "PETSCSPACE_CLASSID" PetscClassId PETSC_DUALSPACE_CLASSID "PETSCDUALSPACE_CLASSID" PetscClassId PETSC_DEVICE_CLASSID "PETSC_DEVICE_CLASSID" PetscClassId PETSC_DEVICE_CONTEXT_CLASSID "PETSC_DEVICE_CONTEXT_CLASSID" cdef bint registercalled = 0 cdef const char *citation = b"""\ @Article{Dalcin2011, Author = {Lisandro D. Dalcin and Rodrigo R. Paz and Pablo A. Kler and Alejandro Cosimo}, Title = {Parallel distributed computing using {P}ython}, Journal = {Advances in Water Resources}, Note = {New Computational Methods and Software Tools}, Volume = {34}, Number = {9}, Pages = {1124--1139}, Year = {2011}, DOI = {https://doi.org/10.1016/j.advwatres.2011.04.013} } """ cdef int register() except -1: global registercalled if registercalled: return 0 registercalled = True # register citation CHKERR( PetscCitationsRegister(citation, NULL) ) # make sure all PETSc packages are initialized CHKERR( PetscInitializePackageAll() ) # register custom implementations CHKERR( PetscPythonRegisterAll() ) # register Python types PyPetscType_Register(PETSC_OBJECT_CLASSID, Object) PyPetscType_Register(PETSC_VIEWER_CLASSID, Viewer) PyPetscType_Register(PETSC_RANDOM_CLASSID, Random) PyPetscType_Register(PETSC_DEVICE_CLASSID, Device) PyPetscType_Register(PETSC_DEVICE_CONTEXT_CLASSID, DeviceContext) PyPetscType_Register(PETSC_IS_CLASSID, IS) PyPetscType_Register(PETSC_LGMAP_CLASSID, LGMap) PyPetscType_Register(PETSC_SF_CLASSID, SF) PyPetscType_Register(PETSC_VEC_CLASSID, Vec) PyPetscType_Register(PETSC_SECTION_CLASSID, Section) PyPetscType_Register(PETSC_MAT_CLASSID, Mat) PyPetscType_Register(PETSC_MAT_PARTITIONING_CLASSID, MatPartitioning) PyPetscType_Register(PETSC_NULLSPACE_CLASSID, NullSpace) PyPetscType_Register(PETSC_PC_CLASSID, PC) PyPetscType_Register(PETSC_KSP_CLASSID, KSP) PyPetscType_Register(PETSC_SNES_CLASSID, SNES) PyPetscType_Register(PETSC_TS_CLASSID, TS) PyPetscType_Register(PETSC_TAO_CLASSID, TAO) PyPetscType_Register(PETSC_PARTITIONER_CLASSID, Partitioner) PyPetscType_Register(PETSC_AO_CLASSID, AO) PyPetscType_Register(PETSC_DM_CLASSID, DM) PyPetscType_Register(PETSC_DS_CLASSID, DS) PyPetscType_Register(PETSC_FE_CLASSID, FE) PyPetscType_Register(PETSC_DMLABEL_CLASSID, DMLabel) PyPetscType_Register(PETSC_SPACE_CLASSID, Space) PyPetscType_Register(PETSC_DUALSPACE_CLASSID, DualSpace) return 0 # and we are done, enjoy !! # -------------------------------------------------------------------- def _initialize(args=None, comm=None): import atexit global tracebacklist Error._traceback_ = tracebacklist global PetscError PetscError = Error # cdef int ready = initialize(args, comm) if ready: register() # global __COMM_SELF__, __COMM_WORLD__ __COMM_SELF__.comm = PETSC_COMM_SELF __COMM_WORLD__.comm = PETSC_COMM_WORLD # global PETSC_COMM_DEFAULT PETSC_COMM_DEFAULT = PETSC_COMM_WORLD # Register finalizer atexit.register(_pre_finalize) def _pre_finalize(): # Called while the Python interpreter is still running garbage_cleanup() def _finalize(): finalize() # global __COMM_SELF__ __COMM_SELF__.comm = MPI_COMM_NULL global __COMM_WORLD__ __COMM_WORLD__.comm = MPI_COMM_NULL # global PETSC_COMM_DEFAULT PETSC_COMM_DEFAULT = MPI_COMM_NULL # global type_registry type_registry.clear() global stage_registry stage_registry.clear() global class_registry class_registry.clear() global event_registry event_registry.clear() global citations_registry citations_registry.clear() def _push_python_vfprintf(): _push_vfprintf(&PetscVFPrintf_PythonStdStream) def _pop_python_vfprintf(): _pop_vfprintf() def _stdout_is_stderr(): global PETSC_STDOUT, PETSC_STDERR return PETSC_STDOUT == PETSC_STDERR # -------------------------------------------------------------------- ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/src/petsc4py/PETSc/Partitioner.pyx0000644000175000017500000001203014567251135020705 0ustar00balaybalay# -------------------------------------------------------------------- class PartitionerType(object): PARMETIS = S_(PETSCPARTITIONERPARMETIS) PTSCOTCH = S_(PETSCPARTITIONERPTSCOTCH) CHACO = S_(PETSCPARTITIONERCHACO) SIMPLE = S_(PETSCPARTITIONERSIMPLE) SHELL = S_(PETSCPARTITIONERSHELL) GATHER = S_(PETSCPARTITIONERGATHER) MATPARTITIONING = S_(PETSCPARTITIONERMATPARTITIONING) # -------------------------------------------------------------------- cdef class Partitioner(Object): """A graph partitioner.""" Type = PartitionerType def __cinit__(self): self.obj = &self.part self.part = NULL def view(self, Viewer viewer=None) -> None: """View the partitioner. Collective. Parameters ---------- viewer A `Viewer` to display the graph. See Also -------- petsc.PetscPartitionerView """ cdef PetscViewer vwr = NULL if viewer is not None: vwr = viewer.vwr CHKERR( PetscPartitionerView(self.part, vwr) ) def destroy(self) -> Self: """Destroy the partitioner object. Collective. See Also -------- petsc.PetscPartitionerDestroy """ CHKERR( PetscPartitionerDestroy(&self.part) ) return self def create(self, comm: Comm | None = None) -> Self: """Create an empty partitioner object. Collective. The type can be set with `setType`. Parameters ---------- comm MPI communicator, defaults to `Sys.getDefaultComm`. See Also -------- setType, petsc.PetscPartitionerCreate """ cdef MPI_Comm ccomm = def_Comm(comm, PETSC_COMM_DEFAULT) cdef PetscPartitioner newpart = NULL CHKERR( PetscPartitionerCreate(ccomm, &newpart) ) CHKERR( PetscCLEAR(self.obj) ); self.part = newpart return self def setType(self, part_type: Type | str) -> None: """Build a particular type of the partitioner. Collective. Parameters ---------- part_type The kind of partitioner. See Also -------- getType, petsc.PetscPartitionerSetType """ cdef PetscPartitionerType cval = NULL part_type = str2bytes(part_type, &cval) CHKERR( PetscPartitionerSetType(self.part, cval) ) def getType(self) -> Type: """Return the partitioner type. Not collective. See Also -------- setType, petsc.PetscPartitionerGetType """ cdef PetscPartitionerType cval = NULL CHKERR( PetscPartitionerGetType(self.part, &cval) ) return bytes2str(cval) def setFromOptions(self) -> None: """Set parameters in the partitioner from the options database. Collective. See Also -------- petsc_options, petsc.PetscPartitionerSetFromOptions """ CHKERR( PetscPartitionerSetFromOptions(self.part) ) def setUp(self) -> None: """Construct data structures for the partitioner. Collective. See Also -------- petsc.PetscPartitionerSetUp """ CHKERR( PetscPartitionerSetUp(self.part) ) def reset(self) -> None: """Reset data structures of the partitioner. Collective. See Also -------- petsc.PetscPartitionerReset """ CHKERR( PetscPartitionerReset(self.part) ) def setShellPartition( self, numProcs: int, sizes: Sequence[int] | None = None, points: Sequence[int] | None = None, ) -> None: """Set a custom partition for a mesh. Collective. Parameters ---------- sizes The number of points in each partition. points A permutation of the points that groups those assigned to each partition in order (i.e., partition 0 first, partition 1 next, etc.). See Also -------- petsc.PetscPartitionerShellSetPartition """ cdef PetscInt cnumProcs = asInt(numProcs) cdef PetscInt *csizes = NULL cdef PetscInt *cpoints = NULL cdef PetscInt nsize = 0 if sizes is not None: sizes = iarray_i(sizes, &nsize, &csizes) if nsize != cnumProcs: raise ValueError("sizes array should have %d entries (has %d)" % numProcs, toInt(nsize)) if points is None: raise ValueError("Must provide both sizes and points arrays") if points is not None: points = iarray_i(points, NULL, &cpoints) CHKERR( PetscPartitionerShellSetPartition(self.part, cnumProcs, csizes, cpoints) ) # -------------------------------------------------------------------- del PartitionerType # -------------------------------------------------------------------- ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/src/petsc4py/PETSc/Random.pyx0000644000175000017500000001404014567251135017630 0ustar00balaybalay# -------------------------------------------------------------------- class RandomType(object): """The random number generator type.""" RAND = S_(PETSCRAND) RAND48 = S_(PETSCRAND48) SPRNG = S_(PETSCSPRNG) RANDER48 = S_(PETSCRANDER48) RANDOM123 = S_(PETSCRANDOM123) # -------------------------------------------------------------------- cdef class Random(Object): """The random number generator object. See Also -------- petsc.PetscRandom """ Type = RandomType def __cinit__(self) -> None: self.obj = &self.rnd self.rnd = NULL def __call__(self) -> Scalar: """Generate a scalar random number. Not collective. See Also -------- petsc.PetscRandomGetValue """ return self.getValue() def view(self, Viewer viewer=None) -> None: """View a random number generator object. Collective. Parameters ---------- viewer A `Viewer` instance or `None` for the default viewer. See Also -------- petsc.PetscRandomView """ assert self.obj != NULL cdef PetscViewer vwr = NULL if viewer is not None: vwr = viewer.vwr CHKERR( PetscRandomView(self.rnd, vwr) ) def destroy(self) -> Self: """Destroy the random number generator object. Collective. See Also -------- petsc.PetscRandomDestroy """ CHKERR( PetscRandomDestroy(&self.rnd) ) return self def create(self, comm: Comm | None = None) -> Self: """Create a random number generator object. Collective. Parameters ---------- comm MPI communicator, defaults to `Sys.getDefaultComm`. See Also -------- Sys.getDefaultComm, petsc.PetscRandomCreate """ cdef MPI_Comm ccomm = def_Comm(comm, PETSC_COMM_DEFAULT) CHKERR( PetscRandomCreate(ccomm, &self.rnd) ) return self def setType(self, rnd_type: Random.Type | str) -> None: """Set the type of the random number generator object. Collective. Parameters ---------- rnd_type The type of the generator. See Also -------- getType, petsc.PetscRandomSetType """ cdef PetscRandomType cval = NULL rnd_type = str2bytes(rnd_type, &cval) CHKERR( PetscRandomSetType(self.rnd, cval) ) def getType(self) -> str: """Return the type of the random number generator object. Not collective. See Also -------- setType, petsc.PetscRandomGetType """ cdef PetscRandomType cval = NULL CHKERR( PetscRandomGetType(self.rnd, &cval) ) return bytes2str(cval) def setFromOptions(self) -> None: """Configure the random number generator from the options database. Collective. See Also -------- petsc_options, petsc.PetscRandomSetFromOptions """ CHKERR( PetscRandomSetFromOptions(self.rnd) ) def getValue(self) -> Scalar: """Generate a scalar random number. Not collective. See Also -------- petsc.PetscRandomGetValue """ cdef PetscScalar sval = 0 CHKERR( PetscRandomGetValue(self.rnd, &sval) ) return toScalar(sval) def getValueReal(self) -> float: """Generate a real random number. Not collective. See Also -------- petsc.PetscRandomGetValueReal """ cdef PetscReal rval = 0 CHKERR( PetscRandomGetValueReal(self.rnd, &rval) ) return toReal(rval) def getSeed(self) -> int: """Return the random number generator seed. Not collective. See Also -------- setSeed, petsc.PetscRandomGetSeed """ cdef unsigned long seed = 0 CHKERR( PetscRandomGetSeed(self.rnd, &seed) ) return seed def setSeed(self, seed: int | None = None) -> None: """Set the seed of random number generator. Not collective. Parameters ---------- seed The value for the seed. If `None`, it only seeds the generator. See Also -------- getSeed, petsc.PetscRandomSetSeed, petsc.PetscRandomSeed """ if seed is not None: CHKERR( PetscRandomSetSeed(self.rnd, seed) ) CHKERR( PetscRandomSeed(self.rnd) ) def getInterval(self) -> tuple[Scalar, Scalar]: """Return the interval containing the random numbers generated. Not collective. See Also -------- setInterval, petsc.PetscRandomGetInterval """ cdef PetscScalar sval1 = 0 cdef PetscScalar sval2 = 1 CHKERR( PetscRandomGetInterval(self.rnd, &sval1, &sval2) ) return (toScalar(sval1), toScalar(sval2)) def setInterval(self, interval: tuple[Scalar, Scalar]) -> None: """Set the interval of the random number generator. Not collective. See Also -------- getInterval, petsc.PetscRandomSetInterval """ cdef PetscScalar sval1 = 0 cdef PetscScalar sval2 = 1 low, high = interval sval1 = asScalar(low) sval2 = asScalar(high) CHKERR( PetscRandomSetInterval(self.rnd, sval1, sval2) ) # property seed: """The seed of the random number generator.""" def __get__(self) -> int: return self.getSeed() def __set__(self, value: int | None) -> None: self.setSeed(value) property interval: """The interval of the generated random numbers.""" def __get__(self) -> tuple[Scalar, Scalar]: return self.getInterval() def __set__(self, value: tuple[Scalar, Scalar]): self.setInterval(value) # -------------------------------------------------------------------- del RandomType # -------------------------------------------------------------------- ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/src/petsc4py/PETSc/SF.pyx0000644000175000017500000005073614567251135016734 0ustar00balaybalay# -------------------------------------------------------------------- class SFType(object): BASIC = S_(PETSCSFBASIC) NEIGHBOR = S_(PETSCSFNEIGHBOR) ALLGATHERV = S_(PETSCSFALLGATHERV) ALLGATHER = S_(PETSCSFALLGATHER) GATHERV = S_(PETSCSFGATHERV) GATHER = S_(PETSCSFGATHER) ALLTOALL = S_(PETSCSFALLTOALL) WINDOW = S_(PETSCSFWINDOW) # -------------------------------------------------------------------- cdef class SF(Object): """Star Forest object for communication. SF is used for setting up and managing the communication of certain entries of arrays and `Vec` between MPI processes. """ Type = SFType def __cinit__(self): self.obj = &self.sf self.sf = NULL def __dealloc__(self): CHKERR( PetscSFDestroy(&self.sf) ) self.sf = NULL def view(self, Viewer viewer=None) -> None: """View a star forest. Collective. Parameters ---------- viewer A `Viewer` to display the graph. See Also -------- petsc.PetscSFView """ cdef PetscViewer vwr = NULL if viewer is not None: vwr = viewer.vwr CHKERR( PetscSFView(self.sf, vwr) ) def destroy(self) -> Self: """Destroy the star forest. Collective. See Also -------- petsc.PetscSFDestroy """ CHKERR( PetscSFDestroy(&self.sf) ) return self def create(self, comm: Comm | None = None) -> Self: """Create a star forest communication context. Collective. Parameters ---------- comm MPI communicator, defaults to `Sys.getDefaultComm`. See Also -------- petsc.PetscSFCreate """ cdef MPI_Comm ccomm = def_Comm(comm, PETSC_COMM_DEFAULT) cdef PetscSF newsf = NULL CHKERR( PetscSFCreate(ccomm, &newsf) ) CHKERR( PetscCLEAR(self.obj) ); self.sf = newsf return self def setType(self, sf_type: Type | str) -> None: """Set the type of the star forest. Collective. Parameters ---------- sf_type The star forest type. See Also -------- petsc.PetscSFSetType """ cdef PetscSFType cval = NULL sf_type = str2bytes(sf_type, &cval) CHKERR( PetscSFSetType(self.sf, cval) ) def getType(self) -> str: """Return the type name of the star forest. Collective. See Also -------- petsc.PetscSFGetType """ cdef PetscSFType cval = NULL CHKERR( PetscSFGetType(self.sf, &cval) ) return bytes2str(cval) def setFromOptions(self) -> None: """Set options using the options database. Logically collective. See Also -------- petsc_options, petsc.PetscSFSetFromOptions """ CHKERR( PetscSFSetFromOptions(self.sf) ) def setUp(self) -> None: """Set up communication structures. Collective. See Also -------- petsc.PetscSFSetUp """ CHKERR( PetscSFSetUp(self.sf) ) def reset(self) -> None: """Reset a star forest so that different sizes or neighbors can be used. Collective. See Also -------- petsc.PetscSFReset """ CHKERR( PetscSFReset(self.sf) ) # def getGraph(self) -> tuple[int, ArrayInt, ArrayInt]: """Return star forest graph. Not collective. The number of leaves can be determined from the size of ``ilocal``. Returns ------- nroots : int Number of root vertices on the current process (these are possible targets for other process to attach leaves). ilocal : ArrayInt Locations of leaves in leafdata buffers. iremote : ArrayInt Remote locations of root vertices for each leaf on the current process. See Also -------- petsc.PetscSFGetGraph """ cdef PetscInt nroots = 0, nleaves = 0 cdef const PetscInt *ilocal = NULL cdef const PetscSFNode *iremote = NULL CHKERR( PetscSFGetGraph(self.sf, &nroots, &nleaves, &ilocal, &iremote) ) if ilocal == NULL: local = arange(0, nleaves, 1) else: local = array_i(nleaves, ilocal) remote = array_i(nleaves*2, iremote) remote = remote.reshape(nleaves, 2) return toInt(nroots), local, remote def setGraph(self, nroots: int, local: Sequence[int], remote: Sequence[int]) -> None: """Set star forest graph. Collective. The number of leaves argument can be determined from the size of ``local`` and/or ``remote``. Parameters ---------- nroots Number of root vertices on the current process (these are possible targets for other process to attach leaves). local Locations of leaves in leafdata buffers, pass `None` for contiguous storage. remote Remote locations of root vertices for each leaf on the current process. Should be ``2*nleaves`` long as (rank, index) pairs. See Also -------- petsc.PetscSFSetGraph """ cdef PetscInt cnroots = asInt(nroots) cdef PetscInt nleaves = 0 cdef PetscInt nremote = 0 cdef PetscInt *ilocal = NULL cdef PetscSFNode* iremote = NULL remote = iarray_i(remote, &nremote, &iremote) if local is not None: local = iarray_i(local, &nleaves, &ilocal) assert 2*nleaves == nremote else: assert nremote % 2 == 0 nleaves = nremote // 2 CHKERR( PetscSFSetGraph(self.sf, cnroots, nleaves, ilocal, PETSC_COPY_VALUES, iremote, PETSC_COPY_VALUES) ) def setRankOrder(self, flag: bool) -> None: """Sort multi-points for gathers and scatters by rank order. Logically collective. Parameters ---------- flag `True` to sort, `False` to skip sorting. See Also -------- petsc.PetscSFSetRankOrder """ cdef PetscBool bval = asBool(flag) CHKERR( PetscSFSetRankOrder(self.sf, bval) ) def getMulti(self) -> SF: """Return the inner SF implementing gathers and scatters. Collective. See Also -------- petsc.PetscSFGetMultiSF """ cdef SF sf = SF() CHKERR( PetscSFGetMultiSF(self.sf, &sf.sf) ) CHKERR( PetscINCREF(sf.obj) ) return sf def createInverse(self) -> SF: """Create the inverse map. Collective. Create the inverse map given a PetscSF in which all vertices have degree 1. See Also -------- petsc.PetscSFCreateInverseSF """ cdef SF sf = SF() CHKERR( PetscSFCreateInverseSF(self.sf, &sf.sf) ) return sf def computeDegree(self) -> ArrayInt: """Compute and return the degree of each root vertex. Collective. See Also -------- petsc.PetscSFComputeDegreeBegin, petsc.PetscSFComputeDegreeEnd """ cdef const PetscInt *cdegree = NULL cdef PetscInt nroots CHKERR( PetscSFComputeDegreeBegin(self.sf, &cdegree) ) CHKERR( PetscSFComputeDegreeEnd(self.sf, &cdegree) ) CHKERR( PetscSFGetGraph(self.sf, &nroots, NULL, NULL, NULL) ) degree = array_i(nroots, cdegree) return degree def createEmbeddedRootSF(self, selected: Sequence[int]) -> SF: """Remove edges from all but the selected roots. Collective. Does not remap indices. Parameters ---------- selected Indices of the selected roots on this process. See Also -------- petsc.PetscSFCreateEmbeddedRootSF """ cdef PetscInt nroots = asInt(len(selected)) cdef PetscInt *cselected = NULL selected = iarray_i(selected, &nroots, &cselected) cdef SF sf = SF() CHKERR( PetscSFCreateEmbeddedRootSF(self.sf, nroots, cselected, &sf.sf) ) return sf def createEmbeddedLeafSF(self, selected: Sequence[int]) -> SF: """Remove edges from all but the selected leaves. Collective. Does not remap indices. Parameters ---------- selected Indices of the selected roots on this process. See Also -------- petsc.PetscSFCreateEmbeddedLeafSF """ cdef PetscInt nleaves = asInt(len(selected)) cdef PetscInt *cselected = NULL selected = iarray_i(selected, &nleaves, &cselected) cdef SF sf = SF() CHKERR( PetscSFCreateEmbeddedLeafSF(self.sf, nleaves, cselected, &sf.sf) ) return sf def createSectionSF(self, Section rootSection, remoteOffsets: Sequence[int] | None, Section leafSection) -> SF: """Create an expanded `SF` of DOFs. Collective. Assumes the input `SF` relates points. Parameters ---------- rootSection Data layout of remote points for outgoing data (this is usually the serial section). remoteOffsets Offsets for point data on remote processes (these are offsets from the root section), or `None`. leafSection Data layout of local points for incoming data (this is the distributed section). See Also -------- petsc.PetscSFCreateSectionSF """ cdef SF sectionSF = SF() cdef PetscInt noffsets = 0 cdef PetscInt *cremoteOffsets = NULL if remoteOffsets is not None: remoteOffsets = iarray_i(remoteOffsets, &noffsets, &cremoteOffsets) CHKERR( PetscSFCreateSectionSF(self.sf, rootSection.sec, cremoteOffsets, leafSection.sec, §ionSF.sf) ) return sectionSF def distributeSection(self, Section rootSection, Section leafSection=None) -> tuple[ArrayInt, Section]: """Create a new, reorganized `Section`. Collective. Moves from the root to the leaves of the `SF`. Parameters ---------- rootSection Section defined on root space. leafSection Section defined on the leaf space. See Also -------- petsc.PetscSFDistributeSection """ cdef PetscInt lpStart cdef PetscInt lpEnd cdef PetscInt *cremoteOffsets = NULL cdef ndarray remoteOffsets cdef MPI_Comm ccomm = def_Comm(self.comm, PETSC_COMM_DEFAULT) if leafSection is None: leafSection = Section() if leafSection.sec == NULL: CHKERR( PetscSectionCreate(ccomm, &leafSection.sec) ) CHKERR( PetscSFDistributeSection(self.sf, rootSection.sec, &cremoteOffsets, leafSection.sec) ) CHKERR( PetscSectionGetChart(leafSection.sec, &lpStart, &lpEnd) ) remoteOffsets = array_i(lpEnd-lpStart, cremoteOffsets) CHKERR( PetscFree(cremoteOffsets) ) return (remoteOffsets, leafSection) def compose(self, SF sf) -> SF: """Compose a new `SF`. Collective. Puts the ``sf`` under this object in a top (roots) down (leaves) view. Parameters ---------- sf `SF` to put under this object. See Also -------- petsc.PetscSFCompose """ cdef SF csf = SF() CHKERR( PetscSFCompose(self.sf, sf.sf, &csf.sf)) return csf def bcastBegin(self, unit: Datatype, ndarray rootdata, ndarray leafdata, op: Op) -> None: """Begin pointwise broadcast. Collective. Root values are reduced to leaf values. This call has to be concluded with a call to `bcastEnd`. Parameters ---------- unit MPI datatype. rootdata Buffer to broadcast. leafdata Buffer to be reduced with values from each leaf's respective root. op MPI reduction operation. See Also -------- bcastEnd, petsc.PetscSFBcastBegin """ cdef MPI_Datatype dtype = mpi4py_Datatype_Get(unit) cdef MPI_Op cop = mpi4py_Op_Get(op) CHKERR( PetscSFBcastBegin(self.sf, dtype, PyArray_DATA(rootdata), PyArray_DATA(leafdata), cop) ) def bcastEnd(self, unit: Datatype, ndarray rootdata, ndarray leafdata, op: Op) -> None: """End a broadcast & reduce operation started with `bcastBegin`. Collective. Parameters ---------- unit MPI datatype. rootdata Buffer to broadcast. leafdata Buffer to be reduced with values from each leaf's respective root. op MPI reduction operation. See Also -------- bcastBegin, petsc.PetscSFBcastEnd """ cdef MPI_Datatype dtype = mpi4py_Datatype_Get(unit) cdef MPI_Op cop = mpi4py_Op_Get(op) CHKERR( PetscSFBcastEnd(self.sf, dtype, PyArray_DATA(rootdata), PyArray_DATA(leafdata), cop) ) def reduceBegin(self, unit: Datatype, ndarray leafdata, ndarray rootdata, op: Op) -> None: """Begin reduction of leafdata into rootdata. Collective. This call has to be completed with call to `reduceEnd`. Parameters ---------- unit MPI datatype. leafdata Values to reduce. rootdata Result of reduction of values from all leaves of each root. op MPI reduction operation. See Also -------- reduceEnd, petsc.PetscSFReduceBegin """ cdef MPI_Datatype dtype = mpi4py_Datatype_Get(unit) cdef MPI_Op cop = mpi4py_Op_Get(op) CHKERR( PetscSFReduceBegin(self.sf, dtype, PyArray_DATA(leafdata), PyArray_DATA(rootdata), cop) ) def reduceEnd(self, unit: Datatype, ndarray leafdata, ndarray rootdata, op: Op) -> None: """End a reduction operation started with `reduceBegin`. Collective. Parameters ---------- unit MPI datatype. leafdata Values to reduce. rootdata Result of reduction of values from all leaves of each root. op MPI reduction operation. See Also -------- reduceBegin, petsc.PetscSFReduceEnd """ cdef MPI_Datatype dtype = mpi4py_Datatype_Get(unit) cdef MPI_Op cop = mpi4py_Op_Get(op) CHKERR( PetscSFReduceEnd(self.sf, dtype, PyArray_DATA(leafdata), PyArray_DATA(rootdata), cop) ) def scatterBegin(self, unit: Datatype, ndarray multirootdata, ndarray leafdata) -> None: """Begin pointwise scatter operation. Collective. Operation is from multi-roots to leaves. This call has to be completed with `scatterEnd`. Parameters ---------- unit MPI datatype. multirootdata Root buffer to send to each leaf, one unit of data per leaf. leafdata Leaf data to be updated with personal data from each respective root. See Also -------- scatterEnd, petsc.PetscSFScatterBegin """ cdef MPI_Datatype dtype = mpi4py_Datatype_Get(unit) CHKERR( PetscSFScatterBegin(self.sf, dtype, PyArray_DATA(multirootdata), PyArray_DATA(leafdata)) ) def scatterEnd(self, unit: Datatype, ndarray multirootdata, ndarray leafdata) -> None: """End scatter operation that was started with `scatterBegin`. Collective. Parameters ---------- unit MPI datatype. multirootdata Root buffer to send to each leaf, one unit of data per leaf. leafdata Leaf data to be updated with personal data from each respective root. See Also -------- scatterBegin, petsc.PetscSFScatterEnd """ cdef MPI_Datatype dtype = mpi4py_Datatype_Get(unit) CHKERR( PetscSFScatterEnd(self.sf, dtype, PyArray_DATA(multirootdata), PyArray_DATA(leafdata)) ) def gatherBegin(self, unit: Datatype, ndarray leafdata, ndarray multirootdata) -> None: """Begin pointwise gather of all leaves into multi-roots. Collective. This call has to be completed with `gatherEnd`. Parameters ---------- unit MPI datatype. leafdata Leaf data to gather to roots. multirootdata Root buffer to gather into, amount of space per root is equal to its degree. See Also -------- gatherEnd, petsc.PetscSFGatherBegin """ cdef MPI_Datatype dtype = mpi4py_Datatype_Get(unit) CHKERR( PetscSFGatherBegin(self.sf, dtype, PyArray_DATA(leafdata), PyArray_DATA(multirootdata)) ) def gatherEnd(self, unit: Datatype, ndarray leafdata, ndarray multirootdata) -> None: """End gather operation that was started with `gatherBegin`. Collective. Parameters ---------- unit MPI datatype. leafdata Leaf data to gather to roots. multirootdata Root buffer to gather into, amount of space per root is equal to its degree. See Also -------- gatherBegin, petsc.PetscSFGatherEnd """ cdef MPI_Datatype dtype = mpi4py_Datatype_Get(unit) CHKERR( PetscSFGatherEnd(self.sf, dtype, PyArray_DATA(leafdata), PyArray_DATA(multirootdata)) ) def fetchAndOpBegin(self, unit: Datatype, rootdata: ndarray, leafdata: ndarray, leafupdate: ndarray, op: Op) -> None: """Begin fetch and update operation. Collective. This operation fetches values from root and updates atomically by applying an operation using the leaf value. This call has to be completed with `fetchAndOpEnd`. Parameters ---------- unit MPI datatype. rootdata Root values to be updated, input state is seen by first process to perform an update. leafdata Leaf values to use in reduction. leafupdate State at each leaf's respective root immediately prior to my atomic update. op MPI reduction operation. See Also -------- fetchAndOpEnd, petsc.PetscSFFetchAndOpBegin """ cdef MPI_Datatype dtype = mpi4py_Datatype_Get(unit) cdef MPI_Op cop = mpi4py_Op_Get(op) CHKERR( PetscSFFetchAndOpBegin(self.sf, dtype, PyArray_DATA(rootdata), PyArray_DATA(leafdata), PyArray_DATA(leafupdate), cop) ) def fetchAndOpEnd(self, unit: Datatype, rootdata: ndarray, leafdata: ndarray, leafupdate: ndarray, op: Op) -> None: """End operation started in a matching call to `fetchAndOpBegin`. Collective. Parameters ---------- unit MPI datatype. rootdata Root values to be updated, input state is seen by first process to perform an update. leafdata Leaf values to use in reduction. leafupdate State at each leaf's respective root immediately prior to my atomic update. op MPI reduction operation. See Also -------- fetchAndOpBegin, petsc.PetscSFFetchAndOpEnd """ cdef MPI_Datatype dtype = mpi4py_Datatype_Get(unit) cdef MPI_Op cop = mpi4py_Op_Get(op) CHKERR( PetscSFFetchAndOpEnd(self.sf, dtype, PyArray_DATA(rootdata), PyArray_DATA(leafdata), PyArray_DATA(leafupdate), cop) ) # -------------------------------------------------------------------- del SFType # -------------------------------------------------------------------- ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/src/petsc4py/PETSc/SNES.pyx0000644000175000017500000020533514567251135017171 0ustar00balaybalay# -------------------------------------------------------------------- class SNESType(object): """SNES solver type. See Also -------- petsc.SNESType """ NEWTONLS = S_(SNESNEWTONLS) NEWTONTR = S_(SNESNEWTONTR) PYTHON = S_(SNESPYTHON) NRICHARDSON = S_(SNESNRICHARDSON) KSPONLY = S_(SNESKSPONLY) KSPTRANSPOSEONLY = S_(SNESKSPTRANSPOSEONLY) VINEWTONRSLS = S_(SNESVINEWTONRSLS) VINEWTONSSLS = S_(SNESVINEWTONSSLS) NGMRES = S_(SNESNGMRES) QN = S_(SNESQN) SHELL = S_(SNESSHELL) NGS = S_(SNESNGS) NCG = S_(SNESNCG) FAS = S_(SNESFAS) MS = S_(SNESMS) NASM = S_(SNESNASM) ANDERSON = S_(SNESANDERSON) ASPIN = S_(SNESASPIN) COMPOSITE = S_(SNESCOMPOSITE) PATCH = S_(SNESPATCH) class SNESNormSchedule(object): """SNES norm schedule. See Also -------- petsc.SNESNormSchedule """ # native NORM_DEFAULT = SNES_NORM_DEFAULT NORM_NONE = SNES_NORM_NONE NORM_ALWAYS = SNES_NORM_ALWAYS NORM_INITIAL_ONLY = SNES_NORM_INITIAL_ONLY NORM_FINAL_ONLY = SNES_NORM_FINAL_ONLY NORM_INITIAL_FINAL_ONLY = SNES_NORM_INITIAL_FINAL_ONLY # aliases DEFAULT = NORM_DEFAULT NONE = NORM_NONE ALWAYS = NORM_ALWAYS INITIAL_ONLY = NORM_INITIAL_ONLY FINAL_ONLY = NORM_FINAL_ONLY INITIAL_FINAL_ONLY = NORM_INITIAL_FINAL_ONLY # FIXME Missing reference petsc.SNESConvergedReason class SNESConvergedReason(object): """SNES solver termination reason. See Also -------- petsc.SNESGetConvergedReason """ # iterating CONVERGED_ITERATING = SNES_CONVERGED_ITERATING ITERATING = SNES_CONVERGED_ITERATING # converged CONVERGED_FNORM_ABS = SNES_CONVERGED_FNORM_ABS CONVERGED_FNORM_RELATIVE = SNES_CONVERGED_FNORM_RELATIVE CONVERGED_SNORM_RELATIVE = SNES_CONVERGED_SNORM_RELATIVE CONVERGED_ITS = SNES_CONVERGED_ITS # diverged DIVERGED_FUNCTION_DOMAIN = SNES_DIVERGED_FUNCTION_DOMAIN DIVERGED_FUNCTION_COUNT = SNES_DIVERGED_FUNCTION_COUNT DIVERGED_LINEAR_SOLVE = SNES_DIVERGED_LINEAR_SOLVE DIVERGED_FNORM_NAN = SNES_DIVERGED_FNORM_NAN DIVERGED_MAX_IT = SNES_DIVERGED_MAX_IT DIVERGED_LINE_SEARCH = SNES_DIVERGED_LINE_SEARCH DIVERGED_INNER = SNES_DIVERGED_INNER DIVERGED_LOCAL_MIN = SNES_DIVERGED_LOCAL_MIN DIVERGED_DTOL = SNES_DIVERGED_DTOL DIVERGED_JACOBIAN_DOMAIN = SNES_DIVERGED_JACOBIAN_DOMAIN DIVERGED_TR_DELTA = SNES_DIVERGED_TR_DELTA # -------------------------------------------------------------------- cdef class SNES(Object): """Nonlinear equations solver. SNES is described in the `PETSc manual `. See Also -------- petsc.SNES """ Type = SNESType NormSchedule = SNESNormSchedule ConvergedReason = SNESConvergedReason # --- xxx --- def __cinit__(self): self.obj = &self.snes self.snes = NULL # --- xxx --- def view(self, Viewer viewer=None) -> None: """View the solver. Collective. Parameters ---------- viewer A `Viewer` instance or `None` for the default viewer. See Also -------- petsc.SNESView """ cdef PetscViewer cviewer = NULL if viewer is not None: cviewer = viewer.vwr CHKERR( SNESView(self.snes, cviewer) ) def destroy(self) -> Self: """Destroy the solver. Collective. See Also -------- petsc.SNESDestroy """ CHKERR( SNESDestroy(&self.snes) ) return self def create(self, comm: Comm | None = None) -> Self: """Create a SNES solver. Collective. Parameters ---------- comm MPI communicator, defaults to `Sys.getDefaultComm`. See Also -------- Sys.getDefaultComm, petsc.SNESCreate """ cdef MPI_Comm ccomm = def_Comm(comm, PETSC_COMM_DEFAULT) cdef PetscSNES newsnes = NULL CHKERR( SNESCreate(ccomm, &newsnes) ) CHKERR( PetscCLEAR(self.obj) ); self.snes = newsnes return self def setType(self, snes_type: Type | str) -> None: """Set the type of the solver. Logically collective. Parameters ---------- snes_type The type of the solver. See Also -------- getType, petsc.SNESSetType """ cdef PetscSNESType cval = NULL snes_type = str2bytes(snes_type, &cval) CHKERR( SNESSetType(self.snes, cval) ) def getType(self) -> str: """Return the type of the solver. Not collective. See Also -------- setType, petsc.SNESGetType """ cdef PetscSNESType cval = NULL CHKERR( SNESGetType(self.snes, &cval) ) return bytes2str(cval) def setOptionsPrefix(self, prefix: str) -> None: """Set the prefix used for searching for options in the database. Logically collective. See Also -------- petsc_options, petsc.SNESSetOptionsPrefix """ cdef const char *cval = NULL prefix = str2bytes(prefix, &cval) CHKERR( SNESSetOptionsPrefix(self.snes, cval) ) def getOptionsPrefix(self) -> str: """Return the prefix used for searching for options in the database. Not collective. See Also -------- petsc_options, setOptionsPrefix, petsc.SNESGetOptionsPrefix """ cdef const char *cval = NULL CHKERR( SNESGetOptionsPrefix(self.snes, &cval) ) return bytes2str(cval) def appendOptionsPrefix(self, prefix: str) -> None: """Append to the prefix used for searching for options in the database. Logically collective. See Also -------- petsc_options, setOptionsPrefix, petsc.SNESAppendOptionsPrefix """ cdef const char *cval = NULL prefix = str2bytes(prefix, &cval) CHKERR( SNESAppendOptionsPrefix(self.snes, cval) ) def setFromOptions(self) -> None: """Configure the solver from the options database. Collective. See Also -------- petsc_options, petsc.SNESSetFromOptions """ CHKERR( SNESSetFromOptions(self.snes) ) # --- application context --- def setApplicationContext(self, appctx: Any) -> None: """Set the application context.""" self.set_attr('__appctx__', appctx) if appctx is not None: registerAppCtx(appctx) CHKERR( SNESSetApplicationContext(self.snes, appctx) ) else: CHKERR( SNESSetApplicationContext(self.snes, NULL) ) def getApplicationContext(self) -> Any: """Return the application context.""" cdef void *ctx appctx = self.get_attr('__appctx__') if appctx is None: CHKERR( SNESGetApplicationContext(self.snes, &ctx) ) appctx = toAppCtx(ctx) return appctx # backward compatibility setAppCtx = setApplicationContext getAppCtx = getApplicationContext # --- discretization space --- def getDM(self) -> DM: """Return the `DM` associated with the solver. Not collective. See Also -------- setDM, petsc.SNESGetDM """ cdef PetscDM newdm = NULL CHKERR( SNESGetDM(self.snes, &newdm) ) cdef DM dm = subtype_DM(newdm)() dm.dm = newdm CHKERR( PetscINCREF(dm.obj) ) return dm def setDM(self, DM dm) -> None: """Associate a `DM` with the solver. Not collective. See Also -------- getDM, petsc.SNESSetDM """ CHKERR( SNESSetDM(self.snes, dm.dm) ) # --- FAS --- def setFASInterpolation(self, level: int, Mat mat) -> None: """Set the `Mat` to be used to apply the interpolation from level-1 to level. Collective. See Also -------- getFASInterpolation, setFASRestriction, setFASInjection petsc.SNESFASSetInterpolation, petsc.SNESFAS """ cdef PetscInt clevel = asInt(level) CHKERR( SNESFASSetInterpolation(self.snes, clevel, mat.mat) ) def getFASInterpolation(self, level: int) -> Mat: """Return the `Mat` used to apply the interpolation from level-1 to level. Not collective. See Also -------- setFASInterpolation, petsc.SNESFASGetInterpolation, petsc.SNESFAS """ cdef PetscInt clevel = asInt(level) cdef Mat mat = Mat() CHKERR( SNESFASGetInterpolation(self.snes, clevel, &mat.mat) ) CHKERR( PetscINCREF(mat.obj) ) return mat def setFASRestriction(self, level: int, Mat mat) -> None: """Set the `Mat` to be used to apply the restriction from level-1 to level. Collective. See Also -------- setFASRScale, getFASRestriction, setFASInterpolation, setFASInjection petsc.SNESFASSetRestriction, petsc.SNESFAS """ cdef PetscInt clevel = asInt(level) CHKERR( SNESFASSetRestriction(self.snes, clevel, mat.mat) ) def getFASRestriction(self, level: int) -> Mat: """Return the `Mat` used to apply the restriction from level-1 to level. Not collective. See Also -------- setFASRestriction, petsc.SNESFASGetRestriction, petsc.SNESFAS """ cdef PetscInt clevel = asInt(level) cdef Mat mat = Mat() CHKERR( SNESFASGetRestriction(self.snes, clevel, &mat.mat) ) CHKERR( PetscINCREF(mat.obj) ) return mat def setFASInjection(self, level: int, Mat mat) -> None: """Set the `Mat` to be used to apply the injection from level-1 to level. Collective. See Also -------- getFASInjection, setFASInterpolation, setFASRestriction petsc.SNESFASSetInjection, petsc.SNESFAS """ cdef PetscInt clevel = asInt(level) CHKERR( SNESFASSetInjection(self.snes, clevel, mat.mat) ) def getFASInjection(self, level: int) -> Mat: """Return the `Mat` used to apply the injection from level-1 to level. Not collective. See Also -------- setFASInjection, petsc.SNESFASGetInjection, petsc.SNESFAS """ cdef PetscInt clevel = asInt(level) cdef Mat mat = Mat() CHKERR( SNESFASGetInjection(self.snes, clevel, &mat.mat) ) CHKERR( PetscINCREF(mat.obj) ) return mat def setFASRScale(self, level: int, Vec vec) -> None: """Set the scaling factor of the restriction operator from level to level-1. Collective. See Also -------- setFASRestriction, petsc.SNESFASSetRScale, petsc.SNESFAS """ cdef PetscInt clevel = asInt(level) CHKERR( SNESFASSetRScale(self.snes, clevel, vec.vec) ) def setFASLevels(self, levels: int, comms: Sequence[Comm] = None) -> None: """Set the number of levels to use with FAS. Collective. Parameters ---------- levels The number of levels comms An optional sequence of communicators of length `levels`, or `None` for the default communicator `Sys.getDefaultComm`. See Also -------- getFASLevels, petsc.SNESFASSetLevels, petsc.SNESFAS """ cdef PetscInt clevels = asInt(levels) cdef MPI_Comm *ccomms = NULL cdef Py_ssize_t i = 0 if comms is not None: if clevels != len(comms): raise ValueError("Must provide as many communicators as levels") CHKERR( PetscMalloc(sizeof(MPI_Comm)*clevels, &ccomms) ) try: for i, comm in enumerate(comms): ccomms[i] = def_Comm(comm, MPI_COMM_NULL) CHKERR( SNESFASSetLevels(self.snes, clevels, ccomms) ) finally: CHKERR( PetscFree(ccomms) ) else: CHKERR( SNESFASSetLevels(self.snes, clevels, ccomms) ) def getFASLevels(self) -> int: """Return the number of levels used. Not collective. See Also -------- setFASLevels, petsc.SNESFASGetLevels, petsc.SNESFAS """ cdef PetscInt levels = 0 CHKERR( SNESFASGetLevels(self.snes, &levels) ) return toInt(levels) def getFASCycleSNES(self, level: int) -> SNES: """Return the `SNES` corresponding to a particular level of the FAS hierarchy. Not collective. See Also -------- setFASLevels, getFASCoarseSolve, getFASSmoother petsc.SNESFASGetCycleSNES, petsc.SNESFAS """ cdef PetscInt clevel = asInt(level) cdef SNES lsnes = SNES() CHKERR( SNESFASGetCycleSNES(self.snes, clevel, &lsnes.snes) ) CHKERR( PetscINCREF(lsnes.obj) ) return lsnes def getFASCoarseSolve(self) -> SNES: """Return the `SNES` used at the coarsest level of the FAS hierarchy. Not collective. See Also -------- getFASSmoother, petsc.SNESFASGetCoarseSolve, petsc.SNESFAS """ cdef SNES smooth = SNES() CHKERR( SNESFASGetCoarseSolve(self.snes, &smooth.snes) ) CHKERR( PetscINCREF(smooth.obj) ) return smooth def getFASSmoother(self, level: int) -> SNES: """Return the smoother used at a given level of the FAS hierarchy. Not collective. See Also -------- setFASLevels, getFASCoarseSolve, getFASSmootherDown, getFASSmootherUp petsc.SNESFASGetSmoother, petsc.SNESFAS """ cdef PetscInt clevel = asInt(level) cdef SNES smooth = SNES() CHKERR( SNESFASGetSmoother(self.snes, clevel, &smooth.snes) ) CHKERR( PetscINCREF(smooth.obj) ) return smooth def getFASSmootherDown(self, level: int) -> SNES: """Return the downsmoother used at a given level of the FAS hierarchy. Not collective. See Also -------- setFASLevels, getFASCoarseSolve, getFASSmoother, getFASSmootherUp petsc.SNESFASGetSmootherDown, petsc.SNESFAS """ cdef PetscInt clevel = asInt(level) cdef SNES smooth = SNES() CHKERR( SNESFASGetSmootherDown(self.snes, clevel, &smooth.snes) ) CHKERR( PetscINCREF(smooth.obj) ) return smooth def getFASSmootherUp(self, level: int) -> SNES: """Return the upsmoother used at a given level of the FAS hierarchy. Not collective. See Also -------- setFASLevels, getFASCoarseSolve, getFASSmoother, getFASSmootherDown petsc.SNESFASGetSmootherUp, petsc.SNESFAS """ cdef PetscInt clevel = asInt(level) cdef SNES smooth = SNES() CHKERR( SNESFASGetSmootherUp(self.snes, clevel, &smooth.snes) ) CHKERR( PetscINCREF(smooth.obj) ) return smooth # --- nonlinear preconditioner --- def getNPC(self) -> SNES: """Return the nonlinear preconditioner associated with the solver. Not collective. See Also -------- setNPC, hasNPC, setNPCSide, getNPCSide, petsc.SNESGetNPC """ cdef SNES snes = SNES() CHKERR( SNESGetNPC(self.snes, &snes.snes) ) CHKERR( PetscINCREF(snes.obj) ) return snes def hasNPC(self) -> bool: """Return a boolean indicating whether the solver has a nonlinear preconditioner. Not collective. See Also -------- setNPC, getNPC, setNPCSide, getNPCSide, petsc.SNESHasNPC """ cdef PetscBool flag = PETSC_FALSE CHKERR( SNESHasNPC(self.snes, &flag) ) return toBool(flag) def setNPC(self, SNES snes) -> None: """Set the nonlinear preconditioner. Logically collective. See Also -------- getNPC, hasNPC, setNPCSide, getNPCSide, petsc.SNESSetNPC """ CHKERR( SNESSetNPC(self.snes, snes.snes) ) def setNPCSide(self, side: PC.Side) -> None: """Set the nonlinear preconditioning side. Collective. See Also -------- setNPC, getNPC, hasNPC, getNPCSide, petsc.SNESSetNPCSide """ CHKERR( SNESSetNPCSide(self.snes, side) ) def getNPCSide(self) -> PC.Side: """Return the nonlinear preconditioning side. Not collective. See Also -------- setNPC, getNPC, hasNPC, setNPCSide, petsc.SNESGetNPCSide """ cdef PetscPCSide side = PC_RIGHT CHKERR( SNESGetNPCSide(self.snes, &side) ) return side # --- user Function/Jacobian routines --- def setLineSearchPreCheck(self, precheck: SNESLSPreFunction, args: tuple[Any, ...] | None = None, kargs: dict[str, Any] | None = None) -> None: """Set the callback that will be called before applying the linesearch. Logically collective. Parameters ---------- precheck The callback. args Positional arguments for the callback. kargs Keyword arguments for the callback. See Also -------- petsc.SNESLineSearchSetPreCheck """ cdef PetscSNESLineSearch snesls = NULL CHKERR( SNESGetLineSearch(self.snes, &snesls) ) if precheck is not None: if args is None: args = () if kargs is None: kargs = {} context = (precheck, args, kargs) self.set_attr('__precheck__', context) # FIXME callback CHKERR( SNESLineSearchSetPreCheck(snesls, SNES_PreCheck, context) ) else: self.set_attr('__precheck__', None) CHKERR( SNESLineSearchSetPreCheck(snesls, NULL, NULL) ) def setInitialGuess(self, initialguess: SNESGuessFunction, args: tuple[Any, ...] | None = None, kargs: dict[str, Any] | None = None) -> None: """Set the callback to compute the initial guess. Logically collective. Parameters ---------- initialguess The callback. args Positional arguments for the callback. kargs Keyword arguments for the callback. See Also -------- getInitialGuess, petsc.SNESSetComputeInitialGuess """ if initialguess is not None: if args is None: args = () if kargs is None: kargs = {} context = (initialguess, args, kargs) self.set_attr('__initialguess__', context) CHKERR( SNESSetComputeInitialGuess(self.snes, SNES_InitialGuess, context) ) else: self.set_attr('__initialguess__', None) CHKERR( SNESSetComputeInitialGuess(self.snes, NULL, NULL) ) def getInitialGuess(self) -> SNESGuessFunction: """Return the callback to compute the initial guess. Not collective. See Also -------- setInitialGuess """ return self.get_attr('__initialguess__') def setFunction(self, function: SNESFunction, Vec f=None, args: tuple[Any, ...] | None = None, kargs: dict[str, Any] | None = None) -> None: """Set the callback to compute the nonlinear function. Logically collective. Parameters ---------- function The callback. f An optional vector to store the result. args Positional arguments for the callback. kargs Keyword arguments for the callback. See Also -------- getFunction, petsc.SNESSetFunction """ cdef PetscVec fvec=NULL if f is not None: fvec = f.vec if function is not None: if args is None: args = () if kargs is None: kargs = {} context = (function, args, kargs) self.set_attr('__function__', context) CHKERR( SNESSetFunction(self.snes, fvec, SNES_Function, context) ) else: CHKERR( SNESSetFunction(self.snes, fvec, NULL, NULL) ) def getFunction(self) -> SNESFunction: """Return the callback to compute the nonlinear function. Not collective. See Also -------- setFunction, petsc.SNESGetFunction """ cdef Vec f = Vec() cdef void* ctx cdef PetscErrorCode (*fun)(PetscSNES,PetscVec,PetscVec,void*) CHKERR( SNESGetFunction(self.snes, &f.vec, &fun, &ctx) ) CHKERR( PetscINCREF(f.obj) ) cdef object function = self.get_attr('__function__') cdef object context if function is not None: return (f, function) if ctx != NULL and SNES_Function == fun: context = ctx if context is not None: assert type(context) is tuple return (f, context) return (f, None) def setUpdate(self, update: SNESUpdateFunction, args: tuple[Any, ...] | None = None, kargs: dict[str, Any] | None = None) -> None: """Set the callback to compute update at the beginning of each step. Logically collective. Parameters ---------- update The callback. args Positional arguments for the callback. kargs Keyword arguments for the callback. See Also -------- getUpdate, petsc.SNESSetUpdate """ if update is not None: if args is None: args = () if kargs is None: kargs = {} context = (update, args, kargs) self.set_attr('__update__', context) CHKERR( SNESSetUpdate(self.snes, SNES_Update) ) else: self.set_attr('__update__', None) CHKERR( SNESSetUpdate(self.snes, NULL) ) def getUpdate(self) -> SNESUpdateFunction: """Return the callback to compute the update at the beginning of each step. Not collective. See Also -------- setUpdate """ return self.get_attr('__update__') def setJacobian(self, jacobian: SNESJacobianFunction, Mat J=None, Mat P=None, args: tuple[Any, ...] | None = None, kargs: dict[str, Any] | None = None) -> None: """Set the callback to compute the Jacobian. Logically collective. Parameters ---------- jacobian The Jacobian callback. J The matrix to store the Jacobian. P The matrix to construct the preconditioner. args Positional arguments for the callback. kargs Keyword arguments for the callback. See Also -------- getJacobian, petsc.SNESSetJacobian """ cdef PetscMat Jmat=NULL if J is not None: Jmat = J.mat cdef PetscMat Pmat=Jmat if P is not None: Pmat = P.mat if jacobian is not None: if args is None: args = () if kargs is None: kargs = {} context = (jacobian, args, kargs) self.set_attr('__jacobian__', context) CHKERR( SNESSetJacobian(self.snes, Jmat, Pmat, SNES_Jacobian, context) ) else: CHKERR( SNESSetJacobian(self.snes, Jmat, Pmat, NULL, NULL) ) def getJacobian(self) -> tuple[Mat, Mat, SNESJacobianFunction]: """Return the matrices used to compute the Jacobian and the callback tuple. Not collective. Returns ------- J : Mat The matrix to store the Jacobian. P : Mat The matrix to construct the preconditioner. callback : SNESJacobianFunction callback, positional and keyword arguments. See Also -------- setJacobian, petsc.SNESGetJacobian """ cdef Mat J = Mat() cdef Mat P = Mat() CHKERR( SNESGetJacobian(self.snes, &J.mat, &P.mat, NULL, NULL) ) CHKERR( PetscINCREF(J.obj) ) CHKERR( PetscINCREF(P.obj) ) cdef object jacobian = self.get_attr('__jacobian__') return (J, P, jacobian) def setObjective(self, objective: SNESObjFunction, args: tuple[Any, ...] | None = None, kargs: dict[str, Any] | None = None) -> None: """Set the callback to compute the objective function. Logically collective. Parameters ---------- objective The Jacobian callback. args Positional arguments for the callback. kargs Keyword arguments for the callback. See Also -------- getObjective, petsc.SNESSetObjective """ if objective is not None: if args is None: args = () if kargs is None: kargs = {} context = (objective, args, kargs) self.set_attr('__objective__', context) CHKERR( SNESSetObjective(self.snes, SNES_Objective, context) ) else: CHKERR( SNESSetObjective(self.snes, NULL, NULL) ) def getObjective(self) -> SNESObjFunction: """Return the objective callback tuple. Not collective. See Also -------- setObjective """ CHKERR( SNESGetObjective(self.snes, NULL, NULL) ) cdef object objective = self.get_attr('__objective__') return objective def computeFunction(self, Vec x, Vec f) -> None: """Compute the function. Collective. Parameters ---------- x The input state vector. f The output vector. See Also -------- setFunction, petsc.SNESComputeFunction """ CHKERR( SNESComputeFunction(self.snes, x.vec, f.vec) ) def computeJacobian(self, Vec x, Mat J, Mat P=None) -> None: """Compute the Jacobian. Collective. Parameters ---------- x The input state vector. J The output Jacobian matrix. P The output Jacobian matrix used to construct the preconditioner. See Also -------- setJacobian, petsc.SNESComputeJacobian """ cdef PetscMat jmat = J.mat, pmat = J.mat if P is not None: pmat = P.mat CHKERR( SNESComputeJacobian(self.snes, x.vec, jmat, pmat) ) def computeObjective(self, Vec x) -> float: """Compute the value of the objective function. Collective. Parameters ---------- x The input state vector. See Also -------- setObjective, petsc.SNESComputeObjective """ cdef PetscReal o = 0 CHKERR( SNESComputeObjective(self.snes, x.vec, &o) ) return toReal(o) def setNGS(self, ngs: SNESNGSFunction, args: tuple[Any, ...] | None = None, kargs: dict[str, Any] | None = None) -> None: """Set the callback to compute nonlinear Gauss-Seidel. Logically collective. Parameters ---------- ngs The nonlinear Gauss-Seidel callback. args Positional arguments for the callback. kargs Keyword arguments for the callback. See Also -------- getNGS, computeNGS, petsc.SNESSetNGS """ if args is None: args = () if kargs is None: kargs = {} context = (ngs, args, kargs) self.set_attr('__ngs__', context) CHKERR( SNESSetNGS(self.snes, SNES_NGS, context) ) def getNGS(self) -> SNESNGSFunction: """Return the nonlinear Gauss-Seidel callback tuple. Not collective. See Also -------- setNGS, computeNGS """ CHKERR( SNESGetNGS(self.snes, NULL, NULL) ) cdef object ngs = self.get_attr('__ngs__') return ngs def computeNGS(self, Vec x, Vec b=None) -> None: """Compute a nonlinear Gauss-Seidel step. Collective. Parameters ---------- x The input/output state vector. b The input right-hand side vector. See Also -------- setNGS, getNGS, petsc.SNESComputeNGS """ cdef PetscVec bvec = NULL if b is not None: bvec = b.vec CHKERR( SNESComputeNGS(self.snes, bvec, x.vec) ) # --- tolerances and convergence --- def setTolerances(self, rtol: float = None, atol: float = None, stol: float = None, max_it: int = None) -> None: """Set the tolerance parameters used in the solver convergence tests. Collective. Parameters ---------- rtol The relative norm of the residual. Defaults to `DEFAULT`. atol The absolute norm of the residual. Defaults to `DEFAULT`. stol The absolute norm of the step. Defaults to `DEFAULT`. max_it The maximum allowed number of iterations. Defaults to `DEFAULT` See Also -------- getTolerances, petsc.SNESSetTolerances """ cdef PetscReal crtol, catol, cstol crtol = catol = cstol = PETSC_DEFAULT cdef PetscInt cmaxit = PETSC_DEFAULT if rtol is not None: crtol = asReal(rtol) if atol is not None: catol = asReal(atol) if stol is not None: cstol = asReal(stol) if max_it is not None: cmaxit = asInt(max_it) CHKERR( SNESSetTolerances(self.snes, catol, crtol, cstol, cmaxit, PETSC_DEFAULT) ) def getTolerances(self) -> tuple[float, float, float, int]: """Return the tolerance parameters used in the solver convergence tests. Collective. Returns ------- rtol : float The relative norm of the residual. atol : float The absolute norm of the residual. stol : float The absolute norm of the step. max_it : int The maximum allowed number of iterations. See Also -------- setTolerances, petsc.SNESGetTolerances """ cdef PetscReal crtol=0, catol=0, cstol=0 cdef PetscInt cmaxit=0 CHKERR( SNESGetTolerances(self.snes, &catol, &crtol, &cstol, &cmaxit, NULL) ) return (toReal(crtol), toReal(catol), toReal(cstol), toInt(cmaxit)) def setNormSchedule(self, normsched: NormSchedule) -> None: """Set the norm schedule. Collective. See Also -------- getNormSchedule, petsc.SNESSetNormSchedule """ CHKERR( SNESSetNormSchedule(self.snes, normsched) ) def getNormSchedule(self) -> NormSchedule: """Return the norm schedule. Not collective. See Also -------- setNormSchedule, petsc.SNESGetNormSchedule """ cdef PetscSNESNormSchedule normsched = SNES_NORM_NONE CHKERR( SNESGetNormSchedule(self.snes, &normsched) ) return normsched def setConvergenceTest(self, converged: SNESConvergedFunction | Literal["skip", "default"], args: tuple[Any, ...] | None = None, kargs: dict[str, Any] | None = None) -> None: """Set the callback to use as convergence test. Logically collective. Parameters ---------- converged The convergence testing callback. args Positional arguments for the callback. kargs Keyword arguments for the callback. See Also -------- getConvergenceTest, callConvergenceTest, petsc.SNESSetConvergenceTest """ if converged == "skip": self.set_attr('__converged__', None) CHKERR( SNESSetConvergenceTest(self.snes, SNESConvergedSkip, NULL, NULL) ) elif converged is None or converged == "default": self.set_attr('__converged__', None) CHKERR( SNESSetConvergenceTest(self.snes, SNESConvergedDefault, NULL, NULL) ) else: assert callable(converged) if args is None: args = () if kargs is None: kargs = {} context = (converged, args, kargs) self.set_attr('__converged__', context) CHKERR( SNESSetConvergenceTest(self.snes, SNES_Converged, context, NULL) ) def getConvergenceTest(self) -> SNESConvergedFunction: """Return the callback to used as convergence test. Not collective. See Also -------- setConvergenceTest, callConvergenceTest """ return self.get_attr('__converged__') def callConvergenceTest(self, its: int, xnorm: float, ynorm: float, fnorm: float) -> ConvergedReason: """Compute the convergence test. Collective. Parameters ---------- its Iteration number. xnorm Solution norm. ynorm Update norm. fnorm Function norm. See Also -------- setConvergenceTest, getConvergenceTest """ cdef PetscInt ival = asInt(its) cdef PetscReal rval1 = asReal(xnorm) cdef PetscReal rval2 = asReal(ynorm) cdef PetscReal rval3 = asReal(fnorm) cdef PetscSNESConvergedReason reason = SNES_CONVERGED_ITERATING CHKERR( SNESConvergenceTestCall(self.snes, ival, rval1, rval2, rval3, &reason) ) return reason def converged(self, its: int, xnorm: float, ynorm: float, fnorm: float) -> None: """Compute the convergence test and update the solver converged reason. Collective. Parameters ---------- its Iteration number. xnorm Solution norm. ynorm Update norm. fnorm Function norm. See Also -------- setConvergenceTest, getConvergenceTest, petsc.SNESConverged """ cdef PetscInt ival = asInt(its) cdef PetscReal rval1 = asReal(xnorm) cdef PetscReal rval2 = asReal(ynorm) cdef PetscReal rval3 = asReal(fnorm) CHKERR( SNESConverged(self.snes, ival, rval1, rval2, rval3) ) def setConvergenceHistory(self, length=None, reset=False) -> None: """Set the convergence history. Logically collective. See Also -------- petsc.SNESSetConvergenceHistory """ cdef PetscReal *rdata = NULL cdef PetscInt *idata = NULL cdef PetscInt size = 1000 cdef PetscBool flag = PETSC_FALSE #FIXME if length is True: pass elif length is not None: size = asInt(length) if size < 0: size = 1000 if reset: flag = PETSC_TRUE cdef object rhist = oarray_r(empty_r(size), NULL, &rdata) cdef object ihist = oarray_i(empty_i(size), NULL, &idata) self.set_attr('__history__', (rhist, ihist)) CHKERR( SNESSetConvergenceHistory(self.snes, rdata, idata, size, flag) ) def getConvergenceHistory(self) -> tuple[ArrayReal, ArrayInt]: """Return the convergence history. Not collective. See Also -------- petsc.SNESGetConvergenceHistory """ cdef PetscReal *rdata = NULL cdef PetscInt *idata = NULL cdef PetscInt size = 0 CHKERR( SNESGetConvergenceHistory(self.snes, &rdata, &idata, &size) ) cdef object rhist = array_r(size, rdata) cdef object ihist = array_i(size, idata) return (rhist, ihist) def logConvergenceHistory(self, norm: float, linear_its: int = 0) -> None: """Log residual norm and linear iterations.""" cdef PetscReal rval = asReal(norm) cdef PetscInt ival = asInt(linear_its) CHKERR( SNESLogConvergenceHistory(self.snes, rval, ival) ) def setResetCounters(self, reset: bool = True) -> None: """Set the flag to reset the counters. Collective. See Also -------- petsc.SNESSetCountersReset """ cdef PetscBool flag = reset CHKERR( SNESSetCountersReset(self.snes, flag) ) # --- monitoring --- def setMonitor(self, monitor: SNESMonitorFunction, args: tuple[Any, ...] | None = None, kargs: dict[str, Any] | None = None) -> None: """Set the callback used to monitor solver convergence. Logically collective. Parameters ---------- monitor The callback. args Positional arguments for the callback. kargs Keyword arguments for the callback. See Also -------- getMonitor, petsc.SNESMonitorSet """ if monitor is None: return cdef object monitorlist = self.get_attr('__monitor__') if monitorlist is None: monitorlist = [] self.set_attr('__monitor__', monitorlist) CHKERR( SNESMonitorSet(self.snes, SNES_Monitor, NULL, NULL) ) if args is None: args = () if kargs is None: kargs = {} context = (monitor, args, kargs) monitorlist.append(context) def getMonitor(self) -> list[tuple[SNESMonitorFunction, tuple[Any, ...], dict[str, Any]]]: """Return the callback used to monitor solver convergence. Not collective. See Also -------- setMonitor """ return self.get_attr('__monitor__') def monitorCancel(self) -> None: """Cancel all the monitors of the solver. Logically collective. See Also -------- setMonitor, petsc.SNESMonitorCancel """ CHKERR( SNESMonitorCancel(self.snes) ) self.set_attr('__monitor__', None) cancelMonitor = monitorCancel def monitor(self, its, rnorm) -> None: """Monitor the solver. Collective. Parameters ---------- its Current number of iterations. rnorm Current value of the residual norm. See Also -------- setMonitor, petsc.SNESMonitor """ cdef PetscInt ival = asInt(its) cdef PetscReal rval = asReal(rnorm) CHKERR( SNESMonitor(self.snes, ival, rval) ) # --- more tolerances --- def setMaxFunctionEvaluations(self, max_funcs: int) -> None: """Set the maximum allowed number of function evaluations. Collective. See Also -------- getMaxFunctionEvaluations, petsc.SNESSetTolerances """ cdef PetscReal r = PETSC_DEFAULT cdef PetscInt i = PETSC_DEFAULT cdef PetscInt ival = asInt(max_funcs) CHKERR( SNESSetTolerances(self.snes, r, r, r, i, ival) ) def getMaxFunctionEvaluations(self) -> int: """Return the maximum allowed number of function evaluations. Not collective. See Also -------- setMaxFunctionEvaluations, petsc.SNESSetTolerances """ cdef PetscReal *r = NULL cdef PetscInt *i = NULL cdef PetscInt ival = 0 CHKERR( SNESGetTolerances(self.snes, r, r, r, i, &ival) ) return toInt(ival) def getFunctionEvaluations(self) -> int: """Return the current number of function evaluations. Not collective. See Also -------- setMaxFunctionEvaluations, petsc.SNESGetNumberFunctionEvals """ cdef PetscInt ival = 0 CHKERR( SNESGetNumberFunctionEvals(self.snes, &ival) ) return toInt(ival) def setMaxStepFailures(self, max_fails: int) -> None: """Set the maximum allowed number of step failures. Collective. See Also -------- getMaxStepFailures, petsc.SNESSetMaxNonlinearStepFailures """ cdef PetscInt ival = asInt(max_fails) CHKERR( SNESSetMaxNonlinearStepFailures(self.snes, ival) ) def getMaxStepFailures(self) -> int: """Return the maximum allowed number of step failures. Not collective. See Also -------- setMaxStepFailures, petsc.SNESGetMaxNonlinearStepFailures """ cdef PetscInt ival = 0 CHKERR( SNESGetMaxNonlinearStepFailures(self.snes, &ival) ) return toInt(ival) def getStepFailures(self) -> int: """Return the current number of step failures. Not collective. See Also -------- getMaxStepFailures, petsc.SNESGetNonlinearStepFailures """ cdef PetscInt ival = 0 CHKERR( SNESGetNonlinearStepFailures(self.snes, &ival) ) return toInt(ival) def setMaxKSPFailures(self, max_fails: int) -> None: """Set the maximum allowed number of linear solve failures. Collective. See Also -------- getMaxKSPFailures, petsc.SNESSetMaxLinearSolveFailures """ cdef PetscInt ival = asInt(max_fails) CHKERR( SNESSetMaxLinearSolveFailures(self.snes, ival) ) def getMaxKSPFailures(self) -> int: """Return the maximum allowed number of linear solve failures. Not collective. See Also -------- setMaxKSPFailures, petsc.SNESGetMaxLinearSolveFailures """ cdef PetscInt ival = 0 CHKERR( SNESGetMaxLinearSolveFailures(self.snes, &ival) ) return toInt(ival) def getKSPFailures(self) -> int: """Return the current number of linear solve failures. Not collective. See Also -------- getMaxKSPFailures, petsc.SNESGetLinearSolveFailures """ cdef PetscInt ival = 0 CHKERR( SNESGetLinearSolveFailures(self.snes, &ival) ) return toInt(ival) setMaxNonlinearStepFailures = setMaxStepFailures getMaxNonlinearStepFailures = getMaxStepFailures getNonlinearStepFailures = getStepFailures setMaxLinearSolveFailures = setMaxKSPFailures getMaxLinearSolveFailures = getMaxKSPFailures getLinearSolveFailures = getKSPFailures # --- solving --- def setUp(self) -> None: """Set up the internal data structures for using the solver. Collective. See Also -------- petsc.SNESSetUp """ CHKERR( SNESSetUp(self.snes) ) def setUpMatrices(self) -> None: """Ensures that matrices are available for Newton-like methods. Collective. This is only of use to implementers of custom SNES types. See Also -------- setUp, petsc.SNESSetUpMatrices """ CHKERR( SNESSetUpMatrices(self.snes) ) def reset(self) -> None: """Reset the solver. Collective. See Also -------- petsc.SNESReset """ CHKERR( SNESReset(self.snes) ) def solve(self, Vec b = None, Vec x = None) -> None: """Solve the nonlinear equations. Collective. Parameters ---------- b The affine right-hand side or `None` to use zero. x The starting vector or `None` to use the vector stored internally. See Also -------- setSolution, getSolution, petsc.SNESSolve """ cdef PetscVec rhs = NULL cdef PetscVec sol = NULL if b is not None: rhs = b.vec if x is not None: sol = x.vec CHKERR( SNESSolve(self.snes, rhs, sol) ) def setConvergedReason(self, reason: ConvergedReason) -> None: """Set the termination flag. Collective. See Also -------- getConvergedReason, petsc.SNESSetConvergedReason """ cdef PetscSNESConvergedReason eval = reason CHKERR( SNESSetConvergedReason(self.snes, eval) ) def getConvergedReason(self) -> ConvergedReason: """Return the termination flag. Not collective. See Also -------- setConvergedReason, petsc.SNESGetConvergedReason """ cdef PetscSNESConvergedReason reason = SNES_CONVERGED_ITERATING CHKERR( SNESGetConvergedReason(self.snes, &reason) ) return reason def setErrorIfNotConverged(self, flag: bool) -> None: """Immediately generate an error if the solver has not converged. Collective. See Also -------- getErrorIfNotConverged, petsc.SNESSetErrorIfNotConverged """ cdef PetscBool ernc = asBool(flag) CHKERR( SNESSetErrorIfNotConverged(self.snes, ernc) ) def getErrorIfNotConverged(self) -> bool: """Return the flag indicating error on divergence. Not collective. See Also -------- setErrorIfNotConverged, petsc.SNESGetErrorIfNotConverged """ cdef PetscBool flag = PETSC_FALSE CHKERR( SNESGetErrorIfNotConverged(self.snes, &flag) ) return toBool(flag) def setIterationNumber(self, its: int) -> None: """Set the current iteration number. Collective. This is only of use to implementers of custom SNES types. See Also -------- getIterationNumber, petsc.SNESSetIterationNumber """ cdef PetscInt ival = asInt(its) CHKERR( SNESSetIterationNumber(self.snes, ival) ) def getIterationNumber(self) -> int: """Return the current iteration number. Not collective. See Also -------- setIterationNumber, petsc.SNESGetIterationNumber """ cdef PetscInt ival = 0 CHKERR( SNESGetIterationNumber(self.snes, &ival) ) return toInt(ival) def setForceIteration(self, force: bool) -> None: """Force solve to take at least one iteration. Collective. See Also -------- petsc.SNESSetForceIteration """ cdef PetscBool bval = asBool(force) CHKERR( SNESSetForceIteration(self.snes, bval) ) def setFunctionNorm(self, norm: float) -> None: """Set the function norm value. Collective. This is only of use to implementers of custom SNES types. See Also -------- getFunctionNorm, petsc.SNESSetFunctionNorm """ cdef PetscReal rval = asReal(norm) CHKERR( SNESSetFunctionNorm(self.snes, rval) ) def getFunctionNorm(self) -> float: """Return the function norm. Not collective. See Also -------- setFunctionNorm, petsc.SNESGetFunctionNorm """ cdef PetscReal rval = 0 CHKERR( SNESGetFunctionNorm(self.snes, &rval) ) return toReal(rval) def getLinearSolveIterations(self) -> int: """Return the total number of linear iterations. Not collective. See Also -------- petsc.SNESGetLinearSolveIterations """ cdef PetscInt ival = 0 CHKERR( SNESGetLinearSolveIterations(self.snes, &ival) ) return toInt(ival) def getRhs(self) -> Vec: """Return the vector holding the right-hand side. Not collective. See Also -------- petsc.SNESGetRhs """ cdef Vec vec = Vec() CHKERR( SNESGetRhs(self.snes, &vec.vec) ) CHKERR( PetscINCREF(vec.obj) ) return vec def getSolution(self) -> Vec: """Return the vector holding the solution. Not collective. See Also -------- setSolution, petsc.SNESGetSolution """ cdef Vec vec = Vec() CHKERR( SNESGetSolution(self.snes, &vec.vec) ) CHKERR( PetscINCREF(vec.obj) ) return vec def setSolution(self, Vec vec) -> None: """Set the vector used to store the solution. Collective. See Also -------- getSolution, petsc.SNESSetSolution """ CHKERR( SNESSetSolution(self.snes, vec.vec) ) def getSolutionUpdate(self) -> Vec: """Return the vector holding the solution update. Not collective. See Also -------- petsc.SNESGetSolutionUpdate """ cdef Vec vec = Vec() CHKERR( SNESGetSolutionUpdate(self.snes, &vec.vec) ) CHKERR( PetscINCREF(vec.obj) ) return vec # --- linear solver --- def setKSP(self, KSP ksp) -> None: """Set the linear solver that will be used by the nonlinear solver. Logically collective. See Also -------- getKSP, petsc.SNESSetKSP """ CHKERR( SNESSetKSP(self.snes, ksp.ksp) ) def getKSP(self) -> KSP: """Return the linear solver used by the nonlinear solver. Not collective. See Also -------- setKSP, petsc.SNESGetKSP """ cdef KSP ksp = KSP() CHKERR( SNESGetKSP(self.snes, &ksp.ksp) ) CHKERR( PetscINCREF(ksp.obj) ) return ksp def setUseEW(self, flag: bool = True, *targs: Any, **kargs: Any) -> None: """Tell the solver to use the Eisenstat-Walker trick. Logically collective. Parameters ---------- flag Whether or not to use the Eisenstat-Walker trick. *targs Positional arguments for `setParamsEW`. **kargs Keyword arguments for `setParamsEW`. See Also -------- getUseEW, setParamsEW, petsc.SNESKSPSetUseEW """ cdef PetscBool bval = flag CHKERR( SNESKSPSetUseEW(self.snes, bval) ) if targs or kargs: self.setParamsEW(*targs, **kargs) def getUseEW(self) -> bool: """Return the flag indicating if the solver uses the Eisenstat-Walker trick. Not Collective. See Also -------- setUseEW, setParamsEW, petsc.SNESKSPGetUseEW """ cdef PetscBool flag = PETSC_FALSE CHKERR( SNESKSPGetUseEW(self.snes, &flag) ) return toBool(flag) def setParamsEW(self, version: int = None, rtol_0: float = None, rtol_max: float = None, gamma: float = None, alpha: float = None, alpha2: float = None, threshold: float = None) -> None: """Set the parameters for the Eisenstat and Walker trick. Logically collective. Parameters ---------- version The version of the algorithm. Defaults to `DEFAULT`. rtol_0 The initial relative residual norm. Defaults to `DEFAULT`. rtol_max The maximum relative residual norm. Defaults to `DEFAULT`. gamma Parameter. Defaults to `DEFAULT`. alpha Parameter. Defaults to `DEFAULT`. alpha2 Parameter. Defaults to `DEFAULT`. threshold Parameter. Defaults to `DEFAULT`. See Also -------- setUseEW, getParamsEW, petsc.SNESKSPSetParametersEW """ cdef PetscInt cversion = PETSC_DEFAULT cdef PetscReal crtol_0 = PETSC_DEFAULT cdef PetscReal crtol_max = PETSC_DEFAULT cdef PetscReal cgamma = PETSC_DEFAULT cdef PetscReal calpha = PETSC_DEFAULT cdef PetscReal calpha2 = PETSC_DEFAULT cdef PetscReal cthreshold = PETSC_DEFAULT if version is not None: cversion = asInt(version) if rtol_0 is not None: crtol_0 = asReal(rtol_0) if rtol_max is not None: crtol_max = asReal(rtol_max) if gamma is not None: cgamma = asReal(gamma) if alpha is not None: calpha = asReal(alpha) if alpha2 is not None: calpha2 = asReal(alpha2) if threshold is not None: cthreshold = asReal(threshold) CHKERR( SNESKSPSetParametersEW( self.snes, cversion, crtol_0, crtol_max, cgamma, calpha, calpha2, cthreshold) ) def getParamsEW(self) -> dict[str, int | float]: """Get the parameters of the Eisenstat and Walker trick. Not collective. See Also -------- setUseEW, setParamsEW, petsc.SNESKSPGetParametersEW """ cdef PetscInt version=0 cdef PetscReal rtol_0=0, rtol_max=0 cdef PetscReal gamma=0, alpha=0, alpha2=0 cdef PetscReal threshold=0 CHKERR( SNESKSPGetParametersEW( self.snes, &version, &rtol_0, &rtol_max, &gamma, &alpha, &alpha2, &threshold) ) return {'version' : toInt(version), 'rtol_0' : toReal(rtol_0), 'rtol_max' : toReal(rtol_max), 'gamma' : toReal(gamma), 'alpha' : toReal(alpha), 'alpha2' : toReal(alpha2), 'threshold' : toReal(threshold),} # --- matrix-free / finite differences --- def setUseMF(self, flag=True) -> None: """Set the boolean flag indicating to use matrix-free finite-differencing. Logically collective. See Also -------- getUseMF """ cdef PetscBool bval = flag CHKERR( SNESSetUseMFFD(self.snes, bval) ) def getUseMF(self) -> bool: """Return the flag indicating if the solver uses matrix-free finite-differencing. Not collective. See Also -------- setUseMF """ cdef PetscBool flag = PETSC_FALSE CHKERR( SNESGetUseMFFD(self.snes, &flag) ) return toBool(flag) def setUseFD(self, flag=True) -> None: """Set the boolean flag to use coloring finite-differencing for Jacobian assembly. Logically collective. See Also -------- getUseFD """ cdef PetscBool bval = flag CHKERR( SNESSetUseFDColoring(self.snes, bval) ) def getUseFD(self) -> False: """Return ``true`` if the solver uses color finite-differencing for the Jacobian. Not collective. See Also -------- setUseFD """ cdef PetscBool flag = PETSC_FALSE CHKERR( SNESGetUseFDColoring(self.snes, &flag) ) return toBool(flag) # --- VI --- def setVariableBounds(self, Vec xl, Vec xu) -> None: """Set the vector for the variable bounds. Collective. See Also -------- petsc.SNESVISetVariableBounds """ CHKERR( SNESVISetVariableBounds(self.snes, xl.vec, xu.vec) ) def getVIInactiveSet(self) -> IS: """Return the index set for the inactive set. Not collective. See Also -------- petsc.SNESVIGetInactiveSet """ cdef IS inact = IS() CHKERR( SNESVIGetInactiveSet(self.snes, &inact.iset) ) CHKERR( PetscINCREF(inact.obj) ) return inact # --- Python --- def createPython(self, context: Any = None, comm: Comm | None = None) -> Self: """Create a nonlinear solver of Python type. Collective. Parameters ---------- context An instance of the Python class implementing the required methods. comm MPI communicator, defaults to `Sys.getDefaultComm`. See Also -------- petsc_python_snes, setType, setPythonContext, Type.PYTHON """ cdef MPI_Comm ccomm = def_Comm(comm, PETSC_COMM_DEFAULT) cdef PetscSNES newsnes = NULL CHKERR( SNESCreate(ccomm, &newsnes) ) CHKERR( PetscCLEAR(self.obj) ); self.snes = newsnes CHKERR( SNESSetType(self.snes, SNESPYTHON) ) CHKERR( SNESPythonSetContext(self.snes, context) ) return self def setPythonContext(self, context: Any) -> None: """Set the instance of the class implementing the required Python methods. Not collective. See Also -------- petsc_python_snes, getPythonContext """ CHKERR( SNESPythonSetContext(self.snes, context) ) def getPythonContext(self) -> Any: """Return the instance of the class implementing the required Python methods. Not collective. See Also -------- petsc_python_snes, setPythonContext """ cdef void *context = NULL CHKERR( SNESPythonGetContext(self.snes, &context) ) if context == NULL: return None else: return context def setPythonType(self, py_type: str) -> None: """Set the fully qualified Python name of the class to be used. Collective. See Also -------- petsc_python_snes, setPythonContext, getPythonType petsc.SNESPythonSetType """ cdef const char *cval = NULL py_type = str2bytes(py_type, &cval) CHKERR( SNESPythonSetType(self.snes, cval) ) def getPythonType(self) -> str: """Return the fully qualified Python name of the class used by the solver. Not collective. See Also -------- petsc_python_snes, setPythonContext, setPythonType petsc.SNESPythonGetType """ cdef const char *cval = NULL CHKERR( SNESPythonGetType(self.snes, &cval) ) return bytes2str(cval) # --- Composite --- def getCompositeSNES(self, int n) -> SNES: """Return the n-th solver in the composite. Not collective. See Also -------- getCompositeNumber, petsc.SNESCompositeGetSNES, petsc.SNESCOMPOSITE """ cdef PetscInt cn cdef SNES snes = SNES() cn = asInt(n) CHKERR( SNESCompositeGetSNES(self.snes, cn, &snes.snes) ) CHKERR( PetscINCREF(snes.obj) ) return snes def getCompositeNumber(self) -> int: """Return the number of solvers in the composite. Not collective. See Also -------- getCompositeSNES, petsc.SNESCompositeGetNumber, petsc.SNESCOMPOSITE """ cdef PetscInt cn = 0 CHKERR( SNESCompositeGetNumber(self.snes, &cn) ) return toInt(cn) # --- NASM --- def getNASMSNES(self, n: int) -> SNES: """Return the n-th solver in NASM. Not collective. See Also -------- getNASMNumber, petsc.SNESNASMGetSNES, petsc.SNESNASM """ cdef PetscInt cn = asInt(n) cdef SNES snes = SNES() CHKERR( SNESNASMGetSNES(self.snes, cn, &snes.snes) ) CHKERR( PetscINCREF(snes.obj) ) return snes def getNASMNumber(self) -> int: """Return the number of solvers in NASM. Not collective. See Also -------- getNASMSNES, petsc.SNESNASMGetNumber, petsc.SNESNASM """ cdef PetscInt cn = 0 CHKERR( SNESNASMGetNumber(self.snes, &cn) ) return toInt(cn) # --- Patch --- def setPatchCellNumbering(self, Section sec) -> None: """Set cell patch numbering.""" CHKERR( SNESPatchSetCellNumbering(self.snes, sec.sec) ) def setPatchDiscretisationInfo(self, dms, bs, cellNodeMaps, subspaceOffsets, ghostBcNodes, globalBcNodes) -> None: """Set patch discretisation information.""" cdef PetscInt numSubSpaces = 0 cdef PetscInt numGhostBcs = 0, numGlobalBcs = 0 cdef PetscInt *nodesPerCell = NULL cdef const PetscInt **ccellNodeMaps = NULL cdef PetscDM *cdms = NULL cdef PetscInt *cbs = NULL cdef PetscInt *csubspaceOffsets = NULL cdef PetscInt *cghostBcNodes = NULL cdef PetscInt *cglobalBcNodes = NULL cdef PetscInt i = 0 bs = iarray_i(bs, &numSubSpaces, &cbs) ghostBcNodes = iarray_i(ghostBcNodes, &numGhostBcs, &cghostBcNodes) globalBcNodes = iarray_i(globalBcNodes, &numGlobalBcs, &cglobalBcNodes) subspaceOffsets = iarray_i(subspaceOffsets, NULL, &csubspaceOffsets) CHKERR( PetscMalloc(numSubSpaces*sizeof(PetscInt), &nodesPerCell) ) CHKERR( PetscMalloc(numSubSpaces*sizeof(PetscDM), &cdms) ) CHKERR( PetscMalloc(numSubSpaces*sizeof(PetscInt*), &ccellNodeMaps) ) for i in range(numSubSpaces): cdms[i] = (dms[i]).dm _, nodes = asarray(cellNodeMaps[i]).shape cellNodeMaps[i] = iarray_i(cellNodeMaps[i], NULL, &(ccellNodeMaps[i])) nodesPerCell[i] = asInt(nodes) # TODO: refactor on the PETSc side to take ISes? CHKERR( SNESPatchSetDiscretisationInfo(self.snes, numSubSpaces, cdms, cbs, nodesPerCell, ccellNodeMaps, csubspaceOffsets, numGhostBcs, cghostBcNodes, numGlobalBcs, cglobalBcNodes) ) CHKERR( PetscFree(nodesPerCell) ) CHKERR( PetscFree(cdms) ) CHKERR( PetscFree(ccellNodeMaps) ) def setPatchComputeOperator(self, operator, args=None, kargs=None) -> None: """Set patch compute operator.""" if args is None: args = () if kargs is None: kargs = {} context = (operator, args, kargs) self.set_attr("__patch_compute_operator__", context) CHKERR( SNESPatchSetComputeOperator(self.snes, PCPatch_ComputeOperator, context) ) def setPatchComputeFunction(self, function, args=None, kargs=None) -> None: """Set patch compute function.""" if args is None: args = () if kargs is None: kargs = {} context = (function, args, kargs) self.set_attr("__patch_compute_function__", context) CHKERR( SNESPatchSetComputeFunction(self.snes, PCPatch_ComputeFunction, context) ) def setPatchConstructType(self, typ, operator=None, args=None, kargs=None) -> None: """Set patch construct type.""" if args is None: args = () if kargs is None: kargs = {} if typ in {PC.PatchConstructType.PYTHON, PC.PatchConstructType.USER} and operator is None: raise ValueError("Must provide operator for USER or PYTHON type") if operator is not None: context = (operator, args, kargs) else: context = None self.set_attr("__patch_construction_operator__", context) CHKERR( SNESPatchSetConstructType(self.snes, typ, PCPatch_UserConstructOperator, context) ) # --- application context --- property appctx: """Application context.""" def __get__(self) -> Any: return self.getAppCtx() def __set__(self, value): self.setAppCtx(value) # --- discretization space --- property dm: """`DM`.""" def __get__(self) -> DM: return self.getDM() def __set__(self, value): self.setDM(value) # --- nonlinear preconditioner --- property npc: """Nonlinear preconditioner.""" def __get__(self) -> SNES: return self.getNPC() def __set__(self, value): self.setNPC(value) # --- vectors --- property vec_sol: """Solution vector.""" def __get__(self) -> Vec: return self.getSolution() property vec_upd: """Update vector.""" def __get__(self) -> Vec: return self.getSolutionUpdate() property vec_rhs: """Right-hand side vector.""" def __get__(self) -> Vec: return self.getRhs() # --- linear solver --- property ksp: """Linear solver.""" def __get__(self) -> KSP: return self.getKSP() def __set__(self, value): self.setKSP(value) property use_ew: def __get__(self): return self.getUseEW() def __set__(self, value): self.setUseEW(value) # --- tolerances --- property rtol: """Relative residual tolerance.""" def __get__(self) -> float: return self.getTolerances()[0] def __set__(self, value): self.setTolerances(rtol=value) property atol: """Absolute residual tolerance.""" def __get__(self) -> float: return self.getTolerances()[1] def __set__(self, value): self.setTolerances(atol=value) property stol: """Solution update tolerance.""" def __get__(self) -> float: return self.getTolerances()[2] def __set__(self, value): self.setTolerances(stol=value) property max_it: """Maximum number of iterations.""" def __get__(self) -> int: return self.getTolerances()[3] def __set__(self, value): self.setTolerances(max_it=value) # --- more tolerances --- property max_funcs: """Maximum number of function evaluations.""" def __get__(self) -> int: return self.getMaxFunctionEvaluations() def __set__(self, value): self.setMaxFunctionEvaluations(value) # --- iteration --- property its: """Number of iterations.""" def __get__(self) -> int: return self.getIterationNumber() def __set__(self, value): self.setIterationNumber(value) property norm: """Function norm.""" def __get__(self) -> float: return self.getFunctionNorm() def __set__(self, value): self.setFunctionNorm(value) property history: """Convergence history.""" def __get__(self) -> tuple[ArrayReal, ArrayInt]: return self.getConvergenceHistory() # --- convergence --- property reason: """Converged reason.""" def __get__(self) -> ConvergedReason: return self.getConvergedReason() def __set__(self, value): self.setConvergedReason(value) property is_iterating: """Boolean indicating if the solver has not converged yet.""" def __get__(self) -> bool: return self.reason == 0 property is_converged: """Boolean indicating if the solver has converged.""" def __get__(self) -> bool: return self.reason > 0 property is_diverged: """Boolean indicating if the solver has failed.""" def __get__(self) -> bool: return self.reason < 0 # --- matrix-free / finite differences --- property use_mf: """Boolean indicating if the solver uses matrix-free finite-differencing.""" def __get__(self) -> bool: return self.getUseMF() def __set__(self, value): self.setUseMF(value) property use_fd: """Boolean indicating if the solver uses coloring finite-differencing.""" def __get__(self) -> bool: return self.getUseFD() def __set__(self, value): self.setUseFD(value) # -------------------------------------------------------------------- del SNESType del SNESNormSchedule del SNESConvergedReason # -------------------------------------------------------------------- ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/src/petsc4py/PETSc/Scatter.pyx0000644000175000017500000002206514567251135020023 0ustar00balaybalay# -------------------------------------------------------------------- class ScatterType(object): """Scatter type. See Also -------- petsc.VecScatterType """ BASIC = S_(PETSCSFBASIC) NEIGHBOR = S_(PETSCSFNEIGHBOR) ALLGATHERV = S_(PETSCSFALLGATHERV) ALLGATHER = S_(PETSCSFALLGATHER) GATHERV = S_(PETSCSFGATHERV) GATHER = S_(PETSCSFGATHER) ALLTOALL = S_(PETSCSFALLTOALL) WINDOW = S_(PETSCSFWINDOW) # -------------------------------------------------------------------- cdef class Scatter(Object): """Scatter object. The object used to perform data movement between vectors. Scatter is described in the `PETSc manual `. See Also -------- Vec, SF, petsc.VecScatter """ Type = ScatterType Mode = ScatterMode # def __cinit__(self): self.obj = &self.sct self.sct = NULL def __call__(self, x, y, addv=None, mode=None): """Perform the scatter. Collective. See Also -------- scatter """ self.scatter(x, y, addv, mode) # def view(self, Viewer viewer=None) -> None: """View the scatter. Collective. Parameters ---------- viewer A `Viewer` instance or `None` for the default viewer. See Also -------- petsc.VecScatterView """ cdef PetscViewer vwr = NULL if viewer is not None: vwr = viewer.vwr CHKERR( VecScatterView(self.sct, vwr) ) def destroy(self) -> Self: """Destroy the scatter. Collective. See Also -------- petsc.VecScatterDestroy """ CHKERR( VecScatterDestroy(&self.sct) ) return self def create( self, Vec vec_from, IS is_from or None, Vec vec_to, IS is_to or None, ) -> Self: """Create a scatter object. Collective. Parameters ---------- vec_from Representative vector from which to scatter the data. is_from Indices of ``vec_from`` to scatter. If `None`, use all indices. vec_to Representative vector to which scatter the data. is_to Indices of ``vec_to`` where to receive. If `None`, use all indices. Examples -------- The scatter object can be used to repeatedly perform data movement. It is the PETSc equivalent of NumPy-like indexing and slicing, with support for parallel communications: >>> revmode = PETSc.Scatter.Mode.REVERSE >>> v1 = PETSc.Vec().createWithArray([1, 2, 3]) >>> v2 = PETSc.Vec().createWithArray([0, 0, 0]) >>> sct = PETSc.Scatter().create(v1,None,v2,None) >>> sct.scatter(v1,v2) # v2[:] = v1[:] >>> sct.scatter(v2,v1,mode=revmode) # v1[:] = v2[:] >>> revmode = PETSc.Scatter.Mode.REVERSE >>> v1 = PETSc.Vec().createWithArray([1, 2, 3, 4]) >>> v2 = PETSc.Vec().createWithArray([0, 0]) >>> is1 = PETSc.IS().createStride(2, 3, -2) >>> sct = PETSc.Scatter().create(v1,is1,v2,None) >>> sct.scatter(v1,v2) # v2[:] = v1[3:0:-2] >>> sct.scatter(v2,v1,mode=revmode) # v1[3:0:-2] = v2[:] See Also -------- IS, petsc.VecScatterCreate """ cdef PetscIS cisfrom = NULL, cisto = NULL if is_from is not None: cisfrom = is_from.iset if is_to is not None: cisto = is_to.iset cdef PetscScatter newsct = NULL CHKERR( VecScatterCreate( vec_from.vec, cisfrom, vec_to.vec, cisto, &newsct) ) CHKERR( PetscCLEAR(self.obj) ); self.sct = newsct return self def setType(self, scatter_type: Type | str) -> None: """Set the type of the scatter. Logically collective. See Also -------- getType, petsc.VecScatterSetType """ cdef PetscScatterType cval = NULL vec_type = str2bytes(scatter_type, &cval) CHKERR( VecScatterSetType(self.sct, cval) ) def getType(self) -> str: """Return the type of the scatter. Not collective. See Also -------- setType, petsc.VecScatterGetType """ cdef PetscScatterType cval = NULL CHKERR( VecScatterGetType(self.sct, &cval) ) return bytes2str(cval) def setFromOptions(self) -> None: """Configure the scatter from the options database. Collective. See Also -------- petsc_options, petsc.VecScatterSetFromOptions """ CHKERR( VecScatterSetFromOptions(self.sct) ) def setUp(self) -> Self: """Set up the internal data structures for using the scatter. Collective. See Also -------- petsc.VecScatterSetUp """ CHKERR( VecScatterSetUp(self.sct) ) return self def copy(self) -> Scatter: """Return a copy of the scatter.""" cdef Scatter scatter = Scatter() CHKERR( VecScatterCopy(self.sct, &scatter.sct) ) return scatter @classmethod def toAll(cls, Vec vec) -> tuple[Scatter, Vec]: """Create a scatter that communicates a vector to all sharing processes. Collective. Parameters ---------- vec The vector to scatter from. Notes ----- The created scatter will have the same communicator of ``vec``. The method also returns an output vector of appropriate size to contain the result of the operation. See Also -------- toZero, petsc.VecScatterCreateToAll """ cdef Scatter scatter = Scatter() cdef Vec ovec = Vec() CHKERR( VecScatterCreateToAll( vec.vec, &scatter.sct, &ovec.vec) ) return (scatter, ovec) @classmethod def toZero(cls, Vec vec) -> tuple[Scatter, Vec]: """Create a scatter that communicates a vector to rank zero. Collective. Parameters ---------- vec The vector to scatter from. Notes ----- The created scatter will have the same communicator of ``vec``. The method also returns an output vector of appropriate size to contain the result of the operation. See Also -------- toAll, petsc.VecScatterCreateToZero """ cdef Scatter scatter = Scatter() cdef Vec ovec = Vec() CHKERR( VecScatterCreateToZero( vec.vec, &scatter.sct, &ovec.vec) ) return (scatter, ovec) # def begin( self, Vec vec_from, Vec vec_to, addv: InsertModeSpec = None, mode: ScatterModeSpec = None, ) -> None: """Begin a generalized scatter from one vector into another. Collective. This call has to be concluded with a call to `end`. For additional details on the Parameters, see `scatter`. See Also -------- create, end, petsc.VecScatterBegin """ cdef PetscInsertMode caddv = insertmode(addv) cdef PetscScatterMode csctm = scattermode(mode) CHKERR( VecScatterBegin(self.sct, vec_from.vec, vec_to.vec, caddv, csctm) ) def end( self, Vec vec_from, Vec vec_to, addv: InsertModeSpec = None, mode: ScatterModeSpec = None, ) -> None: """Complete a generalized scatter from one vector into another. Collective. This call has to be preceded by a call to `begin`. For additional details on the Parameters, see `scatter`. See Also -------- create, begin, petsc.VecScatterEnd """ cdef PetscInsertMode caddv = insertmode(addv) cdef PetscScatterMode csctm = scattermode(mode) CHKERR( VecScatterEnd(self.sct, vec_from.vec, vec_to.vec, caddv, csctm) ) def scatter( self, Vec vec_from, Vec vec_to, addv: InsertModeSpec = None, mode: ScatterModeSpec = None, ) -> None: """Perform a generalized scatter from one vector into another. Collective. Parameters ---------- vec_from The source vector. vec_to The destination vector. addv Insertion mode. mode Scatter mode. See Also -------- create, begin, end, petsc.VecScatterBegin, petsc.VecScatterEnd """ cdef PetscInsertMode caddv = insertmode(addv) cdef PetscScatterMode csctm = scattermode(mode) CHKERR( VecScatterBegin(self.sct, vec_from.vec, vec_to.vec, caddv, csctm) ) CHKERR( VecScatterEnd(self.sct, vec_from.vec, vec_to.vec, caddv, csctm) ) scatterBegin = begin scatterEnd = end # -------------------------------------------------------------------- del ScatterType # -------------------------------------------------------------------- ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/src/petsc4py/PETSc/Section.pyx0000644000175000017500000005702414567251135020025 0ustar00balaybalay# -------------------------------------------------------------------- cdef class Section(Object): """Mapping from integers in a range to unstructured set of integers.""" def __cinit__(self): self.obj = &self.sec self.sec = NULL def __dealloc__(self): CHKERR( PetscSectionDestroy(&self.sec) ) self.sec = NULL def view(self, Viewer viewer=None) -> None: """View the section. Collective. Parameters ---------- viewer A `Viewer` to display the section. See Also -------- petsc.PetscSectionView """ cdef PetscViewer vwr = NULL if viewer is not None: vwr = viewer.vwr CHKERR( PetscSectionView(self.sec, vwr) ) def destroy(self) -> Self: """Destroy a section. Not collective. See Also -------- petsc.PetscSectionDestroy """ CHKERR( PetscSectionDestroy(&self.sec) ) return self def create(self, comm: Comm | None = None) -> Self: """Allocate a section and set the map contents to the default. Collective. Typical calling sequence: - `create` - `setNumFields` - `setChart` - `setDof` - `setUp` - `getOffset` - `destroy` The `Section` object and methods are intended to be used in the PETSc Vec and Mat implementations. The indices returned by the `Section` are appropriate for the kind of `Vec` it is associated with. For example, if the vector being indexed is a local vector, we call the section a local section. If the section indexes a global vector, we call it a global section. For parallel vectors, like global vectors, we use negative indices to indicate DOFs owned by other processes. Parameters ---------- comm MPI communicator, defaults to `Sys.getDefaultComm`. See Also -------- petsc.PetscSectionCreate """ cdef MPI_Comm ccomm = def_Comm(comm, PETSC_COMM_DEFAULT) cdef PetscSection newsec = NULL CHKERR( PetscSectionCreate(ccomm, &newsec) ) CHKERR( PetscCLEAR(self.obj) ); self.sec = newsec return self def clone(self) -> Section: """Return a copy of the section. Collective. The copy is shallow, if possible. See Also -------- petsc.PetscSectionClone """ cdef Section sec =
type(self)() CHKERR( PetscSectionClone(self.sec, &sec.sec) ) return sec def setUp(self) -> None: """Calculate offsets. Not collective. Offsets are based on the number of degrees of freedom for each point. See Also -------- petsc.PetscSectionSetUp """ CHKERR( PetscSectionSetUp(self.sec) ) def reset(self) -> None: """Free all section data. Not collective. See Also -------- petsc.PetscSectionReset """ CHKERR( PetscSectionReset(self.sec) ) def getNumFields(self) -> int: """Return the number of fields in a section. Not collective. Returns ``0`` if no fields were defined. See Also -------- setNumFields, petsc.PetscSectionGetNumFields """ cdef PetscInt numFields = 0 CHKERR( PetscSectionGetNumFields(self.sec, &numFields) ) return toInt(numFields) def setNumFields(self, numFields: int) -> None: """Set the number of fields in a section. Not collective. Parameters ---------- numFields The number of fields. See Also -------- getNumFields, petsc.PetscSectionSetNumFields """ cdef PetscInt cnumFields = asInt(numFields) CHKERR( PetscSectionSetNumFields(self.sec, cnumFields) ) def getFieldName(self, field: int) -> str: """Return the name of a field in the section. Not collective. Parameters ---------- field The field number. See Also -------- setFieldName, petsc.PetscSectionGetFieldName """ cdef PetscInt cfield = asInt(field) cdef const char *fieldName = NULL CHKERR( PetscSectionGetFieldName(self.sec,cfield,&fieldName) ) return bytes2str(fieldName) def setFieldName(self, field: int, fieldName: str) -> None: """Set the name of a field in the section. Not collective. Parameters ---------- field The field number. fieldName The field name. See Also -------- getFieldName, petsc.PetscSectionSetFieldName """ cdef PetscInt cfield = asInt(field) cdef const char *cname = NULL fieldName = str2bytes(fieldName, &cname) CHKERR( PetscSectionSetFieldName(self.sec,cfield,cname) ) def getFieldComponents(self, field: int) -> int: """Return the number of field components for the given field. Not collective. Parameters ---------- field The field number. See Also -------- setFieldComponents, petsc.PetscSectionGetFieldComponents """ cdef PetscInt cfield = asInt(field), cnumComp = 0 CHKERR( PetscSectionGetFieldComponents(self.sec,cfield,&cnumComp) ) return toInt(cnumComp) def setFieldComponents(self, field: int, numComp: int) -> None: """Set the number of field components for the given field. Not collective. Parameters ---------- field The field number. numComp The number of field components. See Also -------- getFieldComponents, petsc.PetscSectionSetFieldComponents """ cdef PetscInt cfield = asInt(field) cdef PetscInt cnumComp = asInt(numComp) CHKERR( PetscSectionSetFieldComponents(self.sec,cfield,cnumComp) ) def getChart(self) -> tuple[int, int]: """Return the range in which points (indices) lie for this section. Not collective. The range is [pStart, pEnd), i.e., from the first point to one past the last point. See Also -------- petsc.PetscSectionGetChart """ cdef PetscInt pStart = 0, pEnd = 0 CHKERR( PetscSectionGetChart(self.sec, &pStart, &pEnd) ) return toInt(pStart), toInt(pEnd) def setChart(self, pStart: int, pEnd: int) -> None: """Set the range in which points (indices) lie for this section. Not collective. The range is [pStart, pEnd), i.e., from the first point to one past the last point. Parameters ---------- pStart The first point. pEnd One past the last point. See Also -------- petsc.PetscSectionSetChart """ cdef PetscInt cStart = asInt(pStart) cdef PetscInt cEnd = asInt(pEnd) CHKERR( PetscSectionSetChart(self.sec, cStart, cEnd) ) def getPermutation(self) -> IS: """Return the permutation that was set with `setPermutation`. Not collective. See Also -------- setPermutation, petsc.PetscSectionGetPermutation """ cdef IS perm = IS() CHKERR( PetscSectionGetPermutation(self.sec, &perm.iset)) CHKERR( PetscINCREF(perm.obj) ) return perm def setPermutation(self, IS perm) -> None: """Set the permutation for [0, pEnd - pStart). Not collective. Parameters ---------- perm The permutation of points. See Also -------- getPermutation, petsc.PetscSectionSetPermutation """ CHKERR( PetscSectionSetPermutation(self.sec, perm.iset)) def getDof(self, point: int) -> int: """Return the number of degrees of freedom for a given point. Not collective. In a global section, this value will be negative for points not owned by this process. Parameters ---------- point The point. See Also -------- setDof, addDof, petsc.PetscSectionGetDof """ cdef PetscInt cpoint = asInt(point), cnumDof = 0 CHKERR( PetscSectionGetDof(self.sec,cpoint,&cnumDof) ) return toInt(cnumDof) def setDof(self, point: int, numDof: int) -> None: """Set the number of degrees of freedom associated with a given point. Not collective. Parameters ---------- point The point. numDof The number of DOFs. See Also -------- getDof, addDof, petsc.PetscSectionSetDof """ cdef PetscInt cpoint = asInt(point) cdef PetscInt cnumDof = asInt(numDof) CHKERR( PetscSectionSetDof(self.sec,cpoint,cnumDof) ) def addDof(self, point: int, numDof: int) -> None: """Add ``numDof`` degrees of freedom associated with a given point. Not collective. Parameters ---------- point The point. numDof The number of additional DOFs. See Also -------- setDof, getDof, petsc.PetscSectionAddDof """ cdef PetscInt cpoint = asInt(point) cdef PetscInt cnumDof = asInt(numDof) CHKERR( PetscSectionAddDof(self.sec,cpoint,cnumDof) ) def getFieldDof(self, point: int, field: int) -> int: """Return the number of DOFs associated with a field on a given point. Not collective. Parameters ---------- point The point. field The field. See Also -------- setFieldDof, petsc.PetscSectionGetFieldDof """ cdef PetscInt cpoint = asInt(point), cnumDof = 0 cdef PetscInt cfield = asInt(field) CHKERR( PetscSectionGetFieldDof(self.sec,cpoint,cfield,&cnumDof) ) return toInt(cnumDof) def setFieldDof(self, point: int, field: int, numDof: int) -> None: """Set the number of DOFs associated with a field on a given point. Not collective. Parameters ---------- point The point. field The field. numDof The number of DOFs. See Also -------- getFieldDof, addFieldDof, petsc.PetscSectionSetFieldDof """ cdef PetscInt cpoint = asInt(point) cdef PetscInt cfield = asInt(field) cdef PetscInt cnumDof = asInt(numDof) CHKERR( PetscSectionSetFieldDof(self.sec,cpoint,cfield,cnumDof) ) def addFieldDof(self, point: int, field: int, numDof: int) -> None: """Add ``numDof`` DOFs associated with a field on a given point. Not collective. Parameters ---------- point The point. field The field. numDof The number of additional DOFs. See Also -------- setFieldDof, getFieldDof, petsc.PetscSectionAddFieldDof """ cdef PetscInt cpoint = asInt(point) cdef PetscInt cfield = asInt(field) cdef PetscInt cnumDof = asInt(numDof) CHKERR( PetscSectionAddFieldDof(self.sec,cpoint,cfield,cnumDof) ) def getConstraintDof(self, point: int) -> int: """Return the number of constrained DOFs associated with a given point. Not collective. Parameters ---------- point The point. See Also -------- setConstraintDof, petsc.PetscSectionGetConstraintDof """ cdef PetscInt cpoint = asInt(point), cnumDof = 0 CHKERR( PetscSectionGetConstraintDof(self.sec,cpoint,&cnumDof) ) return toInt(cnumDof) def setConstraintDof(self, point: int, numDof: int) -> None: """Set the number of constrained DOFs associated with a given point. Not collective. Parameters ---------- point The point. numDof The number of DOFs which are fixed by constraints. See Also -------- getConstraintDof, addConstraintDof, petsc.PetscSectionSetConstraintDof """ cdef PetscInt cpoint = asInt(point) cdef PetscInt cnumDof = asInt(numDof) CHKERR( PetscSectionSetConstraintDof(self.sec,cpoint,cnumDof) ) def addConstraintDof(self, point: int, numDof: int) -> None: """Increment the number of constrained DOFs for a given point. Not collective. Parameters ---------- point The point. numDof The number of additional DOFs which are fixed by constraints. See Also -------- setConstraintDof, getConstraintDof, petsc.PetscSectionAddConstraintDof """ cdef PetscInt cpoint = asInt(point) cdef PetscInt cnumDof = asInt(numDof) CHKERR( PetscSectionAddConstraintDof(self.sec,cpoint,cnumDof) ) def getFieldConstraintDof(self, point: int, field: int) -> int: """Return the number of constrained DOFs for a given field on a point. Not collective. Parameters ---------- point The point. field The field. See Also -------- setFieldConstraintDof, petsc.PetscSectionGetFieldConstraintDof """ cdef PetscInt cpoint = asInt(point), cnumDof = 0 cdef PetscInt cfield = asInt(field) CHKERR( PetscSectionGetFieldConstraintDof(self.sec,cpoint,cfield,&cnumDof) ) return toInt(cnumDof) def setFieldConstraintDof( self, point: int, field: int, numDof: int, ) -> None: """Set the number of constrained DOFs for a given field on a point. Not collective. Parameters ---------- point The point. field The field. numDof The number of DOFs which are fixed by constraints. See Also -------- getFieldConstraintDof, addFieldConstraintDof petsc.PetscSectionSetFieldConstraintDof """ cdef PetscInt cpoint = asInt(point) cdef PetscInt cfield = asInt(field) cdef PetscInt cnumDof = asInt(numDof) CHKERR( PetscSectionSetFieldConstraintDof(self.sec,cpoint,cfield,cnumDof) ) def addFieldConstraintDof( self, point: int, field: int, numDof: int, ) -> None: """Add ``numDof`` constrained DOFs for a given field on a point. Not collective. Parameters ---------- point The point. field The field. numDof The number of additional DOFs which are fixed by constraints. See Also -------- setFieldConstraintDof, getFieldConstraintDof petsc.PetscSectionAddFieldConstraintDof """ cdef PetscInt cpoint = asInt(point) cdef PetscInt cfield = asInt(field) cdef PetscInt cnumDof = asInt(numDof) CHKERR( PetscSectionAddFieldConstraintDof(self.sec,cpoint,cfield,cnumDof) ) def getConstraintIndices(self, point: int) -> ArrayInt: """Return the point DOFs numbers which are constrained for a given point. Not collective. The range is in [0, DOFs). Parameters ---------- point The point. See Also -------- setConstraintIndices, petsc.PetscSectionGetConstraintIndices """ cdef PetscInt cpoint = asInt(point) cdef PetscInt nindex = 0 cdef const PetscInt *indices = NULL CHKERR( PetscSectionGetConstraintDof(self.sec, cpoint, &nindex) ) CHKERR( PetscSectionGetConstraintIndices(self.sec, cpoint, &indices) ) return array_i(nindex, indices) def setConstraintIndices(self, point: int, indices: Sequence[int]) -> None: """Set the point DOFs numbers, in [0, DOFs), which are constrained. Not collective. Parameters ---------- point The point. indices The constrained DOFs. See Also -------- getConstraintIndices, petsc.PetscSectionSetConstraintIndices """ cdef PetscInt cpoint = asInt(point) cdef PetscInt nindex = 0 cdef PetscInt *cindices = NULL indices = iarray_i(indices, &nindex, &cindices) CHKERR( PetscSectionSetConstraintDof(self.sec,cpoint,nindex) ) CHKERR( PetscSectionSetConstraintIndices(self.sec,cpoint,cindices) ) def getFieldConstraintIndices(self, point: int, field: int) -> ArrayInt: """Return the field DOFs numbers, in [0, DOFs), which are constrained. Not collective. The constrained DOFs are sorted in ascending order. Parameters ---------- field The field number. point The point. See Also -------- setFieldConstraintIndices, petsc.PetscSectionGetFieldConstraintIndices """ cdef PetscInt cpoint = asInt(point) cdef PetscInt cfield = asInt(field) cdef PetscInt nindex = 0 cdef const PetscInt *indices = NULL CHKERR( PetscSectionGetFieldConstraintDof(self.sec,cpoint,cfield,&nindex) ) CHKERR( PetscSectionGetFieldConstraintIndices(self.sec,cpoint,cfield,&indices) ) return array_i(nindex, indices) def setFieldConstraintIndices( self, point: int, field: int, indices: Sequence[int], ) -> None: """Set the field DOFs numbers, in [0, DOFs), which are constrained. Not collective. Parameters ---------- point The point. field The field number. indices The constrained DOFs. See Also -------- getFieldConstraintIndices, petsc.PetscSectionSetFieldConstraintIndices """ cdef PetscInt cpoint = asInt(point) cdef PetscInt cfield = asInt(field) cdef PetscInt nindex = 0 cdef PetscInt *cindices = NULL indices = iarray_i(indices, &nindex, &cindices) CHKERR( PetscSectionSetFieldConstraintDof(self.sec,cpoint,cfield,nindex) ) CHKERR( PetscSectionSetFieldConstraintIndices(self.sec,cpoint,cfield,cindices) ) def getMaxDof(self) -> int: """Return the maximum number of DOFs for any point in the section. Not collective. See Also -------- petsc.PetscSectionGetMaxDof """ cdef PetscInt maxDof = 0 CHKERR( PetscSectionGetMaxDof(self.sec,&maxDof) ) return toInt(maxDof) def getStorageSize(self) -> int: """Return the size capable of holding all the DOFs defined in a section. Not collective. See Also -------- getConstrainedStorageSize, petsc.PetscSectionGetStorageSize """ cdef PetscInt size = 0 CHKERR( PetscSectionGetStorageSize(self.sec,&size) ) return toInt(size) def getConstrainedStorageSize(self) -> int: """Return the size capable of holding all unconstrained DOFs in a section. Not collective. See Also -------- getStorageSize, petsc.PetscSectionGetConstrainedStorageSize """ cdef PetscInt size = 0 CHKERR( PetscSectionGetConstrainedStorageSize(self.sec,&size) ) return toInt(size) def getOffset(self, point: int) -> int: """Return the offset for the DOFs associated with the given point. Not collective. In a global section, this offset will be negative for points not owned by this process. Parameters ---------- point The point. See Also -------- setOffset, petsc.PetscSectionGetOffset """ cdef PetscInt cpoint = asInt(point), offset = 0 CHKERR( PetscSectionGetOffset(self.sec,cpoint,&offset) ) return toInt(offset) def setOffset(self, point: int, offset: int) -> None: """Set the offset for the DOFs associated with the given point. Not collective. The user usually does not call this function, but uses `setUp`. Parameters ---------- point The point. offset The offset. See Also -------- getOffset, petsc.PetscSectionSetOffset """ cdef PetscInt cpoint = asInt(point) cdef PetscInt coffset = asInt(offset) CHKERR( PetscSectionSetOffset(self.sec,cpoint,coffset) ) def getFieldOffset(self, point: int, field: int) -> int: """Return the offset for the field DOFs on the given point. Not collective. In a global section, this offset will be negative for points not owned by this process. Parameters ---------- point The point. field The field. See Also -------- setFieldOffset, petsc.PetscSectionGetFieldOffset """ cdef PetscInt cpoint = asInt(point) cdef PetscInt cfield = asInt(field) cdef PetscInt offset = 0 CHKERR( PetscSectionGetFieldOffset(self.sec,cpoint,cfield,&offset) ) return toInt(offset) def setFieldOffset(self, point: int, field: int, offset: int) -> None: """Set the offset for the DOFs on the given field at a point. Not collective. The user usually does not call this function, but uses `setUp`. Parameters ---------- point The point. field The field. offset The offset. See Also -------- getFieldOffset, petsc.PetscSectionSetFieldOffset """ cdef PetscInt cpoint = asInt(point) cdef PetscInt cfield = asInt(field) cdef PetscInt coffset = asInt(offset) CHKERR( PetscSectionSetFieldOffset(self.sec,cpoint,cfield,coffset) ) def getOffsetRange(self) -> tuple[int,int]: """Return the full range of offsets, [start, end), for a section. Not collective. See Also -------- petsc.PetscSectionGetOffsetRange """ cdef PetscInt oStart = 0, oEnd = 0 CHKERR( PetscSectionGetOffsetRange(self.sec,&oStart,&oEnd) ) return toInt(oStart),toInt(oEnd) # FIXME: Hardcoded PETSC_FALSE parameters def createGlobalSection(self, SF sf) -> Section: """Create a section describing the global field layout. Collective. The section describes the global field layout using the local section and an `SF` describing the section point overlap. If we have a set of local sections defining the layout of a set of local vectors, and also an `SF` to determine which section points are shared and the ownership, we can calculate a global section defining the parallel data layout, and the associated global vector. This gives negative sizes and offsets to points not owned by this process. ``includeConstraints`` and ``localOffsets`` parameters of the C API are always set to `False`. Parameters ---------- sf The `SF` describing the parallel layout of the section points (leaves are unowned local points). See Also -------- petsc.PetscSectionCreateGlobalSection """ cdef Section gsec = Section() CHKERR( PetscSectionCreateGlobalSection(self.sec,sf.sf,PETSC_FALSE,PETSC_FALSE,&gsec.sec) ) return gsec ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/src/petsc4py/PETSc/Space.pyx0000644000175000017500000006541614567251135017460 0ustar00balaybalay# -------------------------------------------------------------------- class SpaceType(object): POLYNOMIAL = S_(PETSCSPACEPOLYNOMIAL) PTRIMMED = S_(PETSCSPACEPTRIMMED) TENSOR = S_(PETSCSPACETENSOR) SUM = S_(PETSCSPACESUM) POINT = S_(PETSCSPACEPOINT) SUBSPACE = S_(PETSCSPACESUBSPACE) WXY = S_(PETSCSPACEWXY) # -------------------------------------------------------------------- cdef class Space(Object): """Linear space object.""" Type = SpaceType def __cinit__(self): self.obj = &self.space self.space = NULL def setUp(self) -> None: """Construct data structures for the `Space`. Collective. See Also -------- petsc.PetscSpaceSetUp """ CHKERR( PetscSpaceSetUp(self.space) ) def create(self, comm: Comm | None = None) -> Self: """Create an empty `Space` object. Collective. The type can then be set with `setType`. Parameters ---------- comm MPI communicator, defaults to `Sys.getDefaultComm`. See Also -------- petsc.PetscSpaceCreate """ cdef MPI_Comm ccomm = def_Comm(comm, PETSC_COMM_DEFAULT) cdef PetscSpace newsp = NULL CHKERR( PetscSpaceCreate(ccomm, &newsp) ) CHKERR( PetscCLEAR(self.obj) ); self.space = newsp return self def destroy(self) -> Self: """Destroy the `Space` object. Collective. See Also -------- petsc.PetscSpaceDestroy """ CHKERR( PetscSpaceDestroy(&self.space) ) return self def view(self, Viewer viewer=None) -> None: """View a `Space`. Collective. Parameters ---------- viewer A `Viewer` to display the `Space`. See Also -------- petsc.PetscSpaceView """ cdef PetscViewer vwr = NULL if viewer is not None: vwr = viewer.vwr CHKERR( PetscSpaceView(self.space, vwr) ) def setFromOptions(self) -> None: """Set parameters in `Space` from the options database. Collective. See Also -------- petsc_options, petsc.PetscSpaceSetFromOptions """ CHKERR( PetscSpaceSetFromOptions(self.space) ) def getDimension(self) -> int: """Return the number of basis vectors. See Also -------- petsc.PetscSpaceGetDimension """ cdef PetscInt cdim CHKERR( PetscSpaceGetDimension(self.space, &cdim)) return toInt(cdim) def getDegree(self) -> tuple[int, int]: """Return the polynomial degrees that characterize this space. Returns ------- minDegree : int The degree of the largest polynomial space contained in the space. maxDegree : int The degree of the smallest polynomial space containing the space. See Also -------- setDegree, petsc.PetscSpaceGetDegree """ cdef PetscInt cdegmax, cdegmin CHKERR( PetscSpaceGetDegree(self.space, &cdegmin, &cdegmax)) return toInt(cdegmin), toInt(cdegmax) def setDegree(self, degree: int | None, maxDegree: int | None) -> None: """Set the degree of approximation for this space. One of ``degree`` and ``maxDegree`` can be `None`. Parameters ---------- degree The degree of the largest polynomial space contained in the space. maxDegree The degree of the largest polynomial space containing the space. See Also -------- getDegree, petsc.PetscSpaceSetDegree """ assert( (degree != None) & (maxDegree != None)) cdef PetscInt cdegree = PETSC_DETERMINE if degree is not None: cdegree = asInt(degree) cdef PetscInt cmaxdegree = PETSC_DETERMINE if maxDegree is not None: cmaxdegree = asInt(maxDegree) CHKERR( PetscSpaceSetDegree(self.space, cdegree, cmaxdegree) ) def getNumVariables(self) -> int: """Return the number of variables for this space. See Also -------- setNumVariables, petsc.PetscSpaceGetNumVariables """ cdef PetscInt cnvars CHKERR( PetscSpaceGetNumVariables(self.space, &cnvars)) return toInt(cnvars) def setNumVariables(self, n: int) -> None: """Set the number of variables for this space. Parameters ---------- n The number of variables (``x``, ``y``, ``z`` etc.). See Also -------- getNumVariables, petsc.PetscSpaceSetNumVariables """ cdef PetscInt cn = asInt(n) CHKERR( PetscSpaceSetNumVariables(self.space, cn) ) def getNumComponents(self) -> int: """Return the number of components for this space. See Also -------- setNumComponents, petsc.PetscSpaceGetNumComponents """ cdef PetscInt cncomps CHKERR( PetscSpaceGetNumComponents(self.space, &cncomps)) return toInt(cncomps) def setNumComponents(self, nc: int) -> None: """Set the number of components for this space. Parameters ---------- nc The number of components. See Also -------- getNumComponents, petsc.PetscSpaceSetNumComponents """ cdef PetscInt cnc = asInt(nc) CHKERR( PetscSpaceSetNumComponents(self.space, cnc) ) #def evaluate(self, points): # cdef PetscInt cnpoints = 0, cdim=0, cnfuncs=0 # cdef PetscReal *cpoints = NULL # cdef PetscReal *B = NULL, *D = NULL, *H = NULL # points = iarray_r(points, &cnpoints, &cpoints) # # Get the dimension of the space # CHKERR( PetscSpaceGetDimension( self.space, &cnfuncs) ) # CHKERR( PetscSpace) # CHKERR( PetscSpaceEvaluate(self.space, cnpoints, &cpoints, &B, &D, &H) ) # return array_r(cnpoints*cdim, B), array_r(cnpoints*cnc, D), array_r(, H) def getType(self) -> str: """Return the type of the space object. Not collective. See Also -------- setType, petsc.PetscSpaceGetType """ cdef PetscSpaceType cval = NULL CHKERR( PetscSpaceGetType(self.space, &cval) ) return bytes2str(cval) def setType(self, space_type: Type | str) -> Self: """Build a particular type of space. Collective. Parameters ---------- space_type The kind of space. See Also -------- getType, petsc.PetscSpaceSetType """ cdef PetscSpaceType cval = NULL space_type = str2bytes(space_type, &cval) CHKERR( PetscSpaceSetType(self.space, cval) ) return self def getSumConcatenate(self) -> bool: """Return the concatenate flag for this space. A concatenated sum space will have the number of components equal to the sum of the number of components of all subspaces. A non-concatenated, or direct sum space will have the same number of components as its subspaces. See Also -------- setSumConcatenate, petsc.PetscSpaceSumGetConcatenate """ cdef PetscBool concatenate CHKERR( PetscSpaceSumGetConcatenate(self.space, &concatenate)) return toBool(concatenate) def setSumConcatenate(self, concatenate: bool) -> None: """Set the concatenate flag for this space. A concatenated sum space will have the number of components equal to the sum of the number of components of all subspaces. A non-concatenated, or direct sum space will have the same number of components as its subspaces. Parameters ---------- concatenate `True` if subspaces are concatenated components, `False` if direct summands. See Also -------- getSumConcatenate, petsc.PetscSpaceSumSetConcatenate """ cdef PetscBool cconcatenate = asBool(concatenate) CHKERR( PetscSpaceSumSetConcatenate(self.space, concatenate)) def getSumNumSubspaces(self) -> int: """Return the number of spaces in the sum. See Also -------- setSumNumSubspaces, petsc.PetscSpaceSumGetNumSubspaces """ cdef PetscInt numSumSpaces CHKERR( PetscSpaceSumGetNumSubspaces(self.space, &numSumSpaces)) return toInt(numSumSpaces) def getSumSubspace(self, s: int) -> Space: """Return a space in the sum. Parameters ---------- s The space number. See Also -------- setSumSubspace, petsc.PetscSpaceSumGetSubspace """ cdef Space subsp = Space() cdef PetscInt cs = asInt(s) CHKERR( PetscSpaceSumGetSubspace(self.space, s, &subsp.space) ) return subsp def setSumSubspace(self, s: int, Space subsp) -> None: """Set a space in the sum. Parameters ---------- s The space number. subsp The number of spaces. See Also -------- getSumSubspace, petsc.PetscSpaceSumSetSubspace """ cdef PetscInt cs = asInt(s) CHKERR( PetscSpaceSumSetSubspace(self.space, cs, subsp.space) ) def setSumNumSubspaces(self, numSumSpaces: int) -> None: """Set the number of spaces in the sum. Parameters ---------- numSumSpaces The number of spaces. See Also -------- getSumNumSubspaces, petsc.PetscSpaceSumSetNumSubspaces """ cdef PetscInt cnumSumSpaces = asInt(numSumSpaces) CHKERR( PetscSpaceSumSetNumSubspaces(self.space, cnumSumSpaces) ) def getTensorNumSubspaces(self) -> int: """Return the number of spaces in the tensor product. See Also -------- setTensorNumSubspaces, petsc.PetscSpaceTensorGetNumSubspaces """ cdef PetscInt cnumTensSpaces = 0 CHKERR( PetscSpaceTensorGetNumSubspaces(self.space, &cnumTensSpaces) ) return toInt(cnumTensSpaces) def setTensorSubspace(self, s: int, Space subsp) -> None: """Set a space in the tensor product. Parameters ---------- s The space number. subsp The number of spaces. See Also -------- getTensorSubspace, petsc.PetscSpaceTensorSetSubspace """ cdef PetscInt cs = asInt(s) CHKERR( PetscSpaceTensorSetSubspace(self.space, cs, subsp.space) ) def getTensorSubspace(self, s: int) -> Space: """Return a space in the tensor product. Parameters ---------- s The space number. See Also -------- setTensorSubspace, petsc.PetscSpaceTensorGetSubspace """ cdef PetscInt cs = asInt(s) cdef Space subsp = Space() CHKERR( PetscSpaceTensorGetSubspace(self.space, cs, &subsp.space) ) return subsp def setTensorNumSubspaces(self, numTensSpaces: int) -> None: """Set the number of spaces in the tensor product. Parameters ---------- numTensSpaces The number of spaces. See Also -------- getTensorNumSubspaces, petsc.PetscSpaceTensorSetNumSubspaces """ cdef PetscInt cnumTensSpaces = asInt(numTensSpaces) CHKERR( PetscSpaceTensorSetNumSubspaces(self.space, cnumTensSpaces) ) def getPolynomialTensor(self) -> bool: """Return whether a function space is a space of tensor polynomials. Return `True` if a function space is a space of tensor polynomials (the space is spanned by polynomials whose degree in each variable is bounded by the given order), as opposed to polynomials (the space is spanned by polynomials whose total degree—summing over all variables is bounded by the given order). See Also -------- setPolynomialTensor, petsc.PetscSpacePolynomialGetTensor """ cdef PetscBool ctensor CHKERR( PetscSpacePolynomialGetTensor(self.space, &ctensor) ) return toBool(ctensor) def setPolynomialTensor(self, tensor: bool) -> None: """Set whether a function space is a space of tensor polynomials. Set to `True` for a function space which is a space of tensor polynomials (the space is spanned by polynomials whose degree in each variable is bounded by the given order), as opposed to polynomials (the space is spanned by polynomials whose total degree—summing over all variables is bounded by the given order). Parameters ---------- tensor `True` for a tensor polynomial space, `False` for a polynomial space. See Also -------- getPolynomialTensor, petsc.PetscSpacePolynomialSetTensor """ cdef PetscBool ctensor = asBool(tensor) CHKERR( PetscSpacePolynomialSetTensor(self.space, ctensor) ) def setPointPoints(self, Quad quad) -> None: """Set the evaluation points for the space to be based on a quad. Logically collective. Sets the evaluation points for the space to coincide with the points of a quadrature rule. Parameters ---------- quad The `Quad` defining the points. See Also -------- getPointPoints, petsc.PetscSpacePointSetPoints """ CHKERR( PetscSpacePointSetPoints(self.space, quad.quad)) def getPointPoints(self) -> Quad: """Return the evaluation points for the space as the points of a quad. Logically collective. See Also -------- setPointPoints, petsc.PetscSpacePointGetPoints """ cdef Quad quad = Quad() CHKERR( PetscSpacePointGetPoints(self.space, &quad.quad)) return quad def setPTrimmedFormDegree(self, formDegree: int) -> None: """Set the form degree of the trimmed polynomials. Parameters ---------- formDegree The form degree. See Also -------- getPTrimmedFormDegree, petsc.PetscSpacePTrimmedSetFormDegree """ cdef PetscInt cformDegree = asInt(formDegree) CHKERR( PetscSpacePTrimmedSetFormDegree(self.space, cformDegree) ) def getPTrimmedFormDegree(self) -> int: """Return the form degree of the trimmed polynomials. See Also -------- setPTrimmedFormDegree, petsc.PetscSpacePTrimmedGetFormDegree """ cdef PetscInt cformDegree = 0 CHKERR( PetscSpacePTrimmedGetFormDegree(self.space, &cformDegree) ) return toInt(cformDegree) def viewFromOptions(self, name: str, Object obj=None) -> None: """View a `Space` based on values in the options database. Collective. Parameters ---------- name Command line option name. obj Optional object that provides the options prefix. See Also -------- petsc_options, petsc.PetscSpaceViewFromOptions """ cdef const char *cname = NULL _ = str2bytes(name, &cname) cdef PetscObject cobj = NULL if obj is not None: cobj = obj.obj[0] CHKERR( PetscSpaceViewFromOptions(self.space, cobj, cname) ) # -------------------------------------------------------------------- class DualSpaceType(object): LAGRANGE = S_(PETSCDUALSPACELAGRANGE) SIMPLE = S_(PETSCDUALSPACESIMPLE) REFINED = S_(PETSCDUALSPACEREFINED) BDM = S_(PETSCDUALSPACEBDM) # -------------------------------------------------------------------- cdef class DualSpace(Object): """Dual space to a linear space.""" Type = DualSpaceType def __cinit__(self): self.obj = &self.dualspace self.dualspace = NULL def setUp(self) -> None: """Construct a basis for a `DualSpace`. Collective. See Also -------- petsc.PetscDualSpaceSetUp """ CHKERR( PetscDualSpaceSetUp(self.dualspace) ) def create(self, comm: Comm | None = None) -> Self: """Create an empty `DualSpace` object. Collective. The type can then be set with `setType`. Parameters ---------- comm MPI communicator, defaults to `Sys.getDefaultComm`. See Also -------- petsc.PetscDualSpaceCreate """ cdef MPI_Comm ccomm = def_Comm(comm, PETSC_COMM_DEFAULT) cdef PetscDualSpace newdsp = NULL CHKERR( PetscDualSpaceCreate(ccomm, &newdsp) ) CHKERR( PetscCLEAR(self.obj) ); self.dualspace = newdsp return self def view(self, Viewer viewer=None) -> None: """View a `DualSpace`. Collective. Parameters ---------- viewer A `Viewer` to display the `DualSpace`. See Also -------- petsc.PetscDualSpaceView """ cdef PetscViewer vwr = NULL if viewer is not None: vwr = viewer.vwr CHKERR( PetscDualSpaceView(self.dualspace, vwr) ) def destroy(self) -> Self: """Destroy the `DualSpace` object. Collective. See Also -------- petsc.PetscDualSpaceDestroy """ CHKERR( PetscDualSpaceDestroy(&self.dualspace) ) return self def duplicate(self) -> DualSpace: """Create a duplicate `DualSpace` object that is not set up. Collective. See Also -------- petsc.PetscDualSpaceDuplicate """ cdef DualSpace spNew = DualSpace() CHKERR( PetscDualSpaceDuplicate(self.dualspace, &spNew.dualspace) ) def getDM(self) -> DM: """Return the `DM` representing the reference cell of a `DualSpace`. Not collective. See Also -------- setDM, petsc.PetscDualSpaceGetDM """ cdef DM dm = DM() CHKERR( PetscDualSpaceGetDM(self.dualspace, &dm.dm) ) return dm def setDM(self, DM dm) -> None: """Set the `DM` representing the reference cell. Not collective. Parameters ---------- dm The reference cell. See Also -------- getDM, petsc.PetscDualSpaceSetDM """ CHKERR( PetscDualSpaceSetDM(self.dualspace, dm.dm) ) def getDimension(self) -> int: """Return the dimension of the dual space. Not collective. The dimension of the dual space, i.e. the number of basis functionals. See Also -------- petsc.PetscDualSpaceGetDimension """ cdef PetscInt cdim CHKERR( PetscDualSpaceGetDimension(self.dualspace, &cdim)) return toInt(cdim) def getNumComponents(self) -> int: """Return the number of components for this space. See Also -------- setNumComponents, petsc.PetscDualSpaceGetNumComponents """ cdef PetscInt cncomps CHKERR( PetscDualSpaceGetNumComponents(self.dualspace, &cncomps)) return toInt(cncomps) def setNumComponents(self, nc: int) -> None: """Set the number of components for this space. Parameters ---------- nc The number of components See Also -------- getNumComponents, petsc.PetscDualSpaceSetNumComponents """ cdef PetscInt cnc = asInt(nc) CHKERR( PetscDualSpaceSetNumComponents(self.dualspace, cnc) ) def getType(self) -> str: """Return the type of the dual space object. Not collective. See Also -------- setType, petsc.PetscDualSpaceGetType """ cdef PetscDualSpaceType cval = NULL CHKERR( PetscDualSpaceGetType(self.dualspace, &cval) ) return bytes2str(cval) def setType(self, dualspace_type: Type | str) -> Self: """Build a particular type of dual space. Collective. Parameters ---------- dualspace_type The kind of space. See Also -------- getType, petsc.PetscDualSpaceSetType """ cdef PetscDualSpaceType cval = NULL space_type = str2bytes(dualspace_type, &cval) CHKERR( PetscDualSpaceSetType(self.dualspace, cval) ) return self def getOrder(self) -> int: """Return the order of the dual space. Not collective. See Also -------- setOrder, petsc.PetscDualSpaceGetOrder """ cdef PetscInt corder CHKERR( PetscDualSpaceGetOrder(self.dualspace, &corder)) return toInt(corder) def setOrder(self, order: int) -> None: """Set the order of the dual space. Not collective. Parameters ---------- order The order. See Also -------- getOrder, petsc.PetscDualSpaceSetOrder """ cdef PetscInt corder = asInt(order) CHKERR( PetscDualSpaceSetOrder(self.dualspace, corder) ) def getNumDof(self) -> ArrayInt: """Return the number of degrees of freedom for each spatial dimension. Not collective. See Also -------- petsc.PetscDualSpaceGetNumDof """ cdef const PetscInt *cndof = NULL cdef PetscInt cdim = 0 CHKERR( PetscDualSpaceGetDimension(self.dualspace, &cdim) ) CHKERR( PetscDualSpaceGetNumDof(self.dualspace, &cndof) ) return array_i(cdim + 1, cndof) def getFunctional(self, i: int) -> Quad: """Return the i-th basis functional in the dual space. Not collective. Parameters ---------- i The basis number. See Also -------- petsc.PetscDualSpaceGetFunctional """ cdef PetscInt ci = asInt(i) cdef Quad functional = Quad() CHKERR( PetscDualSpaceGetFunctional( self.dualspace, ci, &functional.quad) ) return functional def getInteriorDimension(self) -> int: """Return the interior dimension of the dual space. Not collective. The interior dimension of the dual space, i.e. the number of basis functionals assigned to the interior of the reference domain. See Also -------- petsc.PetscDualSpaceGetInteriorDimension """ cdef PetscInt cintdim = 0 CHKERR( PetscDualSpaceGetInteriorDimension(self.dualspace, &cintdim) ) return toInt(cintdim) def getLagrangeContinuity(self) -> bool: """Return whether the element is continuous. Not collective. See Also -------- setLagrangeContinuity, petsc.PetscDualSpaceLagrangeGetContinuity """ cdef PetscBool ccontinuous = PETSC_FALSE CHKERR( PetscDualSpaceLagrangeGetContinuity(self.dualspace, &ccontinuous)) return toBool(ccontinuous) def setLagrangeContinuity(self, continuous: bool) -> None: """Indicate whether the element is continuous. Not collective. Parameters ---------- continuous The flag for element continuity. See Also -------- getLagrangeContinuity, petsc.PetscDualSpaceLagrangeSetContinuity """ cdef PetscBool ccontinuous = asBool(continuous) CHKERR( PetscDualSpaceLagrangeSetContinuity(self.dualspace, ccontinuous)) def getLagrangeTensor(self) -> bool: """Return the tensor nature of the dual space. Not collective. See Also -------- setLagrangeTensor, petsc.PetscDualSpaceLagrangeGetTensor """ cdef PetscBool ctensor = PETSC_FALSE CHKERR( PetscDualSpaceLagrangeGetTensor(self.dualspace, &ctensor)) return toBool(ctensor) def setLagrangeTensor(self, tensor: bool) -> None: """Set the tensor nature of the dual space. Not collective. Parameters ---------- tensor Whether the dual space has tensor layout (vs. simplicial). See Also -------- getLagrangeTensor, petsc.PetscDualSpaceLagrangeSetTensor """ cdef PetscBool ctensor = asBool(tensor) CHKERR( PetscDualSpaceLagrangeSetTensor(self.dualspace, ctensor)) def getLagrangeTrimmed(self) -> bool: """Return the trimmed nature of the dual space. Not collective. See Also -------- setLagrangeTrimmed, petsc.PetscDualSpaceLagrangeGetTrimmed """ cdef PetscBool ctrimmed = PETSC_FALSE CHKERR( PetscDualSpaceLagrangeGetTrimmed(self.dualspace, &ctrimmed)) return toBool(ctrimmed) def setLagrangeTrimmed(self, trimmed: bool) -> None: """Set the trimmed nature of the dual space. Not collective. Parameters ---------- trimmed Whether the dual space represents to dual basis of a trimmed polynomial space (e.g. Raviart-Thomas and higher order / other form degree variants). See Also -------- getLagrangeTrimmed, petsc.PetscDualSpaceLagrangeSetTrimmed """ cdef PetscBool ctrimmed = asBool(trimmed) CHKERR( PetscDualSpaceLagrangeSetTrimmed(self.dualspace, ctrimmed)) def viewFromOptions(self, name: str, Object obj=None) -> None: """View a `DualSpace` based on values in the options database. Collective. Parameters ---------- name Command line option name. obj Optional object that provides the options prefix. See Also -------- petsc_options, petsc.PetscSpaceViewFromOptions """ cdef const char *cname = NULL _ = str2bytes(name, &cname) cdef PetscObject cobj = NULL if obj is not None: cobj = obj.obj[0] CHKERR( PetscDualSpaceViewFromOptions(self.dualspace, cobj, cname) ) def setSimpleDimension(self, dim: int) -> None: """Set the number of functionals in the dual space basis. Logically collective. Parameters ---------- dim The basis dimension. See Also -------- petsc.PetscDualSpaceSimpleSetDimension """ cdef PetscInt cdim = asInt(dim) CHKERR( PetscDualSpaceSimpleSetDimension(self.dualspace, cdim) ) def setSimpleFunctional(self, func: int, Quad functional) -> None: """Set the given basis element for this dual space. Not collective. Parameters ---------- func The basis index. functional The basis functional. See Also -------- petsc.PetscDualSpaceSimpleSetFunctional """ cdef PetscInt cfunc = asInt(func) CHKERR( PetscDualSpaceSimpleSetFunctional(self.dualspace, cfunc, functional.quad) ) del SpaceType del DualSpaceType ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/src/petsc4py/PETSc/Sys.pyx0000644000175000017500000003111514567251135017170 0ustar00balaybalay# ------------------------------------------------------------------------------ cdef class Sys: """System utilities.""" @classmethod def getVersion( cls, devel: bool = False, date: bool = False, author: bool = False, ) -> tuple[int, int, int]: """Return PETSc version information. Not collective. Parameters ---------- devel Additionally, return whether using an in-development version. date Additionally, return date information. author Additionally, return author information. Returns ------- major : int Major version number. minor : int Minor version number. micro : int Micro (or patch) version number. See Also -------- petsc.PetscGetVersion, petsc.PetscGetVersionNumber """ cdef char cversion[256] cdef PetscInt major=0, minor=0, micro=0, release=0 CHKERR( PetscGetVersion(cversion, sizeof(cversion)) ) CHKERR( PetscGetVersionNumber(&major, &minor, µ, &release) ) out = version = (toInt(major), toInt(minor), toInt(micro)) if devel or date or author: out = [version] if devel: out.append(not release) if date: vstr = bytes2str(cversion) if release != 0: date = vstr.split(",", 1)[-1].strip() else: date = vstr.split("GIT Date:")[-1].strip() out.append(date) if author: author = bytes2str(PETSC_AUTHOR_INFO).split('\n') author = tuple([s.strip() for s in author if s]) out.append(author) return tuple(out) @classmethod def getVersionInfo(cls) -> dict[str, bool | int | str]: """Return PETSc version information. Not collective. Returns ------- info : dict Dictionary with version information. See Also -------- petsc.PetscGetVersion, petsc.PetscGetVersionNumber """ version, dev, date, author = cls.getVersion(True, True, True) return dict(major = version[0], minor = version[1], subminor = version[2], release = not dev, date = date, authorinfo = author) # --- xxx --- @classmethod def isInitialized(cls) -> bool: """Return whether PETSc has been initialized. Not collective. See Also -------- isFinalized """ return toBool(PetscInitializeCalled) @classmethod def isFinalized(cls) -> bool: """Return whether PETSc has been finalized. Not collective. See Also -------- isInitialized """ return toBool(PetscFinalizeCalled) # --- xxx --- @classmethod def getDefaultComm(cls) -> Comm: """Get the default MPI communicator used to create PETSc objects. Not collective. See Also -------- setDefaultComm """ cdef Comm comm = Comm() comm.comm = PETSC_COMM_DEFAULT return comm @classmethod def setDefaultComm(cls, comm: Comm | None) -> None: """Set the default MPI communicator used to create PETSc objects. Logically collective. Parameters ---------- comm MPI communicator. If set to `None`, uses `COMM_WORLD`. See Also -------- getDefaultComm """ cdef MPI_Comm ccomm = def_Comm(comm, PETSC_COMM_WORLD) if ccomm == MPI_COMM_NULL: raise ValueError("null communicator") global PETSC_COMM_DEFAULT PETSC_COMM_DEFAULT = ccomm # --- xxx --- @classmethod def Print( cls, *args: Any, sep: str = ' ', end: str = '\n', comm: Comm | None = None, **kwargs: Any, ) -> None: """Print output from the first processor of a communicator. Collective. Parameters ---------- *args Positional arguments. sep String inserted between values, by default a space. end String appended after the last value, by default a newline. comm MPI communicator, defaults to `getDefaultComm`. **kwargs Keyword arguments. See Also -------- petsc.PetscPrintf """ cdef MPI_Comm ccomm = def_Comm(comm, PETSC_COMM_DEFAULT) if comm_rank(ccomm) == 0: if not args: args = ('',) format = ['%s', sep] * len(args) format[-1] = end message = ''.join(format) % args else: message = '' cdef const char *m = NULL message = str2bytes(message, &m) CHKERR( PetscPrintf(ccomm, '%s', m) ) @classmethod def syncPrint( cls, *args: Any, sep: str = ' ', end: str = '\n', flush: bool = False, comm: Comm | None = None, **kwargs: Any, ) -> None: """Print synchronized output from several processors of a communicator. Not collective. Parameters ---------- *args Positional arguments. sep String inserted between values, by default a space. end String appended after the last value, by default a newline. flush Whether to flush output with `syncFlush`. comm MPI communicator, defaults to `getDefaultComm`. **kwargs Keyword arguments. See Also -------- petsc.PetscSynchronizedPrintf, petsc.PetscSynchronizedFlush """ cdef MPI_Comm ccomm = def_Comm(comm, PETSC_COMM_DEFAULT) if not args: args = ('',) format = ['%s', sep] * len(args) format[-1] = end message = ''.join(format) % args cdef const char *m = NULL message = str2bytes(message, &m) CHKERR( PetscSynchronizedPrintf(ccomm, '%s', m) ) if flush: CHKERR( PetscSynchronizedFlush(ccomm, PETSC_STDOUT) ) @classmethod def syncFlush(cls, comm: Comm | None = None) -> None: """Flush output from previous `syncPrint` calls. Collective. Parameters ---------- comm MPI communicator, defaults to `getDefaultComm`. See Also -------- petsc.PetscSynchronizedPrintf, petsc.PetscSynchronizedFlush """ cdef MPI_Comm ccomm = def_Comm(comm, PETSC_COMM_DEFAULT) CHKERR( PetscSynchronizedFlush(ccomm, PETSC_STDOUT) ) # --- xxx --- @classmethod def splitOwnership( cls, size: int | tuple[int, int], bsize: int | None = None, comm: Comm | None = None ) -> tuple[int, int]: """Given a global (or local) size determines a local (or global) size. Collective. Parameters ---------- size Global size ``N`` or 2-tuple ``(n, N)`` with local and global sizes. Either of ``n`` or ``N`` (but not both) can be `None`. bsize Block size, defaults to ``1``. comm MPI communicator, defaults to `getDefaultComm`. Returns ------- n : int The local size. N : int The global size. Notes ----- The ``size`` argument corresponds to the full size of the vector. That is, an array with 10 blocks and a block size of 3 will have a ``size`` of 30, not 10. See Also -------- petsc.PetscSplitOwnership """ cdef MPI_Comm ccomm = def_Comm(comm, PETSC_COMM_DEFAULT) cdef PetscInt bs=0, n=0, N=0 Sys_Sizes(size, bsize, &bs, &n, &N) if bs == PETSC_DECIDE: bs = 1 if n > 0: n = n // bs if N > 0: N = N // bs CHKERR( PetscSplitOwnership(ccomm, &n, &N) ) n = n * bs N = N * bs return (toInt(n), toInt(N)) @classmethod def sleep(cls, seconds: float = 1.0) -> None: """Sleep some number of seconds. Not collective. Parameters ---------- seconds Time to sleep in seconds. See Also -------- petsc.PetscSleep """ cdef PetscReal s = asReal(seconds) CHKERR( PetscSleep(s) ) # --- xxx --- @classmethod def pushErrorHandler(cls, errhandler: str) -> None: """Set the current error handler. Logically collective. Parameters ---------- errhandler The name of the error handler. See Also -------- petsc.PetscPushErrorHandler """ cdef PetscErrorHandlerFunction handler = NULL if errhandler == "python": handler = PetscPythonErrorHandler elif errhandler == "debugger": handler = PetscAttachDebuggerErrorHandler elif errhandler == "emacs": handler = PetscEmacsClientErrorHandler elif errhandler == "traceback": handler = PetscTraceBackErrorHandler elif errhandler == "ignore": handler = PetscIgnoreErrorHandler elif errhandler == "mpiabort": handler = PetscMPIAbortErrorHandler elif errhandler == "abort": handler = PetscAbortErrorHandler else: raise ValueError(f"unknown error handler: {errhandler!r}") CHKERR( PetscPushErrorHandler(handler, NULL) ) @classmethod def popErrorHandler(cls) -> None: """Remove the current error handler. Logically collective. See Also -------- petsc.PetscPopErrorHandler """ CHKERR( PetscPopErrorHandler() ) @classmethod def popSignalHandler(cls) -> None: """Remove the current signal handler. Logically collective. See Also -------- petsc.PetscPopSignalHandler """ CHKERR( PetscPopSignalHandler() ) @classmethod def infoAllow( cls, flag: bool, filename: str | None = None, mode: str = "w", ) -> None: """Enables or disables PETSc info messages. Not collective. Parameters ---------- flag Whether to enable info messages. filename Name of a file where to dump output. mode Write mode for file, by default ``"w"``. See Also -------- petsc.PetscInfoAllow, petsc.PetscInfoSetFile """ cdef PetscBool tval = PETSC_FALSE cdef const char *cfilename = NULL cdef const char *cmode = NULL if flag: tval = PETSC_TRUE CHKERR( PetscInfoAllow(tval) ) if filename is not None: filename = str2bytes(filename, &cfilename) mode = str2bytes(mode, &cmode) CHKERR( PetscInfoSetFile(cfilename, cmode) ) @classmethod def registerCitation(cls, citation: str) -> None: """Register BibTeX citation. Not collective. Parameters ---------- citation The BibTex citation entry to register. See Also -------- petsc.PetscCitationsRegister """ if not citation: raise ValueError("empty citation") cdef const char *cit = NULL citation = str2bytes(citation, &cit) cdef PetscBool flag = get_citation(citation) CHKERR( PetscCitationsRegister(cit, &flag) ) set_citation(citation, toBool(flag)) @classmethod def hasExternalPackage(cls, package: str) -> bool: """Return whether PETSc has support for external package. Not collective. Parameters ---------- package The external package name. See Also -------- petsc.PetscHasExternalPackage """ cdef const char *cpackage = NULL package = str2bytes(package, &cpackage) cdef PetscBool has = PETSC_FALSE CHKERR( PetscHasExternalPackage(cpackage, &has) ) return toBool(has) cdef dict citations_registry = { } cdef PetscBool get_citation(object citation): cdef bint is_set = citations_registry.get(citation) return PETSC_TRUE if is_set else PETSC_FALSE cdef set_citation(object citation, bint is_set): citations_registry[citation] = is_set # ------------------------------------------------------------------------------ ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/src/petsc4py/PETSc/TAO.pyx0000644000175000017500000017442114567251135017045 0ustar00balaybalay# -------------------------------------------------------------------- class TAOType: """TAO solver type. See Also -------- petsc.TaoType """ LMVM = S_(TAOLMVM) NLS = S_(TAONLS) NTR = S_(TAONTR) NTL = S_(TAONTL) CG = S_(TAOCG) TRON = S_(TAOTRON) OWLQN = S_(TAOOWLQN) BMRM = S_(TAOBMRM) BLMVM = S_(TAOBLMVM) BQNLS = S_(TAOBQNLS) BNCG = S_(TAOBNCG) BNLS = S_(TAOBNLS) BNTR = S_(TAOBNTR) BNTL = S_(TAOBNTL) BQNKLS = S_(TAOBQNKLS) BQNKTR = S_(TAOBQNKTR) BQNKTL = S_(TAOBQNKTL) BQPIP = S_(TAOBQPIP) GPCG = S_(TAOGPCG) NM = S_(TAONM) POUNDERS = S_(TAOPOUNDERS) BRGN = S_(TAOBRGN) LCL = S_(TAOLCL) SSILS = S_(TAOSSILS) SSFLS = S_(TAOSSFLS) ASILS = S_(TAOASILS) ASFLS = S_(TAOASFLS) IPM = S_(TAOIPM) PDIPM = S_(TAOPDIPM) SHELL = S_(TAOSHELL) ADMM = S_(TAOADMM) ALMM = S_(TAOALMM) PYTHON = S_(TAOPYTHON) class TAOConvergedReason: """TAO solver termination reason. See Also -------- petsc.TaoConvergedReason """ # iterating CONTINUE_ITERATING = TAO_CONTINUE_ITERATING # iterating CONVERGED_ITERATING = TAO_CONTINUE_ITERATING # iterating ITERATING = TAO_CONTINUE_ITERATING # iterating # converged CONVERGED_GATOL = TAO_CONVERGED_GATOL # ||g(X)|| < gatol CONVERGED_GRTOL = TAO_CONVERGED_GRTOL # ||g(X)||/f(X) < grtol CONVERGED_GTTOL = TAO_CONVERGED_GTTOL # ||g(X)||/||g(X0)|| < gttol CONVERGED_STEPTOL = TAO_CONVERGED_STEPTOL # small step size CONVERGED_MINF = TAO_CONVERGED_MINF # f(X) < F_min CONVERGED_USER = TAO_CONVERGED_USER # user defined # diverged DIVERGED_MAXITS = TAO_DIVERGED_MAXITS # DIVERGED_NAN = TAO_DIVERGED_NAN # DIVERGED_MAXFCN = TAO_DIVERGED_MAXFCN # DIVERGED_LS_FAILURE = TAO_DIVERGED_LS_FAILURE # DIVERGED_TR_REDUCTION = TAO_DIVERGED_TR_REDUCTION # DIVERGED_USER = TAO_DIVERGED_USER # user defined class TAOBNCGType: """TAO Bound Constrained Conjugate Gradient (BNCG) Update Type.""" GD = TAO_BNCG_GD PCGD = TAO_BNCG_PCGD HS = TAO_BNCG_HS FR = TAO_BNCG_FR PRP = TAO_BNCG_PRP PRP_PLUS = TAO_BNCG_PRP_PLUS DY = TAO_BNCG_DY HZ = TAO_BNCG_HZ DK = TAO_BNCG_DK KD = TAO_BNCG_KD SSML_BFGS = TAO_BNCG_SSML_BFGS SSML_DFP = TAO_BNCG_SSML_DFP SSML_BRDN = TAO_BNCG_SSML_BRDN # -------------------------------------------------------------------- cdef class TAO(Object): """Optimization solver. TAO is described in the `PETSc manual `. See Also -------- petsc.Tao """ Type = TAOType ConvergedReason = TAOConvergedReason BNCGType = TAOBNCGType # FIXME backward compatibility Reason = TAOConvergedReason def __cinit__(self): self.obj = &self.tao self.tao = NULL def view(self, Viewer viewer=None) -> None: """View the solver. Collective. Parameters ---------- viewer A `Viewer` instance or `None` for the default viewer. See Also -------- petsc.TaoView """ cdef PetscViewer vwr = NULL if viewer is not None: vwr = viewer.vwr CHKERR( TaoView(self.tao, vwr) ) def destroy(self) -> Self: """Destroy the solver. Collective. See Also -------- petsc.TaoDestroy """ CHKERR( TaoDestroy(&self.tao) ) return self def create(self, comm: Comm | None = None) -> Self: """Create a TAO solver. Collective. Parameters ---------- comm MPI communicator, defaults to `Sys.getDefaultComm`. See Also -------- Sys.getDefaultComm, petsc.TaoCreate """ cdef MPI_Comm ccomm = def_Comm(comm, PETSC_COMM_DEFAULT) cdef PetscTAO newtao = NULL CHKERR( TaoCreate(ccomm, &newtao) ) CHKERR( PetscCLEAR(self.obj) ); self.tao = newtao return self def setType(self, tao_type: Type | str) -> None: """Set the type of the solver. Logically collective. Parameters ---------- tao_type The type of the solver. See Also -------- getType, petsc.TaoSetType """ cdef PetscTAOType ctype = NULL tao_type = str2bytes(tao_type, &ctype) CHKERR( TaoSetType(self.tao, ctype) ) def getType(self) -> str: """Return the type of the solver. Not collective. See Also -------- setType, petsc.TaoGetType """ cdef PetscTAOType ctype = NULL CHKERR( TaoGetType(self.tao, &ctype) ) return bytes2str(ctype) def setOptionsPrefix(self, prefix: str) -> None: """Set the prefix used for searching for options in the database. Logically collective. See Also -------- petsc_options, petsc.TaoSetOptionsPrefix """ cdef const char *cprefix = NULL prefix = str2bytes(prefix, &cprefix) CHKERR( TaoSetOptionsPrefix(self.tao, cprefix) ) def appendOptionsPrefix(self, prefix: str) -> None: """Append to the prefix used for searching for options in the database. Logically collective. See Also -------- petsc_options, setOptionsPrefix, petsc.TaoAppendOptionsPrefix """ cdef const char *cprefix = NULL prefix = str2bytes(prefix, &cprefix) CHKERR( TaoAppendOptionsPrefix(self.tao, cprefix) ) def getOptionsPrefix(self) -> str: """Return the prefix used for searching for options in the database. Not collective. See Also -------- petsc_options, setOptionsPrefix, petsc.TaoGetOptionsPrefix """ cdef const char *prefix = NULL CHKERR( TaoGetOptionsPrefix(self.tao, &prefix) ) return bytes2str(prefix) def setFromOptions(self) -> None: """Configure the solver from the options database. Collective. See Also -------- petsc_options, petsc.TaoSetFromOptions """ CHKERR( TaoSetFromOptions(self.tao) ) def setUp(self) -> None: """Set up the internal data structures for using the solver. Collective. See Also -------- petsc.TaoSetUp """ CHKERR( TaoSetUp(self.tao) ) # def setInitialTrustRegionRadius(self, radius: float) -> None: """Set the initial trust region radius. Collective. See Also -------- petsc.TaoSetInitialTrustRegionRadius """ cdef PetscReal cradius = asReal(radius) CHKERR( TaoSetInitialTrustRegionRadius(self.tao, cradius) ) # -------------- def setAppCtx(self, appctx: Any) -> None: """Set the application context.""" self.set_attr("__appctx__", appctx) def getAppCtx(self) -> Any: """Return the application context.""" return self.get_attr("__appctx__") def setSolution(self, Vec x) -> None: """Set the vector used to store the solution. Collective. See Also -------- getSolution, petsc.TaoSetSolution """ CHKERR( TaoSetSolution(self.tao, x.vec) ) def setObjective(self, objective: TAOObjectiveFunction, args: tuple[Any, ...] | None = None, kargs: dict[str, Any] | None = None) -> None: """Set the objective function evaluation callback. Logically collective. Parameters ---------- objective The objective function callback. args Positional arguments for the callback. kargs Keyword arguments for the callback. See Also -------- setGradient, setObjectiveGradient, petsc.TaoSetObjective """ if args is None: args = () if kargs is None: kargs = {} context = (objective, args, kargs) self.set_attr("__objective__", context) CHKERR( TaoSetObjective(self.tao, TAO_Objective, context) ) def setResidual(self, residual: TAOResidualFunction, Vec R=None, args: tuple[Any, ...] | None = None, kargs: dict[str, Any] | None = None) -> None: """Set the residual evaluation callback for least-squares applications. Logically collective. Parameters ---------- residual The residual callback. R The vector to store the residual. args Positional arguments for the callback. kargs Keyword arguments for the callback. See Also -------- setJacobianResidual, petsc.TaoSetResidualRoutine """ cdef PetscVec Rvec = NULL if R is not None: Rvec = R.vec if args is None: args = () if kargs is None: kargs = {} context = (residual, args, kargs) self.set_attr("__residual__", context) CHKERR( TaoSetResidualRoutine(self.tao, Rvec, TAO_Residual, context) ) def setJacobianResidual(self, jacobian: TAOJacobianResidualFunction, Mat J=None, Mat P=None, args: tuple[Any, ...] | None = None, kargs: dict[str, Any] | None = None) -> None: """Set the callback to compute the least-squares residual Jacobian. Logically collective. Parameters ---------- jacobian The Jacobian callback. J The matrix to store the Jacobian. P The matrix to construct the preconditioner. args Positional arguments for the callback. kargs Keyword arguments for the callback. See Also -------- setResidual, petsc.TaoSetJacobianResidualRoutine """ cdef PetscMat Jmat = NULL if J is not None: Jmat = J.mat cdef PetscMat Pmat = Jmat if P is not None: Pmat = P.mat if args is None: args = () if kargs is None: kargs = {} context = (jacobian, args, kargs) self.set_attr("__jacobian_residual__", context) CHKERR( TaoSetJacobianResidualRoutine(self.tao, Jmat, Pmat, TAO_JacobianResidual, context) ) def setGradient(self, gradient: TAOGradientFunction, Vec g=None, args: tuple[Any, ...] | None = None, kargs: dict[str, Any] | None = None) -> None: """Set the gradient evaluation callback. Logically collective. Parameters ---------- gradient The gradient callback. g The vector to store the gradient. args Positional arguments for the callback. kargs Keyword arguments for the callback. See Also -------- setObjective, setObjectiveGradient, setHessian, petsc.TaoSetGradient """ cdef PetscVec gvec = NULL if g is not None: gvec = g.vec if args is None: args = () if kargs is None: kargs = {} context = (gradient, args, kargs) self.set_attr("__gradient__", context) CHKERR( TaoSetGradient(self.tao, gvec, TAO_Gradient, context) ) def getGradient(self) -> tuple[Vec, TAOGradientFunction]: """Return the vector used to store the gradient and the evaluation callback. Not collective. See Also -------- setGradient, setHessian, petsc.TaoGetGradient """ cdef Vec vec = Vec() CHKERR( TaoGetGradient(self.tao, &vec.vec, NULL, NULL) ) CHKERR( PetscINCREF(vec.obj) ) cdef object gradient = self.get_attr("__gradient__") return (vec, gradient) def setObjectiveGradient(self, objgrad: TAOObjectiveGradientFunction, Vec g=None, args: tuple[Any, ...] | None = None, kargs: dict[str, Any] | None = None) -> None: """Set the objective function and gradient evaluation callback. Logically collective. Parameters ---------- objgrad The objective function and gradient callback. g The vector to store the gradient. args Positional arguments for the callback. kargs Keyword arguments for the callback. See Also -------- setObjective, setGradient, setHessian, getObjectiveAndGradient petsc.TaoSetObjectiveAndGradient """ cdef PetscVec gvec = NULL if g is not None: gvec = g.vec if args is None: args = () if kargs is None: kargs = {} context = (objgrad, args, kargs) self.set_attr("__objgrad__", context) CHKERR( TaoSetObjectiveAndGradient(self.tao, gvec, TAO_ObjGrad, context) ) def getObjectiveAndGradient(self) -> tuple[Vec, TAOObjectiveGradientFunction]: """Return the vector used to store the gradient and the evaluation callback. Not collective. See Also -------- setObjectiveGradient, petsc.TaoGetObjectiveAndGradient """ cdef Vec vec = Vec() CHKERR( TaoGetObjectiveAndGradient(self.tao, &vec.vec, NULL, NULL) ) CHKERR( PetscINCREF(vec.obj) ) cdef object objgrad = self.get_attr("__objgrad__") return (vec, objgrad) def setVariableBounds(self, varbounds: tuple[Vec, Vec] | TAOVariableBoundsFunction, args: tuple[Any, ...] | None = None, kargs: dict[str, Any] | None = None) -> None: """Set the upper and lower bounds for the optimization problem. Logically collective. Parameters ---------- varbounds Either a tuple of `Vec` or a `TAOVariableBoundsFunction` callback. args Positional arguments for the callback. kargs Keyword arguments for the callback. See Also -------- petsc.TaoSetVariableBounds, petsc.TaoSetVariableBoundsRoutine """ cdef Vec xl = None, xu = None if (isinstance(varbounds, list) or isinstance(varbounds, tuple)): ol, ou = varbounds xl = ol; xu = ou CHKERR( TaoSetVariableBounds(self.tao, xl.vec, xu.vec) ) return if isinstance(varbounds, Vec): #FIXME ol = varbounds; ou = args xl = ol; xu = ou CHKERR( TaoSetVariableBounds(self.tao, xl.vec, xu.vec) ) return if args is None: args = () if kargs is None: kargs = {} context = (varbounds, args, kargs) self.set_attr("__varbounds__", context) CHKERR( TaoSetVariableBoundsRoutine(self.tao, TAO_VarBounds, context) ) def setConstraints(self, constraints: TAOConstraintsFunction, Vec C=None, args: tuple[Any, ...] | None = None, kargs: dict[str, Any] | None = None) -> None: """Set the callback to compute constraints. Logically collective. Parameters ---------- constraints The callback. C The vector to hold the constraints. args Positional arguments for the callback. kargs Keyword arguments for the callback. See Also -------- petsc.TaoSetConstraintsRoutine """ cdef PetscVec Cvec = NULL if C is not None: Cvec = C.vec if args is None: args = () if kargs is None: kargs = {} context = (constraints, args, kargs) self.set_attr("__constraints__", context) CHKERR( TaoSetConstraintsRoutine(self.tao, Cvec, TAO_Constraints, context) ) def setHessian(self, hessian: TAOHessianFunction, Mat H=None, Mat P=None, args: tuple[Any, ...] | None = None, kargs: dict[str, Any] | None = None) -> None: """Set the callback to compute the Hessian matrix. Logically collective. Parameters ---------- hessian The Hessian callback. H The matrix to store the Hessian. P The matrix to construct the preconditioner. args Positional arguments for the callback. kargs Keyword arguments for the callback. See Also -------- getHessian, setObjective, setObjectiveGradient, setGradient petsc.TaoSetHessian """ cdef PetscMat Hmat = NULL if H is not None: Hmat = H.mat cdef PetscMat Pmat = Hmat if P is not None: Pmat = P.mat if args is None: args = () if kargs is None: kargs = {} context = (hessian, args, kargs) self.set_attr("__hessian__", context) CHKERR( TaoSetHessian(self.tao, Hmat, Pmat, TAO_Hessian, context) ) def getHessian(self) -> tuple[Mat, Mat, TAOHessianFunction]: """Return the matrices used to store the Hessian and the evaluation callback. Not collective. See Also -------- setHessian, petsc.TaoGetHessian """ cdef Mat J = Mat() cdef Mat P = Mat() CHKERR( TaoGetHessian(self.tao, &J.mat, &P.mat, NULL, NULL) ) CHKERR( PetscINCREF(J.obj) ) CHKERR( PetscINCREF(P.obj) ) cdef object hessian = self.get_attr("__hessian__") return (J, P, hessian) def setJacobian(self, jacobian: TAOJacobianFunction, Mat J=None, Mat P=None, args: tuple[Any, ...] | None = None, kargs: dict[str, Any] | None = None) -> None: """Set the callback to compute the Jacobian. Logically collective. Parameters ---------- jacobian The Jacobian callback. J The matrix to store the Jacobian. P The matrix to construct the preconditioner. args Positional arguments for the callback. kargs Keyword arguments for the callback. See Also -------- petsc.TaoSetJacobianRoutine """ cdef PetscMat Jmat = NULL if J is not None: Jmat = J.mat cdef PetscMat Pmat = Jmat if P is not None: Pmat = P.mat if args is None: args = () if kargs is None: kargs = {} context = (jacobian, args, kargs) self.set_attr("__jacobian__", context) CHKERR( TaoSetJacobianRoutine(self.tao, Jmat, Pmat, TAO_Jacobian, context) ) def setStateDesignIS(self, IS state=None, IS design=None) -> None: """Set the index sets indicating state and design variables. Collective. See Also -------- petsc.TaoSetStateDesignIS """ cdef PetscIS s_is = NULL, d_is = NULL if state is not None: s_is = state.iset if design is not None: d_is = design.iset CHKERR( TaoSetStateDesignIS(self.tao, s_is, d_is) ) def setJacobianState(self, jacobian_state, Mat J=None, Mat P=None, Mat I=None, args: tuple[Any, ...] | None = None, kargs: dict[str, Any] | None = None) -> None: """Set Jacobian state callback. Logically collective. See Also -------- petsc.TaoSetJacobianStateRoutine """ cdef PetscMat Jmat = NULL if J is not None: Jmat = J.mat cdef PetscMat Pmat = Jmat if P is not None: Pmat = P.mat cdef PetscMat Imat = NULL if I is not None: Imat = I.mat if args is None: args = () if kargs is None: kargs = {} context = (jacobian_state, args, kargs) self.set_attr("__jacobian_state__", context) CHKERR( TaoSetJacobianStateRoutine(self.tao, Jmat, Pmat, Imat, TAO_JacobianState, context) ) def setJacobianDesign(self, jacobian_design, Mat J=None, args: tuple[Any, ...] | None = None, kargs: dict[str, Any] | None = None) -> None: """Set Jacobian design callback. Logically collective. See Also -------- petsc.TaoSetJacobianDesignRoutine """ cdef PetscMat Jmat = NULL if J is not None: Jmat = J.mat if args is None: args = () if kargs is None: kargs = {} context = (jacobian_design, args, kargs) self.set_attr("__jacobian_design__", context) CHKERR( TaoSetJacobianDesignRoutine(self.tao, Jmat, TAO_JacobianDesign, context) ) def setEqualityConstraints(self, equality_constraints, Vec c, args: tuple[Any, ...] | None = None, kargs: dict[str, Any] | None = None) -> None: """Set equality constraints callback. Logically collective. See Also -------- petsc.TaoSetEqualityConstraintsRoutine """ if args is None: args = () if kargs is None: kargs = {} context = (equality_constraints, args, kargs) self.set_attr("__equality_constraints__", context) CHKERR( TaoSetEqualityConstraintsRoutine(self.tao, c.vec, TAO_EqualityConstraints, context) ) def setJacobianEquality(self, jacobian_equality, Mat J=None, Mat P=None, args: tuple[Any, ...] | None = None, kargs: dict[str, Any] | None = None) -> None: """Set Jacobian equality constraints callback. Logically collective. See Also -------- petsc.TaoSetJacobianEqualityRoutine """ cdef PetscMat Jmat = NULL if J is not None: Jmat = J.mat cdef PetscMat Pmat = Jmat if P is not None: Pmat = P.mat if args is None: args = () if kargs is None: kargs = {} context = (jacobian_equality, args, kargs) self.set_attr("__jacobian_equality__", context) CHKERR( TaoSetJacobianEqualityRoutine(self.tao, Jmat, Pmat, TAO_JacobianEquality, context) ) def setUpdate(self, update: TAOUpdateFunction, args: tuple[Any, ...] | None = None, kargs: dict[str, Any] | None = None) -> None: """Set the callback to compute update at each optimization step. Logically collective. Parameters ---------- update The update callback or `None` to reset it. args Positional arguments for the callback. kargs Keyword arguments for the callback. See Also -------- getUpdate, petsc.TaoSetUpdate """ if update is not None: if args is None: args = () if kargs is None: kargs = {} context = (update, args, kargs) self.set_attr('__update__', context) CHKERR( TaoSetUpdate(self.tao, TAO_Update, context) ) else: self.set_attr('__update__', None) CHKERR( TaoSetUpdate(self.tao, NULL, NULL) ) def getUpdate(self) -> tuple[TAOUpdateFunction, tuple[Any,...], dict[str, Any]]: """Return the callback to compute the update. Not collective. See Also -------- setUpdate """ return self.get_attr('__update__') # -------------- def computeObjective(self, Vec x) -> float: """Compute the value of the objective function. Collective. Parameters ---------- x The parameter vector. See Also -------- setObjective, petsc.TaoComputeObjective """ cdef PetscReal f = 0 CHKERR( TaoComputeObjective(self.tao, x.vec, &f) ) return toReal(f) def computeResidual(self, Vec x, Vec f) -> None: """Compute the residual. Collective. Parameters ---------- x The parameter vector. f The output vector. See Also -------- setResidual, petsc.TaoComputeResidual """ CHKERR( TaoComputeResidual(self.tao, x.vec, f.vec) ) def computeGradient(self, Vec x, Vec g) -> None: """Compute the gradient of the objective function. Collective. Parameters ---------- x The parameter vector. g The output gradient vector. See Also -------- setGradient, petsc.TaoComputeGradient """ CHKERR( TaoComputeGradient(self.tao, x.vec, g.vec) ) def computeObjectiveGradient(self, Vec x, Vec g) -> float: """Compute the gradient of the objective function and its value. Collective. Parameters ---------- x The parameter vector. g The output gradient vector. See Also -------- setObjectiveGradient, setGradient, setObjective petsc.TaoComputeObjectiveAndGradient """ cdef PetscReal f = 0 CHKERR( TaoComputeObjectiveAndGradient(self.tao, x.vec, &f, g.vec) ) return toReal(f) def computeDualVariables(self, Vec xl, Vec xu) -> None: """Compute the dual vectors corresponding to variables' bounds. Collective. See Also -------- petsc.TaoComputeDualVariables """ CHKERR( TaoComputeDualVariables(self.tao, xl.vec, xu.vec) ) def computeVariableBounds(self, Vec xl, Vec xu) -> None: """Compute the vectors corresponding to variables' bounds. Collective. See Also -------- setVariableBounds, petsc.TaoComputeVariableBounds """ CHKERR( TaoComputeVariableBounds(self.tao) ) cdef PetscVec Lvec = NULL, Uvec = NULL CHKERR( TaoGetVariableBounds(self.tao, &Lvec, &Uvec) ) if xl.vec != NULL: if Lvec != NULL: CHKERR( VecCopy(Lvec, xl.vec) ) else: CHKERR( VecSet(xl.vec, PETSC_NINFINITY) ) if xu.vec != NULL: if Uvec != NULL: CHKERR( VecCopy(Uvec, xu.vec) ) else: CHKERR( VecSet(xu.vec, PETSC_INFINITY) ) def computeConstraints(self, Vec x, Vec c) -> None: """Compute the vector corresponding to the constraints. Collective. Parameters ---------- x The parameter vector. c The output constraints vector. See Also -------- setVariableBounds, petsc.TaoComputeVariableBounds """ CHKERR( TaoComputeConstraints(self.tao, x.vec, c.vec) ) def computeHessian(self, Vec x, Mat H, Mat P=None) -> None: """Compute the Hessian of the objective function. Collective. Parameters ---------- x The parameter vector. H The output Hessian matrix. P The output Hessian matrix used to construct the preconditioner. See Also -------- setHessian, petsc.TaoComputeHessian """ cdef PetscMat hmat = H.mat, pmat = H.mat if P is not None: pmat = P.mat CHKERR( TaoComputeHessian(self.tao, x.vec, hmat, pmat) ) def computeJacobian(self, Vec x, Mat J, Mat P=None) -> None: """Compute the Jacobian. Collective. Parameters ---------- x The parameter vector. J The output Jacobian matrix. P The output Jacobian matrix used to construct the preconditioner. See Also -------- setJacobian, petsc.TaoComputeJacobian """ cdef PetscMat jmat = J.mat, pmat = J.mat if P is not None: pmat = P.mat CHKERR( TaoComputeJacobian(self.tao, x.vec, jmat, pmat) ) # -------------- def setTolerances(self, gatol: float = None, grtol: float = None, gttol: float = None) -> None: """Set the tolerance parameters used in the solver convergence tests. Collective. Parameters ---------- gatol The absolute norm of the gradient. Defaults to `DEFAULT`. grtol The relative norm of the gradient with respect to the initial norm of the objective. Defaults to `DEFAULT`. gttol The relative norm of the gradient with respect to the initial norm of the gradient. Defaults to `DEFAULT`. See Also -------- getTolerances, petsc.TaoSetTolerances """ cdef PetscReal _gatol=PETSC_DEFAULT, _grtol=PETSC_DEFAULT, _gttol=PETSC_DEFAULT if gatol is not None: _gatol = asReal(gatol) if grtol is not None: _grtol = asReal(grtol) if gttol is not None: _gttol = asReal(gttol) CHKERR( TaoSetTolerances(self.tao, _gatol, _grtol, _gttol) ) def getTolerances(self) -> tuple[float, float, float]: """Return the tolerance parameters used in the solver convergence tests. Not collective. Returns ------- gatol : float The absolute norm of the gradient. grtol : float The relative norm of the gradient with respect to the initial norm of the objective. gttol : float The relative norm of the gradient with respect to the initial norm of the gradient. See Also -------- setTolerances, petsc.TaoGetTolerances """ cdef PetscReal _gatol=PETSC_DEFAULT, _grtol=PETSC_DEFAULT, _gttol=PETSC_DEFAULT CHKERR( TaoGetTolerances(self.tao, &_gatol, &_grtol, &_gttol) ) return (toReal(_gatol), toReal(_grtol), toReal(_gttol)) def setMaximumIterations(self, mit: int) -> float: """Set the maximum number of solver iterations. Collective. See Also -------- setTolerances, petsc.TaoSetMaximumIterations """ cdef PetscInt _mit = asInt(mit) CHKERR( TaoSetMaximumIterations(self.tao, _mit) ) def getMaximumIterations(self) -> int: """Return the maximum number of solver iterations. Not collective. See Also -------- setMaximumIterations, petsc.TaoGetMaximumIterations """ cdef PetscInt _mit = PETSC_DEFAULT CHKERR( TaoGetMaximumIterations(self.tao, &_mit) ) return toInt(_mit) def setMaximumFunctionEvaluations(self, mit: int) -> None: """Set the maximum number of objective evaluations within the solver. Collective. See Also -------- setMaximumIterations, petsc.TaoSetMaximumFunctionEvaluations """ cdef PetscInt _mit = asInt(mit) CHKERR( TaoSetMaximumFunctionEvaluations(self.tao, _mit) ) def getMaximumFunctionEvaluations(self) -> int: """Return the maximum number of objective evaluations within the solver. Not collective. See Also -------- setMaximumFunctionEvaluations, petsc.TaoGetMaximumFunctionEvaluations """ cdef PetscInt _mit = PETSC_DEFAULT CHKERR( TaoGetMaximumFunctionEvaluations(self.tao, &_mit) ) return toInt(_mit) def setConstraintTolerances(self, catol: float = None, crtol: float = None) -> None: """Set the constraints tolerance parameters used in the solver convergence tests. Collective. Parameters ---------- catol The absolute norm of the constraints. Defaults to `DEFAULT`. crtol The relative norm of the constraints. Defaults to `DEFAULT`. See Also -------- getConstraintTolerances, petsc.TaoSetConstraintTolerances """ cdef PetscReal _catol=PETSC_DEFAULT, _crtol=PETSC_DEFAULT if catol is not None: _catol = asReal(catol) if crtol is not None: _crtol = asReal(crtol) CHKERR( TaoSetConstraintTolerances(self.tao, _catol, _crtol) ) def getConstraintTolerances(self) -> tuple[float, float]: """Return the constraints tolerance parameters used in the convergence tests. Not collective. Returns ------- catol : float The absolute norm of the constraints. crtol : float The relative norm of the constraints. See Also -------- setConstraintTolerances, petsc.TaoGetConstraintTolerances """ cdef PetscReal _catol=PETSC_DEFAULT, _crtol=PETSC_DEFAULT CHKERR( TaoGetConstraintTolerances(self.tao, &_catol, &_crtol) ) return (toReal(_catol), toReal(_crtol)) def setConvergenceTest(self, converged: TAOConvergedFunction | None, args: tuple[Any, ...] | None = None, kargs: dict[str, Any] | None = None) -> None: """Set the callback used to test for solver convergence. Logically collective. Parameters ---------- converged The callback. If `None`, reset to the default convergence test. args Positional arguments for the callback. kargs Keyword arguments for the callback. See Also -------- getConvergenceTest, petsc.TaoSetConvergenceTest """ if converged is None: CHKERR( TaoSetConvergenceTest(self.tao, TaoDefaultConvergenceTest, NULL) ) self.set_attr('__converged__', None) else: if args is None: args = () if kargs is None: kargs = {} self.set_attr('__converged__', (converged, args, kargs)) CHKERR( TaoSetConvergenceTest(self.tao, TAO_Converged, NULL) ) def getConvergenceTest(self) -> tuple[TAOConvergedFunction, tuple[Any, ...], dict[str, Any]]: """Return the callback used to test for solver convergence. Not collective. See Also -------- setConvergenceTest """ return self.get_attr('__converged__') def setConvergedReason(self, reason: ConvergedReason) -> None: """Set the termination flag. Collective. See Also -------- getConvergedReason, petsc.TaoSetConvergedReason """ cdef PetscTAOConvergedReason creason = reason CHKERR( TaoSetConvergedReason(self.tao, creason) ) def getConvergedReason(self) -> ConvergedReason: """Return the termination flag. Not collective. See Also -------- setConvergedReason, petsc.TaoGetConvergedReason """ cdef PetscTAOConvergedReason creason = TAO_CONTINUE_ITERATING CHKERR( TaoGetConvergedReason(self.tao, &creason) ) return creason def setMonitor(self, monitor: TAOMonitorFunction, args: tuple[Any, ...] | None = None, kargs: dict[str, Any] | None = None) -> None: """Set the callback used to monitor solver convergence. Logically collective. Parameters ---------- monitor The callback. args Positional arguments for the callback. kargs Keyword arguments for the callback. See Also -------- getMonitor, petsc.TaoSetMonitor """ if monitor is None: return cdef object monitorlist = self.get_attr('__monitor__') if args is None: args = () if kargs is None: kargs = {} if monitorlist is None: CHKERR( TaoSetMonitor(self.tao, TAO_Monitor, NULL, NULL) ) self.set_attr('__monitor__', [(monitor, args, kargs)]) else: monitorlist.append((monitor, args, kargs)) def getMonitor(self) -> list[tuple[TAOMonitorFunction, tuple[Any, ...], dict[str, Any]]]: """Return the callback used to monitor solver convergence. Not collective. See Also -------- setMonitor """ return self.get_attr('__monitor__') def cancelMonitor(self) -> None: """Cancel all the monitors of the solver. Logically collective. See Also -------- setMonitor, petsc.TaoCancelMonitors """ CHKERR( TaoCancelMonitors(self.tao) ) self.set_attr('__monitor__', None) # Tao overwrites these statistics. Copy user defined only if present def monitor(self, its: int = None, f: float = None, res: float = None, cnorm: float = None, step: float = None) -> None: """Monitor the solver. Collective. This function should be called without arguments, unless users want to modify the values internally stored by the solver. Parameters ---------- its Current number of iterations or `None` to use the value stored internally by the solver. f Current value of the objective function or `None` to use the value stored internally by the solver. res Current value of the residual norm or `None` to use the value stored internally by the solver. cnorm Current value of the constrains norm or `None` to use the value stored internally by the solver. step Current value of the step or `None` to use the value stored internally by the solver. See Also -------- setMonitor, petsc.TaoMonitor """ cdef PetscInt cits = 0 cdef PetscReal cf = 0.0 cdef PetscReal cres = 0.0 cdef PetscReal ccnorm = 0.0 cdef PetscReal cstep = 0.0 CHKERR( TaoGetSolutionStatus(self.tao, &cits, &cf, &cres, &ccnorm, &cstep, NULL) ) if its is not None: cits = asInt(its) if f is not None: cf = asReal(f) if res is not None: cres = asReal(res) if cnorm is not None: ccnorm = asReal(cnorm) if step is not None: cstep = asReal(step) CHKERR( TaoMonitor(self.tao, cits, cf, cres, ccnorm, cstep) ) # def solve(self, Vec x=None) -> None: """Solve the optimization problem. Collective. Parameters ---------- x The starting vector or `None` to use the vector stored internally. See Also -------- setSolution, getSolution, petsc.TaoSolve """ if x is not None: CHKERR( TaoSetSolution(self.tao, x.vec) ) CHKERR( TaoSolve(self.tao) ) def getSolution(self) -> Vec: """Return the vector holding the solution. Not collective. See Also -------- setSolution, petsc.TaoGetSolution """ cdef Vec vec = Vec() CHKERR( TaoGetSolution(self.tao, &vec.vec) ) CHKERR( PetscINCREF(vec.obj) ) return vec def setGradientNorm(self, Mat mat) -> None: """Set the matrix used to compute inner products. Collective. See Also -------- getGradientNorm, petsc.TaoSetGradientNorm """ CHKERR( TaoSetGradientNorm(self.tao, mat.mat) ) def getGradientNorm(self) -> Mat: """Return the matrix used to compute inner products. Not collective. See Also -------- setGradientNorm, petsc.TaoGetGradientNorm """ cdef Mat mat = Mat() CHKERR( TaoGetGradientNorm(self.tao, &mat.mat) ) CHKERR( PetscINCREF(mat.obj) ) return mat def setLMVMH0(self, Mat mat) -> None: """Set the initial Hessian for the quasi-Newton approximation. Collective. See Also -------- getLMVMH0, petsc.TaoLMVMSetH0 """ CHKERR( TaoLMVMSetH0(self.tao, mat.mat) ) def getLMVMH0(self) -> Mat: """Return the initial Hessian for the quasi-Newton approximation. Not collective. See Also -------- setLMVMH0, petsc.TaoLMVMGetH0 """ cdef Mat mat = Mat() CHKERR( TaoLMVMGetH0(self.tao, &mat.mat) ) CHKERR( PetscINCREF(mat.obj) ) return mat def getLMVMH0KSP(self) -> KSP: """Return the `KSP` for the inverse of the initial Hessian approximation. Not collective. See Also -------- setLMVMH0, petsc.TaoLMVMGetH0KSP """ cdef KSP ksp = KSP() CHKERR( TaoLMVMGetH0KSP(self.tao, &ksp.ksp) ) CHKERR( PetscINCREF(ksp.obj) ) return ksp def getVariableBounds(self) -> tuple[Vec, Vec]: """Return the upper and lower bounds vectors. Not collective. See Also -------- setVariableBounds, petsc.TaoGetVariableBounds """ cdef Vec xl = Vec(), xu = Vec() CHKERR( TaoGetVariableBounds(self.tao, &xl.vec, &xu.vec) ) CHKERR( PetscINCREF(xl.obj) ); CHKERR( PetscINCREF(xu.obj) ) return (xl, xu) def setBNCGType(self, cg_type: BNCGType) -> None: """Set the type of the BNCG solver. Collective. See Also -------- getBNCGType, petsc.TaoBNCGSetType """ cdef PetscTAOBNCGType ctype = cg_type CHKERR( TaoBNCGSetType(self.tao, ctype) ) def getBNCGType(self) -> BNCGType: """Return the type of the BNCG solver. Not collective. See Also -------- setBNCGType, petsc.TaoBNCGGetType """ cdef PetscTAOBNCGType cg_type = TAO_BNCG_SSML_BFGS CHKERR( TaoBNCGGetType(self.tao, &cg_type) ) return cg_type def setIterationNumber(self, its: int) -> None: """Set the current iteration number. Collective. See Also -------- getIterationNumber, petsc.TaoSetIterationNumber """ cdef PetscInt ival = asInt(its) CHKERR( TaoSetIterationNumber(self.tao, ival) ) def getIterationNumber(self) -> int: """Return the current iteration number. Not collective. See Also -------- setIterationNumber, petsc.TaoGetIterationNumber """ cdef PetscInt its=0 CHKERR( TaoGetIterationNumber(self.tao, &its) ) return toInt(its) def getObjectiveValue(self) -> float: """Return the current value of the objective function. Not collective. See Also -------- setObjective, petsc.TaoGetSolutionStatus """ cdef PetscReal fval=0 CHKERR( TaoGetSolutionStatus(self.tao, NULL, &fval, NULL, NULL, NULL, NULL) ) return toReal(fval) getFunctionValue = getObjectiveValue def getConvergedReason(self) -> ConvergedReason: """Return the reason for the solver convergence. Not collective. See Also -------- petsc.TaoGetConvergedReason """ cdef PetscTAOConvergedReason reason = TAO_CONTINUE_ITERATING CHKERR( TaoGetConvergedReason(self.tao, &reason) ) return reason def getSolutionNorm(self) -> tuple[float, float, float]: """Return the objective function value and the norms of gradient and constraints. Not collective. Returns ------- f : float Current value of the objective function. res : float Current value of the residual norm. cnorm : float Current value of the constrains norm. See Also -------- getSolutionStatus, petsc.TaoGetSolutionStatus """ cdef PetscReal gnorm=0 cdef PetscReal cnorm=0 cdef PetscReal fval=0 CHKERR( TaoGetSolutionStatus(self.tao, NULL, &fval, &gnorm, &cnorm, NULL, NULL) ) return (toReal(fval), toReal(gnorm), toReal(cnorm)) def getSolutionStatus(self) -> tuple[int, float, float, float, float, ConvergedReason]: """Return the solution status. Not collective. Returns ------- its : int Current number of iterations. f : float Current value of the objective function. res : float Current value of the residual norm. cnorm : float Current value of the constrains norm. step : float Current value of the step. reason : ConvergedReason Current value of converged reason. See Also -------- petsc.TaoGetSolutionStatus """ cdef PetscInt its=0 cdef PetscReal fval=0, gnorm=0, cnorm=0, xdiff=0 cdef PetscTAOConvergedReason reason = TAO_CONTINUE_ITERATING CHKERR( TaoGetSolutionStatus(self.tao, &its, &fval, &gnorm, &cnorm, &xdiff, &reason) ) return (toInt(its), toReal(fval), toReal(gnorm), toReal(cnorm), toReal(xdiff), reason) def getKSP(self) -> KSP: """Return the linear solver used by the nonlinear solver. Not collective. See Also -------- petsc.TaoGetKSP """ cdef KSP ksp = KSP() CHKERR( TaoGetKSP(self.tao, &ksp.ksp) ) CHKERR( PetscINCREF(ksp.obj) ) return ksp # BRGN routines def getBRGNSubsolver(self) -> TAO: """Return the subsolver inside the BRGN solver. Not collective. See Also -------- petsc.TaoBRGNGetSubsolver """ cdef TAO subsolver = TAO() CHKERR( TaoBRGNGetSubsolver(self.tao, &subsolver.tao) ) CHKERR( PetscINCREF(subsolver.obj) ) return subsolver def setBRGNRegularizerObjectiveGradient(self, objgrad, args: tuple[Any, ...] | None = None, kargs: dict[str, Any] | None = None) -> None: """Set the callback to compute the regularizer objective and gradient. Logically collective. See Also -------- petsc.TaoBRGNSetRegularizerObjectiveAndGradientRoutine """ if args is None: args = () if kargs is None: kargs = {} context = (objgrad, args, kargs) self.set_attr("__brgnregobjgrad__", context) CHKERR( TaoBRGNSetRegularizerObjectiveAndGradientRoutine(self.tao, TAO_BRGNRegObjGrad, context) ) def setBRGNRegularizerHessian(self, hessian, Mat H=None, args: tuple[Any, ...] | None = None, kargs: dict[str, Any] | None = None) -> None: """Set the callback to compute the regularizer Hessian. Logically collective. See Also -------- petsc.TaoBRGNSetRegularizerHessianRoutine """ cdef PetscMat Hmat = NULL if H is not None: Hmat = H.mat if args is None: args = () if kargs is None: kargs = {} context = (hessian, args, kargs) self.set_attr("__brgnreghessian__", context) CHKERR( TaoBRGNSetRegularizerHessianRoutine(self.tao, Hmat, TAO_BRGNRegHessian, context) ) def setBRGNRegularizerWeight(self, weight: float) -> None: """Set the regularizer weight. Collective. """ cdef PetscReal cweight = asReal(weight) CHKERR( TaoBRGNSetRegularizerWeight(self.tao, cweight) ) def setBRGNSmoothL1Epsilon(self, epsilon: float) -> None: """Set the smooth L1 epsilon. Collective. See Also -------- petsc.TaoBRGNSetL1SmoothEpsilon """ cdef PetscReal ceps = asReal(epsilon) CHKERR( TaoBRGNSetL1SmoothEpsilon(self.tao, ceps) ) def setBRGNDictionaryMatrix(self, Mat D) -> None: """Set the dictionary matrix. Collective. See Also -------- petsc.TaoBRGNSetDictionaryMatrix """ CHKERR( TaoBRGNSetDictionaryMatrix(self.tao, D.mat) ) def getBRGNDampingVector(self) -> Vec: """Return the damping vector. Not collective. """ #FIXME #See Also #-------- #petsc.TaoBRGNGetDampingVector cdef Vec damp = Vec() CHKERR( TaoBRGNGetDampingVector(self.tao, &damp.vec) ) CHKERR( PetscINCREF(damp.obj) ) return damp def createPython(self, context: Any = None, comm: Comm | None = None) -> Self: """Create an optimization solver of Python type. Collective. Parameters ---------- context An instance of the Python class implementing the required methods. comm MPI communicator, defaults to `Sys.getDefaultComm`. See Also -------- petsc_python_tao, setType, setPythonContext, Type.PYTHON """ cdef MPI_Comm ccomm = def_Comm(comm, PETSC_COMM_DEFAULT) cdef PetscTAO tao = NULL CHKERR( TaoCreate(ccomm, &tao) ) CHKERR( PetscCLEAR(self.obj) ); self.tao = tao CHKERR( TaoSetType(self.tao, TAOPYTHON) ) CHKERR( TaoPythonSetContext(self.tao, context) ) return self def setPythonContext(self, context: Any) -> None: """Set the instance of the class implementing the required Python methods. Not collective. See Also -------- petsc_python_tao, getPythonContext """ CHKERR( TaoPythonSetContext(self.tao, context) ) def getPythonContext(self) -> Any: """Return the instance of the class implementing the required Python methods. Not collective. See Also -------- petsc_python_tao, setPythonContext """ cdef void *context = NULL CHKERR( TaoPythonGetContext(self.tao, &context) ) if context == NULL: return None else: return context def setPythonType(self, py_type: str) -> None: """Set the fully qualified Python name of the class to be used. Collective. See Also -------- petsc_python_tao, setPythonContext, getPythonType petsc.TaoPythonSetType """ cdef const char *cval = NULL py_type = str2bytes(py_type, &cval) CHKERR( TaoPythonSetType(self.tao, cval) ) def getPythonType(self) -> str: """Return the fully qualified Python name of the class used by the solver. Not collective. See Also -------- petsc_python_tao, setPythonContext, setPythonType petsc.TaoPythonGetType """ cdef const char *cval = NULL CHKERR( TaoPythonGetType(self.tao, &cval) ) return bytes2str(cval) def getLineSearch(self) -> TAOLineSearch: """Return the TAO Line Search object. Not collective. See Also ------- petsc.TaoGetLineSearch """ cdef TAOLineSearch ls = TAOLineSearch() CHKERR( TaoGetLineSearch(self.tao, &ls.taols) ) CHKERR( PetscINCREF(ls.obj) ) return ls # --- backward compatibility --- setInitial = setSolution # --- application context --- property appctx: """Application context.""" def __get__(self) -> Any: return self.getAppCtx() def __set__(self, value: Any): self.setAppCtx(value) # --- linear solver --- property ksp: """Linear solver.""" def __get__(self) -> KSP: return self.getKSP() # --- tolerances --- # FIXME: tolerances all broken property ftol: """Broken.""" def __get__(self) -> Any: return self.getFunctionTolerances() def __set__(self, value): if isinstance(value, (tuple, list)): self.setFunctionTolerances(*value) elif isinstance(value, dict): self.setFunctionTolerances(**value) else: raise TypeError("expecting tuple/list or dict") property gtol: """Broken.""" def __get__(self) -> Any: return self.getGradientTolerances() def __set__(self, value): if isinstance(value, (tuple, list)): self.getGradientTolerances(*value) elif isinstance(value, dict): self.getGradientTolerances(**value) else: raise TypeError("expecting tuple/list or dict") property ctol: """Broken.""" def __get__(self) -> Any: return self.getConstraintTolerances() def __set__(self, value): if isinstance(value, (tuple, list)): self.getConstraintTolerances(*value) elif isinstance(value, dict): self.getConstraintTolerances(**value) else: raise TypeError("expecting tuple/list or dict") # --- iteration --- property its: """Number of iterations.""" def __get__(self) -> int: return self.getIterationNumber() property gnorm: """Gradient norm.""" def __get__(self) -> float: return self.getSolutionNorm()[1] property cnorm: """Constraints norm.""" def __get__(self) -> float: return self.getSolutionNorm()[2] property solution: """Solution vector.""" def __get__(self) -> Vec: return self.getSolution() property objective: """Objective value.""" def __get__(self) -> float: return self.getObjectiveValue() property function: """Objective value.""" def __get__(self) -> float: return self.getFunctionValue() property gradient: """Gradient vector.""" def __get__(self) -> Vec: return self.getGradient()[0] # --- convergence --- property reason: """Converged reason.""" def __get__(self) -> ConvergedReason: return self.getConvergedReason() property iterating: """Boolean indicating if the solver has not converged yet.""" def __get__(self) -> bool: return self.reason == 0 property converged: """Boolean indicating if the solver has converged.""" def __get__(self) -> bool: return self.reason > 0 property diverged: """Boolean indicating if the solver has failed.""" def __get__(self) -> bool: return self.reason < 0 # -------------------------------------------------------------------- del TAOType del TAOConvergedReason del TAOBNCGType # -------------------------------------------------------------------- class TAOLineSearchType: """TAO Line Search Types.""" UNIT = S_(TAOLINESEARCHUNIT) ARMIJO = S_(TAOLINESEARCHARMIJO) MORETHUENTE = S_(TAOLINESEARCHMT) IPM = S_(TAOLINESEARCHIPM) OWARMIJO = S_(TAOLINESEARCHOWARMIJO) GPCG = S_(TAOLINESEARCHGPCG) class TAOLineSearchConvergedReason: """TAO Line Search Termination Reasons.""" # iterating CONTINUE_SEARCH = TAOLINESEARCH_CONTINUE_ITERATING # failed FAILED_INFORNAN = TAOLINESEARCH_FAILED_INFORNAN # inf or NaN in user function FAILED_BADPARAMETER = TAOLINESEARCH_FAILED_BADPARAMETER # negative value set as parameter FAILED_ASCENT = TAOLINESEARCH_FAILED_ASCENT # search direction is not a descent direction # succeeded SUCCESS = TAOLINESEARCH_SUCCESS # found step length SUCCESS_USER = TAOLINESEARCH_SUCCESS_USER # user-defined success criteria reached # halted HALTED_OTHER = TAOLINESEARCH_HALTED_OTHER # stopped search with unknown reason HALTED_MAXFCN = TAOLINESEARCH_HALTED_MAXFCN # maximum function evaluations reached HALTED_UPPERBOUND = TAOLINESEARCH_HALTED_UPPERBOUND # stopped at upper bound HALTED_LOWERBOUND = TAOLINESEARCH_HALTED_LOWERBOUND # stopped at lower bound HALTED_RTOL = TAOLINESEARCH_HALTED_RTOL # range of uncertainty is below tolerance HALTED_USER = TAOLINESEARCH_HALTED_USER # user-defined halt criteria reached # -------------------------------------------------------------------- cdef class TAOLineSearch(Object): """TAO Line Search.""" Type = TAOLineSearchType Reason = TAOLineSearchConvergedReason def __cinit__(self): self.obj = &self.taols self.taols = NULL def view(self, Viewer viewer=None) -> None: """View the linesearch object. Collective. Parameters ---------- viewer A `Viewer` instance or `None` for the default viewer. See Also -------- petsc.TaoLineSearchView """ cdef PetscViewer vwr = NULL if viewer is not None: vwr = viewer.vwr CHKERR( TaoLineSearchView(self.taols, vwr) ) def destroy(self) -> Self: """Destroy the linesearch object. Collective. See Also -------- petsc.TaoLineSearchDestroy """ CHKERR( TaoLineSearchDestroy(&self.taols) ) return self def create(self, comm=None) -> Self: """Create a TAO linesearch. Collective. Parameters ---------- comm MPI communicator, defaults to `Sys.getDefaultComm`. See Also -------- Sys.getDefaultComm, petsc.TaoLineSearchCreate """ cdef MPI_Comm ccomm = def_Comm(comm, PETSC_COMM_DEFAULT) cdef PetscTAOLineSearch newtaols = NULL CHKERR( TaoLineSearchCreate(ccomm, &newtaols) ) CHKERR( PetscCLEAR(self.obj) ); self.taols = newtaols return self def setType(self, ls_type: Type | str) -> None: """Set the type of the linesearch. Logically collective. Parameters ---------- ls_type The type of the solver. See Also -------- getType, petsc.TaoLineSearchSetType """ cdef PetscTAOLineSearchType ctype = NULL ls_type = str2bytes(ls_type, &ctype) CHKERR( TaoLineSearchSetType(self.taols, ctype) ) def getType(self) -> str: """Return the type of the linesearch. Not collective. See Also -------- setType, petsc.TaoLineSearchGetType """ cdef PetscTAOLineSearchType ctype = NULL CHKERR( TaoLineSearchGetType(self.taols, &ctype) ) return bytes2str(ctype) def setFromOptions(self) -> None: """Configure the linesearch from the options database. Collective. See Also -------- petsc_options, petsc.TaoLineSearchSetFromOptions """ CHKERR( TaoLineSearchSetFromOptions(self.taols) ) def setUp(self) -> None: """Set up the internal data structures for using the linesearch. Collective. See Also -------- petsc.TaoLineSearchSetUp """ CHKERR( TaoLineSearchSetUp(self.taols) ) def setOptionsPrefix(self, prefix) -> None: """Set the prefix used for searching for options in the database. Logically collective. See Also -------- petsc_options, petsc.TaoLineSearchSetOptionsPrefix """ cdef const char *cprefix = NULL prefix = str2bytes(prefix, &cprefix) CHKERR( TaoLineSearchSetOptionsPrefix(self.taols, cprefix) ) def getOptionsPrefix(self) -> str: """Return the prefix used for searching for options in the database. Not collective. See Also -------- petsc_options, setOptionsPrefix, petsc.TaoLineSearchGetOptionsPrefix """ cdef const char *prefix = NULL CHKERR( TaoLineSearchGetOptionsPrefix(self.taols, &prefix) ) return bytes2str(prefix) def setObjective(self, objective : TAOLSObjectiveFunction, args: tuple[Any, ...] | None = None, kargs: dict[str, Any] | None = None) -> None: """Set the objective function evaluation callback. Logically collective. Parameters ---------- objective The objective function callback. args Positional arguments for the callback. kargs Keyword arguments for the callback. See Also -------- setGradient, setObjectiveGradient petsc.TaoLineSearchSetObjectiveRoutine """ CHKERR( TaoLineSearchSetObjectiveRoutine(self.taols, TAOLS_Objective, NULL) ) if args is None: args = () if kargs is None: kargs = {} self.set_attr("__objective__", (objective, args, kargs)) def setGradient(self, gradient: TAOLSGradientFunction, args: tuple[Any, ...] | None = None, kargs: dict[str, Any] | None = None) -> None: """Set the gradient evaluation callback. Logically collective. Parameters ---------- gradient The gradient callback. g The vector to store the gradient. args Positional arguments for the callback. kargs Keyword arguments for the callback. See Also -------- setObjective, setObjectiveGradient, setHessian petsc.TaoLineSearchSetGradientRoutine """ CHKERR( TaoLineSearchSetGradientRoutine(self.taols, TAOLS_Gradient, NULL) ) if args is None: args = () if kargs is None: kargs = {} self.set_attr("__gradient__", (gradient, args, kargs)) def setObjectiveGradient(self, objgrad: TAOLSObjectiveGradientFunction, args: tuple[Any, ...] | None = None, kargs: dict[str, Any] | None = None) -> None: """Set the objective function and gradient evaluation callback. Logically collective. Parameters ---------- objgrad The objective function and gradient callback. g The vector to store the gradient. args Positional arguments for the callback. kargs Keyword arguments for the callback. See Also -------- setObjective, setGradient, setHessian, getObjectiveAndGradient petsc.TaoLineSearchSetObjectiveAndGradientRoutine """ CHKERR( TaoLineSearchSetObjectiveAndGradientRoutine(self.taols, TAOLS_ObjGrad, NULL) ) if args is None: args = () if kargs is None: kargs = {} self.set_attr("__objgrad__", (objgrad, args, kargs)) def useTAORoutine(self, TAO tao) -> None: """Use the objective and gradient evaluation routines from the given Tao object. Logically collective. See Also -------- petsc.TaoLineSearchUseTaoRoutines """ CHKERR( TaoLineSearchUseTaoRoutines(self.taols, tao.tao) ) def apply(self, Vec x, Vec g, Vec s) -> tuple[float, float, str]: """Performs a line-search in a given step direction. Collective. See Also -------- petsc.TaoLineSearchApply """ cdef PetscReal f = 0 cdef PetscReal steplen = 0 cdef PetscTAOLineSearchConvergedReason reason = TAOLINESEARCH_CONTINUE_ITERATING CHKERR( TaoLineSearchApply(self.taols,x.vec,&f,g.vec,s.vec,&steplen,&reason)) return (toReal(f), toReal(steplen), reason) # -------------------------------------------------------------------- del TAOLineSearchType del TAOLineSearchConvergedReason ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/src/petsc4py/PETSc/TS.pyx0000644000175000017500000023662414567251135016754 0ustar00balaybalay# ----------------------------------------------------------------------------- class TSType(object): """The time stepping method.""" # native EULER = S_(TSEULER) BEULER = S_(TSBEULER) BASICSYMPLECTIC = S_(TSBASICSYMPLECTIC) PSEUDO = S_(TSPSEUDO) CN = S_(TSCN) SUNDIALS = S_(TSSUNDIALS) RK = S_(TSRK) PYTHON = S_(TSPYTHON) THETA = S_(TSTHETA) ALPHA = S_(TSALPHA) ALPHA2 = S_(TSALPHA2) GLLE = S_(TSGLLE) GLEE = S_(TSGLEE) SSP = S_(TSSSP) ARKIMEX = S_(TSARKIMEX) DIRK = S_(TSDIRK) ROSW = S_(TSROSW) EIMEX = S_(TSEIMEX) MIMEX = S_(TSMIMEX) BDF = S_(TSBDF) RADAU5 = S_(TSRADAU5) MPRK = S_(TSMPRK) DISCGRAD = S_(TSDISCGRAD) # aliases FE = EULER BE = BEULER TH = THETA CRANK_NICOLSON = CN RUNGE_KUTTA = RK class TSRKType(object): """The *RK* subtype.""" RK1FE = S_(TSRK1FE) RK2A = S_(TSRK2A) RK2B = S_(TSRK2B) RK4 = S_(TSRK4) RK3BS = S_(TSRK3BS) RK3 = S_(TSRK3) RK5F = S_(TSRK5F) RK5DP = S_(TSRK5DP) RK5BS = S_(TSRK5BS) RK6VR = S_(TSRK6VR) RK7VR = S_(TSRK7VR) RK8VR = S_(TSRK8VR) class TSARKIMEXType(object): """The *ARKIMEX* subtype.""" ARKIMEX1BEE = S_(TSARKIMEX1BEE) ARKIMEXA2 = S_(TSARKIMEXA2) ARKIMEXL2 = S_(TSARKIMEXL2) ARKIMEXARS122 = S_(TSARKIMEXARS122) ARKIMEX2C = S_(TSARKIMEX2C) ARKIMEX2D = S_(TSARKIMEX2D) ARKIMEX2E = S_(TSARKIMEX2E) ARKIMEXPRSSP2 = S_(TSARKIMEXPRSSP2) ARKIMEX3 = S_(TSARKIMEX3) ARKIMEXBPR3 = S_(TSARKIMEXBPR3) ARKIMEXARS443 = S_(TSARKIMEXARS443) ARKIMEX4 = S_(TSARKIMEX4) ARKIMEX5 = S_(TSARKIMEX5) class TSDIRKType(object): """The *DIRK* subtype.""" DIRKS212 = S_(TSDIRKS212) DIRKES122SAL = S_(TSDIRKES122SAL) DIRKES213SAL = S_(TSDIRKES213SAL) DIRKES324SAL = S_(TSDIRKES324SAL) DIRKES325SAL = S_(TSDIRKES325SAL) DIRK657A = S_(TSDIRK657A) DIRKES648SA = S_(TSDIRKES648SA) DIRK658A = S_(TSDIRK658A) DIRKS659A = S_(TSDIRKS659A) DIRK7510SAL = S_(TSDIRK7510SAL) DIRKES7510SA = S_(TSDIRKES7510SA) DIRK759A = S_(TSDIRK759A) DIRKS7511SAL = S_(TSDIRKS7511SAL) DIRK8614A = S_(TSDIRK8614A) DIRK8616SAL = S_(TSDIRK8616SAL) DIRKES8516SAL = S_(TSDIRKES8516SAL) class TSProblemType(object): """Distinguishes linear and nonlinear problems.""" LINEAR = TS_LINEAR NONLINEAR = TS_NONLINEAR class TSEquationType(object): """Distinguishes among types of explicit and implicit equations.""" UNSPECIFIED = TS_EQ_UNSPECIFIED EXPLICIT = TS_EQ_EXPLICIT ODE_EXPLICIT = TS_EQ_ODE_EXPLICIT DAE_SEMI_EXPLICIT_INDEX1 = TS_EQ_DAE_SEMI_EXPLICIT_INDEX1 DAE_SEMI_EXPLICIT_INDEX2 = TS_EQ_DAE_SEMI_EXPLICIT_INDEX2 DAE_SEMI_EXPLICIT_INDEX3 = TS_EQ_DAE_SEMI_EXPLICIT_INDEX3 DAE_SEMI_EXPLICIT_INDEXHI = TS_EQ_DAE_SEMI_EXPLICIT_INDEXHI IMPLICIT = TS_EQ_IMPLICIT ODE_IMPLICIT = TS_EQ_ODE_IMPLICIT DAE_IMPLICIT_INDEX1 = TS_EQ_DAE_IMPLICIT_INDEX1 DAE_IMPLICIT_INDEX2 = TS_EQ_DAE_IMPLICIT_INDEX2 DAE_IMPLICIT_INDEX3 = TS_EQ_DAE_IMPLICIT_INDEX3 DAE_IMPLICIT_INDEXHI = TS_EQ_DAE_IMPLICIT_INDEXHI class TSExactFinalTime(object): """The method for ending time stepping.""" UNSPECIFIED = TS_EXACTFINALTIME_UNSPECIFIED STEPOVER = TS_EXACTFINALTIME_STEPOVER INTERPOLATE = TS_EXACTFINALTIME_INTERPOLATE MATCHSTEP = TS_EXACTFINALTIME_MATCHSTEP class TSConvergedReason(object): """The reason the time step is converging.""" # iterating CONVERGED_ITERATING = TS_CONVERGED_ITERATING ITERATING = TS_CONVERGED_ITERATING # converged CONVERGED_TIME = TS_CONVERGED_TIME CONVERGED_ITS = TS_CONVERGED_ITS CONVERGED_USER = TS_CONVERGED_USER CONVERGED_EVENT = TS_CONVERGED_EVENT # diverged DIVERGED_NONLINEAR_SOLVE = TS_DIVERGED_NONLINEAR_SOLVE DIVERGED_STEP_REJECTED = TS_DIVERGED_STEP_REJECTED # ----------------------------------------------------------------------------- cdef class TS(Object): """ODE integrator. TS is described in the `PETSc manual `. See Also -------- petsc.TS """ Type = TSType RKType = TSRKType ARKIMEXType = TSARKIMEXType DIRKType = TSDIRKType ProblemType = TSProblemType EquationType = TSEquationType ExactFinalTime = TSExactFinalTime ExactFinalTimeOption = TSExactFinalTime ConvergedReason = TSConvergedReason # --- xxx --- def __cinit__(self): self.obj = &self.ts self.ts = NULL # --- xxx --- def view(self, Viewer viewer=None) -> None: """Print the `TS` object. Collective. Parameters ---------- viewer The visualization context. Notes ----- ``-ts_view`` calls TSView at the end of TSStep See Also -------- petsc.TSView """ cdef PetscViewer cviewer = NULL if viewer is not None: cviewer = viewer.vwr CHKERR( TSView(self.ts, cviewer) ) def load(self, Viewer viewer) -> None: """Load a `TS` that has been stored in binary with `view`. Parameters ---------- viewer The visualization context. See Also -------- petsc.TSLoad """ CHKERR( TSLoad(self.ts, viewer.vwr) ) def destroy(self) -> Self: """Destroy the `TS` that was created with `create`. See Also -------- petsc.TSDestroy """ CHKERR( TSDestroy(&self.ts) ) return self def create(self, comm: Comm | None = None) -> Self: """Create an empty `TS`. The problem type can then be set with `setProblemType` and the type of solver can then be set with `setType`. Parameters ---------- comm MPI communicator, defaults to `Sys.getDefaultComm`. See Also -------- petsc.TSCreate """ cdef MPI_Comm ccomm = def_Comm(comm, PETSC_COMM_DEFAULT) cdef PetscTS newts = NULL CHKERR( TSCreate(ccomm, &newts) ) CHKERR( PetscCLEAR(self.obj) ); self.ts = newts return self def clone(self) -> TS: """Return a shallow clone of the `TS` object. Collective. See Also -------- petsc.TSClone """ cdef TS ts = TS() CHKERR( TSClone(self.ts, &ts.ts) ) return ts def setType(self, ts_type: Type | str) -> None: """Set the method to be used as the `TS` solver. Parameters ---------- ts_type The solver type. Notes ----- ``-ts_type`` sets the method from the commandline See Also -------- petsc.TSSetType """ cdef PetscTSType cval = NULL ts_type = str2bytes(ts_type, &cval) CHKERR( TSSetType(self.ts, cval) ) def setRKType(self, ts_type: RKType | str) -> None: """Set the type of the *Runge-Kutta* scheme. Parameters ---------- ts_type The type of scheme. Notes ----- ``-ts_rk_type`` sets scheme type from the commandline. See Also -------- petsc.TSRKSetType """ cdef PetscTSRKType cval = NULL ts_type = str2bytes(ts_type, &cval) CHKERR( TSRKSetType(self.ts, cval) ) def setARKIMEXType(self, ts_type: ARKIMEXType | str) -> None: """Set the type of `Type.ARKIMEX` scheme. Parameters ---------- ts_type The type of `Type.ARKIMEX` scheme. Notes ----- ``-ts_arkimex_type`` sets scheme type from the commandline. See Also -------- petsc.TSARKIMEXSetType """ cdef PetscTSARKIMEXType cval = NULL ts_type = str2bytes(ts_type, &cval) CHKERR( TSARKIMEXSetType(self.ts, cval) ) def setARKIMEXFullyImplicit(self, flag: bool) -> None: """Solve both parts of the equation implicitly. Parameters ---------- flag Set to True for fully implicit. See Also -------- petsc.TSARKIMEXSetFullyImplicit """ cdef PetscBool bval = asBool(flag) CHKERR( TSARKIMEXSetFullyImplicit(self.ts, bval) ) def getType(self) -> str: """Return the `TS` type. See Also -------- petsc.TSGetType """ cdef PetscTSType cval = NULL CHKERR( TSGetType(self.ts, &cval) ) return bytes2str(cval) def getRKType(self) -> str: """Return the `Type.RK` scheme. See Also -------- petsc.TSRKGetType """ cdef PetscTSRKType cval = NULL CHKERR( TSRKGetType(self.ts, &cval) ) return bytes2str(cval) def getARKIMEXType(self) -> str: """Return the `Type.ARKIMEX` scheme. See Also -------- petsc.TSARKIMEXGetType """ cdef PetscTSARKIMEXType cval = NULL CHKERR( TSARKIMEXGetType(self.ts, &cval) ) return bytes2str(cval) def setDIRKType(self, ts_type: DIRKType | str) -> None: """Set the type of `Type.DIRK` scheme. Parameters ---------- ts_type The type of `Type.DIRK` scheme. Notes ----- ``-ts_dirk_type`` sets scheme type from the commandline. See Also -------- petsc.TSDIRKSetType """ cdef PetscTSDIRKType cval = NULL ts_type = str2bytes(ts_type, &cval) CHKERR( TSDIRKSetType(self.ts, cval) ) def getDIRKType(self) -> str: """Return the `Type.DIRK` scheme. See Also -------- setDIRKType, petsc.TSDIRKGetType """ cdef PetscTSDIRKType cval = NULL CHKERR( TSDIRKGetType(self.ts, &cval) ) return bytes2str(cval) def setProblemType(self, ptype: ProblemType) -> None: """Set the type of problem to be solved. Parameters ---------- ptype The type of problem of the forms. See Also -------- petsc.TSSetProblemType """ CHKERR( TSSetProblemType(self.ts, ptype) ) def getProblemType(self) -> ProblemType: """Return the type of problem to be solved. See Also -------- petsc.TSGetProblemType """ cdef PetscTSProblemType ptype = TS_NONLINEAR CHKERR( TSGetProblemType(self.ts, &ptype) ) return ptype def setEquationType(self, eqtype: EquationType) -> None: """Set the type of the equation that `TS` is solving. Not collective. Parameters ---------- eqtype The type of equation. See Also -------- petsc.TSSetEquationType """ CHKERR( TSSetEquationType(self.ts, eqtype) ) def getEquationType(self) -> EquationType: """Get the type of the equation that `TS` is solving. Not collective. See Also -------- petsc.TSGetEquationType """ cdef PetscTSEquationType eqtype = TS_EQ_UNSPECIFIED CHKERR( TSGetEquationType(self.ts, &eqtype) ) return eqtype def setOptionsPrefix(self, prefix : str) -> None: """Set the prefix used for all the `TS` options. Logically collective. Parameters ---------- prefix The prefix to prepend to all option names. Notes ----- A hyphen must not be given at the beginning of the prefix name. See Also -------- petsc_options, petsc.TSSetOptionsPrefix """ cdef const char *cval = NULL prefix = str2bytes(prefix, &cval) CHKERR( TSSetOptionsPrefix(self.ts, cval) ) def getOptionsPrefix(self) -> str: """Return the prefix used for all the `TS` options. Not collective. See Also -------- petsc.TSGetOptionsPrefix """ cdef const char *cval = NULL CHKERR( TSGetOptionsPrefix(self.ts, &cval) ) return bytes2str(cval) def appendOptionsPrefix(self, prefix: str) -> None: """Append to the prefix used for all the `TS` options. Logically collective. Parameters ---------- prefix The prefix to append to the current prefix. Notes ----- A hyphen must not be given at the beginning of the prefix name. See Also -------- petsc_options, petsc.TSAppendOptionsPrefix """ cdef const char *cval = NULL prefix = str2bytes(prefix, &cval) CHKERR( TSAppendOptionsPrefix(self.ts, cval) ) def setFromOptions(self) -> None: """Set various `TS` parameters from user options. Collective. See Also -------- petsc_options, petsc.TSSetFromOptions """ CHKERR( TSSetFromOptions(self.ts) ) # --- application context --- def setAppCtx(self, appctx: Any) -> None: """Set the application context. Not collective. Parameters ---------- appctx The application context. """ self.set_attr('__appctx__', appctx) def getAppCtx(self) -> Any: """Return the application context.""" return self.get_attr('__appctx__') # --- user RHS Function/Jacobian routines --- def setRHSFunction( self, function: TSRHSFunction, Vec f=None, args : tuple[Any, ...] | None = None, kargs : dict[str, Any] | None = None) -> None: """Set the routine for evaluating the function ``G`` in ``U_t = G(t,u)``. Parameters ---------- function The right-hand side function. f The vector into which the right-hand side is computed. args Additional positional arguments for ``function``. kargs Additional keyword arguments for ``function``. See Also -------- petsc.TSSetRHSFunction """ cdef PetscVec fvec=NULL if f is not None: fvec = f.vec if function is not None: if args is None: args = () if kargs is None: kargs = {} context = (function, args, kargs) self.set_attr('__rhsfunction__', context) CHKERR( TSSetRHSFunction(self.ts, fvec, TS_RHSFunction, context) ) else: CHKERR( TSSetRHSFunction(self.ts, fvec, NULL, NULL) ) def setRHSJacobian( self, jacobian: TSRHSJacobian, Mat J=None, Mat P=None, args : tuple[Any, ...] | None = None, kargs : dict[str, Any] | None = None) -> None: """Set the function to compute the Jacobian of ``G`` in ``U_t = G(U,t)``. Logically collective. Parameters ---------- jacobian The right-hand side function. J The matrix into which the jacobian is computed. P The matrix into which the preconditioner is computed. args Additional positional arguments for ``jacobian``. kargs Additional keyword arguments for ``jacobian``. See Also -------- petsc.TSSetRHSJacobian """ cdef PetscMat Jmat=NULL if J is not None: Jmat = J.mat cdef PetscMat Pmat=Jmat if P is not None: Pmat = P.mat if jacobian is not None: if args is None: args = () if kargs is None: kargs = {} context = (jacobian, args, kargs) self.set_attr('__rhsjacobian__', context) CHKERR( TSSetRHSJacobian(self.ts, Jmat, Pmat, TS_RHSJacobian, context) ) else: CHKERR( TSSetRHSJacobian(self.ts, Jmat, Pmat, NULL, NULL) ) def computeRHSFunction(self, t: float, Vec x, Vec f) -> None: """Evaluate the right-hand side function. Parameters ---------- t The time at which to evaluate the RHS. x The state vector. f The Vec into which the RHS is computed. See Also -------- petsc.TSComputeRHSFunction """ cdef PetscReal time = asReal(t) CHKERR( TSComputeRHSFunction(self.ts, time, x.vec, f.vec) ) def computeRHSFunctionLinear(self, t: float, Vec x, Vec f) -> None: """Evaluate the right-hand side via the user-provided Jacobian. Parameters ---------- t The time at which to evaluate the RHS. x The state vector. f The Vec into which the RHS is computed. See Also -------- petsc.TSComputeRHSFunctionLinear """ cdef PetscReal time = asReal(t) CHKERR( TSComputeRHSFunctionLinear(self.ts, time, x.vec, f.vec, NULL) ) def computeRHSJacobian(self, t: float, Vec x, Mat J, Mat P=None) -> None: """Compute the Jacobian matrix that has been set with `setRHSJacobian`. Collective. Parameters ---------- t The time at which to evaluate the Jacobian. x The state vector. J The matrix into which the Jacobian is computed. P The optional matrix to use for building a preconditioner matrix. See Also -------- petsc.TSComputeRHSJacobian """ cdef PetscReal time = asReal(t) cdef PetscMat jmat = J.mat, pmat = J.mat if P is not None: pmat = P.mat CHKERR( TSComputeRHSJacobian(self.ts, time, x.vec, jmat, pmat) ) def computeRHSJacobianConstant(self, t: float, Vec x, Mat J, Mat P=None) -> None: """Reuse a Jacobian that is time-independent. Collective. Parameters ---------- t The time at which to evaluate the Jacobian. x The state vector. J A pointer to the stored Jacobian. P An optional pointer to the preconditioner matrix. See Also -------- petsc.TSComputeRHSJacobianConstant """ cdef PetscReal time = asReal(t) cdef PetscMat jmat = J.mat, pmat = J.mat if P is not None: pmat = P.mat CHKERR( TSComputeRHSJacobianConstant(self.ts, time, x.vec, jmat, pmat, NULL) ) def getRHSFunction(self) -> tuple[Vec, TSRHSFunction]: """Return the vector where the rhs is stored and the function used to compute it. Not collective. See Also -------- petsc.TSGetRHSFunction """ cdef Vec f = Vec() CHKERR( TSGetRHSFunction(self.ts, &f.vec, NULL, NULL) ) CHKERR( PetscINCREF(f.obj) ) cdef object function = self.get_attr('__rhsfunction__') return (f, function) def getRHSJacobian(self) -> tuple[Mat, Mat, TSRHSJacobian]: """Return the Jacobian and the function used to compute them. Not collective. See Also -------- petsc.TSGetRHSJacobian """ cdef Mat J = Mat(), P = Mat() CHKERR( TSGetRHSJacobian(self.ts, &J.mat, &P.mat, NULL, NULL) ) CHKERR( PetscINCREF(J.obj) ); CHKERR( PetscINCREF(P.obj) ) cdef object jacobian = self.get_attr('__rhsjacobian__') return (J, P, jacobian) # --- user Implicit Function/Jacobian routines --- def setIFunction( self, function: TSIFunction, Vec f=None, args : tuple[Any, ...] | None = None, kargs : dict[str, Any] | None = None) -> None: """Set the function representing the DAE to be solved. Logically collective. Parameters ---------- function The right-hand side function. f The vector to store values or `None` to be created internally. args Additional positional arguments for ``function``. kargs Additional keyword arguments for ``function``. See Also -------- petsc.TSSetIFunction """ cdef PetscVec fvec=NULL if f is not None: fvec = f.vec if function is not None: if args is None: args = () if kargs is None: kargs = {} context = (function, args, kargs) self.set_attr('__ifunction__', context) CHKERR( TSSetIFunction(self.ts, fvec, TS_IFunction, context) ) else: CHKERR( TSSetIFunction(self.ts, fvec, NULL, NULL) ) def setIJacobian( self, jacobian: TSIJacobian, Mat J=None, Mat P=None, args : tuple[Any, ...] | None = None, kargs : dict[str, Any] | None = None) -> None: """Set the function to compute the Jacobian. Logically collective. Set the function to compute the matrix ``dF/dU + a*dF/dU_t`` where ``F(t,U,U_t)`` is the function provided with `setIFunction`. Parameters ---------- jacobian The function which computes the Jacobian. J The matrix into which the Jacobian is computed. P The optional matrix to use for building a preconditioner matrix. args Additional positional arguments for ``jacobian``. kargs Additional keyword arguments for ``jacobian``. See Also -------- petsc.TSSetIJacobian """ cdef PetscMat Jmat=NULL if J is not None: Jmat = J.mat cdef PetscMat Pmat=Jmat if P is not None: Pmat = P.mat if jacobian is not None: if args is None: args = () if kargs is None: kargs = {} context = (jacobian, args, kargs) self.set_attr('__ijacobian__', context) CHKERR( TSSetIJacobian(self.ts, Jmat, Pmat, TS_IJacobian, context) ) else: CHKERR( TSSetIJacobian(self.ts, Jmat, Pmat, NULL, NULL) ) def setIJacobianP( self, jacobian, Mat J=None, args : tuple[Any, ...] | None = None, kargs : dict[str, Any] | None = None) -> None: """Set the function that computes the Jacobian. Logically collective. Set the function that computes the Jacobian of ``F`` with respect to the parameters ``P`` where ``F(Udot,U,t) = G(U,P,t)``, as well as the location to store the matrix. Parameters ---------- jacobian The function which computes the Jacobian. J The matrix into which the Jacobian is computed. args Additional positional arguments for ``jacobian``. kargs Additional keyword arguments for ``jacobian``. See Also -------- petsc.TSSetIJacobianP """ cdef PetscMat Jmat=NULL if J is not None: Jmat = J.mat if jacobian is not None: if args is None: args = () if kargs is None: kargs = {} context = (jacobian, args, kargs) self.set_attr('__ijacobianp__', context) CHKERR( TSSetIJacobianP(self.ts, Jmat, TS_IJacobianP, context) ) else: CHKERR( TSSetIJacobianP(self.ts, Jmat, NULL, NULL) ) def computeIFunction(self, t: float, Vec x, Vec xdot, Vec f, imex: bool=False) -> None: """Evaluate the DAE residual written in implicit form. Collective. Parameters ---------- t The current time. x The state vector. xdot The time derivative of the state vector. f The vector into which the residual is stored. imex A flag which indicates if the RHS should be kept separate. See Also -------- petsc.TSComputeIFunction """ cdef PetscReal rval = asReal(t) cdef PetscBool bval = imex CHKERR( TSComputeIFunction(self.ts, rval, x.vec, xdot.vec, f.vec, bval) ) def computeIJacobian(self, t: float, Vec x, Vec xdot, a: float, Mat J, Mat P=None, imex: bool=False) -> None: """Evaluate the Jacobian of the DAE. Collective. If ``F(t,U,Udot)=0`` is the DAE, the required Jacobian is ``dF/dU + shift*dF/dUdot`` Parameters ---------- t The current time. x The state vector. xdot The time derivative of the state vector. a The shift to apply J The matrix into which the Jacobian is computed. P The optional matrix to use for building a preconditioner matrix. imex A flag which indicates if the RHS should be kept separate. See Also -------- petsc.TSComputeIJacobian """ cdef PetscReal rval1 = asReal(t) cdef PetscReal rval2 = asReal(a) cdef PetscBool bval = imex cdef PetscMat jmat = J.mat, pmat = J.mat if P is not None: pmat = P.mat CHKERR( TSComputeIJacobian(self.ts, rval1, x.vec, xdot.vec, rval2, jmat, pmat, bval) ) def computeIJacobianP(self, t: float, Vec x, Vec xdot, a: float, Mat J, imex: bool=False) -> None: """Evaluate the Jacobian with respect to parameters. Collective. Parameters ---------- t The current time. x The state vector. xdot The time derivative of the state vector. a The shift to apply J The matrix into which the Jacobian is computed. imex A flag which indicates if the RHS should be kept separate. See Also -------- petsc.TSComputeIJacobianP """ cdef PetscReal rval1 = asReal(t) cdef PetscReal rval2 = asReal(a) cdef PetscBool bval = asBool(imex) cdef PetscMat jmat = J.mat CHKERR( TSComputeIJacobianP(self.ts, rval1, x.vec, xdot.vec, rval2, jmat, bval) ) def getIFunction(self) -> tuple[Vec, TSIFunction]: """Return the vector and function which computes the implicit residual. Not collective. See Also -------- petsc.TSGetIFunction """ cdef Vec f = Vec() CHKERR( TSGetIFunction(self.ts, &f.vec, NULL, NULL) ) CHKERR( PetscINCREF(f.obj) ) cdef object function = self.get_attr('__ifunction__') return (f, function) def getIJacobian(self) -> tuple[Mat, Mat, TSIJacobian]: """Return the matrices and function which computes the implicit Jacobian. Not collective. See Also -------- petsc.TSGetIJacobian """ cdef Mat J = Mat(), P = Mat() CHKERR( TSGetIJacobian(self.ts, &J.mat, &P.mat, NULL, NULL) ) CHKERR( PetscINCREF(J.obj) ); CHKERR( PetscINCREF(P.obj) ) cdef object jacobian = self.get_attr('__ijacobian__') return (J, P, jacobian) def setI2Function( self, function: TSI2Function, Vec f=None, args : tuple[Any, ...] | None = None, kargs : dict[str, Any] | None = None) -> None: """Set the function to compute the 2nd order DAE. Logically collective. Parameters ---------- function The right-hand side function. f The vector to store values or `None` to be created internally. args Additional positional arguments for ``function``. kargs Additional keyword arguments for ``function``. See Also -------- petsc.TSSetI2Function """ cdef PetscVec fvec=NULL if f is not None: fvec = f.vec if function is not None: if args is None: args = () if kargs is None: kargs = {} context = (function, args, kargs) self.set_attr('__i2function__', context) CHKERR( TSSetI2Function(self.ts, fvec, TS_I2Function, context) ) else: CHKERR( TSSetI2Function(self.ts, fvec, NULL, NULL) ) def setI2Jacobian( self, jacobian: TSI2Jacobian, Mat J=None, Mat P=None, args=None, kargs=None) -> None: """Set the function to compute the Jacobian of the 2nd order DAE. Logically collective. Parameters ---------- jacobian The function which computes the Jacobian. J The matrix into which the Jacobian is computed. P The optional matrix to use for building a preconditioner matrix. args Additional positional arguments for ``jacobian``. kargs Additional keyword arguments for ``jacobian``. See Also -------- petsc.TSSetI2Jacobian """ cdef PetscMat Jmat=NULL if J is not None: Jmat = J.mat cdef PetscMat Pmat=Jmat if P is not None: Pmat = P.mat if jacobian is not None: if args is None: args = () if kargs is None: kargs = {} context = (jacobian, args, kargs) self.set_attr('__i2jacobian__', context) CHKERR( TSSetI2Jacobian(self.ts, Jmat, Pmat, TS_I2Jacobian, context) ) else: CHKERR( TSSetI2Jacobian(self.ts, Jmat, Pmat, NULL, NULL) ) def computeI2Function(self, t: float, Vec x, Vec xdot, Vec xdotdot, Vec f) -> None: """Evaluate the DAE residual in implicit form. Collective. Parameters ---------- t The current time. x The state vector. xdot The time derivative of the state vector. xdotdot The second time derivative of the state vector. f The vector into which the residual is stored. See Also -------- petsc.TSComputeI2Function """ cdef PetscReal rval = asReal(t) CHKERR( TSComputeI2Function(self.ts, rval, x.vec, xdot.vec, xdotdot.vec, f.vec) ) def computeI2Jacobian( self, t: float, Vec x, Vec xdot, Vec xdotdot, v: float, a: float, Mat J, Mat P=None) -> None: """Evaluate the Jacobian of the DAE. Collective. If ``F(t,U,V,A)=0`` is the DAE, the required Jacobian is ``dF/dU + v dF/dV + a dF/dA``. Parameters ---------- t The current time. x The state vector. xdot The time derivative of the state vector. xdotdot The second time derivative of the state vector. v The shift to apply to the first derivative. a The shift to apply to the second derivative. J The matrix into which the Jacobian is computed. P The optional matrix to use for building a preconditioner matrix. See Also -------- petsc.TSComputeI2Jacobian """ cdef PetscReal rval1 = asReal(t) cdef PetscReal rval2 = asReal(v) cdef PetscReal rval3 = asReal(a) cdef PetscMat jmat = J.mat, pmat = J.mat if P is not None: pmat = P.mat CHKERR( TSComputeI2Jacobian(self.ts, rval1, x.vec, xdot.vec, xdotdot.vec, rval2, rval3, jmat, pmat) ) def getI2Function(self) -> tuple[Vec, TSI2Function]: """Return the vector and function which computes the residual. Not collective. See Also -------- petsc.TSGetI2Function """ cdef Vec f = Vec() CHKERR( TSGetI2Function(self.ts, &f.vec, NULL, NULL) ) CHKERR( PetscINCREF(f.obj) ) cdef object function = self.get_attr('__i2function__') return (f, function) def getI2Jacobian(self) -> tuple[Mat, Mat, TSI2Jacobian]: """Return the matrices and function which computes the Jacobian. Not collective. See Also -------- petsc.TSGetI2Jacobian """ cdef Mat J = Mat(), P = Mat() CHKERR( TSGetI2Jacobian(self.ts, &J.mat, &P.mat, NULL, NULL) ) CHKERR( PetscINCREF(J.obj) ); CHKERR( PetscINCREF(P.obj) ) cdef object jacobian = self.get_attr('__i2jacobian__') return (J, P, jacobian) # --- solution vector --- def setSolution(self, Vec u) -> None: """Set the initial solution vector. Logically collective. Parameters ---------- u The solution vector. See Also -------- petsc.TSSetSolution """ CHKERR( TSSetSolution(self.ts, u.vec) ) def getSolution(self) -> Vec: """Return the solution at the present timestep. Not collective. It is valid to call this routine inside the function that you are evaluating in order to move to the new timestep. This vector is not changed until the solution at the next timestep has been calculated. See Also -------- petsc.TSGetSolution """ cdef Vec u = Vec() CHKERR( TSGetSolution(self.ts, &u.vec) ) CHKERR( PetscINCREF(u.obj) ) return u def setSolution2(self, Vec u, Vec v) -> None: """Set the initial solution and its time derivative. Logically collective. Parameters ---------- u The solution vector. v The time derivative vector. See Also -------- petsc.TS2SetSolution """ CHKERR( TS2SetSolution(self.ts, u.vec, v.vec) ) def getSolution2(self) -> tuple[Vec, Vec]: """Return the solution and time derivative at the present timestep. Not collective. It is valid to call this routine inside the function that you are evaluating in order to move to the new timestep. These vectors are not changed until the solution at the next timestep has been calculated. See Also -------- petsc.TS2GetSolution """ cdef Vec u = Vec() cdef Vec v = Vec() CHKERR( TS2GetSolution(self.ts, &u.vec, &v.vec) ) CHKERR( PetscINCREF(u.obj) ) CHKERR( PetscINCREF(v.obj) ) return (u, v) # --- time span --- def setTimeSpan(self, tspan: Sequence[float]) -> None: """Set the time span. Collective. The solution will be computed and stored for each time requested in the span. The times must be all increasing and correspond to the intermediate points for time integration. `ExactFinalTime.MATCHSTEP` must be used to make the last time step in each sub-interval match the intermediate points specified. The intermediate solutions are saved in a vector array that can be accessed with `getTimeSpanSolutions`. Parameters ---------- tspan The sequence of time points. Notes ----- ``-ts_time_span `` sets the time span from the commandline See Also -------- petsc.TSSetTimeSpan """ cdef PetscInt nt = 0 cdef PetscReal *rtspan = NULL cdef object tmp = oarray_r(tspan, &nt, &rtspan) CHKERR( TSSetTimeSpan(self.ts, nt, rtspan) ) def getTimeSpan(self) -> ArrayReal: """Return the time span. Not collective. See Also -------- petsc.TSGetTimeSpan """ cdef const PetscReal *rtspan = NULL cdef PetscInt nt = 0 CHKERR( TSGetTimeSpan(self.ts, &nt, &rtspan) ) cdef object tspan = array_r(nt, rtspan) return tspan def getTimeSpanSolutions(self) -> list[Vec]: """Return the solutions at the times in the time span. See Also -------- setTimeSpan, petsc.TSGetTimeSpanSolutions """ cdef PetscInt nt = 0 cdef PetscVec *sols = NULL CHKERR( TSGetTimeSpanSolutions(self.ts, &nt, &sols) ) cdef object sollist = None if sols != NULL: sollist = [ref_Vec(sols[i]) for i from 0 <= i < nt] return sollist # --- inner solver --- def getSNES(self) -> SNES: """Return the `SNES` associated with the `TS`. Not collective. See Also -------- petsc.TSGetSNES """ cdef SNES snes = SNES() CHKERR( TSGetSNES(self.ts, &snes.snes) ) CHKERR( PetscINCREF(snes.obj) ) return snes def getKSP(self) -> KSP: """Return the `KSP` associated with the `TS`. Not collective. See Also -------- petsc.TSGetKSP """ cdef KSP ksp = KSP() CHKERR( TSGetKSP(self.ts, &ksp.ksp) ) CHKERR( PetscINCREF(ksp.obj) ) return ksp # --- discretization space --- def getDM(self) -> DM: """Return the `DM` associated with the `TS`. Not collective. Only valid if nonlinear solvers or preconditioners are used which use the `DM`. See Also -------- petsc.TSGetDM """ cdef PetscDM newdm = NULL CHKERR( TSGetDM(self.ts, &newdm) ) cdef DM dm = subtype_DM(newdm)() dm.dm = newdm CHKERR( PetscINCREF(dm.obj) ) return dm def setDM(self, DM dm) -> None: """Set the DM that may be used by some nonlinear solvers or preconditioners. Logically collective. Parameters ---------- dm The `DM` object. See Also -------- petsc.TSSetDM """ CHKERR( TSSetDM(self.ts, dm.dm) ) # --- customization --- def setTime(self, t: float) -> None: """Set the time. Logically collective. Parameters ---------- t The time. See Also -------- petsc.TSSetTime """ cdef PetscReal rval = asReal(t) CHKERR( TSSetTime(self.ts, rval) ) def getTime(self) -> float: """Return the time of the most recently completed step. Not collective. When called during time step evaluation (e.g. during residual evaluation or via hooks set using `setPreStep` or `setPostStep`), the time returned is at the start of the step. See Also -------- petsc.TSGetTime """ cdef PetscReal rval = 0 CHKERR( TSGetTime(self.ts, &rval) ) return toReal(rval) def getPrevTime(self) -> float: """Return the starting time of the previously completed step. Not collective. See Also -------- petsc.TSGetPrevTime """ cdef PetscReal rval = 0 CHKERR( TSGetPrevTime(self.ts, &rval) ) return toReal(rval) def getSolveTime(self) -> float: """Return the time after a call to `solve`. Not collective. This time corresponds to the final time set with `setMaxTime`. See Also -------- petsc.TSGetSolveTime """ cdef PetscReal rval = 0 CHKERR( TSGetSolveTime(self.ts, &rval) ) return toReal(rval) def setTimeStep(self, time_step: float) -> None: """Set the duration of the timestep. Logically collective. Parameters ---------- time_step the duration of the timestep See Also -------- petsc.TSSetTimeStep """ cdef PetscReal rval = asReal(time_step) CHKERR( TSSetTimeStep(self.ts, rval) ) def getTimeStep(self) -> float: """Return the duration of the current timestep. Not collective. See Also -------- petsc.TSGetTimeStep """ cdef PetscReal tstep = 0 CHKERR( TSGetTimeStep(self.ts, &tstep) ) return toReal(tstep) def setStepNumber(self, step_number: int) -> None: """Set the number of steps completed. Logically collective. For most uses of the `TS` solvers the user need not explicitly call `setStepNumber`, as the step counter is appropriately updated in `solve`/`step`/`rollBack`. Power users may call this routine to reinitialize timestepping by setting the step counter to zero (and time to the initial time) to solve a similar problem with different initial conditions or parameters. It may also be used to continue timestepping from a previously interrupted run in such a way that `TS` monitors will be called with a initial nonzero step counter. Parameters ---------- step_number the number of steps completed See Also -------- petsc.TSSetStepNumber """ cdef PetscInt ival = asInt(step_number) CHKERR( TSSetStepNumber(self.ts, ival) ) def getStepNumber(self) -> int: """Return the number of time steps completed. Not collective. See Also -------- petsc.TSGetStepNumber """ cdef PetscInt ival = 0 CHKERR( TSGetStepNumber(self.ts, &ival) ) return toInt(ival) def setMaxTime(self, max_time: float) -> None: """Set the maximum (final) time. Logically collective. Parameters ---------- max_time the final time Notes ----- ``-ts_max_time`` sets the max time from the commandline See Also -------- petsc.TSSetMaxTime """ cdef PetscReal rval = asReal(max_time) CHKERR( TSSetMaxTime(self.ts, rval) ) def getMaxTime(self) -> float: """Return the maximum (final) time. Not collective. Defaults to ``5``. See Also -------- petsc.TSGetMaxTime """ cdef PetscReal rval = 0 CHKERR( TSGetMaxTime(self.ts, &rval) ) return toReal(rval) def setMaxSteps(self, max_steps: int) -> None: """Set the maximum number of steps to use. Logically collective. Defaults to ``5000``. Parameters ---------- max_steps The maximum number of steps to use. See Also -------- petsc.TSSetMaxSteps """ cdef PetscInt ival = asInt(max_steps) CHKERR( TSSetMaxSteps(self.ts, ival) ) def getMaxSteps(self) -> int: """Return the maximum number of steps to use. Not collective. See Also -------- petsc.TSGetMaxSteps """ cdef PetscInt ival = 0 CHKERR( TSGetMaxSteps(self.ts, &ival) ) return toInt(ival) def getSNESIterations(self) -> int: """Return the total number of nonlinear iterations used by the `TS`. Not collective. This counter is reset to zero for each successive call to `solve`. See Also -------- petsc.TSGetSNESIterations """ cdef PetscInt n = 0 CHKERR( TSGetSNESIterations(self.ts, &n) ) return toInt(n) def getKSPIterations(self) -> int: """Return the total number of linear iterations used by the `TS`. Not collective. This counter is reset to zero for each successive call to `solve`. See Also -------- petsc.TSGetKSPIterations """ cdef PetscInt n = 0 CHKERR( TSGetKSPIterations(self.ts, &n) ) return toInt(n) def setMaxStepRejections(self, n: int) -> None: """Set the maximum number of step rejections before a time step fails. Not collective. Parameters ---------- n The maximum number of rejected steps, use ``-1`` for unlimited. Notes ----- ``-ts_max_reject`` can be used to set this from the commandline See Also -------- petsc.TSSetMaxStepRejections """ cdef PetscInt rej = asInt(n) CHKERR( TSSetMaxStepRejections(self.ts, rej)) #def getMaxStepRejections(self): # cdef PetscInt n = 0 # CHKERR( TSGetMaxStepRejections(self.ts, &n)) # return toInt(n) def getStepRejections(self) -> int: """Return the total number of rejected steps. Not collective. This counter is reset to zero for each successive call to `solve`. See Also -------- petsc.TSGetStepRejections """ cdef PetscInt n = 0 CHKERR( TSGetStepRejections(self.ts, &n) ) return toInt(n) def setMaxSNESFailures(self, n: int) -> None: """Set the maximum number of SNES solves failures allowed. Not collective. Parameters ---------- n The maximum number of failed nonlinear solver, use ``-1`` for unlimited. See Also -------- petsc.TSSetMaxSNESFailures """ cdef PetscInt fails = asInt(n) CHKERR( TSSetMaxSNESFailures(self.ts, fails)) #def getMaxSNESFailures(self, n): # cdef PetscInt n = 0 # CHKERR( TSGetMaxSNESFailures(self.ts, &n)) # return toInt(n) def getSNESFailures(self) -> int: """Return the total number of failed `SNES` solves in the `TS`. Not collective. This counter is reset to zero for each successive call to `solve`. See Also -------- petsc.TSGetSNESFailures """ cdef PetscInt n = 0 CHKERR( TSGetSNESFailures(self.ts, &n) ) return toInt(n) def setErrorIfStepFails(self, flag: bool=True) -> None: """Immediately error is no step succeeds. Not collective. Parameters ---------- flag Enable to error if no step succeeds. Notes ----- ``-ts_error_if_step_fails`` to enable from the commandline. See Also -------- petsc.TSSetErrorIfStepFails """ cdef PetscBool bval = flag CHKERR( TSSetErrorIfStepFails(self.ts, bval)) def setTolerances(self, rtol: float=None, atol: float=None) -> None: """Set tolerances for local truncation error when using an adaptive controller. Logically collective. Parameters ---------- rtol The relative tolerance or `None` to leave the current value. atol The absolute tolerance or `None` to leave the current value. Notes ----- ``-ts_rtol`` and ``-ts_atol`` may be used to set values from the commandline. See Also -------- petsc.TSSetTolerances """ cdef PetscReal rrtol = PETSC_DEFAULT cdef PetscReal ratol = PETSC_DEFAULT cdef PetscVec vrtol = NULL cdef PetscVec vatol = NULL if rtol is None: pass elif isinstance(rtol, Vec): vrtol = (rtol).vec else: rrtol = asReal(rtol) if atol is None: pass elif isinstance(atol, Vec): vatol = (atol).vec else: ratol = asReal(atol) CHKERR( TSSetTolerances(self.ts, ratol, vatol, rrtol, vrtol) ) def getTolerances(self) ->tuple[float,float]: """Return the tolerances for local truncation error. Logically collective. Returns ------- rtol : float the relative tolerance atol : float the absolute tolerance See Also -------- petsc.TSGetTolerances """ cdef PetscReal rrtol = PETSC_DEFAULT cdef PetscReal ratol = PETSC_DEFAULT cdef PetscVec vrtol = NULL cdef PetscVec vatol = NULL CHKERR( TSGetTolerances(self.ts, &ratol, &vatol, &rrtol, &vrtol) ) cdef object rtol = None if vrtol != NULL: rtol = ref_Vec(vrtol) else: rtol = toReal(rrtol) cdef object atol = None if vatol != NULL: atol = ref_Vec(vatol) else: atol = toReal(ratol) return (rtol, atol) def setExactFinalTime(self, option: ExactFinalTime) -> None: """Set method of computing the final time step. Logically collective. Parameters ---------- option The exact final time option Notes ----- ``-ts_exact_final_time`` may be used to specify from the commandline. See Also -------- petsc.TSSetExactFinalTime """ cdef PetscTSExactFinalTimeOption oval = option CHKERR( TSSetExactFinalTime(self.ts, oval) ) def setConvergedReason(self, reason: ConvergedReason) -> None: """Set the reason for handling the convergence of `solve`. Logically collective. Can only be called when `solve` is active and ``reason`` must contain common value. Parameters ---------- reason The reason for convergence. See Also -------- petsc.TSSetConvergedReason """ cdef PetscTSConvergedReason cval = reason CHKERR( TSSetConvergedReason(self.ts, cval) ) def getConvergedReason(self) -> ConvergedReason: """Return the reason the `TS` step was stopped. Not collective. Can only be called once `solve` is complete. See Also -------- petsc.TSGetConvergedReason """ cdef PetscTSConvergedReason reason = TS_CONVERGED_ITERATING CHKERR( TSGetConvergedReason(self.ts, &reason) ) return reason # --- monitoring --- def setMonitor( self, monitor: TSMonitorFunction, args : tuple[Any, ...] | None = None, kargs : dict[str, Any] | None = None) -> None: """Set an additional monitor to the `TS`. Logically collective. Parameters ---------- monitor The custom monitor function. args Additional positional arguments for ``monitor``. kargs Additional keyword arguments for ``monitor``. See Also -------- petsc.TSMonitorSet """ if monitor is None: return cdef object monitorlist = self.get_attr('__monitor__') if monitorlist is None: monitorlist = [] self.set_attr('__monitor__', monitorlist) CHKERR( TSMonitorSet(self.ts, TS_Monitor, NULL, NULL) ) if args is None: args = () if kargs is None: kargs = {} context = (monitor, args, kargs) monitorlist.append(context) def getMonitor(self) -> list[tuple[TSMonitorFunction,tuple[Any, ...],dict[str, Any]]]: """Return the monitor. See Also -------- setMonitor """ return self.get_attr('__monitor__') def monitorCancel(self) -> None: """Clear all the monitors that have been set. Logically collective. See Also -------- petsc.TSMonitorCancel """ self.set_attr('__monitor__', None) CHKERR( TSMonitorCancel(self.ts) ) cancelMonitor = monitorCancel def monitor(self, step: int, time: float, Vec u=None) -> None: """Monitor the solve. Parameters ---------- step The step number that has just completed. time The model time of the state. u The state at the current model time. See Also -------- petsc.TSMonitor """ cdef PetscInt ival = asInt(step) cdef PetscReal rval = asReal(time) cdef PetscVec uvec = NULL if u is not None: uvec = u.vec if uvec == NULL: CHKERR( TSGetSolution(self.ts, &uvec) ) CHKERR( TSMonitor(self.ts, ival, rval, uvec) ) # --- event handling --- def setEventHandler( self, direction: Sequence[int], terminate: Sequence[bool], eventhandler: TSEventHandlerFunction, postevent: TSPostEventFunction=None, args: tuple[Any, ...] | None = None, kargs: dict[str, Any] | None = None) -> None: """Set a function used for detecting events. Logically collective. Parameters ---------- direction Direction of zero crossing to be detected {-1,0,+1}. terminate Flags for each event to indicate stepping should be terminated. eventhandler Function for detecting the event postevent Function to execute after the event args Additional positional arguments for ``eventhandler``. kargs Additional keyword arguments for ``eventhandler``. See Also -------- petsc.TSSetEventHandler """ cdef PetscInt ndirs = 0 cdef PetscInt *idirs = NULL direction = iarray_i(direction, &ndirs, &idirs) cdef PetscInt nterm = 0 cdef PetscBool *iterm = NULL terminate = iarray_b(terminate, &nterm, &iterm) assert nterm == ndirs cdef PetscInt nevents = ndirs if eventhandler is not None: if args is None: args = () if kargs is None: kargs = {} self.set_attr('__eventhandler__', (eventhandler, args, kargs)) if postevent is not None: self.set_attr('__postevent__', (postevent, args, kargs)) CHKERR( TSSetEventHandler(self.ts, nevents, idirs, iterm, TS_EventHandler, TS_PostEvent, NULL) ) else: self.set_attr('__postevent__', None) CHKERR( TSSetEventHandler(self.ts, nevents, idirs, iterm, TS_EventHandler, NULL, NULL) ) else: CHKERR( TSSetEventHandler(self.ts, nevents, idirs, iterm, NULL, NULL, NULL) ) def setEventTolerances(self, tol: float=None, vtol: Sequence[float]=None) -> None: """Set tolerances for event zero crossings when using event handler. Logically collective. ``setEventHandler`` must have already been called. Parameters ---------- tol The scalar tolerance or `None` to leave at the current value vtol A sequence of scalar tolerance for each event. Used in preference to ``tol`` if present. Set to `None` to leave at the current value. Notes ----- ``-ts_event_tol`` can be used to set values from the commandline. See Also -------- petsc.TSSetEventTolerances """ cdef PetscInt nevents = 0 cdef PetscReal tolr = PETSC_DEFAULT cdef PetscInt ntolr = 0 cdef PetscReal *vtolr = NULL if tol is not None: tolr = asReal(tol) if vtol is not None: CHKERR( TSGetNumEvents(self.ts, &nevents) ) vtol = iarray_r(vtol, &ntolr, &vtolr) assert ntolr == nevents CHKERR( TSSetEventTolerances(self.ts, tolr, vtolr) ) def getNumEvents(self) -> int: """Return the number of events. Logically collective. See Also -------- petsc.TSGetNumEvents """ cdef PetscInt nevents = 0 CHKERR( TSGetNumEvents(self.ts, &nevents) ) return toInt(nevents) # --- solving --- def setPreStep( self, prestep: TSPreStepFunction, args: tuple[Any, ...] | None = None, kargs: dict[str, Any] | None = None) -> None: """Set a function to be called at the beginning of each time step. Logically collective. Parameters ---------- prestep The function to be called at the beginning of each step. args Additional positional arguments for ``prestep``. kargs Additional keyword arguments for ``prestep``. See Also -------- petsc.TSSetPreStep """ if prestep is not None: if args is None: args = () if kargs is None: kargs = {} context = (prestep, args, kargs) self.set_attr('__prestep__', context) CHKERR( TSSetPreStep(self.ts, TS_PreStep) ) else: self.set_attr('__prestep__', None) CHKERR( TSSetPreStep(self.ts, NULL) ) def getPreStep(self) -> tuple[TSPreStepFunction,tuple[Any, ...] | None,dict[str, Any] | None]: """Return the prestep function. See Also -------- setPreStep """ return self.get_attr('__prestep__') def setPostStep(self, poststep: TSPostStepFunction, args: tuple[Any, ...] | None = None, kargs: dict[str, Any] | None = None) -> None: """Set a function to be called at the end of each time step. Logically collective. Parameters ---------- poststep The function to be called at the end of each step. args Additional positional arguments for ``poststep``. kargs Additional keyword arguments for ``poststep``. See Also -------- petsc.TSSetPostStep """ if poststep is not None: if args is None: args = () if kargs is None: kargs = {} context = (poststep, args, kargs) self.set_attr('__poststep__', context) CHKERR( TSSetPostStep(self.ts, TS_PostStep) ) else: self.set_attr('__poststep__', None) CHKERR( TSSetPostStep(self.ts, NULL) ) def getPostStep(self) -> tuple[TSPostStepFunction,tuple[Any, ...] | None,dict[str, Any] | None]: """Return the poststep function.""" return self.get_attr('__poststep__') def setUp(self) -> None: """Set up the internal data structures for the `TS`. Collective. See Also -------- petsc.TSSetUp """ CHKERR( TSSetUp(self.ts) ) def reset(self) -> None: """Reset the `TS`, removing any allocated vectors and matrices. Collective. See Also -------- petsc.TSReset """ CHKERR( TSReset(self.ts) ) def step(self) -> None: """Take one step. Collective. The preferred interface for the `TS` solvers is `solve`. If you need to execute code at the beginning or ending of each step, use `setPreStep` and `setPostStep` respectively. See Also -------- petsc.TSStep """ CHKERR( TSStep(self.ts) ) def restartStep(self) -> None: """Flag the solver to restart the next step. Collective. Multistep methods like TSBDF or Runge-Kutta methods with FSAL property require restarting the solver in the event of discontinuities. These discontinuities may be introduced as a consequence of explicitly modifications to the solution vector (which PETSc attempts to detect and handle) or problem coefficients (which PETSc is not able to detect). For the sake of correctness and maximum safety, users are expected to call TSRestart() whenever they introduce discontinuities in callback routines (e.g. prestep and poststep routines, or implicit/rhs function routines with discontinuous source terms). See Also -------- petsc.TSRestartStep """ CHKERR( TSRestartStep(self.ts) ) def rollBack(self) -> None: """Roll back one time step. See Also -------- petsc.TSRollBack """ CHKERR( TSRollBack(self.ts) ) def solve(self, Vec u) -> None: """Step the requested number of timesteps. Collective. Parameters ---------- u The solution vector. Can be `None` if `setSolution` was used and `setExactFinalTime` is not set as ``TS_EXACTFINALTIME_MATCHSTEP``. Otherwise this vector must contain the initial conditions and will contain the solution at the final requested time. See Also -------- petsc.TSSolve """ CHKERR( TSSolve(self.ts, u.vec) ) def interpolate(self, t: float, Vec u) -> None: """Interpolate the solution to a given time. Collective. Parameters ---------- t The time to interpolate. u The state vector to interpolate. See Also -------- petsc.TSInterpolate """ cdef PetscReal rval = asReal(t) CHKERR( TSInterpolate(self.ts, rval, u.vec) ) def setStepLimits(self, hmin: float, hmax: float) -> None: """Set the minimum and maximum allowed step sizes. Logically collective. Parameters ---------- hmin the minimum step size hmax the maximum step size See Also -------- petsc.TSAdaptSetStepLimits """ cdef PetscTSAdapt tsadapt = NULL cdef PetscReal hminr = toReal(hmin) cdef PetscReal hmaxr = toReal(hmax) TSGetAdapt(self.ts, &tsadapt) CHKERR( TSAdaptSetStepLimits(tsadapt, hminr, hmaxr) ) def getStepLimits(self) -> tuple[float,float]: """Return the minimum and maximum allowed time step sizes. See Also -------- petsc.TSAdaptGetStepLimits """ cdef PetscTSAdapt tsadapt = NULL cdef PetscReal hminr = 0. cdef PetscReal hmaxr = 0. TSGetAdapt(self.ts, &tsadapt) CHKERR( TSAdaptGetStepLimits(tsadapt, &hminr, &hmaxr) ) return (asReal(hminr), asReal(hmaxr)) # --- Adjoint methods --- def setSaveTrajectory(self) -> None: """Enable to save solutions as an internal `TS` trajectory. Collective. This routine should be called after all `TS` options have been set. Notes ----- ``-ts_save_trajectory`` can be used to save a trajectory to a file. See Also -------- petsc.TSSetSaveTrajectory """ CHKERR(TSSetSaveTrajectory(self.ts)) def removeTrajectory(self) -> None: """Remove the internal `TS` trajectory object. Collective. See Also -------- petsc.TSRemoveTrajectory """ CHKERR(TSRemoveTrajectory(self.ts)) def getCostIntegral(self) -> Vec: """Return a vector of values of the integral term in the cost functions. See Also -------- petsc.TSGetCostIntegral """ cdef Vec cost = Vec() CHKERR( TSGetCostIntegral(self.ts, &cost.vec) ) CHKERR( PetscINCREF(cost.obj) ) return cost def setCostGradients( self, vl: Vec | Sequence[Vec] | None, vm: Vec | Sequence[Vec] | None = None) -> None: """Set the cost gradients. Logically collective. Parameters ---------- vl gradients with respect to the initial condition variables, the dimension and parallel layout of these vectors is the same as the ODE solution vector vm gradients with respect to the parameters, the number of entries in these vectors is the same as the number of parameters See Also -------- petsc.TSSetCostGradients """ cdef PetscInt n = 0; cdef PetscVec *vecl = NULL cdef PetscVec *vecm = NULL cdef mem1 = None, mem2 = None if isinstance(vl, Vec): vl = [vl] if isinstance(vm, Vec): vm = [vm] if vl is not None: n = len(vl) elif vm is not None: n = len(vm) if vl is not None: assert len(vl) == n mem1 = oarray_p(empty_p(n), NULL, &vecl) for i from 0 <= i < n: vecl[i] = (vl[i]).vec if vm is not None: assert len(vm) == n mem2 = oarray_p(empty_p(n), NULL, &vecm) for i from 0 <= i < n: vecm[i] = (vm[i]).vec self.set_attr('__costgradients_memory', (mem1, mem2)) CHKERR( TSSetCostGradients(self.ts, n, vecl, vecm) ) def getCostGradients(self) -> tuple[list[Vec],list[Vec]]: """Return the cost gradients. See Also -------- setCostGradients, petsc.TSGetCostGradients """ cdef PetscInt i = 0, n = 0 cdef PetscVec *vecl = NULL cdef PetscVec *vecm = NULL CHKERR( TSGetCostGradients(self.ts, &n, &vecl, &vecm) ) cdef object vl = None, vm = None if vecl != NULL: vl = [ref_Vec(vecl[i]) for i from 0 <= i < n] if vecm != NULL: vm = [ref_Vec(vecm[i]) for i from 0 <= i < n] return (vl, vm) def setRHSJacobianP( self, jacobianp: TSRHSJacobianP, Mat A=None, args: tuple[Any, ...] | None = None, kargs: dict[str, Any] | None = None) -> None: """Set the function that computes the Jacobian with respect to the parameters. Logically collective. Parameters ---------- jacobianp The user-defined function. A The matrix into which the Jacobian will be computed. args Additional positional arguments for ``jacobianp``. kargs Additional keyword arguments for ``jacobianp``. See Also -------- petsc.TSSetRHSJacobianP """ cdef PetscMat Amat=NULL if A is not None: Amat = A.mat if jacobianp is not None: if args is None: args = () if kargs is None: kargs = {} context = (jacobianp, args, kargs) self.set_attr('__rhsjacobianp__', context) CHKERR( TSSetRHSJacobianP(self.ts, Amat, TS_RHSJacobianP, context) ) else: CHKERR( TSSetRHSJacobianP(self.ts, Amat, NULL, NULL) ) def createQuadratureTS(self, forward: bool=True) -> TS: """Create a sub `TS` that evaluates integrals over time. Parameters ---------- forward Enable to evaluate forward in time. See Also -------- petsc.TSCreateQuadratureTS """ cdef TS qts = TS() cdef PetscBool fwd = forward CHKERR( TSCreateQuadratureTS(self.ts, fwd, &qts.ts) ) CHKERR( PetscINCREF(qts.obj) ) return qts def getQuadratureTS(self) -> tuple[bool, TS]: """Return the sub `TS` that evaluates integrals over time. Returns ------- forward : bool True if evaluating the integral forward in time qts : TS The sub `TS` See Also -------- petsc.TSGetQuadratureTS """ cdef TS qts = TS() cdef PetscBool fwd = PETSC_FALSE CHKERR( TSGetQuadratureTS(self.ts, &fwd, &qts.ts) ) CHKERR( PetscINCREF(qts.obj) ) return (toBool(fwd), qts) def setRHSJacobianP( self, rhsjacobianp: TSRHSJacobianP, Mat A=None, args: tuple[Any, ...] | None = None, kargs: dict[str, Any] | None = None) -> None: """Set the function that computes the Jacobian with respect to the parameters. Parameters ---------- rhsjacobianp The function to compute the Jacobian A The JacobianP matrix args Additional positional arguments for ``rhsjacobianp``. kargs Additional keyword arguments for ``rhsjacobianp``. See Also -------- petsc.TSSetRHSJacobianP """ cdef PetscMat Amat=NULL if A is not None: Amat = A.mat if rhsjacobianp is not None: if args is None: args = () if kargs is None: kargs = {} context = (rhsjacobianp, args, kargs) self.set_attr('__rhsjacobianp__', context) CHKERR( TSSetRHSJacobianP(self.ts, Amat, TS_RHSJacobianP, context) ) else: CHKERR( TSSetRHSJacobianP(self.ts, Amat, NULL, NULL) ) def computeRHSJacobianP(self, t: float, Vec x, Mat J) -> None: """Run the user-defined JacobianP function. Parameters ---------- t The time at which to compute the Jacobian. x The solution at which to compute the Jacobian. J The output Jacobian matrx. See Also -------- petsc.TSComputeRHSJacobianP """ cdef PetscReal rval = asReal(t) CHKERR( TSComputeRHSJacobianP(self.ts, rval, x.vec, J.mat) ) def adjointSetSteps(self, adjoint_steps: int) -> None: """Set the number of steps the adjoint solver should take backward in time. Parameters ---------- adjoint_steps The number of steps to take. See Also -------- petsc.TSAdjointSetSteps """ cdef PetscInt ival = asInt(adjoint_steps) CHKERR( TSAdjointSetSteps(self.ts, ival) ) def adjointSetUp(self) -> None: """Set up the internal data structures for the later use of an adjoint solver. Collective. See Also -------- petsc.TSAdjointSetUp """ CHKERR(TSAdjointSetUp(self.ts)) def adjointSolve(self) -> None: """Solve the discrete adjoint problem for an ODE/DAE. Collective. See Also -------- petsc.TSAdjointSolve """ CHKERR( TSAdjointSolve(self.ts) ) def adjointStep(self) -> None: """Step one time step backward in the adjoint run. Collective. See Also -------- petsc.TSAdjointStep """ CHKERR(TSAdjointStep(self.ts)) def adjointReset(self) -> None: """Reset a `TS`, removing any allocated vectors and matrices. Collective. See Also -------- petsc.TSAdjointReset """ CHKERR(TSAdjointReset(self.ts)) # --- Python --- def createPython(self, context: Any = None, comm: Comm | None = None) -> Self: """Create an integrator of Python type. Collective. Parameters ---------- context An instance of the Python class implementing the required methods. comm MPI communicator, defaults to `Sys.getDefaultComm`. See Also -------- petsc_python_ts, setType, setPythonContext, Type.PYTHON """ cdef MPI_Comm ccomm = def_Comm(comm, PETSC_COMM_DEFAULT) cdef PetscTS newts = NULL CHKERR( TSCreate(ccomm, &newts) ) CHKERR( PetscCLEAR(self.obj) ); self.ts = newts CHKERR( TSSetType(self.ts, TSPYTHON) ) CHKERR( TSPythonSetContext(self.ts, context) ) return self def setPythonContext(self, context: Any) -> None: """Set the instance of the class implementing the required Python methods. Not collective. See Also -------- petsc_python_ts, getPythonContext """ CHKERR( TSPythonSetContext(self.ts, context) ) def getPythonContext(self) -> Any: """Return the instance of the class implementing the required Python methods. Not collective. See Also -------- petsc_python_ts, setPythonContext """ cdef void *context = NULL CHKERR( TSPythonGetContext(self.ts, &context) ) if context == NULL: return None else: return context def setPythonType(self, py_type: str) -> None: """Set the fully qualified Python name of the class to be used. Collective. See Also -------- petsc_python_ts, setPythonContext, getPythonType, petsc.TSPythonSetType """ cdef const char *cval = NULL py_type = str2bytes(py_type, &cval) CHKERR( TSPythonSetType(self.ts, cval) ) def getPythonType(self) -> str: """Return the fully qualified Python name of the class used by the solver. Not collective. See Also -------- petsc_python_ts, setPythonContext, setPythonType, petsc.TSPythonGetType """ cdef const char *cval = NULL CHKERR( TSPythonGetType(self.ts, &cval) ) return bytes2str(cval) # --- Theta --- def setTheta(self, theta: float) -> None: """Set the abscissa of the stage in ``(0,1]`` for `Type.THETA`. Parameters ---------- theta stage abscissa Notes ----- ``-ts_theta_theta`` can be used to set a value from the commandline. See Also -------- petsc.TSThetaSetTheta """ cdef PetscReal rval = asReal(theta) CHKERR( TSThetaSetTheta(self.ts, rval) ) def getTheta(self) -> float: """Return the abscissa of the stage in ``(0,1]`` for `Type.THETA`. Not collective. See Also -------- petsc.TSThetaGetTheta """ cdef PetscReal rval = 0 CHKERR( TSThetaGetTheta(self.ts, &rval) ) return toReal(rval) def setThetaEndpoint(self, flag=True) -> None: """Set to use the endpoint variant of `Type.THETA`. Parameters ---------- flag Enable to use the endpoint variant. See Also -------- petsc.TSThetaSetEndpoint """ cdef PetscBool bval = flag CHKERR( TSThetaSetEndpoint(self.ts, bval) ) def getThetaEndpoint(self) -> bool: """Return whether the endpoint variable of `Type.THETA` is used. See Also -------- petsc.TSThetaGetEndpoint """ cdef PetscBool flag = PETSC_FALSE CHKERR( TSThetaGetEndpoint(self.ts, &flag) ) return toBool(flag) # --- Alpha --- def setAlphaRadius(self, radius: float) -> None: """Set the spectral radius for `Type.ALPHA`. Logically collective. Parameters ---------- radius the spectral radius Notes ----- ``-ts_alpha_radius`` can be used to set this from the commandline. See Also -------- petsc.TSAlphaSetRadius """ cdef PetscReal rval = asReal(radius) CHKERR( TSAlphaSetRadius(self.ts, rval) ) def setAlphaParams( self, alpha_m: float | None=None, alpha_f: float | None=None, gamma: float | None=None) -> None: """Set the algorithmic parameters for `Type.ALPHA`. Logically collective. Users should call `setAlphaRadius`. Parameters ---------- alpha_m Parameter, leave `None` to keep current value. alpha_f Parameter, leave `None` to keep current value. gamma Parameter, leave `None` to keep current value. See Also -------- petsc.TSAlphaSetParams """ cdef PetscReal rval1 = 0, rval2 = 0, rval3 = 0 try: CHKERR( TSAlphaGetParams(self.ts, &rval1, &rval2, &rval3) ) except PetscError: pass if alpha_m is not None: rval1 = asReal(alpha_m) if alpha_f is not None: rval2 = asReal(alpha_f) if gamma is not None: rval3 = asReal(gamma) CHKERR( TSAlphaSetParams(self.ts, rval1, rval2, rval3) ) def getAlphaParams(self) -> tuple[float, float, float]: """Return the algorithmic parameters for `Type.ALPHA`. See Also -------- petsc.TSAlphaGetParams """ cdef PetscReal rval1 = 0, rval2 = 0, rval3 = 0 CHKERR( TSAlphaGetParams(self.ts, &rval1, &rval2, &rval3) ) return (toReal(rval1), toReal(rval2), toReal(rval3)) # --- application context --- property appctx: """Application context.""" def __get__(self) -> Any: return self.getAppCtx() def __set__(self, value) -> None: self.setAppCtx(value) # --- discretization space --- property dm: """The `DM`.""" def __get__(self) -> DM: return self.getDM() def __set__(self, value) -> None: self.setDM(value) # --- xxx --- property problem_type: """The problem type.""" def __get__(self) -> ProblemType: return self.getProblemType() def __set__(self, value) -> None: self.setProblemType(value) property equation_type: """The equation type.""" def __get__(self) -> EquationType: return self.getEquationType() def __set__(self, value) -> None: self.setEquationType(value) property snes: """The `SNES`.""" def __get__(self) -> SNES: return self.getSNES() property ksp: """The `KSP`.""" def __get__(self) -> KSP: return self.getKSP() property vec_sol: """The solution vector.""" def __get__(self) -> Vec: return self.getSolution() # --- xxx --- property time: """The current time.""" def __get__(self) -> float: return self.getTime() def __set__(self, value) -> None: self.setTime(value) property time_step: """The current time step size.""" def __get__(self) -> None: return self.getTimeStep() def __set__(self, value): self.setTimeStep(value) property step_number: """The current step number.""" def __get__(self) -> int: return self.getStepNumber() def __set__(self, value) -> None: self.setStepNumber(value) property max_time: """The maximum time.""" def __get__(self) -> float: return self.getMaxTime() def __set__(self, value) -> None: self.setMaxTime(value) property max_steps: """The maximum number of steps.""" def __get__(self) -> int: return self.getMaxSteps() def __set__(self, value) -> None: self.setMaxSteps(value) # --- convergence --- property rtol: """The relative tolerance.""" def __get__(self) -> float: return self.getTolerances()[0] def __set__(self, value) -> None: self.setTolerances(rtol=value) property atol: """The absolute tolerance.""" def __get__(self) -> float: return self.getTolerances()[1] def __set__(self, value) -> None: self.setTolerances(atol=value) property reason: """The converged reason.""" def __get__(self) -> TSConvergedReason: return self.getConvergedReason() def __set__(self, value) -> None: self.setConvergedReason(value) property iterating: """Indicates the `TS` is still iterating.""" def __get__(self) -> bool: return self.reason == 0 property converged: """Indicates the `TS` has converged.""" def __get__(self) -> bool: return self.reason > 0 property diverged: """Indicates the `TS` has stopped.""" def __get__(self) -> bool: return self.reason < 0 # ----------------------------------------------------------------------------- del TSType del TSRKType del TSARKIMEXType del TSDIRKType del TSProblemType del TSEquationType del TSExactFinalTime del TSConvergedReason # ----------------------------------------------------------------------------- ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/src/petsc4py/PETSc/Vec.pyx0000644000175000017500000027552214567251135017143 0ustar00balaybalay# -------------------------------------------------------------------- class VecType(object): """The vector type.""" SEQ = S_(VECSEQ) MPI = S_(VECMPI) STANDARD = S_(VECSTANDARD) SHARED = S_(VECSHARED) SEQVIENNACL= S_(VECSEQVIENNACL) MPIVIENNACL= S_(VECMPIVIENNACL) VIENNACL = S_(VECVIENNACL) SEQCUDA = S_(VECSEQCUDA) MPICUDA = S_(VECMPICUDA) CUDA = S_(VECCUDA) SEQHIP = S_(VECSEQHIP) MPIHIP = S_(VECMPIHIP) HIP = S_(VECHIP) NEST = S_(VECNEST) SEQKOKKOS = S_(VECSEQKOKKOS) MPIKOKKOS = S_(VECMPIKOKKOS) KOKKOS = S_(VECKOKKOS) class VecOption(object): """Vector assembly option.""" IGNORE_OFF_PROC_ENTRIES = VEC_IGNORE_OFF_PROC_ENTRIES IGNORE_NEGATIVE_INDICES = VEC_IGNORE_NEGATIVE_INDICES # -------------------------------------------------------------------- cdef class Vec(Object): """A vector object. See Also -------- petsc.Vec """ Type = VecType Option = VecOption # def __cinit__(self): self.obj = &self.vec self.vec = NULL # unary operations def __pos__(self): return vec_pos(self) def __neg__(self): return vec_neg(self) def __abs__(self): return vec_abs(self) # inplace binary operations def __iadd__(self, other): return vec_iadd(self, other) def __isub__(self, other): return vec_isub(self, other) def __imul__(self, other): return vec_imul(self, other) def __idiv__(self, other): return vec_idiv(self, other) def __itruediv__(self, other): return vec_idiv(self, other) # binary operations def __add__(self, other): return vec_add(self, other) def __radd__(self, other): return vec_radd(self, other) def __sub__(self, other): return vec_sub(self, other) def __rsub__(self, other): return vec_rsub(self, other) def __mul__(self, other): return vec_mul(self, other) def __rmul__(self, other): return vec_rmul(self, other) def __div__(self, other): return vec_div(self, other) def __rdiv__(self, other): return vec_rdiv(self, other) def __truediv__(self, other): return vec_div(self, other) def __rtruediv__(self, other): return vec_rdiv(self, other) def __matmul__(self, other): return vec_matmul(self, other) # #def __len__(self): # cdef PetscInt size = 0 # CHKERR( VecGetSize(self.vec, &size) ) # return size def __getitem__(self, i): return vec_getitem(self, i) def __setitem__(self, i, v): vec_setitem(self, i, v) # buffer interface (PEP 3118) def __getbuffer__(self, Py_buffer *view, int flags): cdef _Vec_buffer buf = _Vec_buffer(self) buf.acquirebuffer(view, flags) def __releasebuffer__(self, Py_buffer *view): cdef _Vec_buffer buf = <_Vec_buffer>(view.obj) buf.releasebuffer(view) self # unused # 'with' statement (PEP 343) def __enter__(self): cdef _Vec_buffer buf = _Vec_buffer(self) self.set_attr('__buffer__', buf) return buf.enter() def __exit__(self, *exc): cdef _Vec_buffer buf = self.get_attr('__buffer__') self.set_attr('__buffer__', None) return buf.exit() # def view(self, Viewer viewer=None) -> None: """Display the vector. Collective. Parameters ---------- viewer A `Viewer` instance or `None` for the default viewer. See Also -------- load, petsc.VecView """ cdef PetscViewer vwr = NULL if viewer is not None: vwr = viewer.vwr CHKERR( VecView(self.vec, vwr) ) def destroy(self) -> Self: """Destroy the vector. Collective. See Also -------- create, petsc.VecDestroy """ CHKERR( VecDestroy(&self.vec) ) return self def create(self, comm: Comm | None = None) -> Self: """Create a vector object. Collective. After creation the vector type can then be set with `setType`. Parameters ---------- comm MPI communicator, defaults to `Sys.getDefaultComm`. See Also -------- destroy, petsc.VecCreate """ cdef MPI_Comm ccomm = def_Comm(comm, PETSC_COMM_DEFAULT) cdef PetscVec newvec = NULL CHKERR( VecCreate(ccomm, &newvec) ) CHKERR( PetscCLEAR(self.obj) ); self.vec = newvec return self def setType(self, vec_type: Type | str) -> None: """Set the vector type. Collective. Parameters ---------- vec_type The vector type. See Also -------- create, getType, petsc.VecSetType """ cdef PetscVecType cval = NULL vec_type = str2bytes(vec_type, &cval) CHKERR( VecSetType(self.vec, cval) ) def setSizes( self, size: LayoutSizeSpec, bsize: int | None = None, ) -> None: """Set the local and global sizes of the vector. Collective. Parameters ---------- size Vector size. bsize Vector block size. If `None`, ``bsize = 1``. See Also -------- getSizes, petsc.VecSetSizes """ cdef PetscInt bs=0, n=0, N=0 Vec_Sizes(size, bsize, &bs, &n, &N) CHKERR( VecSetSizes(self.vec, n, N) ) if bs != PETSC_DECIDE: CHKERR( VecSetBlockSize(self.vec, bs) ) # # FIXME the comm argument is hideous. def createSeq( self, size: LayoutSizeSpec, bsize: int | None = None, comm: Comm | None = None, ) -> Self: """Create a sequential `Type.SEQ` vector. Collective. Parameters ---------- size Vector size. bsize Vector block size. If `None`, ``bsize = 1``. comm MPI communicator, defaults to `COMM_SELF`. See Also -------- createMPI, petsc.VecCreateSeq """ cdef MPI_Comm ccomm = def_Comm(comm, PETSC_COMM_SELF) cdef PetscInt bs=0, n=0, N=0 Vec_Sizes(size, bsize, &bs, &n, &N) Sys_Layout(ccomm, bs, &n, &N) if bs == PETSC_DECIDE: bs = 1 cdef PetscVec newvec = NULL CHKERR( VecCreate(ccomm,&newvec) ) CHKERR( VecSetSizes(newvec, n, N) ) CHKERR( VecSetBlockSize(newvec, bs) ) CHKERR( VecSetType(newvec, VECSEQ) ) CHKERR( PetscCLEAR(self.obj) ); self.vec = newvec return self def createMPI( self, size: LayoutSizeSpec, bsize: int | None = None, comm: Comm | None = None, ) -> Self: """Create a parallel `Type.MPI` vector. Collective. Parameters ---------- size Vector size. bsize Vector block size. If `None`, ``bsize = 1``. comm MPI communicator, defaults to `Sys.getDefaultComm`. See Also -------- createSeq, petsc.VecCreateMPI """ cdef MPI_Comm ccomm = def_Comm(comm, PETSC_COMM_DEFAULT) cdef PetscInt bs=0, n=0, N=0 Vec_Sizes(size, bsize, &bs, &n, &N) Sys_Layout(ccomm, bs, &n, &N) if bs == PETSC_DECIDE: bs = 1 cdef PetscVec newvec = NULL CHKERR( VecCreate(ccomm, &newvec) ) CHKERR( VecSetSizes(newvec, n, N) ) CHKERR( VecSetBlockSize(newvec, bs) ) CHKERR( VecSetType(newvec, VECMPI) ) CHKERR( PetscCLEAR(self.obj) ); self.vec = newvec return self def createWithArray( self, array: Sequence[Scalar], size: LayoutSizeSpec | None = None, bsize: int | None = None, comm: Comm | None = None, ) -> Self: """Create a vector using a provided array. Collective. This method will create either a `Type.SEQ` or `Type.MPI` depending on the size of the communicator. Parameters ---------- array Array to store the vector values. Must be at least as large as the local size of the vector. size Vector size. bsize Vector block size. If `None`, ``bsize = 1``. comm MPI communicator, defaults to `Sys.getDefaultComm`. See Also -------- petsc.VecCreateSeqWithArray, petsc.VecCreateMPIWithArray """ cdef PetscInt na=0 cdef PetscScalar *sa=NULL array = iarray_s(array, &na, &sa) if size is None: size = (toInt(na), toInt(PETSC_DECIDE)) cdef MPI_Comm ccomm = def_Comm(comm, PETSC_COMM_DEFAULT) cdef PetscInt bs=0, n=0, N=0 Vec_Sizes(size, bsize, &bs, &n, &N) Sys_Layout(ccomm, bs, &n, &N) if bs == PETSC_DECIDE: bs = 1 if na < n: raise ValueError( "array size %d and vector local size %d block size %d" % (toInt(na), toInt(n), toInt(bs))) cdef PetscVec newvec = NULL if comm_size(ccomm) == 1: CHKERR( VecCreateSeqWithArray(ccomm,bs,N,sa,&newvec) ) else: CHKERR( VecCreateMPIWithArray(ccomm,bs,n,N,sa,&newvec) ) CHKERR( PetscCLEAR(self.obj) ); self.vec = newvec self.set_attr('__array__', array) return self def createCUDAWithArrays( self, cpuarray: Sequence[Scalar] | None = None, cudahandle: Any | None = None, # FIXME What type is appropriate here? size: LayoutSizeSpec | None = None, bsize: int | None = None, comm: Comm | None = None, ) -> Self: """Create a `Type.CUDA` vector with optional arrays. Collective. Parameters ---------- cpuarray Host array. Will be lazily allocated if not provided. cudahandle Address of the array on the GPU. Will be lazily allocated if not provided. size Vector size. bsize Vector block size. If `None`, ``bsize = 1``. comm MPI communicator, defaults to `Sys.getDefaultComm`. See Also -------- petsc.VecCreateSeqCUDAWithArrays, petsc.VecCreateMPICUDAWithArrays """ cdef PetscInt na=0 cdef PetscScalar *sa=NULL cdef PetscScalar *gpuarray = NULL if cudahandle: gpuarray = (cudahandle) if cpuarray is not None: cpuarray = iarray_s(cpuarray, &na, &sa) if size is None: size = (toInt(na), toInt(PETSC_DECIDE)) cdef MPI_Comm ccomm = def_Comm(comm, PETSC_COMM_DEFAULT) cdef PetscInt bs=0, n=0, N=0 Vec_Sizes(size, bsize, &bs, &n, &N) Sys_Layout(ccomm, bs, &n, &N) if bs == PETSC_DECIDE: bs = 1 if na < n: raise ValueError( "array size %d and vector local size %d block size %d" % (toInt(na), toInt(n), toInt(bs))) cdef PetscVec newvec = NULL if comm_size(ccomm) == 1: CHKERR( VecCreateSeqCUDAWithArrays(ccomm,bs,N,sa,gpuarray,&newvec) ) else: CHKERR( VecCreateMPICUDAWithArrays(ccomm,bs,n,N,sa,gpuarray,&newvec) ) CHKERR( PetscCLEAR(self.obj) ); self.vec = newvec if cpuarray is not None: self.set_attr('__array__', cpuarray) return self def createHIPWithArrays( self, cpuarray: Sequence[Scalar] | None = None, hiphandle: Any | None = None, # FIXME What type is appropriate here? size: LayoutSizeSpec | None = None, bsize: int | None = None, comm: Comm | None = None, ) -> Self: """Create a `Type.HIP` vector with optional arrays. Collective. Parameters ---------- cpuarray Host array. Will be lazily allocated if not provided. hiphandle Address of the array on the GPU. Will be lazily allocated if not provided. size Vector size. bsize Vector block size. If `None`, ``bsize = 1``. comm MPI communicator, defaults to `Sys.getDefaultComm`. See Also -------- petsc.VecCreateSeqHIPWithArrays, petsc.VecCreateMPIHIPWithArrays """ cdef PetscInt na=0 cdef PetscScalar *sa=NULL cdef PetscScalar *gpuarray = NULL if hiphandle: gpuarray = (hiphandle) if cpuarray is not None: cpuarray = iarray_s(cpuarray, &na, &sa) if size is None: size = (toInt(na), toInt(PETSC_DECIDE)) cdef MPI_Comm ccomm = def_Comm(comm, PETSC_COMM_DEFAULT) cdef PetscInt bs=0, n=0, N=0 Vec_Sizes(size, bsize, &bs, &n, &N) Sys_Layout(ccomm, bs, &n, &N) if bs == PETSC_DECIDE: bs = 1 if na < n: raise ValueError( "array size %d and vector local size %d block size %d" % (toInt(na), toInt(n), toInt(bs))) cdef PetscVec newvec = NULL if comm_size(ccomm) == 1: CHKERR( VecCreateSeqHIPWithArrays(ccomm,bs,N,sa,gpuarray,&newvec) ) else: CHKERR( VecCreateMPIHIPWithArrays(ccomm,bs,n,N,sa,gpuarray,&newvec) ) CHKERR( PetscCLEAR(self.obj) ); self.vec = newvec if cpuarray is not None: self.set_attr('__array__', cpuarray) return self def createViennaCLWithArrays( self, cpuarray: Sequence[Scalar] | None = None, viennaclvechandle: Any | None = None, # FIXME What type is appropriate here? size: LayoutSizeSpec | None = None, bsize: int | None = None, comm: Comm | None = None, ) -> Self: """Create a `Type.VIENNACL` vector with optional arrays. Collective. Parameters ---------- cpuarray Host array. Will be lazily allocated if not provided. viennaclvechandle Address of the array on the GPU. Will be lazily allocated if not provided. size Vector size. bsize Vector block size. If `None`, ``bsize = 1``. comm MPI communicator, defaults to `Sys.getDefaultComm`. See Also -------- petsc.VecCreateSeqViennaCLWithArrays petsc.VecCreateMPIViennaCLWithArrays """ cdef PetscInt na=0 cdef PetscScalar *sa=NULL cdef PetscScalar *vclvec = NULL if viennaclvechandle: vclvec = (viennaclvechandle) if cpuarray is not None: cpuarray = iarray_s(cpuarray, &na, &sa) if size is None: size = (toInt(na), toInt(PETSC_DECIDE)) cdef MPI_Comm ccomm = def_Comm(comm, PETSC_COMM_DEFAULT) cdef PetscInt bs=0, n=0, N=0 Vec_Sizes(size, bsize, &bs, &n, &N) Sys_Layout(ccomm, bs, &n, &N) if bs == PETSC_DECIDE: bs = 1 if na < n: raise ValueError( "array size %d and vector local size %d block size %d" % (toInt(na), toInt(n), toInt(bs))) cdef PetscVec newvec = NULL if comm_size(ccomm) == 1: CHKERR( VecCreateSeqViennaCLWithArrays(ccomm,bs,N,sa,vclvec,&newvec) ) else: CHKERR( VecCreateMPIViennaCLWithArrays(ccomm,bs,n,N,sa,vclvec,&newvec) ) CHKERR( PetscCLEAR(self.obj) ); self.vec = newvec if cpuarray is not None: self.set_attr('__array__', cpuarray) return self # FIXME: object? Do we need to specify it? Can't we just use Any? def createWithDLPack( self, object dltensor, size: LayoutSizeSpec | None = None, bsize: int | None = None, comm: Comm | None = None ) -> Self: """Create a vector wrapping a DLPack object, sharing the same memory. Collective. This operation does not modify the storage of the original tensor and should be used with contiguous tensors only. If the tensor is stored in row-major order (e.g. PyTorch tensors), the resulting vector will look like an unrolled tensor using row-major order. The resulting vector type will be one of `Type.SEQ`, `Type.MPI`, `Type.SEQCUDA`, `Type.MPICUDA`, `Type.SEQHIP` or `Type.MPIHIP` depending on the type of ``dltensor`` and the number of processes in the communicator. Parameters ---------- dltensor Either an object with a ``__dlpack__`` method or a DLPack tensor object. size Vector size. bsize Vector block size. If `None`, ``bsize = 1``. comm MPI communicator, defaults to `Sys.getDefaultComm`. """ cdef DLManagedTensor* ptr = NULL cdef int bits = 0 cdef PetscInt nz = 1 cdef int64_t ndim = 0 cdef int64_t* shape = NULL cdef int64_t* strides = NULL cdef MPI_Comm ccomm = def_Comm(comm, PETSC_COMM_DEFAULT) cdef PetscInt bs = 0,n = 0,N = 0 cdef DLContext* ctx = NULL if not PyCapsule_CheckExact(dltensor): dltensor = dltensor.__dlpack__() if PyCapsule_IsValid(dltensor, 'dltensor'): ptr = PyCapsule_GetPointer(dltensor, 'dltensor') bits = ptr.dl_tensor.dtype.bits if bits != 8*sizeof(PetscScalar): raise TypeError("Tensor dtype = {} does not match PETSc precision".format(ptr.dl_tensor.dtype)) ndim = ptr.dl_tensor.ndim shape = ptr.dl_tensor.shape for s in shape[:ndim]: nz = nz*s strides = ptr.dl_tensor.strides PyCapsule_SetName(dltensor, 'used_dltensor') else: raise ValueError("Expect a dltensor field, pycapsule.PyCapsule can only be consumed once") if size is None: size = (toInt(nz), toInt(PETSC_DECIDE)) Vec_Sizes(size, bsize, &bs, &n, &N) Sys_Layout(ccomm, bs, &n, &N) if bs == PETSC_DECIDE: bs = 1 if nz < n: raise ValueError( "array size %d and vector local size %d block size %d" % (toInt(nz), toInt(n), toInt(bs))) cdef PetscVec newvec = NULL cdef PetscDLDeviceType dltype = ptr.dl_tensor.ctx.device_type if dltype in [kDLCUDA,kDLCUDAManaged]: if comm_size(ccomm) == 1: CHKERR( VecCreateSeqCUDAWithArray(ccomm,bs,N,(ptr.dl_tensor.data),&newvec) ) else: CHKERR( VecCreateMPICUDAWithArray(ccomm,bs,n,N,(ptr.dl_tensor.data),&newvec) ) elif dltype in [kDLCPU,kDLCUDAHost,kDLROCMHost]: if comm_size(ccomm) == 1: CHKERR( VecCreateSeqWithArray(ccomm,bs,N,(ptr.dl_tensor.data),&newvec) ) else: CHKERR( VecCreateMPIWithArray(ccomm,bs,n,N,(ptr.dl_tensor.data),&newvec) ) elif dltype == kDLROCM: if comm_size(ccomm) == 1: CHKERR( VecCreateSeqHIPWithArray(ccomm,bs,N,(ptr.dl_tensor.data),&newvec) ) else: CHKERR( VecCreateMPIHIPWithArray(ccomm,bs,n,N,(ptr.dl_tensor.data),&newvec) ) else: raise TypeError("Device type {} not supported".format(dltype)) CHKERR( PetscCLEAR(self.obj) ); self.vec = newvec self.set_attr('__array__', dltensor) cdef int64_t* shape_arr = NULL cdef int64_t* strides_arr = NULL cdef object s1 = oarray_p(empty_p(ndim), NULL, &shape_arr) cdef object s2 = oarray_p(empty_p(ndim), NULL, &strides_arr) for i in range(ndim): shape_arr[i] = shape[i] strides_arr[i] = strides[i] self.set_attr('__dltensor_ctx__', (ptr.dl_tensor.ctx.device_type, ptr.dl_tensor.ctx.device_id, ndim, s1, s2)) if ptr.manager_deleter != NULL: ptr.manager_deleter(ptr) # free the manager return self def attachDLPackInfo( self, Vec vec=None, object dltensor=None ) -> Self: """Attach tensor information from another vector or DLPack tensor. Logically collective. This tensor information is required when converting a `Vec` to a DLPack object. Parameters ---------- vec Vector with attached tensor information. This is typically created by calling `createWithDLPack`. dltensor DLPack tensor. This will only be used if ``vec`` is `None`. Notes ----- This operation does not copy any data from ``vec`` or ``dltensor``. See Also -------- clearDLPackInfo, createWithDLPack """ cdef object ctx0 = self.get_attr('__dltensor_ctx__'), ctx = None cdef DLManagedTensor* ptr = NULL cdef int64_t* shape_arr = NULL cdef int64_t* strides_arr = NULL cdef object s1 = None, s2 = None if vec is None and dltensor is None: raise ValueError('Missing input parameters') if vec is not None: ctx = (vec).get_attr('__dltensor_ctx__') if ctx is None: raise ValueError('Input vector has no tensor information') self.set_attr('__dltensor_ctx__', ctx) else: if PyCapsule_IsValid(dltensor, 'dltensor'): ptr = PyCapsule_GetPointer(dltensor, 'dltensor') elif PyCapsule_IsValid(dltensor, 'used_dltensor'): ptr = PyCapsule_GetPointer(dltensor, 'used_dltensor') else: raise ValueError("Expect a dltensor or used_dltensor field") bits = ptr.dl_tensor.dtype.bits if bits != 8*sizeof(PetscScalar): raise TypeError("Tensor dtype = {} does not match PETSc precision".format(ptr.dl_tensor.dtype)) ndim = ptr.dl_tensor.ndim shape = ptr.dl_tensor.shape strides = ptr.dl_tensor.strides s1 = oarray_p(empty_p(ndim), NULL, &shape_arr) s2 = oarray_p(empty_p(ndim), NULL, &strides_arr) for i in range(ndim): shape_arr[i] = shape[i] strides_arr[i] = strides[i] self.set_attr('__dltensor_ctx__', (ptr.dl_tensor.ctx.device_type, ptr.dl_tensor.ctx.device_id, ndim, s1, s2)) return self def clearDLPackInfo(self) -> Self: """Clear tensor information. Logically collective. See Also -------- attachDLPackInfo, createWithDLPack """ self.set_attr('__dltensor_ctx__', None) return self # TODO Stream def __dlpack__(self, stream=-1): return self.toDLPack('rw') def __dlpack_device__(self): (dltype, devId, _, _, _) = vec_get_dlpack_ctx(self) return (dltype, devId) def toDLPack(self, mode: AccessModeSpec = 'rw') -> Any: """Return a DLPack `PyCapsule` wrapping the vector data. Collective. Parameters ---------- mode Access mode for the vector. Returns ------- `PyCapsule` Capsule of a DLPack tensor wrapping a `Vec`. Notes ----- It is important that the access mode is respected by the consumer as this is not enforced internally. See Also -------- createWithDLPack """ if mode is None: mode = 'rw' if mode not in ['rw', 'r', 'w']: raise ValueError("Invalid mode: expected 'rw', 'r', or 'w'") cdef int64_t ndim = 0 (device_type, device_id, ndim, shape, strides) = vec_get_dlpack_ctx(self) hostmem = (device_type == kDLCPU) cdef DLManagedTensor* dlm_tensor = malloc(sizeof(DLManagedTensor)) cdef DLTensor* dl_tensor = &dlm_tensor.dl_tensor cdef PetscScalar *a = NULL cdef int64_t* shape_strides = NULL dl_tensor.byte_offset = 0 # DLPack does not currently play well with our get/restore model # Call restore right-away and hope that the consumer will do the right thing # and not modify memory requested with read access # By restoring now, we guarantee the sanity of the ObjectState if mode == 'w': if hostmem: CHKERR( VecGetArrayWrite(self.vec, &a) ) CHKERR( VecRestoreArrayWrite(self.vec, NULL) ) else: CHKERR( VecGetArrayWriteAndMemType(self.vec, &a, NULL) ) CHKERR( VecRestoreArrayWriteAndMemType(self.vec, NULL) ) elif mode == 'r': if hostmem: CHKERR( VecGetArrayRead(self.vec, &a) ) CHKERR( VecRestoreArrayRead(self.vec, NULL) ) else: CHKERR( VecGetArrayReadAndMemType(self.vec, &a, NULL) ) CHKERR( VecRestoreArrayReadAndMemType(self.vec, NULL) ) else: if hostmem: CHKERR( VecGetArray(self.vec, &a) ) CHKERR( VecRestoreArray(self.vec, NULL) ) else: CHKERR( VecGetArrayAndMemType(self.vec, &a, NULL) ) CHKERR( VecRestoreArrayAndMemType(self.vec, NULL) ) dl_tensor.data = a cdef DLContext* ctx = &dl_tensor.ctx ctx.device_type = device_type ctx.device_id = device_id shape_strides = malloc(sizeof(int64_t)*2*ndim) for i in range(ndim): shape_strides[i] = shape[i] for i in range(ndim): shape_strides[i+ndim] = strides[i] dl_tensor.ndim = ndim dl_tensor.shape = shape_strides dl_tensor.strides = shape_strides + ndim cdef DLDataType* dtype = &dl_tensor.dtype dtype.code = DLDataTypeCode.kDLFloat if sizeof(PetscScalar) == 8: dtype.bits = 64 elif sizeof(PetscScalar) == 4: dtype.bits = 32 else: raise ValueError('Unsupported PetscScalar type') dtype.lanes = 1 dlm_tensor.manager_ctx = self.vec CHKERR( PetscObjectReference(self.vec) ) dlm_tensor.manager_deleter = manager_deleter dlm_tensor.del_obj = PetscDEALLOC return PyCapsule_New(dlm_tensor, 'dltensor', pycapsule_deleter) def createGhost( self, ghosts: Sequence[int], size: LayoutSizeSpec, bsize: int | None = None, comm: Comm | None = None, ) -> Self: """Create a parallel vector with ghost padding on each processor. Collective. Parameters ---------- ghosts Global indices of ghost points. size Vector size. bsize Vector block size. If `None`, ``bsize = 1``. comm MPI communicator, defaults to `Sys.getDefaultComm`. See Also -------- createGhostWithArray, petsc.VecCreateGhost, petsc.VecCreateGhostBlock """ cdef MPI_Comm ccomm = def_Comm(comm, PETSC_COMM_DEFAULT) cdef PetscInt ng=0, *ig=NULL ghosts = iarray_i(ghosts, &ng, &ig) cdef PetscInt bs=0, n=0, N=0 Vec_Sizes(size, bsize, &bs, &n, &N) Sys_Layout(ccomm, bs, &n, &N) cdef PetscVec newvec = NULL if bs == PETSC_DECIDE: CHKERR( VecCreateGhost( ccomm, n, N, ng, ig, &newvec) ) else: CHKERR( VecCreateGhostBlock( ccomm, bs, n, N, ng, ig, &newvec) ) CHKERR( PetscCLEAR(self.obj) ); self.vec = newvec return self def createGhostWithArray( self, ghosts: Sequence[int], array: Sequence[Scalar], size: LayoutSizeSpec | None = None, bsize: int | None = None, comm: Comm | None = None, ) -> Self: """Create a parallel vector with ghost padding and provided arrays. Collective. Parameters ---------- ghosts Global indices of ghost points. array Array to store the vector values. Must be at least as large as the local size of the vector (including ghost points). size Vector size. bsize Vector block size. If `None`, ``bsize = 1``. comm MPI communicator, defaults to `Sys.getDefaultComm`. See Also -------- createGhost, petsc.VecCreateGhostWithArray petsc.VecCreateGhostBlockWithArray """ cdef MPI_Comm ccomm = def_Comm(comm, PETSC_COMM_DEFAULT) cdef PetscInt ng=0, *ig=NULL ghosts = iarray_i(ghosts, &ng, &ig) cdef PetscInt na=0 cdef PetscScalar *sa=NULL array = oarray_s(array, &na, &sa) cdef PetscInt b = 1 if bsize is None else asInt(bsize) if size is None: size = (toInt(na-ng*b), toInt(PETSC_DECIDE)) cdef PetscInt bs=0, n=0, N=0 Vec_Sizes(size, bsize, &bs, &n, &N) Sys_Layout(ccomm, bs, &n, &N) if na < (n+ng*b): raise ValueError( "ghosts size %d, array size %d, and " "vector local size %d block size %d" % (toInt(ng), toInt(na), toInt(n), toInt(b))) cdef PetscVec newvec = NULL if bs == PETSC_DECIDE: CHKERR( VecCreateGhostWithArray( ccomm, n, N, ng, ig, sa, &newvec) ) else: CHKERR( VecCreateGhostBlockWithArray( ccomm, bs, n, N, ng, ig, sa, &newvec) ) CHKERR( PetscCLEAR(self.obj) ); self.vec = newvec self.set_attr('__array__', array) return self def createShared( self, size: LayoutSizeSpec, bsize: int | None = None, comm: Comm | None = None, ) -> Self: """Create a `Type.SHARED` vector that uses shared memory. Collective. Parameters ---------- size Vector size. bsize Vector block size. If `None`, ``bsize = 1``. comm MPI communicator, defaults to `Sys.getDefaultComm`. See Also -------- petsc.VecCreateShared """ cdef MPI_Comm ccomm = def_Comm(comm, PETSC_COMM_DEFAULT) cdef PetscInt bs=0, n=0, N=0 Vec_Sizes(size, bsize, &bs, &n, &N) Sys_Layout(ccomm, bs, &n, &N) cdef PetscVec newvec = NULL CHKERR( VecCreateShared(ccomm, n, N, &newvec) ) CHKERR( PetscCLEAR(self.obj) ); self.vec = newvec if bs != PETSC_DECIDE: CHKERR( VecSetBlockSize(self.vec, bs) ) return self def createNest( self, vecs: Sequence[Vec], isets: Sequence[IS] = None, comm: Comm | None = None, ) -> Self: """Create a `Type.NEST` vector containing multiple nested subvectors. Collective. Parameters ---------- vecs Iterable of subvectors. isets Iterable of index sets for each nested subvector. Defaults to contiguous ordering. comm MPI communicator, defaults to `Sys.getDefaultComm`. See Also -------- petsc.VecCreateNest """ vecs = list(vecs) if isets: isets = list(isets) assert len(isets) == len(vecs) else: isets = None cdef MPI_Comm ccomm = def_Comm(comm, PETSC_COMM_DEFAULT) cdef Py_ssize_t i, m = len(vecs) cdef PetscInt n = m cdef PetscVec *cvecs = NULL cdef PetscIS *cisets = NULL cdef object tmp1, tmp2 tmp1 = oarray_p(empty_p(n), NULL, &cvecs) for i from 0 <= i < m: cvecs[i] = (vecs[i]).vec if isets is not None: tmp2 = oarray_p(empty_p(n), NULL, &cisets) for i from 0 <= i < m: cisets[i] = (isets[i]).iset cdef PetscVec newvec = NULL CHKERR( VecCreateNest(ccomm, n, cisets, cvecs,&newvec) ) CHKERR( PetscCLEAR(self.obj) ); self.vec = newvec return self # def setOptionsPrefix(self, prefix: str) -> None: """Set the prefix used for searching for options in the database. Logically collective. See Also -------- petsc_options, getOptionsPrefix, petsc.VecSetOptionsPrefix """ cdef const char *cval = NULL prefix = str2bytes(prefix, &cval) CHKERR( VecSetOptionsPrefix(self.vec, cval) ) def getOptionsPrefix(self) -> str: """Return the prefix used for searching for options in the database. Not collective. See Also -------- petsc_options, setOptionsPrefix, petsc.VecGetOptionsPrefix """ cdef const char *cval = NULL CHKERR( VecGetOptionsPrefix(self.vec, &cval) ) return bytes2str(cval) def appendOptionsPrefix(self, prefix: str) -> None: """Append to the prefix used for searching for options in the database. Logically collective. See Also -------- petsc_options, setOptionsPrefix, petsc.VecAppendOptionsPrefix """ cdef const char *cval = NULL prefix = str2bytes(prefix, &cval) CHKERR( VecAppendOptionsPrefix(self.vec, cval) ) def setFromOptions(self) -> None: """Configure the vector from the options database. Collective. See Also -------- petsc_options, petsc.VecSetFromOptions """ CHKERR( VecSetFromOptions(self.vec) ) def setUp(self) -> Self: """Set up the internal data structures for using the vector. Collective. See Also -------- create, destroy, petsc.VecSetUp """ CHKERR( VecSetUp(self.vec) ) return self def setOption(self, option: Option, flag: bool) -> None: """Set option. Collective. See Also -------- petsc.VecSetOption """ CHKERR( VecSetOption(self.vec, option, flag) ) def getType(self) -> str: """Return the type of the vector. Not collective. See Also -------- setType, petsc.VecGetType """ cdef PetscVecType cval = NULL CHKERR( VecGetType(self.vec, &cval) ) return bytes2str(cval) def getSize(self) -> int: """Return the global size of the vector. Not collective. See Also -------- setSizes, getLocalSize, petsc.VecGetSize """ cdef PetscInt N = 0 CHKERR( VecGetSize(self.vec, &N) ) return toInt(N) def getLocalSize(self) -> int: """Return the local size of the vector. Not collective. See Also -------- setSizes, getSize, petsc.VecGetLocalSize """ cdef PetscInt n = 0 CHKERR( VecGetLocalSize(self.vec, &n) ) return toInt(n) def getSizes(self) -> LayoutSizeSpec: """Return the vector sizes. Not collective. See Also -------- getSize, getLocalSize, petsc.VecGetLocalSize, petsc.VecGetSize """ cdef PetscInt n = 0, N = 0 CHKERR( VecGetLocalSize(self.vec, &n) ) CHKERR( VecGetSize(self.vec, &N) ) return (toInt(n), toInt(N)) def setBlockSize(self, bsize: int) -> None: """Set the block size of the vector. Logically collective. See Also -------- petsc.VecSetBlockSize """ cdef PetscInt bs = asInt(bsize) CHKERR( VecSetBlockSize(self.vec, bs) ) def getBlockSize(self) -> int: """Return the block size of the vector. Not collective. See Also -------- petsc.VecGetBlockSize """ cdef PetscInt bs=0 CHKERR( VecGetBlockSize(self.vec, &bs) ) return toInt(bs) def getOwnershipRange(self) -> tuple[int, int]: """Return the locally owned range of indices ``(start, end)``. Not collective. Returns ------- start : int The first local element. end : int One more than the last local element. See Also -------- getOwnershipRanges, petsc.VecGetOwnershipRange """ cdef PetscInt low=0, high=0 CHKERR( VecGetOwnershipRange(self.vec, &low, &high) ) return (toInt(low), toInt(high)) def getOwnershipRanges(self) -> ArrayInt: """Return the range of indices owned by each process. Not collective. The returned array is the result of exclusive scan of the local sizes. See Also -------- getOwnershipRange, petsc.VecGetOwnershipRanges """ cdef const PetscInt *rng = NULL CHKERR( VecGetOwnershipRanges(self.vec, &rng) ) cdef MPI_Comm comm = MPI_COMM_NULL CHKERR( PetscObjectGetComm(self.vec, &comm) ) cdef int size = -1 CHKERR( MPI_Comm_size(comm, &size) ) return array_i(size+1, rng) def createLocalVector(self) -> Vec: """Create a local vector. Not collective. Returns ------- Vec The local vector. See Also -------- getLocalVector, petsc.VecCreateLocalVector """ lvec = Vec() CHKERR( VecCreateLocalVector(self.vec, &lvec.vec) ) return lvec def getLocalVector(self, Vec lvec, readonly: bool = False) -> None: """Maps the local portion of the vector into a local vector. Logically collective. Parameters ---------- lvec The local vector obtained from `createLocalVector`. readonly Request read-only access. See Also -------- createLocalVector, restoreLocalVector, petsc.VecGetLocalVectorRead petsc.VecGetLocalVector """ if readonly: CHKERR( VecGetLocalVectorRead(self.vec, lvec.vec) ) else: CHKERR( VecGetLocalVector(self.vec, lvec.vec) ) def restoreLocalVector(self, Vec lvec, readonly: bool = False) -> None: """Unmap a local access obtained with `getLocalVector`. Logically collective. Parameters ---------- lvec The local vector. readonly Request read-only access. See Also -------- createLocalVector, getLocalVector, petsc.VecRestoreLocalVectorRead petsc.VecRestoreLocalVector """ if readonly: CHKERR( VecRestoreLocalVectorRead(self.vec, lvec.vec) ) else: CHKERR( VecRestoreLocalVector(self.vec, lvec.vec) ) # FIXME Return type should be more specific def getBuffer(self, readonly: bool = False) -> Any: """Return a buffered view of the local portion of the vector. Logically collective. Parameters ---------- readonly Request read-only access. Returns ------- typing.Any `Buffer object ` wrapping the local portion of the vector data. This can be used either as a context manager providing access as a numpy array or can be passed to array constructors accepting buffered objects such as `numpy.asarray`. Examples -------- Accessing the data with a context manager: >>> vec = PETSc.Vec().createWithArray([1, 2, 3]) >>> with vec.getBuffer() as arr: ... arr array([1., 2., 3.]) Converting the buffer to an `ndarray`: >>> buf = PETSc.Vec().createWithArray([1, 2, 3]).getBuffer() >>> np.asarray(buf) array([1., 2., 3.]) See Also -------- getArray """ if readonly: return vec_getbuffer_r(self) else: return vec_getbuffer_w(self) def getArray(self, readonly: bool=False) -> ArrayScalar: """Return local portion of the vector as an `ndarray`. Logically collective. Parameters ---------- readonly Request read-only access. See Also -------- setArray, getBuffer """ if readonly: return vec_getarray_r(self) else: return vec_getarray_w(self) def setArray(self, array: Sequence[Scalar]) -> None: """Set values for the local portion of the vector. Logically collective. See Also -------- placeArray """ vec_setarray(self, array) def placeArray(self, array: Sequence[Scalar]) -> None: """Set the local portion of the vector to a provided array. Not collective. See Also -------- resetArray, setArray, petsc.VecPlaceArray """ cdef PetscInt nv=0 cdef PetscInt na=0 cdef PetscScalar *a = NULL CHKERR( VecGetLocalSize(self.vec, &nv) ) array = oarray_s(array, &na, &a) if (na != nv): raise ValueError( "cannot place input array size %d, vector size %d" % (toInt(na), toInt(nv))) CHKERR( VecPlaceArray(self.vec, a) ) self.set_attr('__placed_array__', array) def resetArray(self, force: bool = False) -> ArrayScalar | None: """Reset the vector to use its default array. Not collective. Parameters ---------- force Force the calling of `petsc.VecResetArray` even if no user array has been placed with `placeArray`. Returns ------- ArrayScalar The array previously provided by the user with `placeArray`. Can be `None` if ``force`` is `True` and no array was placed before. See Also -------- placeArray, petsc.VecResetArray """ cdef object array = None array = self.get_attr('__placed_array__') if array is None and not force: return None CHKERR( VecResetArray(self.vec) ) self.set_attr('__placed_array__', None) return array def bindToCPU(self, flg: bool) -> None: """Bind vector operations execution on the CPU. Logically collective. See Also -------- boundToCPU, petsc.VecBindToCPU """ cdef PetscBool bindFlg = asBool(flg) CHKERR( VecBindToCPU(self.vec, bindFlg) ) def boundToCPU(self) -> bool: """Return whether the vector has been bound to the CPU. Not collective. See Also -------- bindToCPU, petsc.VecBoundToCPU """ cdef PetscBool flg = PETSC_TRUE CHKERR( VecBoundToCPU(self.vec, &flg) ) return toBool(flg) def getCUDAHandle( self, mode: AccessModeSpec = 'rw', ) -> Any: # FIXME What is the right return type? """Return a pointer to the device buffer. Not collective. The returned pointer should be released using `restoreCUDAHandle` with the same access mode. Returns ------- typing.Any CUDA device pointer. Notes ----- This method may incur a host-to-device copy if the device data is out of date and ``mode`` is ``"r"`` or ``"rw"``. See Also -------- restoreCUDAHandle, petsc.VecCUDAGetArray, petsc.VecCUDAGetArrayRead petsc.VecCUDAGetArrayWrite """ cdef PetscScalar *hdl = NULL cdef const char *m = NULL if mode is not None: mode = str2bytes(mode, &m) if m == NULL or (m[0] == c'r' and m[1] == c'w'): CHKERR( VecCUDAGetArray(self.vec, &hdl) ) elif m[0] == c'r': CHKERR( VecCUDAGetArrayRead(self.vec, &hdl) ) elif m[0] == c'w': CHKERR( VecCUDAGetArrayWrite(self.vec, &hdl) ) else: raise ValueError("Invalid mode: expected 'rw', 'r', or 'w'") return hdl def restoreCUDAHandle( self, handle: Any, # FIXME What type hint is appropriate? mode: AccessModeSpec = 'rw', ) -> None: """Restore a pointer to the device buffer obtained with `getCUDAHandle`. Not collective. Parameters ---------- handle CUDA device pointer. mode Access mode. See Also -------- getCUDAHandle, petsc.VecCUDARestoreArray petsc.VecCUDARestoreArrayRead, petsc.VecCUDARestoreArrayWrite """ cdef PetscScalar *hdl = (handle) cdef const char *m = NULL if mode is not None: mode = str2bytes(mode, &m) if m == NULL or (m[0] == c'r' and m[1] == c'w'): CHKERR( VecCUDARestoreArray(self.vec, &hdl) ) elif m[0] == c'r': CHKERR( VecCUDARestoreArrayRead(self.vec, &hdl) ) elif m[0] == c'w': CHKERR( VecCUDARestoreArrayWrite(self.vec, &hdl) ) else: raise ValueError("Invalid mode: expected 'rw', 'r', or 'w'") def getHIPHandle( self, mode: AccessModeSpec = 'rw', ) -> Any: # FIXME What is the right return type? """Return a pointer to the device buffer. Not collective. The returned pointer should be released using `restoreHIPHandle` with the same access mode. Returns ------- typing.Any HIP device pointer. Notes ----- This method may incur a host-to-device copy if the device data is out of date and ``mode`` is ``"r"`` or ``"rw"``. See Also -------- restoreHIPHandle, petsc.VecHIPGetArray, petsc.VecHIPGetArrayRead petsc.VecHIPGetArrayWrite """ cdef PetscScalar *hdl = NULL cdef const char *m = NULL if mode is not None: mode = str2bytes(mode, &m) if m == NULL or (m[0] == c'r' and m[1] == c'w'): CHKERR( VecHIPGetArray(self.vec, &hdl) ) elif m[0] == c'r': CHKERR( VecHIPGetArrayRead(self.vec, &hdl) ) elif m[0] == c'w': CHKERR( VecHIPGetArrayWrite(self.vec, &hdl) ) else: raise ValueError("Invalid mode: expected 'rw', 'r', or 'w'") return hdl def restoreHIPHandle( self, handle: Any, # FIXME What type hint is appropriate? mode: AccessModeSpec = 'rw', ) -> None: """Restore a pointer to the device buffer obtained with `getHIPHandle`. Not collective. Parameters ---------- handle HIP device pointer. mode Access mode. See Also -------- getHIPHandle, petsc.VecHIPRestoreArray, petsc.VecHIPRestoreArrayRead petsc.VecHIPRestoreArrayWrite """ cdef PetscScalar *hdl = (handle) cdef const char *m = NULL if mode is not None: mode = str2bytes(mode, &m) if m == NULL or (m[0] == c'r' and m[1] == c'w'): CHKERR( VecHIPRestoreArray(self.vec, &hdl) ) elif m[0] == c'r': CHKERR( VecHIPRestoreArrayRead(self.vec, &hdl) ) elif m[0] == c'w': CHKERR( VecHIPRestoreArrayWrite(self.vec, &hdl) ) else: raise ValueError("Invalid mode: expected 'rw', 'r', or 'w'") def getOffloadMask(self) -> int: """Return the offloading status of the vector. Not collective. Common return values include: - 1: ``PETSC_OFFLOAD_CPU`` - CPU has valid entries - 2: ``PETSC_OFFLOAD_GPU`` - GPU has valid entries - 3: ``PETSC_OFFLOAD_BOTH`` - CPU and GPU are in sync Returns ------- int Enum value from `petsc.PetscOffloadMask` describing the offloading status. See Also -------- petsc.VecGetOffloadMask, petsc.PetscOffloadMask """ cdef PetscOffloadMask mask CHKERR( VecGetOffloadMask(self.vec, &mask) ) return mask def getCLContextHandle(self) -> int: """Return the OpenCL context associated with the vector. Not collective. Returns ------- int Pointer to underlying CL context. This can be used with `pyopencl` through `pyopencl.Context.from_int_ptr`. See Also -------- getCLQueueHandle, petsc.VecViennaCLGetCLContext """ cdef Py_uintptr_t ctxhdl = 0 CHKERR( VecViennaCLGetCLContext(self.vec, &ctxhdl) ) return ctxhdl def getCLQueueHandle(self) -> int: """Return the OpenCL command queue associated with the vector. Not collective. Returns ------- int Pointer to underlying CL command queue. This can be used with `pyopencl` through `pyopencl.Context.from_int_ptr`. See Also -------- getCLContextHandle, petsc.VecViennaCLGetCLQueue """ cdef Py_uintptr_t queuehdl = 0 CHKERR( VecViennaCLGetCLQueue(self.vec, &queuehdl) ) return queuehdl def getCLMemHandle( self, mode: AccessModeSpec = 'rw', ) -> int: """Return the OpenCL buffer associated with the vector. Not collective. Returns ------- int Pointer to the device buffer. This can be used with `pyopencl` through `pyopencl.Context.from_int_ptr`. Notes ----- This method may incur a host-to-device copy if the device data is out of date and ``mode`` is ``"r"`` or ``"rw"``. See Also -------- restoreCLMemHandle, petsc.VecViennaCLGetCLMem petsc.VecViennaCLGetCLMemRead, petsc.VecViennaCLGetCLMemWrite """ cdef Py_uintptr_t memhdl = 0 cdef const char *m = NULL mode = str2bytes(mode, &m) if m == NULL or (m[0] == c'r' and m[1] == c'w'): CHKERR( VecViennaCLGetCLMem(self.vec, &memhdl) ) elif m[0] == c'r': CHKERR( VecViennaCLGetCLMemRead(self.vec, &memhdl) ) elif m[0] == c'w': CHKERR( VecViennaCLGetCLMemWrite(self.vec, &memhdl) ) else: raise ValueError("Invalid mode: expected 'r', 'w' or 'rw'") return memhdl def restoreCLMemHandle(self) -> None: """Restore a pointer to the OpenCL buffer obtained with `getCLMemHandle`. Not collective. See Also -------- getCLMemHandle, petsc.VecViennaCLRestoreCLMemWrite """ CHKERR( VecViennaCLRestoreCLMemWrite(self.vec) ) def duplicate(self, array: Sequence[Scalar] | None = None) -> Vec: """Create a new vector with the same type, optionally with data. Collective. Parameters ---------- array Optional values to store in the new vector. See Also -------- copy, petsc.VecDuplicate """ cdef Vec vec = type(self)() CHKERR( VecDuplicate(self.vec, &vec.vec) ) # duplicate tensor context cdef object ctx0 = self.get_attr('__dltensor_ctx__') if ctx0 is not None: vec.set_attr('__dltensor_ctx__', ctx0) if array is not None: vec_setarray(vec, array) return vec def copy(self, Vec result=None) -> Vec: """Return a copy of the vector. Logically collective. This operation copies vector entries to the new vector. Parameters ---------- result Target vector for the copy. If `None` then a new vector is created internally. See Also -------- duplicate, petsc.VecCopy """ if result is None: result = type(self)() if result.vec == NULL: CHKERR( VecDuplicate(self.vec, &result.vec) ) CHKERR( VecCopy(self.vec, result.vec) ) return result def chop(self, tol: float) -> None: """Set all vector entries less than some absolute tolerance to zero. Collective. Parameters ---------- tol The absolute tolerance below which entries are set to zero. See Also -------- petsc.VecFilter """ cdef PetscReal rval = asReal(tol) CHKERR( VecFilter(self.vec, rval) ) def load(self, Viewer viewer) -> Self: """Load a vector. Collective. See Also -------- view, petsc.VecLoad """ cdef MPI_Comm comm = MPI_COMM_NULL cdef PetscObject obj = (viewer.vwr) if self.vec == NULL: CHKERR( PetscObjectGetComm(obj, &comm) ) CHKERR( VecCreate(comm, &self.vec) ) CHKERR( VecLoad(self.vec, viewer.vwr) ) return self def equal(self, Vec vec) -> bool: """Return whether the vector is equal to another. Collective. Parameters ---------- vec Vector to compare with. See Also -------- petsc.VecEqual """ cdef PetscBool flag = PETSC_FALSE CHKERR( VecEqual(self.vec, vec.vec, &flag) ) return toBool(flag) def dot(self, Vec vec) -> Scalar: """Return the dot product with ``vec``. Collective. For complex numbers this computes yᴴ·x with ``self`` as x, ``vec`` as y and where yᴴ denotes the conjugate transpose of y. Use `tDot` for the indefinite form yᵀ·x where yᵀ denotes the transpose of y. Parameters ---------- vec Vector to compute the dot product with. See Also -------- dotBegin, dotEnd, tDot, petsc.VecDot """ cdef PetscScalar sval = 0 CHKERR( VecDot(self.vec, vec.vec, &sval) ) return toScalar(sval) def dotBegin(self, Vec vec) -> None: """Begin computing the dot product. Collective. This should be paired with a call to `dotEnd`. Parameters ---------- vec Vector to compute the dot product with. See Also -------- dotEnd, dot, petsc.VecDotBegin """ cdef PetscScalar sval = 0 CHKERR( VecDotBegin(self.vec, vec.vec, &sval) ) def dotEnd(self, Vec vec) -> Scalar: """Finish computing the dot product initiated with `dotBegin`. Collective. See Also -------- dotBegin, dot, petsc.VecDotEnd """ cdef PetscScalar sval = 0 CHKERR( VecDotEnd(self.vec, vec.vec, &sval) ) return toScalar(sval) def tDot(self, Vec vec) -> Scalar: """Return the indefinite dot product with ``vec``. Collective. This computes yᵀ·x with ``self`` as x, ``vec`` as y and where yᵀ denotes the transpose of y. Parameters ---------- vec Vector to compute the indefinite dot product with. See Also -------- tDotBegin, tDotEnd, dot, petsc.VecTDot """ cdef PetscScalar sval = 0 CHKERR( VecTDot(self.vec, vec.vec, &sval) ) return toScalar(sval) def tDotBegin(self, Vec vec) -> None: """Begin computing the indefinite dot product. Collective. This should be paired with a call to `tDotEnd`. Parameters ---------- vec Vector to compute the indefinite dot product with. See Also -------- tDotEnd, tDot, petsc.VecTDotBegin """ cdef PetscScalar sval = 0 CHKERR( VecTDotBegin(self.vec, vec.vec, &sval) ) def tDotEnd(self, Vec vec) -> Scalar: """Finish computing the indefinite dot product initiated with `tDotBegin`. Collective. See Also -------- tDotBegin, tDot, petsc.VecTDotEnd """ cdef PetscScalar sval = 0 CHKERR( VecTDotEnd(self.vec, vec.vec, &sval) ) return toScalar(sval) def mDot(self, vecs, out=None) -> None: """Not implemented.""" raise NotImplementedError def mDotBegin(self, vecs, out=None) -> None: """Not implemented.""" raise NotImplementedError def mDotEnd(self, vecs, out=None) -> None: """Not implemented.""" raise NotImplementedError def mtDot(self, vecs, out=None) -> None: """Not implemented.""" raise NotImplementedError def mtDotBegin(self, vecs, out=None) -> None: """Not implemented.""" raise NotImplementedError def mtDotEnd(self, vecs, out=None) -> None: """Not implemented.""" raise NotImplementedError def norm( self, norm_type: NormTypeSpec = None, ) -> float | tuple[float, float]: """Compute the vector norm. Collective. A 2-tuple is returned if `NormType.NORM_1_AND_2` is specified. See Also -------- petsc.VecNorm, petsc.NormType """ cdef PetscNormType norm_1_2 = PETSC_NORM_1_AND_2 cdef PetscNormType ntype = PETSC_NORM_2 if norm_type is not None: ntype = norm_type cdef PetscReal rval[2] CHKERR( VecNorm(self.vec, ntype, rval) ) if ntype != norm_1_2: return toReal(rval[0]) else: return (toReal(rval[0]), toReal(rval[1])) def normBegin( self, norm_type: NormTypeSpec = None, ) -> None: """Begin computing the vector norm. Collective. This should be paired with a call to `normEnd`. See Also -------- normEnd, norm, petsc.VecNormBegin """ cdef PetscNormType ntype = PETSC_NORM_2 if norm_type is not None: ntype = norm_type cdef PetscReal dummy[2] CHKERR( VecNormBegin(self.vec, ntype, dummy) ) def normEnd( self, norm_type: NormTypeSpec = None, ) -> float | tuple[float, float]: """Finish computations initiated with `normBegin`. Collective. See Also -------- normBegin, norm, petsc.VecNormEnd """ cdef PetscNormType norm_1_2 = PETSC_NORM_1_AND_2 cdef PetscNormType ntype = PETSC_NORM_2 if norm_type is not None: ntype = norm_type cdef PetscReal rval[2] CHKERR( VecNormEnd(self.vec, ntype, rval) ) if ntype != norm_1_2: return toReal(rval[0]) else: return (toReal(rval[0]), toReal(rval[1])) def dotNorm2(self, Vec vec) -> tuple[Scalar, float]: """Return the dot product with ``vec`` and its squared norm. Collective. See Also -------- dot, norm, petsc.VecDotNorm2 """ cdef PetscScalar sval = 0 cdef PetscReal rval = 0 CHKERR( VecDotNorm2(self.vec, vec.vec, &sval, &rval) ) return toScalar(sval), toReal(float) def sum(self) -> Scalar: """Return the sum of all the entries of the vector. Collective. See Also -------- petsc.VecSum """ cdef PetscScalar sval = 0 CHKERR( VecSum(self.vec, &sval) ) return toScalar(sval) def min(self) -> tuple[int, float]: """Return the vector entry with minimum real part and its location. Collective. Returns ------- p : int Location of the minimum value. If multiple entries exist with the same value then the smallest index will be returned. val : Scalar Minimum value. See Also -------- max, petsc.VecMin """ cdef PetscInt ival = 0 cdef PetscReal rval = 0 CHKERR( VecMin(self.vec, &ival, &rval) ) return (toInt(ival), toReal(rval)) def max(self) -> tuple[int, float]: """Return the vector entry with maximum real part and its location. Collective. Returns ------- p : int Location of the maximum value. If multiple entries exist with the same value then the smallest index will be returned. val : Scalar Minimum value. See Also -------- min, petsc.VecMax """ cdef PetscInt ival = 0 cdef PetscReal rval = 0 CHKERR( VecMax(self.vec, &ival, &rval) ) return (toInt(ival), toReal(rval)) def normalize(self) -> float: """Normalize the vector by its 2-norm. Collective. Returns ------- float The vector norm before normalization. See Also -------- norm, petsc.VecNormalize """ cdef PetscReal rval = 0 CHKERR( VecNormalize(self.vec, &rval) ) return toReal(rval) def reciprocal(self) -> None: """Replace each entry in the vector by its reciprocal. Logically collective. See Also -------- petsc.VecReciprocal """ CHKERR( VecReciprocal(self.vec) ) def exp(self) -> None: """Replace each entry (xₙ) in the vector by exp(xₙ). Logically collective. See Also -------- log, petsc.VecExp """ CHKERR( VecExp(self.vec) ) def log(self) -> None: """Replace each entry in the vector by its natural logarithm. Logically collective. See Also -------- exp, petsc.VecLog """ CHKERR( VecLog(self.vec) ) def sqrtabs(self) -> None: """Replace each entry (xₙ) in the vector by √|xₙ|. Logically collective. See Also -------- petsc.VecSqrtAbs """ CHKERR( VecSqrtAbs(self.vec) ) def abs(self) -> None: """Replace each entry (xₙ) in the vector by abs|xₙ|. Logically collective. See Also -------- petsc.VecAbs """ CHKERR( VecAbs(self.vec) ) def conjugate(self): """Conjugate the vector. Logically collective. See Also -------- petsc.VecConjugate """ CHKERR( VecConjugate(self.vec) ) def setRandom(self, Random random=None) -> None: """Set all components of the vector to random numbers. Collective. Parameters ---------- random Random number generator. If `None` then one will be created internally. See Also -------- petsc.VecSetRandom """ cdef PetscRandom rnd = NULL if random is not None: rnd = random.rnd CHKERR( VecSetRandom(self.vec, rnd) ) def permute(self, IS order, invert: bool = False) -> None: """Permute the vector in-place with a provided ordering. Collective. Parameters ---------- order Ordering for the permutation. invert Whether to invert the permutation. See Also -------- petsc.VecPermute """ cdef PetscBool cinvert = PETSC_FALSE if invert: cinvert = PETSC_TRUE CHKERR( VecPermute(self.vec, order.iset, cinvert) ) def zeroEntries(self) -> None: """Set all entries in the vector to zero. Logically collective. See Also -------- set, petsc.VecZeroEntries """ CHKERR( VecZeroEntries(self.vec) ) def set(self, alpha: Scalar) -> None: """Set all components of the vector to the same value. Collective. See Also -------- zeroEntries, isset, petsc.VecSet """ cdef PetscScalar sval = asScalar(alpha) CHKERR( VecSet(self.vec, sval) ) def isset(self, IS idx, alpha: Scalar) -> None: """Set specific elements of the vector to the same value. Not collective. Parameters ---------- idx Index set specifying the vector entries to set. alpha Value to set the selected entries to. See Also -------- set, zeroEntries, petsc.VecISSet """ cdef PetscScalar aval = asScalar(alpha) CHKERR( VecISSet(self.vec, idx.iset, aval) ) def scale(self, alpha: Scalar) -> None: """Scale all entries of the vector. Collective. This method sets each entry (xₙ) in the vector to ɑ·xₙ. Parameters ---------- alpha The scaling factor. See Also -------- shift, petsc.VecScale """ cdef PetscScalar sval = asScalar(alpha) CHKERR( VecScale(self.vec, sval) ) def shift(self, alpha: Scalar) -> None: """Shift all entries in the vector. Collective. This method sets each entry (xₙ) in the vector to xₙ + ɑ. Parameters ---------- alpha The shift to apply to the vector values. See Also -------- scale, petsc.VecShift """ cdef PetscScalar sval = asScalar(alpha) CHKERR( VecShift(self.vec, sval) ) def swap(self, Vec vec) -> None: """Swap the content of two vectors. Logically collective. Parameters ---------- vec The vector to swap data with. See Also -------- petsc.VecSwap """ CHKERR( VecSwap(self.vec, vec.vec) ) def axpy(self, alpha: Scalar, Vec x) -> None: """Compute and store y = ɑ·x + y. Logically collective. Parameters ---------- alpha Scale factor. x Input vector. See Also -------- isaxpy, petsc.VecAXPY """ cdef PetscScalar sval = asScalar(alpha) CHKERR( VecAXPY(self.vec, sval, x.vec) ) def isaxpy(self, IS idx, alpha: Scalar, Vec x) -> None: """Add a scaled reduced-space vector to a subset of the vector. Logically collective. This is equivalent to ``y[idx[i]] += alpha*x[i]``. Parameters ---------- idx Index set for the reduced space. Negative indices are skipped. alpha Scale factor. x Reduced-space vector. See Also -------- axpy, aypx, axpby, petsc.VecISAXPY """ cdef PetscScalar sval = asScalar(alpha) CHKERR( VecISAXPY(self.vec, idx.iset, sval, x.vec) ) def aypx(self, alpha: Scalar, Vec x) -> None: """Compute and store y = x + ɑ·y. Logically collective. Parameters ---------- alpha Scale factor. x Input vector, must not be the current vector. See Also -------- axpy, axpby, petsc.VecAYPX """ cdef PetscScalar sval = asScalar(alpha) CHKERR( VecAYPX(self.vec, sval, x.vec) ) def axpby(self, alpha: Scalar, beta: Scalar, Vec x) -> None: """Compute and store y = ɑ·x + β·y. Logically collective. Parameters ---------- alpha First scale factor. beta Second scale factor. x Input vector, must not be the current vector. See Also -------- axpy, aypx, waxpy, petsc.VecAXPBY """ cdef PetscScalar sval1 = asScalar(alpha) cdef PetscScalar sval2 = asScalar(beta) CHKERR( VecAXPBY(self.vec, sval1, sval2, x.vec) ) def waxpy(self, alpha: Scalar, Vec x, Vec y) -> None: """Compute and store w = ɑ·x + y. Logically collective. Parameters ---------- alpha Scale factor. x First input vector. y Second input vector. See Also -------- axpy, aypx, axpby, maxpy, petsc.VecWAXPY """ cdef PetscScalar sval = asScalar(alpha) CHKERR( VecWAXPY(self.vec, sval, x.vec, y.vec) ) def maxpy(self, alphas: Sequence[Scalar], vecs: Sequence[Vec]) -> None: """Compute and store y = Σₙ(ɑₙ·Xₙ) + y with X an array of vectors. Logically collective. Equivalent to ``y[:] = alphas[i]*vecs[i, :] + y[:]``. Parameters ---------- alphas Array of scale factors, one for each vector in ``vecs``. vecs Array of vectors. See Also -------- axpy, aypx, axpby, waxpy, petsc.VecMAXPY """ cdef PetscInt n = 0 cdef PetscScalar *a = NULL cdef PetscVec *v = NULL cdef object tmp1 = iarray_s(alphas, &n, &a) cdef object tmp2 = oarray_p(empty_p(n),NULL, &v) assert n == len(vecs) cdef Py_ssize_t i=0 for i from 0 <= i < n: v[i] = ((vecs[i])).vec CHKERR( VecMAXPY(self.vec, n, a, v) ) def pointwiseMult(self, Vec x, Vec y) -> None: """Compute and store the component-wise multiplication of two vectors. Logically collective. Equivalent to ``w[i] = x[i] * y[i]``. Parameters ---------- x, y Input vectors to multiply component-wise. See Also -------- pointwiseDivide, petsc.VecPointwiseMult """ CHKERR( VecPointwiseMult(self.vec, x.vec, y.vec) ) def pointwiseDivide(self, Vec x, Vec y) -> None: """Compute and store the component-wise division of two vectors. Logically collective. Equivalent to ``w[i] = x[i] / y[i]``. Parameters ---------- x Numerator vector. y Denominator vector. See Also -------- pointwiseMult, petsc.VecPointwiseDivide """ CHKERR( VecPointwiseDivide(self.vec, x.vec, y.vec) ) def pointwiseMin(self, Vec x, Vec y) -> None: """Compute and store the component-wise minimum of two vectors. Logically collective. Equivalent to ``w[i] = min(x[i], y[i])``. Parameters ---------- x, y Input vectors to find the component-wise minima. See Also -------- pointwiseMax, pointwiseMaxAbs, petsc.VecPointwiseMin """ CHKERR( VecPointwiseMin(self.vec, x.vec, y.vec) ) def pointwiseMax(self, Vec x, Vec y) -> None: """Compute and store the component-wise maximum of two vectors. Logically collective. Equivalent to ``w[i] = max(x[i], y[i])``. Parameters ---------- x, y Input vectors to find the component-wise maxima. See Also -------- pointwiseMin, pointwiseMaxAbs, petsc.VecPointwiseMax """ CHKERR( VecPointwiseMax(self.vec, x.vec, y.vec) ) def pointwiseMaxAbs(self, Vec x, Vec y) -> None: """Compute and store the component-wise maximum absolute values. Logically collective. Equivalent to ``w[i] = max(abs(x[i]), abs(y[i]))``. Parameters ---------- x, y Input vectors to find the component-wise maxima. See Also -------- pointwiseMin, pointwiseMax, petsc.VecPointwiseMaxAbs """ CHKERR( VecPointwiseMaxAbs(self.vec, x.vec, y.vec) ) def maxPointwiseDivide(self, Vec vec) -> float: """Return the maximum of the component-wise absolute value division. Logically collective. Equivalent to ``result = max_i abs(x[i] / y[i])``. Parameters ---------- x Numerator vector. y Denominator vector. See Also -------- pointwiseMin, pointwiseMax, pointwiseMaxAbs petsc.VecMaxPointwiseDivide """ cdef PetscReal rval = 0 CHKERR( VecMaxPointwiseDivide(self.vec, vec.vec, &rval) ) return toReal(rval) def getValue(self, index: int) -> Scalar: """Return a single value from the vector. Not collective. Only values locally stored may be accessed. Parameters ---------- index Location of the value to read. See Also -------- getValues, petsc.VecGetValues """ cdef PetscInt ival = asInt(index) cdef PetscScalar sval = 0 CHKERR( VecGetValues(self.vec, 1, &ival, &sval) ) return toScalar(sval) def getValues( self, indices: Sequence[int], values: Sequence[Scalar] | None = None, ) -> ArrayScalar: """Return values from certain locations in the vector. Not collective. Only values locally stored may be accessed. Parameters ---------- indices Locations of the values to read. values Location to store the collected values. If not provided then a new array will be allocated. See Also -------- getValue, setValues, petsc.VecGetValues """ return vecgetvalues(self.vec, indices, values) def getValuesStagStencil(self, indices, values=None) -> None: """Not implemented.""" raise NotImplementedError def setValue( self, index: int, value: Scalar, addv: InsertModeSpec = None, ) -> None: """Insert or add a single value in the vector. Not collective. Parameters ---------- index Location to write to. Negative indices are ignored. value Value to insert at ``index``. addv Insertion mode. Notes ----- The values may be cached so `assemblyBegin` and `assemblyEnd` must be called after all calls of this method are completed. Multiple calls to `setValue` cannot be made with different values for ``addv`` without intermediate calls to `assemblyBegin` and `assemblyEnd`. See Also -------- setValues, petsc.VecSetValues """ cdef PetscInt ival = asInt(index) cdef PetscScalar sval = asScalar(value) cdef PetscInsertMode caddv = insertmode(addv) CHKERR( VecSetValues(self.vec, 1, &ival, &sval, caddv) ) def setValues( self, indices: Sequence[int], values: Sequence[Scalar], addv: InsertModeSpec = None, ) -> None: """Insert or add multiple values in the vector. Not collective. Parameters ---------- indices Locations to write to. Negative indices are ignored. values Values to insert at ``indices``. addv Insertion mode. Notes ----- The values may be cached so `assemblyBegin` and `assemblyEnd` must be called after all calls of this method are completed. Multiple calls to `setValues` cannot be made with different values for ``addv`` without intermediate calls to `assemblyBegin` and `assemblyEnd`. See Also -------- setValue, petsc.VecSetValues """ vecsetvalues(self.vec, indices, values, addv, 0, 0) def setValuesBlocked( self, indices: Sequence[int], values: Sequence[Scalar], addv: InsertModeSpec = None, ) -> None: """Insert or add blocks of values in the vector. Not collective. Equivalent to ``x[bs*indices[i]+j] = y[bs*i+j]`` for ``0 <= i < len(indices)``, ``0 <= j < bs`` and ``bs`` `block_size`. Parameters ---------- indices Block indices to write to. Negative indices are ignored. values Values to insert at ``indices``. Should have length ``len(indices) * vec.block_size``. addv Insertion mode. Notes ----- The values may be cached so `assemblyBegin` and `assemblyEnd` must be called after all calls of this method are completed. Multiple calls to `setValuesBlocked` cannot be made with different values for ``addv`` without intermediate calls to `assemblyBegin` and `assemblyEnd`. See Also -------- setValues, petsc.VecSetValuesBlocked """ vecsetvalues(self.vec, indices, values, addv, 1, 0) def setValuesStagStencil(self, indices, values, addv=None) -> None: """Not implemented.""" raise NotImplementedError def setLGMap(self, LGMap lgmap) -> None: """Set the local-to-global mapping. Logically collective. This allows users to insert vector entries using a local numbering with `setValuesLocal`. See Also -------- setValues, setValuesLocal, getLGMap, petsc.VecSetLocalToGlobalMapping """ CHKERR( VecSetLocalToGlobalMapping(self.vec, lgmap.lgm) ) def getLGMap(self) -> LGMap: """Return the local-to-global mapping. Not collective. See Also -------- setLGMap, petsc.VecGetLocalToGlobalMapping """ cdef LGMap cmap = LGMap() CHKERR( VecGetLocalToGlobalMapping(self.vec, &cmap.lgm) ) CHKERR( PetscINCREF(cmap.obj) ) return cmap def setValueLocal( self, index: int, value: Scalar, addv: InsertModeSpec = None, ): """Insert or add a single value in the vector using a local numbering. Not collective. Parameters ---------- index Location to write to. value Value to insert at ``index``. addv Insertion mode. Notes ----- The values may be cached so `assemblyBegin` and `assemblyEnd` must be called after all calls of this method are completed. Multiple calls to `setValueLocal` cannot be made with different values for ``addv`` without intermediate calls to `assemblyBegin` and `assemblyEnd`. See Also -------- setValuesLocal, petsc.VecSetValuesLocal """ cdef PetscInt ival = asInt(index) cdef PetscScalar sval = asScalar(value) cdef PetscInsertMode caddv = insertmode(addv) CHKERR( VecSetValuesLocal(self.vec, 1, &ival, &sval, caddv) ) def setValuesLocal( self, indices: Sequence[int], values: Sequence[Scalar], addv: InsertModeSpec = None, ) -> None: """Insert or add multiple values in the vector with a local numbering. Not collective. Parameters ---------- indices Locations to write to. values Values to insert at ``indices``. addv Insertion mode. Notes ----- The values may be cached so `assemblyBegin` and `assemblyEnd` must be called after all calls of this method are completed. Multiple calls to `setValuesLocal` cannot be made with different values for ``addv`` without intermediate calls to `assemblyBegin` and `assemblyEnd`. See Also -------- setValues, petsc.VecSetValuesLocal """ vecsetvalues(self.vec, indices, values, addv, 0, 1) def setValuesBlockedLocal( self, indices: Sequence[int], values: Sequence[Scalar], addv: InsertModeSpec = None, ) -> None: """Insert or add blocks of values in the vector with a local numbering. Not collective. Equivalent to ``x[bs*indices[i]+j] = y[bs*i+j]`` for ``0 <= i < len(indices)``, ``0 <= j < bs`` and ``bs`` `block_size`. Parameters ---------- indices Local block indices to write to. values Values to insert at ``indices``. Should have length ``len(indices) * vec.block_size``. addv Insertion mode. Notes ----- The values may be cached so `assemblyBegin` and `assemblyEnd` must be called after all calls of this method are completed. Multiple calls to `setValuesBlockedLocal` cannot be made with different values for ``addv`` without intermediate calls to `assemblyBegin` and `assemblyEnd`. See Also -------- setValuesBlocked, setValuesLocal, petsc.VecSetValuesBlockedLocal """ vecsetvalues(self.vec, indices, values, addv, 1, 1) def assemblyBegin(self) -> None: """Begin an assembling stage of the vector. Collective. See Also -------- assemblyEnd, petsc.VecAssemblyBegin """ CHKERR( VecAssemblyBegin(self.vec) ) def assemblyEnd(self) -> None: """Finish the assembling stage initiated with `assemblyBegin`. Collective. See Also -------- assemblyBegin, petsc.VecAssemblyEnd """ CHKERR( VecAssemblyEnd(self.vec) ) def assemble(self) -> None: """Assemble the vector. Collective. See Also -------- assemblyBegin, assemblyEnd """ CHKERR( VecAssemblyBegin(self.vec) ) CHKERR( VecAssemblyEnd(self.vec) ) # --- methods for strided vectors --- def strideScale(self, field: int, alpha: Scalar) -> None: """Scale a component of the vector. Logically collective. Parameters ---------- field Component index. Must be between ``0`` and ``vec.block_size``. alpha Factor to multiple the component entries by. See Also -------- strideSum, strideMin, strideMax, petsc.VecStrideScale """ cdef PetscInt ival = asInt(field) cdef PetscScalar sval = asScalar(alpha) CHKERR( VecStrideScale(self.vec, ival, sval) ) def strideSum(self, field: int) -> Scalar: """Sum subvector entries. Collective. Equivalent to ``sum(x[field], x[field+bs], x[field+2*bs], ...)`` where ``bs`` is `block_size`. Parameters ---------- field Component index. Must be between ``0`` and ``vec.block_size``. See Also -------- strideScale, strideMin, strideMax, petsc.VecStrideSum """ cdef PetscInt ival = asInt(field) cdef PetscScalar sval = 0 CHKERR( VecStrideSum(self.vec, ival, &sval) ) return toScalar(sval) def strideMin(self, field: int) -> tuple[int, float]: """Return the minimum of entries in a subvector. Collective. Equivalent to ``min(x[field], x[field+bs], x[field+2*bs], ...)`` where ``bs`` is `block_size`. Parameters ---------- field Component index. Must be between ``0`` and ``vec.block_size``. Returns ------- int Location of minimum. float Minimum value. See Also -------- strideScale, strideSum, strideMax, petsc.VecStrideMin """ cdef PetscInt ival1 = asInt(field) cdef PetscInt ival2 = 0 cdef PetscReal rval = 0 CHKERR( VecStrideMin(self.vec, ival1, &ival2, &rval) ) return (toInt(ival2), toReal(rval)) def strideMax(self, field: int) -> tuple[int, float]: """Return the maximum of entries in a subvector. Collective. Equivalent to ``max(x[field], x[field+bs], x[field+2*bs], ...)`` where ``bs`` is `block_size`. Parameters ---------- field Component index. Must be between ``0`` and ``vec.block_size``. Returns ------- int Location of maximum. float Maximum value. See Also -------- strideScale, strideSum, strideMin, petsc.VecStrideMax """ cdef PetscInt ival1 = asInt(field) cdef PetscInt ival2 = 0 cdef PetscReal rval = 0 CHKERR( VecStrideMax(self.vec, ival1, &ival2, &rval) ) return (toInt(ival2), toReal(rval)) def strideNorm( self, field: int, norm_type: NormTypeSpec = None, ) -> float | tuple[float, float]: """Return the norm of entries in a subvector. Collective. Equivalent to ``norm(x[field], x[field+bs], x[field+2*bs], ...)`` where ``bs`` is `block_size`. Parameters ---------- field Component index. Must be between ``0`` and ``vec.block_size``. norm_type The norm type. See Also -------- norm, strideScale, strideSum, petsc.VecStrideNorm """ cdef PetscInt ival = asInt(field) cdef PetscNormType norm_1_2 = PETSC_NORM_1_AND_2 cdef PetscNormType ntype = PETSC_NORM_2 if norm_type is not None: ntype = norm_type cdef PetscReal rval[2] CHKERR( VecStrideNorm(self.vec, ival, ntype, rval) ) if ntype != norm_1_2: return toReal(rval[0]) else: return (toReal(rval[0]), toReal(rval[1])) def strideScatter( self, field: int, Vec vec, addv: InsertModeSpec = None, ) -> None: """Scatter entries into a component of another vector. Collective. The current vector is expected to be single-component (`block_size` of ``1``) and the target vector is expected to be multi-component. Parameters ---------- field Component index. Must be between ``0`` and ``vec.block_size``. vec Multi-component vector to be scattered into. addv Insertion mode. See Also -------- strideGather, petsc.VecStrideScatter """ cdef PetscInt ival = asInt(field) cdef PetscInsertMode caddv = insertmode(addv) CHKERR( VecStrideScatter(self.vec, ival, vec.vec, caddv) ) def strideGather( self, field: int, Vec vec, addv: InsertModeSpec = None, ) -> None: """Insert component values into a single-component vector. Collective. The current vector is expected to be multi-component (`block_size` greater than ``1``) and the target vector is expected to be single-component. Parameters ---------- field Component index. Must be between ``0`` and ``vec.block_size``. vec Single-component vector to be inserted into. addv Insertion mode. See Also -------- strideScatter, petsc.VecStrideScatter """ cdef PetscInt ival = asInt(field) cdef PetscInsertMode caddv = insertmode(addv) CHKERR( VecStrideGather(self.vec, ival, vec.vec, caddv) ) # --- methods for vectors with ghost values --- def localForm(self) -> Any: """Return a context manager for viewing ghost vectors in local form. Logically collective. Returns ------- typing.Any Context manager yielding the vector in local (ghosted) form. Notes ----- This operation does not perform a copy. To obtain up-to-date ghost values `ghostUpdateBegin` and `ghostUpdateEnd` must be called first. Non-ghost values can be found at ``values[0:nlocal]`` and ghost values at ``values[nlocal:nlocal+nghost]``. Examples -------- >>> with vec.localForm() as lf: ... # compute with lf See Also -------- createGhost, ghostUpdateBegin, ghostUpdateEnd petsc.VecGhostGetLocalForm, petsc.VecGhostRestoreLocalForm """ return _Vec_LocalForm(self) def ghostUpdateBegin( self, addv: InsertModeSpec = None, mode: ScatterModeSpec = None, ) -> None: """Begin updating ghosted vector entries. Neighborwise collective. See Also -------- ghostUpdateEnd, ghostUpdate, createGhost, petsc.VecGhostUpdateBegin """ cdef PetscInsertMode caddv = insertmode(addv) cdef PetscScatterMode csctm = scattermode(mode) CHKERR( VecGhostUpdateBegin(self.vec, caddv, csctm) ) def ghostUpdateEnd( self, addv: InsertModeSpec = None, mode: ScatterModeSpec = None, ) -> None: """Finish updating ghosted vector entries initiated with `ghostUpdateBegin`. Neighborwise collective. See Also -------- ghostUpdateBegin, ghostUpdate, createGhost, petsc.VecGhostUpdateEnd """ cdef PetscInsertMode caddv = insertmode(addv) cdef PetscScatterMode csctm = scattermode(mode) CHKERR( VecGhostUpdateEnd(self.vec, caddv, csctm) ) def ghostUpdate( self, addv: InsertModeSpec = None, mode: ScatterModeSpec = None, ) -> None: """Update ghosted vector entries. Neighborwise collective. Parameters ---------- addv Insertion mode. mode Scatter mode. Examples -------- To accumulate ghost region values onto owning processes: >>> vec.ghostUpdate(InsertMode.ADD_VALUES, ScatterMode.REVERSE) Update ghost regions: >>> vec.ghostUpdate(InsertMode.INSERT_VALUES, ScatterMode.FORWARD) See Also -------- ghostUpdateBegin, ghostUpdateEnd """ cdef PetscInsertMode caddv = insertmode(addv) cdef PetscScatterMode csctm = scattermode(mode) CHKERR( VecGhostUpdateBegin(self.vec, caddv, csctm) ) CHKERR( VecGhostUpdateEnd(self.vec, caddv, csctm) ) def setMPIGhost(self, ghosts: Sequence[int]) -> None: """Set the ghost points for a ghosted vector. Collective. Parameters ---------- ghosts Global indices of ghost points. See Also -------- createGhost """ cdef PetscInt ng=0, *ig=NULL ghosts = iarray_i(ghosts, &ng, &ig) CHKERR( VecMPISetGhost(self.vec, ng, ig) ) # def getSubVector(self, IS iset, Vec subvec=None) -> Vec: """Return a subvector from given indices. Collective. Once finished with the subvector it should be returned with `restoreSubVector`. Parameters ---------- iset Index set describing which indices to extract into the subvector. subvec Subvector to copy entries into. If `None` then a new `Vec` will be created. See Also -------- restoreSubVector, petsc.VecGetSubVector """ if subvec is None: subvec = Vec() else: CHKERR( VecDestroy(&subvec.vec) ) CHKERR( VecGetSubVector(self.vec, iset.iset, &subvec.vec) ) return subvec def restoreSubVector(self, IS iset, Vec subvec) -> None: """Restore a subvector extracted using `getSubVector`. Collective. Parameters ---------- iset Index set describing the indices represented by the subvector. subvec Subvector to be restored. See Also -------- getSubVector, petsc.VecRestoreSubVector """ CHKERR( VecRestoreSubVector(self.vec, iset.iset, &subvec.vec) ) def getNestSubVecs(self) -> list[Vec]: """Return all the vectors contained in the nested vector. Not collective. See Also -------- setNestSubVecs, petsc.VecNestGetSubVecs """ cdef PetscInt N=0 cdef PetscVec* sx=NULL CHKERR( VecNestGetSubVecs(self.vec, &N, &sx) ) output = [] for i in range(N): pyvec = Vec() pyvec.vec = sx[i] CHKERR( PetscObjectReference( pyvec.vec) ) output.append(pyvec) return output def setNestSubVecs( self, sx: Sequence[Vec], idxm: Sequence[int] | None = None, ) -> None: """Set the component vectors at specified indices in the nested vector. Not collective. Parameters ---------- sx Array of component vectors. idxm Indices of the component vectors, defaults to ``range(len(sx))``. See Also -------- getNestSubVecs, petsc.VecNestSetSubVecs """ if idxm is None: idxm = range(len(sx)) else: assert len(idxm) == len(sx) cdef PetscInt N = 0 cdef PetscInt* cidxm = NULL idxm = iarray_i(idxm, &N, &cidxm) cdef PetscVec* csx = NULL tmp = oarray_p(empty_p(N), NULL, &csx) for i from 0 <= i < N: csx[i] = (sx[i]).vec CHKERR( VecNestSetSubVecs(self.vec, N, cidxm, csx) ) # def setDM(self, DM dm) -> None: """Associate a `DM` to the vector. Not collective. See Also -------- getDM, petsc.VecSetDM """ CHKERR( VecSetDM(self.vec, dm.dm) ) def getDM(self) -> DM: """Return the `DM` associated to the vector. Not collective. See Also -------- setDM, petsc.VecGetDM """ cdef DM dm = DM() CHKERR( VecGetDM(self.vec, &dm.dm) ) return dm # property sizes: """The local and global vector sizes.""" def __get__(self) -> LayoutSizeSpec: return self.getSizes() def __set__(self, value): self.setSizes(value) property size: """The global vector size.""" def __get__(self) -> int: return self.getSize() property local_size: """The local vector size.""" def __get__(self) -> int: return self.getLocalSize() property block_size: """The block size.""" def __get__(self) -> int: return self.getBlockSize() property owner_range: """The locally owned range of indices in the form ``[low, high)``.""" def __get__(self) -> tuple[int, int]: return self.getOwnershipRange() property owner_ranges: """The range of indices owned by each process.""" def __get__(self) -> ArrayInt: return self.getOwnershipRanges() property buffer_w: """Writeable buffered view of the local portion of the vector.""" def __get__(self) -> Any: return self.getBuffer() property buffer_r: """Read-only buffered view of the local portion of the vector.""" def __get__(self) -> Any: return self.getBuffer(True) property array_w: """Writeable `ndarray` containing the local portion of the vector.""" def __get__(self) -> ArrayScalar: return self.getArray() def __set__(self, value): cdef buf = self.getBuffer() with buf as array: array[:] = value property array_r: """Read-only `ndarray` containing the local portion of the vector.""" def __get__(self) -> ArrayScalar: return self.getArray(True) property buffer: """Alias for `buffer_w`.""" def __get__(self) -> Any: return self.buffer_w property array: """Alias for `array_w`.""" def __get__(self) -> ArrayScalar: return self.array_w def __set__(self, value): self.array_w = value # --- NumPy array interface (legacy) --- property __array_interface__: def __get__(self): cdef buf = self.getBuffer() return buf.__array_interface__ # -------------------------------------------------------------------- del VecType del VecOption # -------------------------------------------------------------------- ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/src/petsc4py/PETSc/Viewer.pyx0000644000175000017500000006466714567251135017675 0ustar00balaybalay# -------------------------------------------------------------------- class ViewerType(object): """Viewer type.""" SOCKET = S_(PETSCVIEWERSOCKET) ASCII = S_(PETSCVIEWERASCII) BINARY = S_(PETSCVIEWERBINARY) STRING = S_(PETSCVIEWERSTRING) DRAW = S_(PETSCVIEWERDRAW) VU = S_(PETSCVIEWERVU) MATHEMATICA = S_(PETSCVIEWERMATHEMATICA) HDF5 = S_(PETSCVIEWERHDF5) VTK = S_(PETSCVIEWERVTK) MATLAB = S_(PETSCVIEWERMATLAB) SAWS = S_(PETSCVIEWERSAWS) GLVIS = S_(PETSCVIEWERGLVIS) ADIOS = S_(PETSCVIEWERADIOS) EXODUSII = S_(PETSCVIEWEREXODUSII) class ViewerFormat(object): """Viewer format.""" DEFAULT = PETSC_VIEWER_DEFAULT ASCII_MATLAB = PETSC_VIEWER_ASCII_MATLAB ASCII_MATHEMATICA = PETSC_VIEWER_ASCII_MATHEMATICA ASCII_IMPL = PETSC_VIEWER_ASCII_IMPL ASCII_INFO = PETSC_VIEWER_ASCII_INFO ASCII_INFO_DETAIL = PETSC_VIEWER_ASCII_INFO_DETAIL ASCII_COMMON = PETSC_VIEWER_ASCII_COMMON ASCII_SYMMODU = PETSC_VIEWER_ASCII_SYMMODU ASCII_INDEX = PETSC_VIEWER_ASCII_INDEX ASCII_DENSE = PETSC_VIEWER_ASCII_DENSE ASCII_MATRIXMARKET= PETSC_VIEWER_ASCII_MATRIXMARKET ASCII_VTK = PETSC_VIEWER_ASCII_VTK_DEPRECATED ASCII_VTK_CELL = PETSC_VIEWER_ASCII_VTK_CELL_DEPRECATED ASCII_VTK_COORDS = PETSC_VIEWER_ASCII_VTK_COORDS_DEPRECATED ASCII_PCICE = PETSC_VIEWER_ASCII_PCICE ASCII_PYTHON = PETSC_VIEWER_ASCII_PYTHON ASCII_FACTOR_INFO = PETSC_VIEWER_ASCII_FACTOR_INFO ASCII_LATEX = PETSC_VIEWER_ASCII_LATEX ASCII_XML = PETSC_VIEWER_ASCII_XML ASCII_GLVIS = PETSC_VIEWER_ASCII_GLVIS ASCII_CSV = PETSC_VIEWER_ASCII_CSV DRAW_BASIC = PETSC_VIEWER_DRAW_BASIC DRAW_LG = PETSC_VIEWER_DRAW_LG DRAW_LG_XRANGE = PETSC_VIEWER_DRAW_LG_XRANGE DRAW_CONTOUR = PETSC_VIEWER_DRAW_CONTOUR DRAW_PORTS = PETSC_VIEWER_DRAW_PORTS VTK_VTS = PETSC_VIEWER_VTK_VTS VTK_VTR = PETSC_VIEWER_VTK_VTR VTK_VTU = PETSC_VIEWER_VTK_VTU BINARY_MATLAB = PETSC_VIEWER_BINARY_MATLAB NATIVE = PETSC_VIEWER_NATIVE HDF5_PETSC = PETSC_VIEWER_HDF5_PETSC HDF5_VIZ = PETSC_VIEWER_HDF5_VIZ HDF5_XDMF = PETSC_VIEWER_HDF5_XDMF HDF5_MAT = PETSC_VIEWER_HDF5_MAT NOFORMAT = PETSC_VIEWER_NOFORMAT LOAD_BALANCE = PETSC_VIEWER_LOAD_BALANCE FAILED = PETSC_VIEWER_FAILED class ViewerFileMode(object): """Viewer file mode.""" # native READ = PETSC_FILE_MODE_READ WRITE = PETSC_FILE_MODE_WRITE APPEND = PETSC_FILE_MODE_APPEND UPDATE = PETSC_FILE_MODE_UPDATE APPEND_UPDATE = PETSC_FILE_MODE_APPEND_UPDATE # aliases R, W, A, U = READ, WRITE, APPEND, UPDATE AU = UA = APPEND_UPDATE class ViewerDrawSize(object): """Window size.""" # native FULL_SIZE = PETSC_DRAW_FULL_SIZE HALF_SIZE = PETSC_DRAW_HALF_SIZE THIRD_SIZE = PETSC_DRAW_THIRD_SIZE QUARTER_SIZE = PETSC_DRAW_QUARTER_SIZE # aliases FULL = FULL_SIZE HALF = HALF_SIZE THIRD = THIRD_SIZE QUARTER = QUARTER_SIZE # -------------------------------------------------------------------- cdef class Viewer(Object): """Viewer object. Viewer is described in the `PETSc manual `. Viewers can be called as functions where the argument specified is the PETSc object to be viewed. See the example below. Examples -------- >>> from petsc4py import PETSc >>> u = PETSc.Vec().createWithArray([1,2]) >>> v = PETSc.Viewer() >>> v(u) Vec Object: 1 MPI process type: seq 1. 2. See Also -------- petsc.PetscViewer """ Type = ViewerType Format = ViewerFormat FileMode = ViewerFileMode DrawSize = ViewerDrawSize # backward compatibility Mode = ViewerFileMode Size = ViewerFileMode # def __cinit__(self): self.obj = &self.vwr self.vwr = NULL def __call__(self, Object obj) -> None: """View a generic object.""" assert obj.obj != NULL CHKERR( PetscObjectView(obj.obj[0], self.vwr) ) # def view(self, obj: Viewer | Object | None = None) -> None: """View the viewer. Collective. Parameters ---------- obj A `Viewer` instance or `None` for the default viewer. If none of the above applies, it assumes ``obj`` is an instance of `Object` and it calls the generic view for ``obj``. Notes ----- See Also -------- petsc.PetscViewerView """ if obj is None: CHKERR( PetscViewerView(self.vwr, NULL) ) elif isinstance(obj, Viewer): CHKERR( PetscViewerView(self.vwr, (obj).vwr) ) else: assert (obj).obj != NULL CHKERR( PetscObjectView((obj).obj[0], self.vwr) ) def destroy(self) -> Self: """Destroy the viewer. Collective. See Also -------- petsc.PetscViewerDestroy """ CHKERR( PetscViewerDestroy(&self.vwr) ) return self def create(self, comm: Comm | None = None) -> Self: """Create a viewer. Collective. Parameters ---------- comm MPI communicator, defaults to `Sys.getDefaultComm`. See Also -------- Sys.getDefaultComm, petsc.PetscViewerCreate """ cdef MPI_Comm ccomm = def_Comm(comm, PETSC_COMM_DEFAULT) cdef PetscViewer newvwr = NULL CHKERR( PetscViewerCreate(ccomm, &newvwr) ) CHKERR( PetscCLEAR(self.obj) ); self.vwr = newvwr return self def createASCII( self, name: str, mode: FileMode | str | None = None, comm: Comm | None = None, ) -> Self: """Create a viewer of type `Type.ASCII`. Collective. Parameters ---------- name The filename associated with the viewer. mode The mode type. comm MPI communicator, defaults to `Sys.getDefaultComm`. See Also -------- create, setType, setFileMode, setFileName, Sys.getDefaultComm setASCIITab, addASCIITab, subtractASCIITab, getASCIITab """ cdef MPI_Comm ccomm = def_Comm(comm, PETSC_COMM_DEFAULT) cdef const char *cname = NULL name = str2bytes(name, &cname) cdef PetscFileMode cmode = PETSC_FILE_MODE_WRITE if mode is not None: cmode = filemode(mode) cdef PetscViewer newvwr = NULL CHKERR( PetscViewerCreate(ccomm, &newvwr) ) CHKERR( PetscCLEAR(self.obj) ); self.vwr = newvwr CHKERR( PetscViewerSetType(self.vwr, PETSCVIEWERASCII) ) CHKERR( PetscViewerFileSetMode(self.vwr, cmode) ) CHKERR( PetscViewerFileSetName(self.vwr, cname) ) return self def createBinary( self, name: str, mode: FileMode | str | None = None, comm: Comm | None = None, ) -> Self: """Create a viewer of type `Type.BINARY`. Collective. Parameters ---------- name The filename associated with the viewer. mode The mode type. comm MPI communicator, defaults to `Sys.getDefaultComm`. See Also -------- create, setType, setFileMode, setFileName, Sys.getDefaultComm """ cdef MPI_Comm ccomm = def_Comm(comm, PETSC_COMM_DEFAULT) cdef const char *cname = NULL name = str2bytes(name, &cname) cdef PetscFileMode cmode = filemode(mode) cdef PetscViewer newvwr = NULL CHKERR( PetscViewerBinaryOpen(ccomm, cname, cmode, &newvwr) ) CHKERR( PetscCLEAR(self.obj) ); self.vwr = newvwr return self def createMPIIO( self, name: str, mode: FileMode | str | None = None, comm: Comm | None = None, ) -> Self: """Create a viewer of type `Type.BINARY` supporting MPI-IO. Collective. Parameters ---------- name The filename associated with the viewer. mode The mode type. comm MPI communicator, defaults to `Sys.getDefaultComm`. See Also -------- create, setType, setFileMode, setFileName, Sys.getDefaultComm """ cdef MPI_Comm ccomm = def_Comm(comm, PETSC_COMM_DEFAULT) cdef const char *cname = NULL name = str2bytes(name, &cname) cdef PetscFileMode cmode = filemode(mode) cdef PetscViewer newvwr = NULL CHKERR( PetscViewerCreate(ccomm, &newvwr) ) CHKERR( PetscCLEAR(self.obj) ); self.vwr = newvwr CHKERR( PetscViewerSetType(self.vwr, PETSCVIEWERBINARY) ) CHKERR( PetscViewerBinarySetUseMPIIO(self.vwr, PETSC_TRUE) ) CHKERR( PetscViewerFileSetMode(self.vwr, cmode) ) CHKERR( PetscViewerFileSetName(self.vwr, cname) ) return self def createVTK( self, name: str, mode: FileMode | str | None = None, comm: Comm | None = None, ) -> Self: """Create a viewer of type `Type.VTK`. Collective. Parameters ---------- name The filename associated with the viewer. mode The mode type. comm MPI communicator, defaults to `Sys.getDefaultComm`. See Also -------- create, setType, setFileMode, setFileName, Sys.getDefaultComm """ cdef MPI_Comm ccomm = def_Comm(comm, PETSC_COMM_DEFAULT) cdef const char *cname = NULL name = str2bytes(name, &cname) cdef PetscFileMode cmode = filemode(mode) cdef PetscViewer newvwr = NULL CHKERR( PetscViewerCreate(ccomm, &newvwr) ) CHKERR( PetscCLEAR(self.obj) ); self.vwr = newvwr CHKERR( PetscViewerSetType(self.vwr, PETSCVIEWERVTK) ) CHKERR( PetscViewerFileSetMode(self.vwr, cmode) ) CHKERR( PetscViewerFileSetName(self.vwr, cname) ) return self def createHDF5( self, name: str, mode: FileMode | str | None = None, comm: Comm | None = None, ) -> Self: """Create a viewer of type `Type.HDF5`. Collective. Parameters ---------- name The filename associated with the viewer. mode The mode type. comm MPI communicator, defaults to `Sys.getDefaultComm`. See Also -------- create, setType, setFileMode, setFileName, Sys.getDefaultComm """ cdef MPI_Comm ccomm = def_Comm(comm, PETSC_COMM_DEFAULT) cdef const char *cname = NULL name = str2bytes(name, &cname) cdef PetscFileMode cmode = filemode(mode) cdef PetscViewer newvwr = NULL CHKERR( PetscViewerCreate(ccomm, &newvwr) ) CHKERR( PetscCLEAR(self.obj) ); self.vwr = newvwr CHKERR( PetscViewerSetType(self.vwr, PETSCVIEWERHDF5) ) CHKERR( PetscViewerFileSetMode(self.vwr, cmode) ) CHKERR( PetscViewerFileSetName(self.vwr, cname) ) return self def createDraw( self, display: str | None = None, title: str | None = None, position: tuple[int, int] | None = None, size: tuple[int, int] | int | None = None, comm: Comm | None = None, ) -> Self: """Create a `Type.DRAW` viewer. Collective. Parameters ---------- display The X display to use or `None` for the local machine. title The window title or `None` for no title. position Screen coordinates of the upper left corner, or `None` for default. size Window size or `None` for default. comm MPI communicator, defaults to `Sys.getDefaultComm`. See Also -------- Sys.getDefaultComm, petsc.PetscViewerDrawOpen """ cdef MPI_Comm ccomm = def_Comm(comm, PETSC_COMM_DEFAULT) cdef const char *cdisplay = NULL cdef const char *ctitle = NULL display = str2bytes(display, &cdisplay) title = str2bytes(title, &ctitle) cdef int x, y, h, w x = y = h = w = PETSC_DECIDE if position not in (None, PETSC_DECIDE): x, y = position if size not in (None, PETSC_DECIDE): try: w, h = size except TypeError: w = h = size cdef PetscViewer newvwr = NULL CHKERR( PetscViewerDrawOpen(ccomm, cdisplay, ctitle, x, y, w, h, &newvwr) ) CHKERR( PetscCLEAR(self.obj) ); self.vwr = newvwr return self def setType(self, vwr_type: Type | str) -> None: """Set the type of the viewer. Logically collective. Parameters ---------- vwr_type The type of the viewer. See Also -------- getType, petsc.PetscViewerSetType """ cdef PetscViewerType cval = NULL vwr_type = str2bytes(vwr_type, &cval) CHKERR( PetscViewerSetType(self.vwr, cval) ) def getType(self) -> str: """Return the type of the viewer. Not collective. See Also -------- setType, petsc.PetscViewerGetType """ cdef PetscViewerType cval = NULL CHKERR( PetscViewerGetType(self.vwr, &cval) ) return bytes2str(cval) def getFormat(self) -> Format: """Return the format of the viewer. Not collective. See Also -------- pushFormat, popFormat, petsc.PetscViewerGetFormat """ cdef PetscViewerFormat format = PETSC_VIEWER_DEFAULT CHKERR( PetscViewerGetFormat(self.vwr, &format) ) return format def pushFormat(self, format: Format) -> None: """Push format to the viewer. Collective. See Also -------- popFormat, petsc.PetscViewerPushFormat """ CHKERR( PetscViewerPushFormat(self.vwr, format) ) def popFormat(self) -> None: """Pop format from the viewer. Collective. See Also -------- pushFormat, petsc.PetscViewerPopFormat """ CHKERR( PetscViewerPopFormat(self.vwr) ) def getSubViewer(self, comm: Comm | None = None) -> Viewer: """Return a viewer defined on a subcommunicator. Collective. Parameters ---------- comm The subcommunicator. If `None`, uses `COMM_SELF`. Notes ----- Users must call `restoreSubViewer` when done. See Also -------- restoreSubViewer, petsc.PetscViewerGetSubViewer """ cdef MPI_Comm ccomm = def_Comm(comm, PETSC_COMM_SELF) cdef Viewer sub = Viewer() CHKERR( PetscViewerGetSubViewer(self.vwr, ccomm, &sub.vwr) ) return sub def restoreSubViewer(self, Viewer sub) -> None: """Restore a viewer defined on a subcommunicator. Collective. Parameters ---------- sub The subviewer obtained from `getSubViewer`. See Also -------- getSubViewer, petsc.PetscViewerRestoreSubViewer """ cdef MPI_Comm ccomm = def_Comm(sub.getComm(), PETSC_COMM_SELF) CHKERR( PetscViewerRestoreSubViewer(self.vwr, ccomm, &sub.vwr) ) @classmethod def STDOUT(cls, comm: Comm | None = None) -> Viewer: """Return the standard output viewer associated with the communicator. Collective. Parameters ---------- comm MPI communicator, defaults to `Sys.getDefaultComm`. """ cdef MPI_Comm ccomm = def_Comm(comm, PETSC_COMM_DEFAULT) cdef Viewer viewer = Viewer() viewer.vwr = PETSC_VIEWER_STDOUT_(ccomm) CHKERR( PetscINCREF(viewer.obj) ) return viewer @classmethod def STDERR(cls, comm: Comm | None = None) -> Viewer: """Return the standard error viewer associated with the communicator. Collective. Parameters ---------- comm MPI communicator, defaults to `Sys.getDefaultComm`. """ cdef MPI_Comm ccomm = def_Comm(comm, PETSC_COMM_DEFAULT) cdef Viewer viewer = Viewer() viewer.vwr = PETSC_VIEWER_STDERR_(ccomm) CHKERR( PetscINCREF(viewer.obj) ) return viewer @classmethod def ASCII(cls, name : str, comm: Comm | None = None) -> Viewer: """Return an ASCII viewer associated with the communicator. Collective. Parameters ---------- name The filename. comm MPI communicator, defaults to `Sys.getDefaultComm`. """ cdef MPI_Comm ccomm = def_Comm(comm, PETSC_COMM_DEFAULT) cdef const char *cname = NULL name = str2bytes(name, &cname) cdef Viewer viewer = Viewer() CHKERR( PetscViewerASCIIOpen(ccomm, cname, &viewer.vwr) ) return viewer @classmethod def BINARY(cls, comm: Comm | None = None) -> Viewer: """Return the default `Type.BINARY` viewer associated with the communicator. Collective. Parameters ---------- comm MPI communicator, defaults to `Sys.getDefaultComm`. """ cdef MPI_Comm ccomm = def_Comm(comm, PETSC_COMM_DEFAULT) cdef Viewer viewer = Viewer() viewer.vwr = PETSC_VIEWER_BINARY_(ccomm) CHKERR( PetscINCREF(viewer.obj) ) return viewer @classmethod def DRAW(cls, comm: Comm | None = None) -> Viewer: """Return the default `Type.DRAW` viewer associated with the communicator. Collective. Parameters ---------- comm MPI communicator, defaults to `Sys.getDefaultComm`. """ cdef MPI_Comm ccomm = def_Comm(comm, PETSC_COMM_DEFAULT) cdef Viewer viewer = Viewer() viewer.vwr = PETSC_VIEWER_DRAW_(ccomm) CHKERR( PetscINCREF(viewer.obj) ) return viewer # --- ASCII viewers --- def setASCIITab(self, tabs : int) -> None: """Set ASCII tab level. Collective. See Also -------- getASCIITab, petsc.PetscViewerASCIISetTab """ cdef PetscInt ctabs = asInt(tabs) CHKERR( PetscViewerASCIISetTab(self.vwr, ctabs) ) def getASCIITab(self) -> int: """Return the ASCII tab level. Not collective. See Also -------- setASCIITab, petsc.PetscViewerASCIIGetTab """ cdef PetscInt tabs = 0 CHKERR( PetscViewerASCIIGetTab(self.vwr, &tabs) ) return toInt(tabs) def addASCIITab(self, tabs: int): """Increment the ASCII tab level. Collective. See Also -------- petsc.PetscViewerASCIIAddTab """ cdef PetscInt ctabs = asInt(tabs) CHKERR( PetscViewerASCIIAddTab(self.vwr, ctabs) ) def subtractASCIITab(self, tabs: int) -> None: """Decrement the ASCII tab level. Collective. See Also -------- petsc.PetscViewerASCIISubtractTab """ cdef PetscInt ctabs = asInt(tabs) CHKERR( PetscViewerASCIISubtractTab(self.vwr, ctabs) ) def pushASCIISynchronized(self) -> None: """Allow ASCII synchronized calls. Collective. See Also -------- printfASCIISynchronized, popASCIISynchronized petsc.PetscViewerASCIIPushSynchronized """ CHKERR( PetscViewerASCIIPushSynchronized(self.vwr) ) def popASCIISynchronized(self) -> None: """Disallow ASCII synchronized calls. Collective. See Also -------- printfASCIISynchronized, pushASCIISynchronized petsc.PetscViewerASCIIPopSynchronized """ CHKERR( PetscViewerASCIIPopSynchronized(self.vwr) ) def pushASCIITab(self) -> None: """Push an additional tab level. Collective. See Also -------- popASCIITab, petsc.PetscViewerASCIIPushTab """ CHKERR( PetscViewerASCIIPushTab(self.vwr) ) def popASCIITab(self) -> None: """Pop an additional tab level pushed via `pushASCIITab`. Collective. See Also -------- pushASCIITab, petsc.PetscViewerASCIIPopTab """ CHKERR( PetscViewerASCIIPopTab(self.vwr) ) def useASCIITabs(self, flag: bool) -> None: """Enable/disable the use of ASCII tabs. Collective. See Also -------- petsc.PetscViewerASCIIUseTabs """ cdef PetscBool flg = asBool(flag) CHKERR( PetscViewerASCIIUseTabs(self.vwr, flg) ) def printfASCII(self, msg: str) -> None: """Print a message. Collective. See Also -------- petsc.PetscViewerASCIIPrintf """ cdef const char *cmsg = NULL msg = str2bytes(msg, &cmsg) CHKERR( PetscViewerASCIIPrintf(self.vwr, '%s', cmsg) ) def printfASCIISynchronized(self, msg: str) -> None: """Print a synchronized message. Collective. See Also -------- pushASCIISynchronized, petsc.PetscViewerASCIISynchronizedPrintf """ cdef const char *cmsg = NULL msg = str2bytes(msg, &cmsg) CHKERR( PetscViewerASCIISynchronizedPrintf(self.vwr, '%s', cmsg) ) # --- methods specific to file viewers --- def flush(self) -> None: """Flush the viewer. Collective. See Also -------- petsc.PetscViewerFlush """ CHKERR( PetscViewerFlush(self.vwr) ) def setFileMode(self, mode: FileMode | str) -> None: """Set file mode. Collective. See Also -------- getFileMode, petsc.PetscViewerFileSetMode """ CHKERR( PetscViewerFileSetMode(self.vwr, filemode(mode)) ) def getFileMode(self) -> FileMode: """Return the file mode. Not collective. See Also -------- setFileMode, petsc.PetscViewerFileGetMode """ cdef PetscFileMode mode = PETSC_FILE_MODE_READ CHKERR( PetscViewerFileGetMode(self.vwr, &mode) ) return mode def setFileName(self, name: str) -> None: """Set file name. Collective. See Also -------- getFileName, petsc.PetscViewerFileSetName """ cdef const char *cval = NULL name = str2bytes(name, &cval) CHKERR( PetscViewerFileSetName(self.vwr, cval) ) def getFileName(self) -> str: """Return file name. Not collective. See Also -------- setFileName, petsc.PetscViewerFileGetName """ cdef const char *cval = NULL CHKERR( PetscViewerFileGetName(self.vwr, &cval) ) return bytes2str(cval) # --- methods specific to draw viewers --- def setDrawInfo( self, display: str | None = None, title: str | None = None, position: tuple[int, int] | None = None, size: tuple[int, int] | int | None = None, ) -> None: """Set window information for a `Type.DRAW` viewer. Collective. Parameters ---------- display The X display to use or `None` for the local machine. title The window title or `None` for no title. position Screen coordinates of the upper left corner, or `None` for default. size Window size or `None` for default. """ # FIXME missing manual page # See Also # -------- # petsc.PetscViewerDrawSetInfo cdef const char *cdisplay = NULL cdef const char *ctitle = NULL display = str2bytes(display, &cdisplay) title = str2bytes(title, &ctitle) cdef int x, y, h, w x = y = h = w = PETSC_DECIDE if position not in (None, PETSC_DECIDE): x, y = position if size not in (None, PETSC_DECIDE): try: w, h = size except TypeError: w = h = size CHKERR( PetscViewerDrawSetInfo(self.vwr, cdisplay, ctitle, x, y, w, h) ) def clearDraw(self) -> None: """Reset graphics. Not collective. See Also -------- petsc.PetscViewerDrawClear """ CHKERR( PetscViewerDrawClear(self.vwr) ) # -------------------------------------------------------------------- cdef class ViewerHDF5(Viewer): def create(self, name, mode=None, comm=None): cdef MPI_Comm ccomm = def_Comm(comm, PETSC_COMM_DEFAULT) cdef const char *cname = NULL name = str2bytes(name, &cname) cdef PetscFileMode cmode = filemode(mode) cdef PetscViewer newvwr = NULL CHKERR( PetscViewerCreate(ccomm, &newvwr) ) CHKERR( PetscCLEAR(self.obj) ); self.vwr = newvwr CHKERR( PetscViewerSetType(self.vwr, PETSCVIEWERHDF5) ) CHKERR( PetscViewerFileSetMode(self.vwr, cmode) ) CHKERR( PetscViewerFileSetName(self.vwr, cname) ) return self def pushTimestepping(self): CHKERR( PetscViewerHDF5PushTimestepping(self.vwr) ) def popTimestepping(self): CHKERR( PetscViewerHDF5PopTimestepping(self.vwr) ) def getTimestep(self): cdef PetscInt ctimestep = 0 CHKERR( PetscViewerHDF5GetTimestep(self.vwr, &ctimestep) ) return toInt(ctimestep) def setTimestep(self, timestep): CHKERR( PetscViewerHDF5SetTimestep(self.vwr, asInt(timestep)) ) def incrementTimestep(self): CHKERR( PetscViewerHDF5IncrementTimestep(self.vwr) ) def pushGroup(self, group): cdef const char *cgroup = NULL group = str2bytes(group, &cgroup) CHKERR( PetscViewerHDF5PushGroup(self.vwr, cgroup) ) def popGroup(self): CHKERR( PetscViewerHDF5PopGroup(self.vwr) ) def getGroup(self): cdef char *cgroup = NULL CHKERR( PetscViewerHDF5GetGroup(self.vwr, NULL, &cgroup) ) group = bytes2str(cgroup) CHKERR( PetscFree(cgroup) ) return group # -------------------------------------------------------------------- del ViewerType del ViewerFormat del ViewerFileMode del ViewerDrawSize # -------------------------------------------------------------------- ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/src/petsc4py/PETSc/arraynpy.pxi0000644000175000017500000001676614567251135020256 0ustar00balaybalay# -------------------------------------------------------------------- cdef extern from "": int import_array "_import_array" () except -1 ctypedef long npy_intp ctypedef extern class numpy.dtype [object PyArray_Descr]: pass ctypedef extern class numpy.ndarray [object PyArrayObject]: pass void* PyArray_DATA(ndarray) npy_intp PyArray_SIZE(ndarray) int PyArray_NDIM(ndarray) npy_intp* PyArray_DIMS(ndarray) npy_intp PyArray_DIM(ndarray, int) npy_intp PyArray_MultiplyList(const npy_intp*, int) enum: NPY_INTP dtype PyArray_DescrFromType(int) object PyArray_TypeObjectFromType(int) enum: NPY_ARRAY_ALIGNED enum: NPY_ARRAY_WRITEABLE enum: NPY_ARRAY_NOTSWAPPED enum: NPY_ARRAY_CARRAY enum: NPY_ARRAY_FARRAY ndarray PyArray_FROM_O(object) ndarray PyArray_FROM_OT(object,int) ndarray PyArray_FROM_OTF(object,int,int) ndarray PyArray_Copy(ndarray) ndarray PyArray_ArangeObj(object,object,object,dtype) ndarray PyArray_EMPTY(int,npy_intp[],int,int) ndarray PyArray_ZEROS(int,npy_intp[],int,int) bint PyArray_ISCONTIGUOUS(ndarray) bint PyArray_ISFORTRAN(ndarray) ctypedef enum NPY_ORDER: NPY_ANYORDER NPY_CORDER NPY_FORTRANORDER ndarray PyArray_NewCopy(ndarray,NPY_ORDER) ctypedef struct PyObject ctypedef struct PyTypeObject ndarray PyArray_New(PyTypeObject*,int,npy_intp[],int,npy_intp[],void*,int,int,PyObject*) ndarray PyArray_SimpleNewFromData(int,npy_intp[],int,void*) cdef extern from "": enum: NPY_INT enum: NPY_DOUBLE enum: NPY_PETSC_BOOL enum: NPY_PETSC_INT enum: NPY_PETSC_REAL enum: NPY_PETSC_SCALAR enum: NPY_PETSC_COMPLEX # -------------------------------------------------------------------- cdef inline ndarray asarray(object ob): return PyArray_FROM_O(ob) cdef inline ndarray arange(start, stop, stride): cdef dtype descr = PyArray_DescrFromType(NPY_PETSC_INT) return PyArray_ArangeObj(start, stop, stride, descr) # -------------------------------------------------------------------- cdef inline ndarray empty_i(PetscInt size): cdef npy_intp s = size return PyArray_EMPTY(1, &s, NPY_PETSC_INT, 0) cdef inline ndarray empty_r(PetscInt size): cdef npy_intp s = size return PyArray_EMPTY(1, &s, NPY_PETSC_REAL, 0) cdef inline ndarray empty_s(PetscInt size): cdef npy_intp s = size return PyArray_EMPTY(1, &s, NPY_PETSC_SCALAR, 0) cdef inline ndarray empty_c(PetscInt size): cdef npy_intp s = size return PyArray_EMPTY(1, &s, NPY_PETSC_COMPLEX, 0) cdef inline ndarray empty_p(PetscInt size): cdef npy_intp s = size return PyArray_EMPTY(1, &s, NPY_INTP, 0) # -------------------------------------------------------------------- cdef inline ndarray array_i(PetscInt size, const PetscInt* data): cdef npy_intp s = size cdef ndarray ary = PyArray_EMPTY(1, &s, NPY_PETSC_INT, 0) if data != NULL: memcpy(PyArray_DATA(ary), data, size*sizeof(PetscInt)) return ary cdef inline ndarray array_r(PetscInt size, const PetscReal* data): cdef npy_intp s = size cdef ndarray ary = PyArray_EMPTY(1, &s, NPY_PETSC_REAL, 0) if data != NULL: memcpy(PyArray_DATA(ary), data, size*sizeof(PetscReal)) return ary cdef inline ndarray array_b(PetscInt size, const PetscBool* data): cdef npy_intp s = size cdef ndarray ary = PyArray_EMPTY(1, &s, NPY_PETSC_BOOL, 0) if data != NULL: memcpy(PyArray_DATA(ary), data, size*sizeof(PetscBool)) return ary cdef inline ndarray array_s(PetscInt size, const PetscScalar* data): cdef npy_intp s = size cdef ndarray ary = PyArray_EMPTY(1, &s, NPY_PETSC_SCALAR, 0) if data != NULL: memcpy(PyArray_DATA(ary), data, size*sizeof(PetscScalar)) return ary # -------------------------------------------------------------------- cdef inline ndarray iarray(object ob, int typenum): cdef ndarray ary = PyArray_FROM_OTF( ob, typenum, NPY_ARRAY_ALIGNED|NPY_ARRAY_NOTSWAPPED) if PyArray_ISCONTIGUOUS(ary): return ary if PyArray_ISFORTRAN(ary): return ary return PyArray_Copy(ary) cdef inline ndarray iarray_i(object ob, PetscInt* size, PetscInt** data): cdef ndarray ary = iarray(ob, NPY_PETSC_INT) if size != NULL: size[0] = PyArray_SIZE(ary) if data != NULL: data[0] = PyArray_DATA(ary) return ary cdef inline ndarray iarray_r(object ob, PetscInt* size, PetscReal** data): cdef ndarray ary = iarray(ob, NPY_PETSC_REAL) if size != NULL: size[0] = PyArray_SIZE(ary) if data != NULL: data[0] = PyArray_DATA(ary) return ary cdef inline ndarray iarray_b(object ob, PetscInt* size, PetscBool** data): cdef ndarray ary = iarray(ob, NPY_PETSC_BOOL) if size != NULL: size[0] = PyArray_SIZE(ary) if data != NULL: data[0] = PyArray_DATA(ary) return ary cdef inline ndarray iarray_s(object ob, PetscInt* size, PetscScalar** data): cdef ndarray ary = iarray(ob, NPY_PETSC_SCALAR) if size != NULL: size[0] = PyArray_SIZE(ary) if data != NULL: data[0] = PyArray_DATA(ary) return ary # -------------------------------------------------------------------- cdef inline ndarray oarray(object ob, int typenum): cdef ndarray ary = PyArray_FROM_OTF( ob, typenum, NPY_ARRAY_ALIGNED|NPY_ARRAY_WRITEABLE|NPY_ARRAY_NOTSWAPPED) if PyArray_ISCONTIGUOUS(ary): return ary if PyArray_ISFORTRAN(ary): return ary return PyArray_Copy(ary) cdef inline ndarray oarray_i(object ob, PetscInt* size, PetscInt** data): cdef ndarray ary = oarray(ob, NPY_PETSC_INT) if size != NULL: size[0] = PyArray_SIZE(ary) if data != NULL: data[0] = PyArray_DATA(ary) return ary cdef inline ndarray oarray_r(object ob, PetscInt* size, PetscReal** data): cdef ndarray ary = oarray(ob, NPY_PETSC_REAL) if size != NULL: size[0] = PyArray_SIZE(ary) if data != NULL: data[0] = PyArray_DATA(ary) return ary cdef inline ndarray oarray_s(object ob, PetscInt* size, PetscScalar** data): cdef ndarray ary = oarray(ob, NPY_PETSC_SCALAR) if size != NULL: size[0] = PyArray_SIZE(ary) if data != NULL: data[0] = PyArray_DATA(ary) return ary cdef inline ndarray oarray_p(object ob, PetscInt* size, void** data): cdef ndarray ary = oarray(ob, NPY_INTP) if size != NULL: size[0] = PyArray_SIZE(ary) if data != NULL: data[0] = PyArray_DATA(ary) return ary # -------------------------------------------------------------------- cdef inline ndarray ocarray_s(object ob, PetscInt* size, PetscScalar** data): cdef ndarray ary = PyArray_FROM_OTF( ob, NPY_PETSC_SCALAR, NPY_ARRAY_CARRAY|NPY_ARRAY_NOTSWAPPED) if size != NULL: size[0] = PyArray_SIZE(ary) if data != NULL: data[0] = PyArray_DATA(ary) return ary cdef inline ndarray ofarray_s(object ob, PetscInt* size, PetscScalar** data): cdef ndarray ary = PyArray_FROM_OTF( ob, NPY_PETSC_SCALAR, NPY_ARRAY_FARRAY|NPY_ARRAY_NOTSWAPPED) if size != NULL: size[0] = PyArray_SIZE(ary) if data != NULL: data[0] = PyArray_DATA(ary) return ary # -------------------------------------------------------------------- ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/src/petsc4py/PETSc/cyclicgc.pxi0000644000175000017500000000523514567251135020156 0ustar00balaybalay# -------------------------------------------------------------------- cdef extern from * nogil: int printf(char *, ...) cdef extern from "Python.h": ctypedef struct PyObject ctypedef struct PyTypeObject ctypedef int visitproc(PyObject *, void *) noexcept ctypedef int traverseproc(PyObject *, visitproc, void *) noexcept ctypedef int inquiry(PyObject *) noexcept ctypedef struct PyTypeObject: char* tp_name traverseproc tp_traverse inquiry tp_clear PyTypeObject *Py_TYPE(PyObject *) cdef extern from "" nogil: PetscErrorCode PetscGarbageCleanup(MPI_Comm) PetscErrorCode PetscGarbageView(MPI_Comm,PetscViewer); cdef int tp_traverse(PyObject *o, visitproc visit, void *arg) noexcept: ## printf("%s.tp_traverse(%p)\n", Py_TYPE(o).tp_name, o) cdef PetscObject p = (o).obj[0] if p == NULL: return 0 cdef PyObject *d = p.python_context if d == NULL: return 0 return visit(d, arg) cdef int tp_clear(PyObject *o) noexcept: ## printf("%s.tp_clear(%p)\n", Py_TYPE(o).tp_name, o) cdef PetscObject *p = (o).obj PetscDEALLOC(p) return 0 cdef inline void TypeEnableGC(PyTypeObject *t) noexcept: ## printf("%s: enforcing GC support\n", t.tp_name) t.tp_traverse = tp_traverse t.tp_clear = tp_clear def garbage_cleanup(comm=None): """Clean up unused PETSc objects. Collective. Notes ----- If the communicator ``comm`` if not provided or it is `None`, then `COMM_WORLD` is used. """ if not (PetscInitializeCalled): return if (PetscFinalizeCalled): return cdef MPI_Comm ccomm = MPI_COMM_NULL if comm is None: ccomm = GetComm(COMM_WORLD, MPI_COMM_NULL) CHKERR( PetscGarbageCleanup(ccomm) ) else: ccomm = GetComm(comm, MPI_COMM_NULL) if ccomm == MPI_COMM_NULL: raise ValueError("null communicator") CHKERR( PetscGarbageCleanup(ccomm) ) def garbage_view(comm=None): """Print summary of the garbage PETSc objects. Collective. Notes ----- Print out garbage summary on each rank of the communicator ``comm``. If no communicator is provided then `COMM_WORLD` is used. """ if not (PetscInitializeCalled): return if (PetscFinalizeCalled): return cdef MPI_Comm ccomm = MPI_COMM_NULL if comm is None: comm = COMM_WORLD ccomm = GetComm(comm, MPI_COMM_NULL) if ccomm == MPI_COMM_NULL: raise ValueError("null communicator") CHKERR( PetscGarbageView(ccomm, NULL) ) # -------------------------------------------------------------------- ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/src/petsc4py/PETSc/dlpack.pxi0000644000175000017500000000443414567251135017634 0ustar00balaybalay# DLPack interface cdef extern from "Python.h": ctypedef void (*PyCapsule_Destructor)(object) bint PyCapsule_IsValid(object, const char*) void* PyCapsule_GetPointer(object, const char*) except? NULL int PyCapsule_SetName(object, const char*) except -1 object PyCapsule_New(void*, const char*, PyCapsule_Destructor) int PyCapsule_CheckExact(object) cdef extern from "" nogil: ctypedef signed long int64_t ctypedef unsigned long long uint64_t ctypedef unsigned char uint8_t ctypedef unsigned short uint16_t void free(void* ptr) void* malloc(size_t size) cdef struct DLDataType: uint8_t code uint8_t bits uint16_t lanes cdef enum PetscDLDeviceType: kDLCPU = 1 kDLCUDA = 2 kDLCUDAHost = 3 #kDLOpenCL = 4 #kDLVulkan = 7 #kDLMetal = 8 #kDLVPI = 9 kDLROCM = 10 kDLROCMHost = 11 #kDLExtDev = 12 kDLCUDAManaged = 13 #kDLOneAPI = 14 ctypedef struct DLContext: PetscDLDeviceType device_type int device_id cdef enum DLDataTypeCode: kDLInt = 0 kDLUInt = 1 kDLFloat = 2 cdef struct DLTensor: void* data DLContext ctx int ndim DLDataType dtype int64_t* shape int64_t* strides uint64_t byte_offset ctypedef int (*dlpack_manager_del_obj)(void*) noexcept nogil cdef struct DLManagedTensor: DLTensor dl_tensor void* manager_ctx void (*manager_deleter)(DLManagedTensor*) noexcept nogil dlpack_manager_del_obj del_obj cdef void pycapsule_deleter(object dltensor) noexcept: cdef DLManagedTensor* dlm_tensor = NULL # we do not call a used capsule's deleter if PyCapsule_IsValid(dltensor, b'dltensor'): dlm_tensor = PyCapsule_GetPointer(dltensor, b'dltensor') manager_deleter(dlm_tensor) cdef void manager_deleter(DLManagedTensor* tensor) noexcept nogil: if tensor.manager_ctx is NULL: return free(tensor.dl_tensor.shape) if tensor.del_obj is not NULL: tensor.del_obj(&tensor.manager_ctx) free(tensor) # -------------------------------------------------------------------- ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/src/petsc4py/PETSc/libpetsc4py.pyx0000644000175000017500000030507314567251135020663 0ustar00balaybalay#cython: cdivision=True #cython: binding=False #cython: auto_pickle=False #cython: autotestdict=False #cython: warn.multiple_declarators=False # -------------------------------------------------------------------- cdef extern from "Python.h": ctypedef struct PyObject void Py_INCREF(PyObject*) void Py_DECREF(PyObject*) void Py_CLEAR(PyObject*) object PyModule_New(const char[]) bint PyModule_Check(object) object PyImport_Import(object) # -------------------------------------------------------------------- cdef extern from * nogil: ctypedef struct _p_PetscOptionItems ctypedef _p_PetscOptionItems* PetscOptionItems PetscErrorCode PetscOptionsString(char[],char[],char[],char[],char[],size_t,PetscBool*) cdef extern from * nogil: # custom.h PetscErrorCode PetscObjectComposedDataRegisterPy(PetscInt*) PetscErrorCode PetscObjectComposedDataGetIntPy(PetscObject,PetscInt,PetscInt*,PetscBool*) PetscErrorCode PetscObjectComposedDataSetIntPy(PetscObject,PetscInt,PetscInt) # -------------------------------------------------------------------- cdef char *FUNCT = NULL cdef char *fstack[1024] cdef int istack = 0 cdef inline void FunctionBegin(char name[]) noexcept nogil: global istack, fstack, FUNCT FUNCT = name fstack[istack] = FUNCT istack += 1 if istack >= 1024: istack = 0 return cdef inline PetscErrorCode FunctionEnd() noexcept nogil: global istack, fstack, FUNCT FUNCT = NULL istack -= 1 if istack < 0: istack = 1024 FUNCT = fstack[istack] return PETSC_SUCCESS cdef PetscErrorCode PetscSETERR(PetscErrorCode ierr,char msg[]) noexcept nogil: global istack, fstack istack = 0 fstack[istack] = NULL; return PetscERROR(PETSC_COMM_SELF,FUNCT,ierr, PETSC_ERROR_INITIAL, msg, NULL) cdef PetscErrorCode UNSUPPORTED(char msg[]) noexcept nogil: return PetscERROR(PETSC_COMM_SELF,FUNCT,PETSC_ERR_USER, PETSC_ERROR_INITIAL,b"method %s()",msg) # -------------------------------------------------------------------- cdef inline PetscInt getRef(void *pobj) noexcept nogil: cdef PetscObject obj = pobj if obj == NULL: return 0 else: return obj.refct cdef inline void addRef(void *pobj) noexcept nogil: cdef PetscObject obj = pobj if obj != NULL: obj.refct += 1 cdef inline void delRef(void *pobj) noexcept nogil: cdef PetscObject obj = pobj if obj != NULL: obj.refct -= 1 cdef inline PetscObject newRef(void *pobj) noexcept nogil: cdef PetscObject obj = pobj cdef int ierr = 0 if obj != NULL: ierr = PetscObjectReference(obj) if ierr: return NULL # XXX warning! return obj cdef inline const char* getPrefix(void *pobj) noexcept nogil: cdef PetscObject obj = pobj if obj == NULL: return NULL return obj.prefix cdef inline int getCommSize(void *pobj) noexcept nogil: cdef PetscObject obj = pobj if obj == NULL: return 0 cdef int size = 0 MPI_Comm_size(obj.comm, &size) return size cdef inline Viewer Viewer_(PetscViewer p): cdef Viewer ob = Viewer.__new__(Viewer) ob.obj[0] = newRef(p) return ob cdef inline IS IS_(PetscIS p): cdef IS ob = IS.__new__(IS) ob.obj[0] = newRef(p) return ob cdef inline Vec Vec_(PetscVec p): cdef Vec ob = Vec.__new__(Vec) ob.obj[0] = newRef(p) return ob cdef inline Mat Mat_(PetscMat p): cdef Mat ob = Mat.__new__(Mat) ob.obj[0] = newRef(p) return ob cdef inline PC PC_(PetscPC p): cdef PC ob = PC.__new__(PC) ob.obj[0] = newRef(p) return ob cdef inline KSP KSP_(PetscKSP p): cdef KSP ob = KSP.__new__(KSP) ob.obj[0] = newRef(p) return ob cdef inline SNES SNES_(PetscSNES p): cdef SNES ob = SNES.__new__(SNES) ob.obj[0] = newRef(p) return ob cdef inline TS TS_(PetscTS p): cdef TS ob = TS.__new__(TS) ob.obj[0] = newRef(p) return ob cdef inline TAO TAO_(PetscTAO p): cdef TAO ob = TAO.__new__(TAO) ob.obj[0] = newRef(p) return ob # -------------------------------------------------------------------- cdef object parse_url(object url): path, name = url.rsplit(":", 1) return (path, name) cdef dict module_cache = {} cdef object load_module(object path): if path in module_cache: return module_cache[path] module = PyModule_New("__petsc__") module.__file__ = path module.__package__ = None module_cache[path] = module try: with open(path, 'r') as source: code = compile(source.read(), path, 'exec') exec(code, module.__dict__) except: del module_cache[path] raise return module # ----------------------------------------------------------------------------- @cython.internal cdef class _PyObj: cdef object self cdef bytes name def __getattr__(self, attr): return getattr(self.self, attr, None) cdef int setcontext(self, void *ctx, Object base) except -1: # if ctx == self.self: return 0 # cdef object destroy = self.destroy if destroy is not None: destroy(base) destroy = None # if ctx == NULL: self.self = None self.name = None return 0 # self.self = ctx self.name = None cdef object create = self.create if create is not None: create(base) create = None return 0 cdef int getcontext(self, void **ctx) except -1: if ctx == NULL: return 0 if self.self is not None: ctx[0] = self.self else: ctx[0] = NULL return 0 cdef int setname(self, char name[]) except -1: if name != NULL and name[0] != 0: self.name = name else: self.name = None return 0 cdef char* getname(self) except? NULL: if self.self is None: return NULL if self.name is not None: return self.name cdef ctx = self.self cdef name = None if PyModule_Check(ctx): name = getattr(ctx, '__name__', None) else: modname = getattr(ctx, '__module__', None) clsname = None cls = getattr(ctx, '__class__', None) if cls: clsname = getattr(cls, '__name__', None) if not modname: modname = getattr(cls, '__module__', None) if modname and clsname: name = modname + '.' + clsname elif clsname: name = clsname elif modname: name = modname if name is not None: self.name = name.encode() if self.name is not None: return self.name return NULL cdef createcontext(char name_p[]): if name_p == NULL: return None cdef name = bytes2str(name_p) cdef mod, path, modname=None cdef cls, attr, clsname=None # path/to/filename.py:{function|class} if ':' in name: path, attr = parse_url(name) mod = load_module(path) if attr: cls = getattr(mod, attr) return cls() else: return mod # package.module[.{function|class}] if '.' in name: modname, clsname = name.rsplit('.', 1) mod = PyImport_Import(modname) if hasattr(mod, clsname): cls = getattr(mod, clsname) if not PyModule_Check(cls): return cls() # package[.module] mod = PyImport_Import(name) return mod cdef int viewcontext(_PyObj ctx, PetscViewer viewer) except -1: cdef PetscBool isascii = PETSC_FALSE, isstring = PETSC_FALSE CHKERR( PetscObjectTypeCompare(viewer, PETSCVIEWERASCII, &isascii) ) CHKERR( PetscObjectTypeCompare(viewer, PETSCVIEWERSTRING, &isstring) ) cdef char *name = ctx.getname() if isascii: if name == NULL: name = b"unknown/no yet set" CHKERR( PetscViewerASCIIPrintf(viewer, b" Python: %s\n", name) ) if isstring: if name == NULL: name = b"" CHKERR( PetscViewerStringSPrintf(viewer, "%s", name) ) return 0 # -------------------------------------------------------------------- cdef extern from * nogil: struct _MatOps: PetscErrorCode (*destroy)(PetscMat) except PETSC_ERR_PYTHON PetscErrorCode (*setfromoptions)(PetscMat,PetscOptionItems*) except PETSC_ERR_PYTHON PetscErrorCode (*view)(PetscMat,PetscViewer) except PETSC_ERR_PYTHON PetscErrorCode (*duplicate)(PetscMat,PetscMatDuplicateOption,PetscMat*) except PETSC_ERR_PYTHON PetscErrorCode (*copy)(PetscMat,PetscMat,PetscMatStructure) except PETSC_ERR_PYTHON PetscErrorCode (*createsubmatrix)(PetscMat,PetscIS,PetscIS,PetscMatReuse,PetscMat*) except PETSC_ERR_PYTHON PetscErrorCode (*setoption)(PetscMat,PetscMatOption,PetscBool) except PETSC_ERR_PYTHON PetscErrorCode (*setup)(PetscMat) except PETSC_ERR_PYTHON PetscErrorCode (*assemblybegin)(PetscMat,PetscMatAssemblyType) except PETSC_ERR_PYTHON PetscErrorCode (*assemblyend)(PetscMat,PetscMatAssemblyType) except PETSC_ERR_PYTHON PetscErrorCode (*zeroentries)(PetscMat) except PETSC_ERR_PYTHON PetscErrorCode (*zerorowscolumns)(PetscMat,PetscInt,PetscInt*,PetscScalar,PetscVec,PetscVec) except PETSC_ERR_PYTHON PetscErrorCode (*scale)(PetscMat,PetscScalar) except PETSC_ERR_PYTHON PetscErrorCode (*shift)(PetscMat,PetscScalar) except PETSC_ERR_PYTHON PetscErrorCode (*sor)(PetscMat,PetscVec,PetscReal,PetscMatSORType,PetscReal,PetscInt,PetscInt,PetscVec) except PETSC_ERR_PYTHON PetscErrorCode (*getvecs)(PetscMat,PetscVec*,PetscVec*) except PETSC_ERR_PYTHON PetscErrorCode (*mult)(PetscMat,PetscVec,PetscVec) except PETSC_ERR_PYTHON PetscErrorCode (*multtranspose)(PetscMat,PetscVec,PetscVec) except PETSC_ERR_PYTHON PetscErrorCode (*multhermitian"multhermitiantranspose")(PetscMat,PetscVec,PetscVec) except PETSC_ERR_PYTHON PetscErrorCode (*multadd)(PetscMat,PetscVec,PetscVec,PetscVec) except PETSC_ERR_PYTHON PetscErrorCode (*multtransposeadd)(PetscMat,PetscVec,PetscVec,PetscVec) except PETSC_ERR_PYTHON PetscErrorCode (*multhermitianadd"multhermitiantransposeadd")(PetscMat,PetscVec,PetscVec,PetscVec) except PETSC_ERR_PYTHON PetscErrorCode (*multdiagonalblock)(PetscMat,PetscVec,PetscVec) except PETSC_ERR_PYTHON PetscErrorCode (*solve)(PetscMat,PetscVec,PetscVec) except PETSC_ERR_PYTHON PetscErrorCode (*solvetranspose)(PetscMat,PetscVec,PetscVec) except PETSC_ERR_PYTHON PetscErrorCode (*solveadd)(PetscMat,PetscVec,PetscVec,PetscVec) except PETSC_ERR_PYTHON PetscErrorCode (*solvetransposeadd)(PetscMat,PetscVec,PetscVec,PetscVec) except PETSC_ERR_PYTHON PetscErrorCode (*getdiagonal)(PetscMat,PetscVec) except PETSC_ERR_PYTHON PetscErrorCode (*setdiagonal"diagonalset")(PetscMat,PetscVec,PetscInsertMode) except PETSC_ERR_PYTHON PetscErrorCode (*diagonalscale)(PetscMat,PetscVec,PetscVec) except PETSC_ERR_PYTHON PetscErrorCode (*missingdiagonal)(PetscMat,PetscBool*,PetscInt*) except PETSC_ERR_PYTHON PetscErrorCode (*norm)(PetscMat,PetscNormType,PetscReal*) except PETSC_ERR_PYTHON PetscErrorCode (*realpart)(PetscMat) except PETSC_ERR_PYTHON PetscErrorCode (*imagpart"imaginarypart")(PetscMat) except PETSC_ERR_PYTHON PetscErrorCode (*conjugate)(PetscMat) except PETSC_ERR_PYTHON PetscErrorCode (*getdiagonalblock)(PetscMat,PetscMat*) except PETSC_ERR_PYTHON PetscErrorCode (*productsetfromoptions)(PetscMat) except PETSC_ERR_PYTHON PetscErrorCode (*productsymbolic)(PetscMat) except PETSC_ERR_PYTHON PetscErrorCode (*productnumeric)(PetscMat) except PETSC_ERR_PYTHON PetscErrorCode (*hasoperation)(PetscMat,PetscMatOperation,PetscBool*) except PETSC_ERR_PYTHON ctypedef _MatOps *MatOps ctypedef struct Mat_Product: void *data struct _p_Mat: void *data MatOps ops PetscBool assembled PetscBool preallocated PetscLayout rmap, cmap Mat_Product *product @cython.internal cdef class _PyMat(_PyObj): pass cdef inline _PyMat PyMat(PetscMat mat): if mat != NULL and mat.data != NULL: return <_PyMat>mat.data else: return _PyMat.__new__(_PyMat) cdef public PetscErrorCode MatPythonGetContext(PetscMat mat, void **ctx) \ except PETSC_ERR_PYTHON: FunctionBegin(b"MatPythonGetContext") PyMat(mat).getcontext(ctx) return FunctionEnd() cdef public PetscErrorCode MatPythonSetContext(PetscMat mat, void *ctx) \ except PETSC_ERR_PYTHON: FunctionBegin(b"MatPythonSetContext") PyMat(mat).setcontext(ctx, Mat_(mat)) return FunctionEnd() cdef PetscErrorCode MatPythonSetType_PYTHON(PetscMat mat, char name[]) \ except PETSC_ERR_PYTHON with gil: FunctionBegin(b"MatPythonSetType_PYTHON") if name == NULL: return FunctionEnd() # XXX cdef object ctx = createcontext(name) MatPythonSetContext(mat, ctx) PyMat(mat).setname(name) return FunctionEnd() cdef PetscErrorCode MatPythonGetType_PYTHON(PetscMat mat, const char *name[]) \ except PETSC_ERR_PYTHON with gil: FunctionBegin(b"MatPythonGetType_PYTHON") name[0] = PyMat(mat).getname() return FunctionEnd() #FIXME: view and setFromOptions? cdef dict dMatOps = { 3 : 'mult', 4 : 'multAdd', 5 : 'multTranspose', 6 : 'multTransposeAdd', 7 : 'solve', 8 : 'solveAdd', 9 : 'solveTranspose', 10 : 'solveTransposeAdd', 13 : 'SOR', 17 : 'getDiagonal', 18 : 'diagonalScale', 19 : 'norm', 23 : 'zeroEntries', 32 : 'getDiagonalBlock', 34 : 'duplicate', 43 : 'copy', 45 : 'scale', 46 : 'shift', 47 : 'setDiagonal', 48 : 'zeroRowsColumns', 59 : 'createSubMatrix', 88 : 'getVecs', #FIXME -> createVecs 102 : 'conjugate', 105 : 'realPart', 106 : 'imagPart', 113 : 'missingDiagonal', 119 : 'multDiagonalBlock', 121 : 'multHermitian', 122 : 'multHermitianAdd', } cdef PetscErrorCode MatCreate_Python( PetscMat mat, ) \ except PETSC_ERR_PYTHON with gil: FunctionBegin(b"MatCreate_Python") # cdef MatOps ops = mat.ops ops.destroy = MatDestroy_Python ops.setfromoptions = MatSetFromOptions_Python ops.view = MatView_Python ops.duplicate = MatDuplicate_Python ops.copy = MatCopy_Python ops.createsubmatrix = MatCreateSubMatrix_Python ops.setoption = MatSetOption_Python ops.setup = MatSetUp_Python ops.assemblybegin = MatAssemblyBegin_Python ops.assemblyend = MatAssemblyEnd_Python ops.zeroentries = MatZeroEntries_Python ops.zerorowscolumns = MatZeroRowsColumns_Python ops.scale = MatScale_Python ops.shift = MatShift_Python ops.getvecs = MatCreateVecs_Python ops.mult = MatMult_Python ops.sor = MatSOR_Python ops.multtranspose = MatMultTranspose_Python ops.multhermitian = MatMultHermitian_Python ops.multadd = MatMultAdd_Python ops.multtransposeadd = MatMultTransposeAdd_Python ops.multhermitianadd = MatMultHermitianAdd_Python ops.multdiagonalblock = MatMultDiagonalBlock_Python ops.solve = MatSolve_Python ops.solvetranspose = MatSolveTranspose_Python ops.solveadd = MatSolveAdd_Python ops.solvetransposeadd = MatSolveTransposeAdd_Python ops.getdiagonal = MatGetDiagonal_Python ops.setdiagonal = MatSetDiagonal_Python ops.diagonalscale = MatDiagonalScale_Python ops.missingdiagonal = MatMissingDiagonal_Python ops.norm = MatNorm_Python ops.realpart = MatRealPart_Python ops.imagpart = MatImagPart_Python ops.conjugate = MatConjugate_Python ops.hasoperation = MatHasOperation_Python ops.getdiagonalblock = MatGetDiagonalBlock_Python ops.productsetfromoptions = MatProductSetFromOptions_Python # mat.assembled = PETSC_TRUE # XXX mat.preallocated = PETSC_FALSE # XXX # CHKERR( PetscObjectComposeFunction( mat, b"MatPythonSetType_C", MatPythonSetType_PYTHON) ) CHKERR( PetscObjectComposeFunction( mat, b"MatPythonGetType_C", MatPythonGetType_PYTHON) ) CHKERR( PetscObjectComposeFunction( mat, b"MatProductSetFromOptions_anytype_C", MatProductSetFromOptions_Python) ) CHKERR( PetscObjectChangeTypeName( mat, MATPYTHON) ) # cdef ctx = PyMat(NULL) mat.data = ctx Py_INCREF(mat.data) return FunctionEnd() cdef inline PetscErrorCode MatDestroy_Python_inner( PetscMat mat, ) \ except PETSC_ERR_PYTHON with gil: try: addRef(mat) MatPythonSetContext(mat, NULL) finally: delRef(mat) Py_DECREF(mat.data) mat.data = NULL return PETSC_SUCCESS cdef PetscErrorCode MatDestroy_Python( PetscMat mat, ) \ except PETSC_ERR_PYTHON nogil: FunctionBegin(b"MatDestroy_Python") CHKERR( PetscObjectComposeFunction( mat, b"MatPythonSetType_C", NULL) ) CHKERR( PetscObjectComposeFunction( mat, b"MatPythonGetType_C", NULL) ) CHKERR( PetscObjectComposeFunction( mat, b"MatProductSetFromOptions_anytype_C", NULL) ) CHKERR( PetscObjectChangeTypeName( mat, NULL) ) if Py_IsInitialized(): MatDestroy_Python_inner(mat) return FunctionEnd() cdef PetscErrorCode MatSetFromOptions_Python( PetscMat mat, PetscOptionItems *PetscOptionsObject, ) \ except PETSC_ERR_PYTHON with gil: FunctionBegin(b"MatSetFromOptions_Python") # cdef char name[2048], *defval = PyMat(mat).getname() cdef PetscBool found = PETSC_FALSE cdef PetscOptionItems *opts "PetscOptionsObject" = PetscOptionsObject CHKERR( PetscOptionsString( b"-mat_python_type", b"Python [package.]module[.{class|function}]", b"MatPythonSetType", defval, name, sizeof(name), &found) ); opts; if found and name[0]: CHKERR( MatPythonSetType_PYTHON(mat, name) ) # cdef setFromOptions = PyMat(mat).setFromOptions if setFromOptions is not None: setFromOptions(Mat_(mat)) return FunctionEnd() cdef PetscErrorCode MatView_Python( PetscMat mat, PetscViewer vwr, ) \ except PETSC_ERR_PYTHON with gil: FunctionBegin(b"MatView_Python") viewcontext(PyMat(mat), vwr) cdef view = PyMat(mat).view if view is not None: view(Mat_(mat), Viewer_(vwr)) return FunctionEnd() cdef PetscErrorCode MatDuplicate_Python( PetscMat mat, PetscMatDuplicateOption op, PetscMat* out, ) \ except PETSC_ERR_PYTHON with gil: FunctionBegin(b"MatDuplicate_Python") cdef duplicate = PyMat(mat).duplicate if duplicate is None: return UNSUPPORTED(b"duplicate") cdef Mat m = duplicate(Mat_(mat), op) out[0] = m.mat; m.mat = NULL return FunctionEnd() cdef PetscErrorCode MatCopy_Python( PetscMat mat, PetscMat out, PetscMatStructure op, ) \ except PETSC_ERR_PYTHON with gil: FunctionBegin(b"MatCopy_Python") cdef copy = PyMat(mat).copy if copy is None: return UNSUPPORTED(b"copy") copy(Mat_(mat), Mat_(out), op) return FunctionEnd() cdef PetscErrorCode MatGetDiagonalBlock_Python( PetscMat mat, PetscMat *out ) \ except PETSC_ERR_PYTHON with gil: FunctionBegin(b"MatGetDiagonalBlock_Python") cdef getDiagonalBlock = PyMat(mat).getDiagonalBlock if getDiagonalBlock is None: try: mat.ops.getdiagonalblock = NULL CHKERR( MatGetDiagonalBlock(mat, out) ) finally: mat.ops.getdiagonalblock = MatGetDiagonalBlock_Python return FunctionEnd() cdef Mat sub = getDiagonalBlock(Mat_(mat)) if sub is not None: out[0] = sub.mat return FunctionEnd() cdef PetscErrorCode MatCreateSubMatrix_Python( PetscMat mat, PetscIS row, PetscIS col, PetscMatReuse op, PetscMat *out, ) \ except PETSC_ERR_PYTHON with gil: FunctionBegin(b"MatCreateSubMatrix_Python") cdef createSubMatrix = PyMat(mat).createSubMatrix if createSubMatrix is None: try: mat.ops.createsubmatrix = NULL CHKERR( MatCreateSubMatrix(mat, row, col, op, out) ) finally: mat.ops.createsubmatrix = MatCreateSubMatrix_Python return FunctionEnd() cdef Mat sub = None if op == MAT_IGNORE_MATRIX: sub = None elif op == MAT_INITIAL_MATRIX: sub = createSubMatrix(Mat_(mat), IS_(row), IS_(col), None) if sub is not None: addRef(sub.mat) elif op == MAT_REUSE_MATRIX: sub = createSubMatrix(Mat_(mat), IS_(row), IS_(col), Mat_(out[0])) if sub is not None: out[0] = sub.mat return FunctionEnd() cdef PetscErrorCode MatSetOption_Python( PetscMat mat, PetscMatOption op, PetscBool flag, ) \ except PETSC_ERR_PYTHON with gil: FunctionBegin(b"MatSetOption_Python") cdef setOption = PyMat(mat).setOption if setOption is not None: setOption(Mat_(mat), op, (flag)) return FunctionEnd() cdef PetscErrorCode MatSetUp_Python( PetscMat mat, ) \ except PETSC_ERR_PYTHON with gil: FunctionBegin(b"MatSetUp_Python") cdef PetscInt rbs = -1, cbs = -1 CHKERR( PetscLayoutGetBlockSize(mat.rmap, &rbs) ) CHKERR( PetscLayoutGetBlockSize(mat.cmap, &cbs) ) if rbs == -1: rbs = 1 if cbs == -1: cbs = rbs CHKERR( PetscLayoutSetBlockSize(mat.rmap, rbs) ) CHKERR( PetscLayoutSetBlockSize(mat.cmap, cbs) ) CHKERR( PetscLayoutSetUp(mat.rmap) ) CHKERR( PetscLayoutSetUp(mat.cmap) ) mat.preallocated = PETSC_TRUE # cdef char name[2048] cdef PetscBool found = PETSC_FALSE if PyMat(mat).self is None: CHKERR( PetscOptionsGetString(NULL, getPrefix(mat), b"-mat_python_type", name, sizeof(name), &found) ) if found and name[0]: CHKERR( MatPythonSetType_PYTHON(mat, name) ) if PyMat(mat).self is None: return PetscSETERR(PETSC_ERR_USER, "Python context not set, call one of \n" " * MatPythonSetType(mat, \"[package.]module.class\")\n" " * MatSetFromOptions(mat) and pass option " "-mat_python_type [package.]module.class") # cdef setUp = PyMat(mat).setUp if setUp is not None: setUp(Mat_(mat)) return FunctionEnd() cdef PetscErrorCode MatAssemblyBegin_Python( PetscMat mat, PetscMatAssemblyType at, ) \ except PETSC_ERR_PYTHON with gil: FunctionBegin(b"MatAssemblyBegin_Python") cdef assembly = PyMat(mat).assemblyBegin if assembly is not None: assembly(Mat_(mat), at) return FunctionEnd() cdef PetscErrorCode MatAssemblyEnd_Python( PetscMat mat, PetscMatAssemblyType at, ) \ except PETSC_ERR_PYTHON with gil: FunctionBegin(b"MatAssemblyEnd_Python") cdef assembly = PyMat(mat).assemblyEnd if assembly is None: assembly = PyMat(mat).assembly if assembly is not None: assembly(Mat_(mat), at) return FunctionEnd() cdef PetscErrorCode MatZeroEntries_Python( PetscMat mat, ) \ except PETSC_ERR_PYTHON with gil: FunctionBegin(b"MatZeroEntries_Python") cdef zeroEntries = PyMat(mat).zeroEntries if zeroEntries is None: return UNSUPPORTED(b"zeroEntries") zeroEntries(Mat_(mat)) return FunctionEnd() cdef PetscErrorCode MatZeroRowsColumns_Python( PetscMat mat, PetscInt numRows, const PetscInt* rows, PetscScalar diag, PetscVec x, PetscVec b, ) \ except PETSC_ERR_PYTHON with gil: FunctionBegin(b"MatZeroRowsColumns_Python") cdef zeroRowsColumns = PyMat(mat).zeroRowsColumns if zeroRowsColumns is None: return UNSUPPORTED(b"zeroRowsColumns") cdef ndarray pyrows = array_i(numRows, rows) zeroRowsColumns(Mat_(mat), pyrows, toScalar(diag), Vec_(x), Vec_(b)) return FunctionEnd() cdef PetscErrorCode MatScale_Python( PetscMat mat, PetscScalar s, ) \ except PETSC_ERR_PYTHON with gil: FunctionBegin(b"MatScale_Python") cdef scale = PyMat(mat).scale if scale is None: return UNSUPPORTED(b"scale") scale(Mat_(mat), toScalar(s)) return FunctionEnd() cdef PetscErrorCode MatShift_Python( PetscMat mat, PetscScalar s, ) \ except PETSC_ERR_PYTHON with gil: FunctionBegin(b"MatShift_Python") cdef shift = PyMat(mat).shift if shift is None: return UNSUPPORTED(b"shift") shift(Mat_(mat), toScalar(s)) return FunctionEnd() cdef PetscErrorCode MatCreateVecs_Python( PetscMat mat, PetscVec *x, PetscVec *y, ) \ except PETSC_ERR_PYTHON with gil: FunctionBegin(b"MatCreateVecs_Python") cdef createVecs = PyMat(mat).createVecs if createVecs is None: try: mat.ops.getvecs = NULL CHKERR( MatCreateVecs(mat, x, y) ) finally: mat.ops.getvecs = MatCreateVecs_Python return FunctionEnd() cdef Vec u, v u, v = createVecs(Mat_(mat)) if x != NULL: x[0] = u.vec u.vec = NULL if y != NULL: y[0] = v.vec v.vec = NULL return FunctionEnd() cdef PetscErrorCode MatMult_Python( PetscMat mat, PetscVec x, PetscVec y, ) \ except PETSC_ERR_PYTHON with gil: FunctionBegin(b"MatMult_Python") cdef mult = PyMat(mat).mult if mult is None: return UNSUPPORTED(b"mult") mult(Mat_(mat), Vec_(x), Vec_(y)) return FunctionEnd() cdef PetscErrorCode MatMultTranspose_Python( PetscMat mat, PetscVec x, PetscVec y, ) \ except PETSC_ERR_PYTHON with gil: FunctionBegin(b"MatMultTranspose_Python") cdef multTranspose = PyMat(mat).multTranspose if multTranspose is None: try: mat.ops.multtranspose = NULL CHKERR( MatMultTranspose(mat, x, y) ) finally: mat.ops.multtranspose = MatMultTranspose_Python return FunctionEnd() multTranspose(Mat_(mat), Vec_(x), Vec_(y)) return FunctionEnd() cdef PetscErrorCode MatMultHermitian_Python( PetscMat mat, PetscVec x, PetscVec y, ) \ except PETSC_ERR_PYTHON with gil: FunctionBegin(b"MatMultHermitian_Python") cdef multHermitian = PyMat(mat).multHermitian if multHermitian is None: try: mat.ops.multhermitian = NULL CHKERR( MatMultHermitian(mat, x, y) ) finally: mat.ops.multhermitian = MatMultHermitian_Python return FunctionEnd() multHermitian(Mat_(mat), Vec_(x), Vec_(y)) return FunctionEnd() cdef PetscErrorCode MatMultAdd_Python( PetscMat mat, PetscVec x, PetscVec v, PetscVec y, ) \ except PETSC_ERR_PYTHON with gil: FunctionBegin(b"MatMultAdd_Python") cdef multAdd = PyMat(mat).multAdd cdef PetscVec t = NULL if multAdd is None: if v == y: CHKERR( VecDuplicate(y, &t) ) CHKERR( MatMult(mat, x, t) ) CHKERR( VecAXPY(y, 1.0, t) ) CHKERR( VecDestroy(&t) ) else: CHKERR( MatMult(mat, x, y) ) CHKERR( VecAXPY(y, 1.0, v) ) return FunctionEnd() if multAdd is None: return UNSUPPORTED(b"multAdd") multAdd(Mat_(mat), Vec_(x), Vec_(v), Vec_(y)) return FunctionEnd() cdef PetscErrorCode MatMultTransposeAdd_Python( PetscMat mat, PetscVec x, PetscVec v, PetscVec y, ) \ except PETSC_ERR_PYTHON with gil: FunctionBegin(b"MatMultTransposeAdd_Python") cdef multTransposeAdd = PyMat(mat).multTransposeAdd cdef PetscVec t = NULL if multTransposeAdd is None: if v == y: CHKERR( VecDuplicate(y, &t) ) CHKERR( MatMultTranspose(mat, x, t) ) CHKERR( VecAXPY(y, 1.0, t) ) CHKERR( VecDestroy(&t) ) else: CHKERR( MatMultTranspose(mat, x, y) ) CHKERR( VecAXPY(y, 1.0, v) ) return FunctionEnd() if multTransposeAdd is None: return UNSUPPORTED(b"multTransposeAdd") multTransposeAdd(Mat_(mat), Vec_(x), Vec_(v), Vec_(y)) return FunctionEnd() cdef PetscErrorCode MatMultHermitianAdd_Python( PetscMat mat, PetscVec x, PetscVec v, PetscVec y, ) \ except PETSC_ERR_PYTHON with gil: FunctionBegin(b"MatMultHermitianAdd_Python") cdef multHermitianAdd = PyMat(mat).multHermitianAdd if multHermitianAdd is None: try: mat.ops.multhermitianadd = NULL CHKERR( MatMultHermitianAdd(mat, x, v, y) ) finally: mat.ops.multhermitianadd = MatMultHermitianAdd_Python return FunctionEnd() multHermitianAdd(Mat_(mat), Vec_(x), Vec_(v), Vec_(y)) return FunctionEnd() cdef PetscErrorCode MatMultDiagonalBlock_Python( PetscMat mat, PetscVec x, PetscVec y, ) \ except PETSC_ERR_PYTHON with gil: FunctionBegin(b"MatMultDiagonalBlock_Python") cdef multDiagonalBlock = PyMat(mat).multDiagonalBlock if multDiagonalBlock is None: return UNSUPPORTED(b"multDiagonalBlock") multDiagonalBlock(Mat_(mat), Vec_(x), Vec_(y)) return FunctionEnd() cdef PetscErrorCode MatSolve_Python( PetscMat mat, PetscVec b, PetscVec x, ) \ except PETSC_ERR_PYTHON with gil: FunctionBegin(b"MatSolve_Python") cdef solve = PyMat(mat).solve if solve is None: return UNSUPPORTED(b"solve") solve(Mat_(mat), Vec_(b), Vec_(x)) return FunctionEnd() cdef PetscErrorCode MatSolveTranspose_Python( PetscMat mat, PetscVec b, PetscVec x, ) \ except PETSC_ERR_PYTHON with gil: FunctionBegin(b"MatSolveTranspose_Python") cdef solveTranspose = PyMat(mat).solveTranspose if solveTranspose is None: try: mat.ops.solvetranspose = NULL CHKERR( MatSolveTranspose(mat, b, x) ) finally: mat.ops.solvetranspose = MatSolveTranspose_Python solveTranspose(Mat_(mat), Vec_(b), Vec_(x)) return FunctionEnd() cdef PetscErrorCode MatSolveAdd_Python( PetscMat mat, PetscVec b, PetscVec y, PetscVec x, ) \ except PETSC_ERR_PYTHON with gil: FunctionBegin(b"MatSolveAdd_Python") cdef solveAdd = PyMat(mat).solveAdd if solveAdd is None: try: mat.ops.solveadd = NULL CHKERR( MatSolveAdd(mat, b, y, x) ) finally: mat.ops.solveadd = MatSolveAdd_Python return FunctionEnd() solveAdd(Mat_(mat), Vec_(b), Vec_(y), Vec_(x)) return FunctionEnd() cdef PetscErrorCode MatSolveTransposeAdd_Python( PetscMat mat, PetscVec b, PetscVec y, PetscVec x, ) \ except PETSC_ERR_PYTHON with gil: FunctionBegin(b"MatSolveTransposeAdd_Python") cdef solveTransposeAdd = PyMat(mat).solveTransposeAdd if solveTransposeAdd is None: try: mat.ops.solvetransposeadd = NULL CHKERR( MatSolveTransposeAdd(mat, b, y, x) ) finally: mat.ops.solvetransposeadd = MatSolveTransposeAdd_Python return FunctionEnd() solveTransposeAdd(Mat_(mat), Vec_(b), Vec_(y), Vec_(x)) return FunctionEnd() cdef PetscErrorCode MatSOR_Python( PetscMat mat, PetscVec b, PetscReal omega, PetscMatSORType sortype, PetscReal shift, PetscInt its, PetscInt lits, PetscVec x )\ except PETSC_ERR_PYTHON with gil: FunctionBegin(b"MatSOR_Python") cdef SOR = PyMat(mat).SOR if SOR is None: return UNSUPPORTED(b"SOR") SOR(Mat_(mat), Vec_(b), asReal(omega), asInt(sortype), asReal(shift), asInt(its), asInt(lits), Vec_(x)) return FunctionEnd() cdef PetscErrorCode MatGetDiagonal_Python( PetscMat mat, PetscVec v, ) \ except PETSC_ERR_PYTHON with gil: FunctionBegin(b"MatGetDiagonal_Python") cdef getDiagonal = PyMat(mat).getDiagonal if getDiagonal is None: return UNSUPPORTED(b"getDiagonal") getDiagonal(Mat_(mat), Vec_(v)) return FunctionEnd() cdef PetscErrorCode MatSetDiagonal_Python( PetscMat mat, PetscVec v, PetscInsertMode im, ) \ except PETSC_ERR_PYTHON with gil: FunctionBegin(b"MatSetDiagonal_Python") cdef setDiagonal = PyMat(mat).setDiagonal cdef bint addv = True if im == PETSC_ADD_VALUES else False if setDiagonal is None: return UNSUPPORTED(b"setDiagonal") setDiagonal(Mat_(mat), Vec_(v), addv) return FunctionEnd() cdef PetscErrorCode MatDiagonalScale_Python( PetscMat mat, PetscVec l, PetscVec r, ) \ except PETSC_ERR_PYTHON with gil: FunctionBegin(b"MatDiagonalScale_Python") cdef diagonalScale = PyMat(mat).diagonalScale if diagonalScale is None: return UNSUPPORTED(b"diagonalScale") diagonalScale(Mat_(mat), Vec_(l), Vec_(r)) return FunctionEnd() cdef PetscErrorCode MatMissingDiagonal_Python( PetscMat mat, PetscBool *missing, PetscInt *loc ) \ except PETSC_ERR_PYTHON with gil: FunctionBegin(b"MatMissingDiagonal_Python") cdef missingDiagonal = PyMat(mat).missingDiagonal if missingDiagonal is None: return UNSUPPORTED(b"missingDiagonal") pymissing, pyloc = missingDiagonal(Mat_(mat)) missing[0] = pymissing if loc: loc[0] = asInt(pyloc) return FunctionEnd() cdef PetscErrorCode MatNorm_Python( PetscMat mat, PetscNormType ntype, PetscReal *nrm, ) \ except PETSC_ERR_PYTHON with gil: FunctionBegin(b"MatNorm_Python") cdef norm = PyMat(mat).norm if norm is None: return UNSUPPORTED(b"norm") retval = norm(Mat_(mat), ntype) nrm[0] = retval return FunctionEnd() cdef PetscErrorCode MatRealPart_Python( PetscMat mat, ) \ except PETSC_ERR_PYTHON with gil: FunctionBegin(b"MatRealPart_Python") cdef realPart = PyMat(mat).realPart if realPart is None: return UNSUPPORTED(b"realPart") realPart(Mat_(mat)) return FunctionEnd() cdef PetscErrorCode MatImagPart_Python( PetscMat mat, ) \ except PETSC_ERR_PYTHON with gil: FunctionBegin(b"MatImagPart_Python") cdef imagPart = PyMat(mat).imagPart if imagPart is None: return UNSUPPORTED(b"imagPart") imagPart(Mat_(mat)) return FunctionEnd() cdef PetscErrorCode MatConjugate_Python( PetscMat mat, ) \ except PETSC_ERR_PYTHON with gil: FunctionBegin(b"MatConjugate_Python") cdef conjugate = PyMat(mat).conjugate if conjugate is None: return UNSUPPORTED(b"conjugate") conjugate(Mat_(mat)) return FunctionEnd() cdef PetscErrorCode MatHasOperation_Python( PetscMat mat, PetscMatOperation op, PetscBool *flag ) \ except PETSC_ERR_PYTHON with gil: FunctionBegin(b"MatHasOperation_Python") flag[0] = PETSC_FALSE cdef long i = op global dMatOps name = dMatOps.get(i, None) cdef void** ops = NULL if name is None: ops = mat.ops if ops and ops[i]: flag[0] = PETSC_TRUE else: flag[0] = PETSC_TRUE if getattr(PyMat(mat), name) is not None else PETSC_FALSE return FunctionEnd() cdef PetscErrorCode MatProductNumeric_Python( PetscMat mat ) \ except PETSC_ERR_PYTHON with gil: FunctionBegin(b"MatProductNumeric_Python") cdef PetscMat A = NULL cdef PetscMat B = NULL cdef PetscMat C = NULL cdef PetscMatProductType mtype = MATPRODUCT_UNSPECIFIED CHKERR( MatProductGetMats(mat, &A, &B, &C) ) CHKERR( MatProductGetType(mat, &mtype) ) mtypes = {MATPRODUCT_AB : 'AB', MATPRODUCT_ABt : 'ABt', MATPRODUCT_AtB : 'AtB', MATPRODUCT_PtAP : 'PtAP', MATPRODUCT_RARt: 'RARt', MATPRODUCT_ABC: 'ABC'} cdef Mat_Product *product = mat.product cdef PetscInt i = product.data if i < 0 or i > 2: return PetscSETERR(PETSC_ERR_PLIB, "Corrupted composed id") cdef PetscMat pM = C if i == 2 else B if i == 1 else A cdef Mat PyA = Mat_(A) cdef Mat PyB = Mat_(B) cdef Mat PyC = Mat_(C) if mtype == MATPRODUCT_ABC: mats = (PyA, PyB, PyC) else: mats = (PyA, PyB, None) cdef productNumeric = PyMat(pM).productNumeric if productNumeric is None: return UNSUPPORTED(b"productNumeric") productNumeric(PyC if C == pM else PyB if B == pM else PyA, Mat_(mat), mtypes[mtype], *mats) return FunctionEnd() cdef PetscInt matmatid = -1 cdef PetscErrorCode MatProductSymbolic_Python( PetscMat mat ) \ except PETSC_ERR_PYTHON with gil: FunctionBegin(b"MatProductSymbolic_Python") cdef PetscMat A = NULL cdef PetscMat B = NULL cdef PetscMat C = NULL cdef PetscMatProductType mtype = MATPRODUCT_UNSPECIFIED CHKERR( MatProductGetMats(mat, &A, &B, &C) ) CHKERR( MatProductGetType(mat, &mtype) ) mtypes = {MATPRODUCT_AB : 'AB', MATPRODUCT_ABt : 'ABt', MATPRODUCT_AtB : 'AtB', MATPRODUCT_PtAP : 'PtAP', MATPRODUCT_RARt: 'RARt', MATPRODUCT_ABC: 'ABC'} global matmatid cdef PetscInt i = -1 cdef PetscBool flg = PETSC_FALSE CHKERR( PetscObjectComposedDataGetIntPy(mat, matmatid, &i, &flg) ) if flg is not PETSC_TRUE: return PetscSETERR(PETSC_ERR_PLIB, "Missing composed id") if i < 0 or i > 2: return PetscSETERR(PETSC_ERR_PLIB, "Corrupted composed id") cdef PetscMat pM = C if i == 2 else B if i == 1 else A cdef Mat PyA = Mat_(A) cdef Mat PyB = Mat_(B) cdef Mat PyC = Mat_(C) if mtype == MATPRODUCT_ABC: mats = (PyA, PyB, PyC) else: mats = (PyA, PyB, None) cdef productSymbolic = PyMat(pM).productSymbolic if productSymbolic is None: return UNSUPPORTED(b"productSymbolic") productSymbolic(PyC if C == pM else PyB if B == pM else PyA, Mat_(mat), mtypes[mtype], *mats) # Store id in matrix product cdef Mat_Product *product = mat.product product.data = i cdef MatOps ops = mat.ops ops.productnumeric = MatProductNumeric_Python return FunctionEnd() cdef PetscErrorCode MatProductSetFromOptions_Python( PetscMat mat ) \ except PETSC_ERR_PYTHON with gil: FunctionBegin(b"MatProductSetFromOptions_Python") cdef PetscMat A = NULL cdef PetscMat B = NULL cdef PetscMat C = NULL CHKERR( MatProductGetMats(mat, &A, &B, &C) ) if A == NULL or B == NULL: return PetscSETERR(PETSC_ERR_PLIB, "Missing matrices") cdef PetscMatProductType mtype = MATPRODUCT_UNSPECIFIED CHKERR( MatProductGetType(mat, &mtype) ) if mtype == MATPRODUCT_UNSPECIFIED: return PetscSETERR(PETSC_ERR_PLIB, "Unknown product type") mtypes = {MATPRODUCT_AB : 'AB', MATPRODUCT_ABt : 'ABt', MATPRODUCT_AtB : 'AtB', MATPRODUCT_PtAP : 'PtAP', MATPRODUCT_RARt: 'RARt', MATPRODUCT_ABC: 'ABC'} cdef Mat PyA = Mat_(A) cdef Mat PyB = Mat_(B) cdef Mat PyC = Mat_(C) if mtype == MATPRODUCT_ABC: mats = (PyA, PyB, PyC) else: mats = (PyA, PyB, None) # Find Python matrix in mats able to perform the product found = False cdef PetscBool mispy = PETSC_FALSE cdef PetscMat pM = NULL cdef Mat mm cdef PetscInt i = -1 for i in range(len(mats)): if mats[i] is None: continue mm = mats[i] pM = mm.mat CHKERR( PetscObjectTypeCompare(pM, MATPYTHON, &mispy) ) if mispy: if PyMat(pM).productSetFromOptions is not None: found = PyMat(pM).productSetFromOptions(PyC if C == pM else PyB if B == pM else PyA, mtypes[mtype], *mats) if found: break if not found: return FunctionEnd() cdef MatOps ops = mat.ops ops.productsymbolic = MatProductSymbolic_Python # Store index (within the product) of the Python matrix which is capable of performing the operation # Cannot be stored in mat.product.data at this stage # Symbolic operation will get this index and store it in the product data global matmatid if matmatid < 0: CHKERR( PetscObjectComposedDataRegisterPy(&matmatid) ) CHKERR( PetscObjectComposedDataSetIntPy(mat, matmatid, i) ) return FunctionEnd() # -------------------------------------------------------------------- cdef extern from * nogil: struct _PCOps: PetscErrorCode (*destroy)(PetscPC) except PETSC_ERR_PYTHON PetscErrorCode (*setup)(PetscPC) except PETSC_ERR_PYTHON PetscErrorCode (*reset)(PetscPC) except PETSC_ERR_PYTHON PetscErrorCode (*setfromoptions)(PetscPC,PetscOptionItems*) except PETSC_ERR_PYTHON PetscErrorCode (*view)(PetscPC,PetscViewer) except PETSC_ERR_PYTHON PetscErrorCode (*presolve)(PetscPC,PetscKSP,PetscVec,PetscVec) except PETSC_ERR_PYTHON PetscErrorCode (*postsolve)(PetscPC,PetscKSP,PetscVec,PetscVec) except PETSC_ERR_PYTHON PetscErrorCode (*apply)(PetscPC,PetscVec,PetscVec) except PETSC_ERR_PYTHON PetscErrorCode (*matapply)(PetscPC,PetscMat,PetscMat) except PETSC_ERR_PYTHON PetscErrorCode (*applytranspose)(PetscPC,PetscVec,PetscVec) except PETSC_ERR_PYTHON PetscErrorCode (*applysymmetricleft)(PetscPC,PetscVec,PetscVec) except PETSC_ERR_PYTHON PetscErrorCode (*applysymmetricright)(PetscPC,PetscVec,PetscVec) except PETSC_ERR_PYTHON ctypedef _PCOps *PCOps struct _p_PC: void *data PCOps ops @cython.internal cdef class _PyPC(_PyObj): pass cdef inline _PyPC PyPC(PetscPC pc): if pc != NULL and pc.data != NULL: return <_PyPC>pc.data else: return _PyPC.__new__(_PyPC) cdef public PetscErrorCode PCPythonGetContext(PetscPC pc, void **ctx) \ except PETSC_ERR_PYTHON: FunctionBegin(b"PCPythonGetContext") PyPC(pc).getcontext(ctx) return FunctionEnd() cdef public PetscErrorCode PCPythonSetContext(PetscPC pc, void *ctx) \ except PETSC_ERR_PYTHON: FunctionBegin(b"PCPythonSetContext") PyPC(pc).setcontext(ctx, PC_(pc)) return FunctionEnd() cdef PetscErrorCode PCPythonSetType_PYTHON(PetscPC pc, char name[]) \ except PETSC_ERR_PYTHON with gil: FunctionBegin(b"PCPythonSetType_PYTHON") if name == NULL: return FunctionEnd() # XXX cdef object ctx = createcontext(name) PCPythonSetContext(pc, ctx) PyPC(pc).setname(name) return FunctionEnd() cdef PetscErrorCode PCPythonGetType_PYTHON(PetscPC pc, const char *name[]) \ except PETSC_ERR_PYTHON with gil: FunctionBegin(b"PCPythonGetType_PYTHON") name[0] = PyPC(pc).getname() return FunctionEnd() cdef PetscErrorCode PCCreate_Python( PetscPC pc, ) \ except PETSC_ERR_PYTHON with gil: FunctionBegin(b"PCCreate_Python") # cdef PCOps ops = pc.ops ops.reset = PCReset_Python ops.destroy = PCDestroy_Python ops.setup = PCSetUp_Python ops.setfromoptions = PCSetFromOptions_Python ops.view = PCView_Python ops.presolve = PCPreSolve_Python ops.postsolve = PCPostSolve_Python ops.apply = PCApply_Python ops.matapply = PCMatApply_Python ops.applytranspose = PCApplyTranspose_Python ops.applysymmetricleft = PCApplySymmetricLeft_Python ops.applysymmetricright = PCApplySymmetricRight_Python # CHKERR( PetscObjectComposeFunction( pc, b"PCPythonSetType_C", PCPythonSetType_PYTHON) ) CHKERR( PetscObjectComposeFunction( pc, b"PCPythonGetType_C", PCPythonGetType_PYTHON) ) # cdef ctx = PyPC(NULL) pc.data = ctx Py_INCREF(pc.data) return FunctionEnd() cdef inline PetscErrorCode PCDestroy_Python_inner( PetscPC pc, ) \ except PETSC_ERR_PYTHON with gil: try: addRef(pc) PCPythonSetContext(pc, NULL) finally: delRef(pc) Py_DECREF(pc.data) pc.data = NULL return PETSC_SUCCESS cdef PetscErrorCode PCDestroy_Python( PetscPC pc, ) \ except PETSC_ERR_PYTHON nogil: FunctionBegin(b"PCDestroy_Python") CHKERR( PetscObjectComposeFunction( pc, b"PCPythonSetType_C", NULL) ) CHKERR( PetscObjectComposeFunction( pc, b"PCPythonGetType_C", NULL) ) # if Py_IsInitialized(): PCDestroy_Python_inner(pc) return FunctionEnd() cdef PetscErrorCode PCSetUp_Python( PetscPC pc, ) \ except PETSC_ERR_PYTHON with gil: FunctionBegin(b"PCSetUp_Python") # cdef char name[2048] cdef PetscBool found = PETSC_FALSE if PyPC(pc).self is None: CHKERR( PetscOptionsGetString(NULL, getPrefix(pc), b"-pc_python_type", name, sizeof(name), &found) ) if found and name[0]: CHKERR( PCPythonSetType_PYTHON(pc, name) ) if PyPC(pc).self is None: return PetscSETERR(PETSC_ERR_USER, "Python context not set, call one of \n" " * PCPythonSetType(pc, \"[package.]module.class\")\n" " * PCSetFromOptions(pc) and pass option " "-pc_python_type [package.]module.class") # cdef setUp = PyPC(pc).setUp if setUp is not None: setUp(PC_(pc)) # cdef o = PyPC(pc) cdef PCOps ops = pc.ops if o.applyTranspose is None: ops.applytranspose = NULL if o.applySymmetricLeft is None: ops.applysymmetricleft = NULL if o.applySymmetricRight is None: ops.applysymmetricright = NULL # return FunctionEnd() cdef inline PetscErrorCode PCReset_Python_inner( PetscPC pc, ) \ except PETSC_ERR_PYTHON with gil: cdef reset = PyPC(pc).reset if reset is not None: reset(PC_(pc)) return PETSC_SUCCESS cdef PetscErrorCode PCReset_Python( PetscPC pc, ) \ except PETSC_ERR_PYTHON nogil: if getRef(pc) == 0: return PETSC_SUCCESS FunctionBegin(b"PCReset_Python") if Py_IsInitialized(): PCReset_Python_inner(pc) return FunctionEnd() cdef PetscErrorCode PCSetFromOptions_Python( PetscPC pc, PetscOptionItems *PetscOptionsObject, ) \ except PETSC_ERR_PYTHON with gil: FunctionBegin(b"PCSetFromOptions_Python") # cdef char name[2048], *defval = PyPC(pc).getname() cdef PetscBool found = PETSC_FALSE cdef PetscOptionItems *opts "PetscOptionsObject" = PetscOptionsObject CHKERR( PetscOptionsString( b"-pc_python_type", b"Python [package.]module[.{class|function}]", b"PCPythonSetType", defval, name, sizeof(name), &found) ); opts; if found and name[0]: CHKERR( PCPythonSetType_PYTHON(pc, name) ) # cdef setFromOptions = PyPC(pc).setFromOptions if setFromOptions is not None: setFromOptions(PC_(pc)) return FunctionEnd() cdef PetscErrorCode PCView_Python( PetscPC pc, PetscViewer vwr, ) \ except PETSC_ERR_PYTHON with gil: FunctionBegin(b"PCView_Python") viewcontext(PyPC(pc), vwr) cdef view = PyPC(pc).view if view is not None: view(PC_(pc), Viewer_(vwr)) return FunctionEnd() cdef PetscErrorCode PCPreSolve_Python( PetscPC pc, PetscKSP ksp, PetscVec b, PetscVec x, ) \ except PETSC_ERR_PYTHON with gil: FunctionBegin(b"PCPreSolve_Python") cdef preSolve = PyPC(pc).preSolve if preSolve is not None: preSolve(PC_(pc), KSP_(ksp), Vec_(b), Vec_(x)) return FunctionEnd() cdef PetscErrorCode PCPostSolve_Python( PetscPC pc, PetscKSP ksp, PetscVec b, PetscVec x, ) \ except PETSC_ERR_PYTHON with gil: FunctionBegin(b"PCPostSolve_Python") cdef postSolve = PyPC(pc).postSolve if postSolve is not None: postSolve(PC_(pc), KSP_(ksp), Vec_(b), Vec_(x)) return FunctionEnd() cdef PetscErrorCode PCApply_Python( PetscPC pc, PetscVec x, PetscVec y, ) \ except PETSC_ERR_PYTHON with gil: FunctionBegin(b"PCApply_Python") cdef apply = PyPC(pc).apply apply(PC_(pc), Vec_(x), Vec_(y)) return FunctionEnd() cdef PetscErrorCode PCApplyTranspose_Python( PetscPC pc, PetscVec x, PetscVec y, ) \ except PETSC_ERR_PYTHON with gil: FunctionBegin(b"PCApplyTranspose_Python") cdef applyTranspose = PyPC(pc).applyTranspose applyTranspose(PC_(pc), Vec_(x), Vec_(y)) return FunctionEnd() cdef PetscErrorCode PCApplySymmetricLeft_Python( PetscPC pc, PetscVec x, PetscVec y, ) \ except PETSC_ERR_PYTHON with gil: FunctionBegin(b"PCApplySymmetricLeft_Python") cdef applySymmetricLeft = PyPC(pc).applySymmetricLeft applySymmetricLeft(PC_(pc), Vec_(x), Vec_(y)) return FunctionEnd() cdef PetscErrorCode PCApplySymmetricRight_Python( PetscPC pc, PetscVec x, PetscVec y, ) \ except PETSC_ERR_PYTHON with gil: FunctionBegin(b"PCApplySymmetricRight_Python") cdef applySymmetricRight = PyPC(pc).applySymmetricRight applySymmetricRight(PC_(pc), Vec_(x), Vec_(y)) return FunctionEnd() cdef PetscErrorCode PCMatApply_Python( PetscPC pc, PetscMat X, PetscMat Y, ) \ except PETSC_ERR_PYTHON with gil: FunctionBegin(b"PCMatApply_Python") cdef matApply = PyPC(pc).matApply if matApply is None: try: pc.ops.matapply = NULL CHKERR( PCMatApply(pc, X, Y) ) finally: pc.ops.matapply = PCMatApply_Python return FunctionEnd() matApply(PC_(pc), Mat_(X), Mat_(Y)) return FunctionEnd() # -------------------------------------------------------------------- cdef extern from * nogil: struct _KSPOps: PetscErrorCode (*destroy)(PetscKSP) except PETSC_ERR_PYTHON PetscErrorCode (*setup)(PetscKSP) except PETSC_ERR_PYTHON PetscErrorCode (*reset)(PetscKSP) except PETSC_ERR_PYTHON PetscErrorCode (*setfromoptions)(PetscKSP,PetscOptionItems*) except PETSC_ERR_PYTHON PetscErrorCode (*view)(PetscKSP,PetscViewer) except PETSC_ERR_PYTHON PetscErrorCode (*solve)(PetscKSP) except PETSC_ERR_PYTHON PetscErrorCode (*buildsolution)(PetscKSP,PetscVec,PetscVec*) except PETSC_ERR_PYTHON PetscErrorCode (*buildresidual)(PetscKSP,PetscVec,PetscVec,PetscVec*) except PETSC_ERR_PYTHON ctypedef _KSPOps *KSPOps struct _p_KSP: void *data KSPOps ops PetscBool transpose_solve PetscInt iter"its",max_its"max_it" PetscReal norm"rnorm" PetscKSPConvergedReason reason cdef extern from * nogil: # custom.h PetscErrorCode KSPConverged(PetscKSP,PetscInt,PetscReal,PetscKSPConvergedReason*) PetscErrorCode KSPLogHistory(PetscKSP,PetscReal) @cython.internal cdef class _PyKSP(_PyObj): pass cdef inline _PyKSP PyKSP(PetscKSP ksp): if ksp != NULL and ksp.data != NULL: return <_PyKSP>ksp.data else: return _PyKSP.__new__(_PyKSP) cdef public PetscErrorCode KSPPythonGetContext(PetscKSP ksp, void **ctx) \ except PETSC_ERR_PYTHON: FunctionBegin(b"KSPPythonGetContext") PyKSP(ksp).getcontext(ctx) return FunctionEnd() cdef public PetscErrorCode KSPPythonSetContext(PetscKSP ksp, void *ctx) \ except PETSC_ERR_PYTHON: FunctionBegin(b"KSPPythonSetContext") PyKSP(ksp).setcontext(ctx, KSP_(ksp)) return FunctionEnd() cdef PetscErrorCode KSPPythonSetType_PYTHON(PetscKSP ksp, char name[]) \ except PETSC_ERR_PYTHON with gil: FunctionBegin(b"KSPPythonSetType_PYTHON") if name == NULL: return FunctionEnd() # XXX cdef object ctx = createcontext(name) KSPPythonSetContext(ksp, ctx) PyKSP(ksp).setname(name) return FunctionEnd() cdef PetscErrorCode KSPPythonGetType_PYTHON(PetscKSP ksp, const char *name[]) \ except PETSC_ERR_PYTHON with gil: FunctionBegin(b"KSPPythonGetType_PYTHON") name[0] = PyKSP(ksp).getname() return FunctionEnd() cdef PetscErrorCode KSPCreate_Python( PetscKSP ksp, ) \ except PETSC_ERR_PYTHON with gil: FunctionBegin(b"KSPCreate_Python") # cdef KSPOps ops = ksp.ops ops.reset = KSPReset_Python ops.destroy = KSPDestroy_Python ops.setup = KSPSetUp_Python ops.setfromoptions = KSPSetFromOptions_Python ops.view = KSPView_Python ops.solve = KSPSolve_Python ops.buildsolution = KSPBuildSolution_Python ops.buildresidual = KSPBuildResidual_Python # CHKERR( PetscObjectComposeFunction( ksp, b"KSPPythonSetType_C", KSPPythonSetType_PYTHON) ) CHKERR( PetscObjectComposeFunction( ksp, b"KSPPythonGetType_C", KSPPythonGetType_PYTHON) ) # cdef ctx = PyKSP(NULL) ksp.data = ctx Py_INCREF(ksp.data) # CHKERR( KSPSetSupportedNorm( ksp, KSP_NORM_PRECONDITIONED, PC_LEFT, 3) ) CHKERR( KSPSetSupportedNorm( ksp, KSP_NORM_UNPRECONDITIONED, PC_RIGHT, 3) ) CHKERR( KSPSetSupportedNorm( ksp, KSP_NORM_UNPRECONDITIONED, PC_LEFT, 2) ) CHKERR( KSPSetSupportedNorm( ksp, KSP_NORM_PRECONDITIONED, PC_RIGHT, 2) ) CHKERR( KSPSetSupportedNorm( ksp, KSP_NORM_PRECONDITIONED, PC_SYMMETRIC, 1) ) CHKERR( KSPSetSupportedNorm( ksp, KSP_NORM_UNPRECONDITIONED, PC_SYMMETRIC, 1) ) return FunctionEnd() cdef inline PetscErrorCode KSPDestroy_Python_inner( PetscKSP ksp, ) \ except PETSC_ERR_PYTHON with gil: try: addRef(ksp) KSPPythonSetContext(ksp, NULL) finally: delRef(ksp) Py_DECREF(ksp.data) ksp.data = NULL return PETSC_SUCCESS cdef PetscErrorCode KSPDestroy_Python( PetscKSP ksp, ) \ except PETSC_ERR_PYTHON nogil: FunctionBegin(b"KSPDestroy_Python") CHKERR( PetscObjectComposeFunction( ksp, b"KSPPythonSetType_C", NULL)) CHKERR( PetscObjectComposeFunction( ksp, b"KSPPythonGetType_C", NULL)) # if Py_IsInitialized(): KSPDestroy_Python_inner(ksp) return FunctionEnd() cdef PetscErrorCode KSPSetUp_Python( PetscKSP ksp, ) \ except PETSC_ERR_PYTHON with gil: FunctionBegin(b"KSPSetUp_Python") # cdef char name[2048] cdef PetscBool found = PETSC_FALSE if PyKSP(ksp).self is None: CHKERR( PetscOptionsGetString(NULL, getPrefix(ksp), b"-ksp_python_type", name, sizeof(name), &found) ) if found and name[0]: CHKERR( KSPPythonSetType_PYTHON(ksp, name) ) if PyKSP(ksp).self is None: return PetscSETERR(PETSC_ERR_USER, "Python context not set, call one of \n" " * KSPPythonSetType(ksp, \"[package.]module.class\")\n" " * KSPSetFromOptions(ksp) and pass option " "-ksp_python_type [package.]module.class") # cdef setUp = PyKSP(ksp).setUp if setUp is not None: setUp(KSP_(ksp)) return FunctionEnd() cdef inline PetscErrorCode KSPReset_Python_inner( PetscKSP ksp, ) \ except PETSC_ERR_PYTHON with gil: cdef reset = PyKSP(ksp).reset if reset is not None: reset(KSP_(ksp)) return PETSC_SUCCESS cdef PetscErrorCode KSPReset_Python( PetscKSP ksp, ) \ except PETSC_ERR_PYTHON nogil: if getRef(ksp) == 0: return PETSC_SUCCESS FunctionBegin(b"KSPReset_Python") CHKERR( PetscObjectCompose(ksp, b"@ksp.vec_work_sol", NULL) ) CHKERR( PetscObjectCompose(ksp, b"@ksp.vec_work_res", NULL) ) if Py_IsInitialized(): KSPReset_Python_inner(ksp) return FunctionEnd() cdef PetscErrorCode KSPSetFromOptions_Python( PetscKSP ksp, PetscOptionItems *PetscOptionsObject ) \ except PETSC_ERR_PYTHON with gil: FunctionBegin(b"KSPSetFromOptions_Python") # cdef char name[2048], *defval = PyKSP(ksp).getname() cdef PetscBool found = PETSC_FALSE cdef PetscOptionItems *opts "PetscOptionsObject" = PetscOptionsObject CHKERR( PetscOptionsString( b"-ksp_python_type", b"Python [package.]module[.{class|function}]", b"KSPPythonSetType", defval, name, sizeof(name), &found) ); opts; if found and name[0]: CHKERR( KSPPythonSetType_PYTHON(ksp, name) ) # cdef setFromOptions = PyKSP(ksp).setFromOptions if setFromOptions is not None: setFromOptions(KSP_(ksp)) return FunctionEnd() cdef PetscErrorCode KSPView_Python( PetscKSP ksp, PetscViewer vwr, ) \ except PETSC_ERR_PYTHON with gil: FunctionBegin(b"KSPView_Python") viewcontext(PyKSP(ksp), vwr) cdef view = PyKSP(ksp).view if view is not None: view(KSP_(ksp), Viewer_(vwr)) return FunctionEnd() cdef PetscErrorCode KSPBuildSolution_Python( PetscKSP ksp, PetscVec v, PetscVec *V, ) \ except PETSC_ERR_PYTHON with gil: FunctionBegin(b"KSPBuildSolution_Python") cdef PetscVec x = v cdef buildSolution = PyKSP(ksp).buildSolution if buildSolution is not None: if x == NULL: pass # XXX buildSolution(KSP_(ksp), Vec_(x)) if V != NULL: V[0] = x else: CHKERR( KSPBuildSolutionDefault(ksp, v, V) ) return FunctionEnd() cdef PetscErrorCode KSPBuildResidual_Python( PetscKSP ksp, PetscVec t, PetscVec v, PetscVec *V, ) \ except PETSC_ERR_PYTHON with gil: FunctionBegin(b"KSPBuildResidual_Python") cdef buildResidual = PyKSP(ksp).buildResidual if buildResidual is not None: buildResidual(KSP_(ksp), Vec_(t), Vec_(v)) if V != NULL: V[0] = v else: CHKERR( KSPBuildResidualDefault(ksp, t, v, V) ) return FunctionEnd() cdef PetscErrorCode KSPSolve_Python( PetscKSP ksp, ) \ except PETSC_ERR_PYTHON with gil: FunctionBegin(b"KSPSolve_Python") cdef PetscVec B = NULL, X = NULL CHKERR( KSPGetRhs(ksp, &B) ) CHKERR( KSPGetSolution(ksp, &X) ) # ksp.iter = 0 ksp.reason = KSP_CONVERGED_ITERATING # cdef solve = None if ksp.transpose_solve: solve = PyKSP(ksp).solveTranspose else: solve = PyKSP(ksp).solve if solve is not None: solve(KSP_(ksp), Vec_(B), Vec_(X)) else: KSPSolve_Python_default(ksp, B, X) return FunctionEnd() cdef PetscErrorCode KSPSolve_Python_default( PetscKSP ksp, PetscVec B, PetscVec X, ) \ except PETSC_ERR_PYTHON with gil: FunctionBegin(b"KSPSolve_Python_default") # cdef PetscVec t = NULL CHKERR( PetscObjectQuery( ksp, b"@ksp.vec_work_sol", &t) ) if t == NULL: CHKERR( VecDuplicate(X, &t) ) CHKERR( PetscObjectCompose( ksp, b"@ksp.vec_work_sol", t) ) cdef PetscVec v = NULL CHKERR( PetscObjectQuery( ksp, b"@ksp.vec_work_res", &v) ) if v == NULL: CHKERR( VecDuplicate(B, &v) ) CHKERR( PetscObjectCompose( ksp, b"@ksp.vec_work_res", v) ) # cdef PetscInt its = 0 cdef PetscVec R = NULL cdef PetscReal rnorm = 0 # CHKERR( KSPBuildResidual(ksp, t, v, &R) ) CHKERR( VecNorm(R, PETSC_NORM_2, &rnorm) ) # CHKERR( KSPConverged(ksp, ksp.iter, rnorm, &ksp.reason) ) CHKERR( KSPLogHistory(ksp, ksp.norm) ) CHKERR( KSPMonitor(ksp, ksp.iter, ksp.norm) ) for its from 0 <= its < ksp.max_its: if ksp.reason: break KSPPreStep_Python(ksp) # KSPStep_Python(ksp, B, X) # FIXME? B? CHKERR( KSPBuildResidual(ksp, t, v, &R) ) CHKERR( VecNorm(R, PETSC_NORM_2, &rnorm) ) ksp.iter += 1 # KSPPostStep_Python(ksp) CHKERR( KSPConverged(ksp, ksp.iter, rnorm, &ksp.reason) ) CHKERR( KSPLogHistory(ksp, ksp.norm) ) CHKERR( KSPMonitor(ksp, ksp.iter, ksp.norm) ) if ksp.iter == ksp.max_its: if ksp.reason == KSP_CONVERGED_ITERATING: ksp.reason = KSP_DIVERGED_MAX_IT # return FunctionEnd() cdef PetscErrorCode KSPPreStep_Python( PetscKSP ksp, ) \ except PETSC_ERR_PYTHON with gil: FunctionBegin(b"KSPPreStep_Python") cdef preStep = PyKSP(ksp).preStep if preStep is not None: preStep(KSP_(ksp)) return FunctionEnd() cdef PetscErrorCode KSPPostStep_Python( PetscKSP ksp, ) \ except PETSC_ERR_PYTHON with gil: FunctionBegin(b"KSPPostStep_Python") cdef postStep = PyKSP(ksp).postStep if postStep is not None: postStep(KSP_(ksp)) return FunctionEnd() cdef PetscErrorCode KSPStep_Python( PetscKSP ksp, PetscVec B, PetscVec X, ) \ except PETSC_ERR_PYTHON with gil: FunctionBegin(b"KSPStep_Python") cdef step = None if ksp.transpose_solve: step = PyKSP(ksp).stepTranspose if step is None: return UNSUPPORTED(b"stepTranspose") else: step = PyKSP(ksp).step if step is None: return UNSUPPORTED(b"step") step(KSP_(ksp), Vec_(B), Vec_(X)) return FunctionEnd() # -------------------------------------------------------------------- cdef extern from * nogil: struct _SNESOps: PetscErrorCode (*destroy)(PetscSNES) except PETSC_ERR_PYTHON PetscErrorCode (*setup)(PetscSNES) except PETSC_ERR_PYTHON PetscErrorCode (*reset)(PetscSNES) except PETSC_ERR_PYTHON PetscErrorCode (*setfromoptions)(PetscSNES,PetscOptionItems*) except PETSC_ERR_PYTHON PetscErrorCode (*view)(PetscSNES,PetscViewer) except PETSC_ERR_PYTHON PetscErrorCode (*solve)(PetscSNES) except PETSC_ERR_PYTHON ctypedef _SNESOps *SNESOps struct _p_SNES: void *data SNESOps ops PetscInt iter,max_its,linear_its PetscReal norm,rtol,ttol PetscSNESConvergedReason reason PetscVec vec_sol,vec_sol_update,vec_func PetscMat jacobian,jacobian_pre PetscKSP ksp cdef extern from * nogil: # custom.h PetscErrorCode SNESLogHistory(PetscSNES,PetscReal,PetscInt) @cython.internal cdef class _PySNES(_PyObj): pass cdef inline _PySNES PySNES(PetscSNES snes): if snes != NULL and snes.data != NULL: return <_PySNES>snes.data else: return _PySNES.__new__(_PySNES) cdef public PetscErrorCode SNESPythonGetContext(PetscSNES snes, void **ctx) \ except PETSC_ERR_PYTHON: FunctionBegin(b"SNESPythonGetContext ") PySNES(snes).getcontext(ctx) return FunctionEnd() cdef public PetscErrorCode SNESPythonSetContext(PetscSNES snes, void *ctx) \ except PETSC_ERR_PYTHON: FunctionBegin(b"SNESPythonSetContext ") PySNES(snes).setcontext(ctx, SNES_(snes)) return FunctionEnd() cdef PetscErrorCode SNESPythonSetType_PYTHON(PetscSNES snes, char name[]) \ except PETSC_ERR_PYTHON with gil: FunctionBegin(b"SNESPythonSetType_PYTHON") if name == NULL: return FunctionEnd() # XXX cdef object ctx = createcontext(name) SNESPythonSetContext(snes, ctx) PySNES(snes).setname(name) return FunctionEnd() cdef PetscErrorCode SNESPythonGetType_PYTHON(PetscSNES snes, const char *name[]) \ except PETSC_ERR_PYTHON with gil: FunctionBegin(b"SNESPythonGetType_PYTHON") name[0] = PySNES(snes).getname() return FunctionEnd() cdef PetscErrorCode SNESCreate_Python( PetscSNES snes, ) \ except PETSC_ERR_PYTHON with gil: FunctionBegin(b"SNESCreate_Python") # cdef SNESOps ops = snes.ops cdef PetscSNESLineSearch ls = NULL ops.reset = SNESReset_Python ops.destroy = SNESDestroy_Python ops.setup = SNESSetUp_Python ops.setfromoptions = SNESSetFromOptions_Python ops.view = SNESView_Python ops.solve = SNESSolve_Python # CHKERR( PetscObjectComposeFunction( snes, b"SNESPythonSetType_C", SNESPythonSetType_PYTHON) ) CHKERR( PetscObjectComposeFunction( snes, b"SNESPythonGetType_C", SNESPythonGetType_PYTHON) ) # cdef ctx = PySNES(NULL) snes.data = ctx # Ensure that the SNES has a linesearch object early enough that # it gets setFromOptions. CHKERR( SNESGetLineSearch(snes, &ls) ) Py_INCREF(snes.data) return FunctionEnd() cdef inline PetscErrorCode SNESDestroy_Python_inner( PetscSNES snes, ) \ except PETSC_ERR_PYTHON with gil: try: addRef(snes) SNESPythonSetContext(snes, NULL) finally: delRef(snes) Py_DECREF(snes.data) snes.data = NULL return PETSC_SUCCESS cdef PetscErrorCode SNESDestroy_Python( PetscSNES snes, ) \ except PETSC_ERR_PYTHON nogil: FunctionBegin(b"SNESDestroy_Python") CHKERR( PetscObjectComposeFunction( snes, b"SNESPythonSetType_C", NULL) ) CHKERR( PetscObjectComposeFunction( snes, b"SNESPythonGetType_C", NULL) ) # if Py_IsInitialized(): SNESDestroy_Python_inner(snes) return FunctionEnd() cdef PetscErrorCode SNESSetUp_Python( PetscSNES snes, ) \ except PETSC_ERR_PYTHON with gil: FunctionBegin(b"SNESSetUp_Python") # #SNESGetKSP(snes,&snes.ksp) # cdef char name[2048] cdef PetscBool found = PETSC_FALSE if PySNES(snes).self is None: CHKERR( PetscOptionsGetString(NULL, getPrefix(snes), b"-snes_python_type", name, sizeof(name), &found) ) if found and name[0]: CHKERR( SNESPythonSetType_PYTHON(snes, name) ) if PySNES(snes).self is None: return PetscSETERR(PETSC_ERR_USER, "Python context not set, call one of \n" " * SNESPythonSetType(snes, \"[package.]module.class\")\n" " * SNESSetFromOptions(snes) and pass option " "-snes_python_type [package.]module.class") # cdef setUp = PySNES(snes).setUp if setUp is not None: setUp(SNES_(snes)) return FunctionEnd() cdef inline PetscErrorCode SNESReset_Python_inner( PetscSNES snes, ) \ except PETSC_ERR_PYTHON with gil: cdef reset = PySNES(snes).reset if reset is not None: reset(SNES_(snes)) return PETSC_SUCCESS cdef PetscErrorCode SNESReset_Python( PetscSNES snes, ) \ except PETSC_ERR_PYTHON nogil: if getRef(snes) == 0: return PETSC_SUCCESS FunctionBegin(b"SNESReset_Python") if Py_IsInitialized(): SNESReset_Python_inner(snes) return FunctionEnd() cdef PetscErrorCode SNESSetFromOptions_Python( PetscSNES snes, PetscOptionItems *PetscOptionsObject, ) \ except PETSC_ERR_PYTHON with gil: FunctionBegin(b"SNESSetFromOptions_Python") # cdef char name[2048], *defval = PySNES(snes).getname() cdef PetscBool found = PETSC_FALSE cdef PetscOptionItems *opts "PetscOptionsObject" = PetscOptionsObject CHKERR( PetscOptionsString( b"-snes_python_type", b"Python [package.]module[.{class|function}]", b"SNESPythonSetType", defval, name, sizeof(name), &found) ); opts; if found and name[0]: CHKERR( SNESPythonSetType_PYTHON(snes, name) ) # cdef setFromOptions = PySNES(snes).setFromOptions if setFromOptions is not None: setFromOptions(SNES_(snes)) return FunctionEnd() cdef PetscErrorCode SNESView_Python( PetscSNES snes, PetscViewer vwr, ) \ except PETSC_ERR_PYTHON with gil: FunctionBegin(b"SNESView_Python") viewcontext(PySNES(snes), vwr) cdef view = PySNES(snes).view if view is not None: view(SNES_(snes), Viewer_(vwr)) return FunctionEnd() cdef PetscErrorCode SNESSolve_Python( PetscSNES snes, ) \ except PETSC_ERR_PYTHON with gil: FunctionBegin(b"SNESSolve_Python") cdef PetscVec b = NULL, x = NULL CHKERR( SNESGetRhs(snes, &b) ) CHKERR( SNESGetSolution(snes, &x) ) # snes.iter = 0 # cdef solve = PySNES(snes).solve if solve is not None: solve(SNES_(snes), Vec_(b) if b != NULL else None, Vec_(x)) else: SNESSolve_Python_default(snes) # return FunctionEnd() cdef PetscErrorCode SNESSolve_Python_default( PetscSNES snes, ) \ except PETSC_ERR_PYTHON with gil: FunctionBegin(b"SNESSolve_Python_default") # cdef PetscVec X=NULL, F=NULL, Y=NULL cdef PetscSNESLineSearch ls CHKERR( SNESGetSolution(snes, &X) ) CHKERR( SNESGetFunction(snes, &F, NULL, NULL) ) CHKERR( SNESGetSolutionUpdate(snes, &Y) ) CHKERR( SNESGetLineSearch(snes, &ls) ) cdef PetscInt its=0, lits=0 cdef PetscReal xnorm = 0.0 cdef PetscReal fnorm = 0.0 cdef PetscReal ynorm = 0.0 # CHKERR( VecSet(Y, 0.0) ) CHKERR( SNESComputeFunction(snes, X, F) ) CHKERR( VecNorm(X, PETSC_NORM_2, &xnorm) ) CHKERR( VecNorm(F, PETSC_NORM_2, &fnorm) ) # CHKERR( SNESLogHistory(snes, snes.norm, lits) ) CHKERR( SNESConverged(snes, snes.iter, xnorm, ynorm, fnorm) ) CHKERR( SNESMonitor(snes, snes.iter, snes.norm) ) if snes.reason: return FunctionEnd() cdef PetscObjectState ostate = -1 cdef PetscObjectState nstate = -1 for its from 0 <= its < snes.max_its: CHKERR( PetscObjectStateGet(X, &ostate) ) SNESPreStep_Python(snes) CHKERR( PetscObjectStateGet(X, &nstate) ) if ostate != nstate: CHKERR( SNESComputeFunction(snes, X, F) ) CHKERR( VecNorm(F, PETSC_NORM_2, &fnorm) ) # lits = -snes.linear_its SNESStep_Python(snes, X, F, Y) lits += snes.linear_its # CHKERR( SNESLineSearchApply(ls, X, F, NULL, Y) ) CHKERR( SNESLineSearchGetNorms(ls, &xnorm, &fnorm, &ynorm) ) snes.iter += 1 # SNESPostStep_Python(snes) CHKERR( SNESLogHistory(snes, snes.norm, lits) ) CHKERR( SNESConverged(snes, snes.iter, xnorm, ynorm, fnorm) ) CHKERR( SNESMonitor(snes, snes.iter, snes.norm) ) if snes.reason: break # return FunctionEnd() cdef PetscErrorCode SNESPreStep_Python( PetscSNES snes, ) \ except PETSC_ERR_PYTHON with gil: FunctionBegin(b"SNESPreStep_Python") cdef preStep = PySNES(snes).preStep if preStep is not None: preStep(SNES_(snes)) return FunctionEnd() cdef PetscErrorCode SNESPostStep_Python( PetscSNES snes, ) \ except PETSC_ERR_PYTHON with gil: FunctionBegin(b"SNESPostStep_Python") cdef postStep = PySNES(snes).postStep if postStep is not None: postStep(SNES_(snes)) return FunctionEnd() cdef PetscErrorCode SNESStep_Python( PetscSNES snes, PetscVec X, PetscVec F, PetscVec Y, ) \ except PETSC_ERR_PYTHON with gil: FunctionBegin(b"SNESStep_Python") cdef step = PySNES(snes).step if step is not None: step(SNES_(snes), Vec_(X), Vec_(F), Vec_(Y)) else: SNESStep_Python_default(snes, X, F, Y) return FunctionEnd() cdef PetscErrorCode SNESStep_Python_default( PetscSNES snes, PetscVec X, PetscVec F, PetscVec Y, ) \ except PETSC_ERR_PYTHON with gil: FunctionBegin(b"SNESStep_Python_default") cdef PetscMat J = NULL, P = NULL cdef PetscInt lits = 0 CHKERR( SNESGetJacobian(snes, &J, &P, NULL, NULL) ) CHKERR( SNESComputeJacobian(snes, X, J, P) ) CHKERR( KSPSetOperators(snes.ksp, J, P) ) CHKERR( KSPSolve(snes.ksp, F, Y) ) CHKERR( KSPGetIterationNumber(snes.ksp, &lits) ) snes.linear_its += lits return FunctionEnd() # -------------------------------------------------------------------- cdef extern from * nogil: struct _TSOps: PetscErrorCode (*destroy)(PetscTS) except PETSC_ERR_PYTHON PetscErrorCode (*setup)(PetscTS) except PETSC_ERR_PYTHON PetscErrorCode (*reset)(PetscTS) except PETSC_ERR_PYTHON PetscErrorCode (*setfromoptions)(PetscTS,PetscOptionItems*) except PETSC_ERR_PYTHON PetscErrorCode (*view)(PetscTS,PetscViewer) except PETSC_ERR_PYTHON PetscErrorCode (*step)(PetscTS) except PETSC_ERR_PYTHON PetscErrorCode (*rollback)(PetscTS) except PETSC_ERR_PYTHON PetscErrorCode (*interpolate)(PetscTS,PetscReal,PetscVec) except PETSC_ERR_PYTHON PetscErrorCode (*evaluatestep)(PetscTS,PetscInt,PetscVec,PetscBool*) except PETSC_ERR_PYTHON PetscErrorCode (*solve)(PetscTS) except PETSC_ERR_PYTHON PetscErrorCode (*snesfunction)(PetscSNES,PetscVec,PetscVec,PetscTS) except PETSC_ERR_PYTHON PetscErrorCode (*snesjacobian)(PetscSNES,PetscVec,PetscMat,PetscMat,PetscTS) except PETSC_ERR_PYTHON ctypedef _TSOps *TSOps struct _TSUserOps: PetscErrorCode (*prestep)(PetscTS) except PETSC_ERR_PYTHON PetscErrorCode (*prestage)(PetscTS,PetscReal) except PETSC_ERR_PYTHON PetscErrorCode (*poststage)(PetscTS,PetscReal,PetscInt,PetscVec*) except PETSC_ERR_PYTHON PetscErrorCode (*poststep)(PetscTS) except PETSC_ERR_PYTHON PetscErrorCode (*rhsfunction)(PetscTS,PetscReal,PetscVec,PetscVec,void*) except PETSC_ERR_PYTHON PetscErrorCode (*ifunction) (PetscTS,PetscReal,PetscVec,PetscVec,PetscVec,void*) except PETSC_ERR_PYTHON PetscErrorCode (*rhsjacobian)(PetscTS,PetscReal,PetscVec,PetscMat,PetscMat,void*) except PETSC_ERR_PYTHON PetscErrorCode (*ijacobian) (PetscTS,PetscReal,PetscVec,PetscVec,PetscReal,PetscMat,PetscMat,void*) except PETSC_ERR_PYTHON ctypedef _TSUserOps *TSUserOps struct _p_TS: void *data PetscDM dm PetscTSAdapt adapt TSOps ops TSUserOps userops PetscTSProblemType problem_type PetscInt snes_its PetscInt ksp_its PetscInt reject PetscInt max_reject PetscInt steps PetscReal ptime PetscVec vec_sol PetscReal time_step PetscInt max_steps PetscReal max_time PetscTSConvergedReason reason PetscSNES snes PetscBool usessnes @cython.internal cdef class _PyTS(_PyObj): pass cdef inline _PyTS PyTS(PetscTS ts): if ts != NULL and ts.data != NULL: return <_PyTS>ts.data else: return _PyTS.__new__(_PyTS) cdef public PetscErrorCode TSPythonGetContext(PetscTS ts, void **ctx) \ except PETSC_ERR_PYTHON: FunctionBegin(b"TSPythonGetContext") PyTS(ts).getcontext(ctx) return FunctionEnd() cdef public PetscErrorCode TSPythonSetContext(PetscTS ts, void *ctx) \ except PETSC_ERR_PYTHON: FunctionBegin(b"TSPythonSetContext") PyTS(ts).setcontext(ctx, TS_(ts)) return FunctionEnd() cdef PetscErrorCode TSPythonSetType_PYTHON(PetscTS ts, char name[]) \ except PETSC_ERR_PYTHON with gil: FunctionBegin(b"TSPythonSetType_PYTHON") if name == NULL: return FunctionEnd() # XXX cdef object ctx = createcontext(name) TSPythonSetContext(ts, ctx) PyTS(ts).setname(name) return FunctionEnd() cdef PetscErrorCode TSPythonGetType_PYTHON(PetscTS ts, const char *name[]) \ except PETSC_ERR_PYTHON with gil: FunctionBegin(b"TSPythonGetType_PYTHON") name[0] = PyTS(ts).getname() return FunctionEnd() cdef PetscErrorCode TSCreate_Python( PetscTS ts, ) \ except PETSC_ERR_PYTHON with gil: FunctionBegin(b"TSCreate_Python") # cdef TSOps ops = ts.ops ops.reset = TSReset_Python ops.destroy = TSDestroy_Python ops.setup = TSSetUp_Python ops.setfromoptions = TSSetFromOptions_Python ops.view = TSView_Python ops.step = TSStep_Python ops.rollback = TSRollBack_Python ops.interpolate = TSInterpolate_Python ops.evaluatestep = TSEvaluateStep_Python ops.snesfunction = SNESTSFormFunction_Python ops.snesjacobian = SNESTSFormJacobian_Python # CHKERR( PetscObjectComposeFunction( ts, b"TSPythonSetType_C", TSPythonSetType_PYTHON) ) CHKERR( PetscObjectComposeFunction( ts, b"TSPythonGetType_C", TSPythonGetType_PYTHON) ) # ts.usessnes = PETSC_TRUE # cdef ctx = PyTS(NULL) ts.data = ctx Py_INCREF(ts.data) return FunctionEnd() cdef inline PetscErrorCode TSDestroy_Python_inner( PetscTS ts, ) \ except PETSC_ERR_PYTHON with gil: try: addRef(ts) TSPythonSetContext(ts, NULL) finally: delRef(ts) Py_DECREF(ts.data) ts.data = NULL return PETSC_SUCCESS cdef PetscErrorCode TSDestroy_Python( PetscTS ts, ) \ except PETSC_ERR_PYTHON nogil: FunctionBegin(b"TSDestroy_Python") CHKERR( PetscObjectComposeFunction( ts, b"TSPythonSetType_C", NULL) ) CHKERR( PetscObjectComposeFunction( ts, b"TSPythonGetType_C", NULL) ) # if Py_IsInitialized(): TSDestroy_Python_inner(ts) return FunctionEnd() cdef PetscErrorCode TSSetUp_Python( PetscTS ts, ) \ except PETSC_ERR_PYTHON with gil: FunctionBegin(b"TSSetUp_Python") # cdef PetscVec vec_update = NULL CHKERR( VecDuplicate(ts.vec_sol, &vec_update) ) CHKERR( PetscObjectCompose(ts, b"@ts.vec_update", vec_update) ) CHKERR( VecDestroy(&vec_update) ) cdef PetscVec vec_dot = NULL CHKERR( VecDuplicate(ts.vec_sol, &vec_dot) ) CHKERR( PetscObjectCompose(ts, b"@ts.vec_dot", vec_dot) ) CHKERR( VecDestroy(&vec_dot) ) # cdef char name[2048] cdef PetscBool found = PETSC_FALSE if PyTS(ts).self is None: CHKERR( PetscOptionsGetString(NULL, getPrefix(ts), b"-ts_python_type", name, sizeof(name), &found) ) if found and name[0]: CHKERR( TSPythonSetType_PYTHON(ts, name) ) if PyTS(ts).self is None: return PetscSETERR(PETSC_ERR_USER, "Python context not set, call one of \n" " * TSPythonSetType(ts, \"[package.]module.class\")\n" " * TSSetFromOptions(ts) and pass option " "-ts_python_type [package.]module.class") # cdef setUp = PyTS(ts).setUp if setUp is not None: setUp(TS_(ts)) return FunctionEnd() cdef inline PetscErrorCode TSReset_Python_inner( PetscTS ts, ) \ except PETSC_ERR_PYTHON with gil: cdef reset = PyTS(ts).reset if reset is not None: reset(TS_(ts)) return PETSC_SUCCESS cdef PetscErrorCode TSReset_Python( PetscTS ts, ) \ except PETSC_ERR_PYTHON nogil: if getRef(ts) == 0: return PETSC_SUCCESS FunctionBegin(b"TSReset_Python") CHKERR( PetscObjectCompose(ts, b"@ts.vec_update", NULL) ) CHKERR( PetscObjectCompose(ts, b"@ts.vec_dot", NULL) ) if Py_IsInitialized(): TSReset_Python_inner(ts) return FunctionEnd() cdef PetscErrorCode TSSetFromOptions_Python( PetscTS ts, PetscOptionItems *PetscOptionsObject, ) \ except PETSC_ERR_PYTHON with gil: FunctionBegin(b"TSSetFromOptions_Python") cdef char name[2048], *defval = PyTS(ts).getname() cdef PetscBool found = PETSC_FALSE cdef PetscOptionItems *opts "PetscOptionsObject" = PetscOptionsObject CHKERR( PetscOptionsString( b"-ts_python_type", b"Python [package.]module[.{class|function}]", b"TSPythonSetType", defval, name, sizeof(name), &found) ); opts; if found and name[0]: CHKERR( TSPythonSetType_PYTHON(ts, name) ) # cdef setFromOptions = PyTS(ts).setFromOptions if setFromOptions is not None: setFromOptions(TS_(ts)) CHKERR( SNESSetFromOptions(ts.snes) ) return FunctionEnd() cdef PetscErrorCode TSView_Python( PetscTS ts, PetscViewer vwr, ) \ except PETSC_ERR_PYTHON with gil: FunctionBegin(b"TSView_Python") viewcontext(PyTS(ts), vwr) cdef view = PyTS(ts).view if view is not None: view(TS_(ts), Viewer_(vwr)) return FunctionEnd() cdef PetscErrorCode TSStep_Python( PetscTS ts, ) \ except PETSC_ERR_PYTHON with gil: FunctionBegin(b"TSStep_Python") cdef step = PyTS(ts).step if step is not None: step(TS_(ts)) else: TSStep_Python_default(ts) return FunctionEnd() cdef PetscErrorCode TSRollBack_Python( PetscTS ts, ) \ except PETSC_ERR_PYTHON with gil: FunctionBegin(b"TSRollBack_Python") cdef rollback = PyTS(ts).rollback if rollback is None: return UNSUPPORTED(b"rollback") rollback(TS_(ts)) return FunctionEnd() cdef PetscErrorCode TSInterpolate_Python( PetscTS ts, PetscReal t, PetscVec x, ) \ except PETSC_ERR_PYTHON with gil: FunctionBegin(b"TSInterpolate _Python") cdef interpolate = PyTS(ts).interpolate if interpolate is None: return UNSUPPORTED(b"interpolate") interpolate(TS_(ts), toReal(t), Vec_(x)) return FunctionEnd() cdef PetscErrorCode TSEvaluateStep_Python( PetscTS ts, PetscInt o, PetscVec x, PetscBool *flag, ) \ except PETSC_ERR_PYTHON with gil: FunctionBegin(b"TSEvaluateStep _Python") cdef evaluatestep = PyTS(ts).evaluatestep if evaluatestep is None: return UNSUPPORTED(b"evaluatestep") cdef done = evaluatestep(TS_(ts), toInt(o), Vec_(x)) if flag != NULL: flag[0] = PETSC_TRUE if done else PETSC_FALSE elif not done: return PetscSETERR(PETSC_ERR_USER, "Cannot evaluate step") return FunctionEnd() cdef PetscErrorCode SNESTSFormFunction_Python( PetscSNES snes, PetscVec x, PetscVec f, PetscTS ts, ) \ except PETSC_ERR_PYTHON with gil: # cdef formSNESFunction = PyTS(ts).formSNESFunction if formSNESFunction is not None: args = (SNES_(snes), Vec_(x), Vec_(f), TS_(ts)) formSNESFunction(args) return FunctionEnd() # cdef PetscVec dx = NULL CHKERR( PetscObjectQuery( ts, b"@ts.vec_dot", &dx) ) # cdef PetscReal t = ts.ptime + ts.time_step cdef PetscReal a = 1.0/ts.time_step CHKERR( VecCopy(ts.vec_sol, dx) ) CHKERR( VecAXPBY(dx, +a, -a, x) ) CHKERR( TSComputeIFunction(ts, t, x, dx, f, PETSC_FALSE) ) return FunctionEnd() cdef PetscErrorCode SNESTSFormJacobian_Python( PetscSNES snes, PetscVec x, PetscMat A, PetscMat B, PetscTS ts, ) \ except PETSC_ERR_PYTHON with gil: # cdef formSNESJacobian = PyTS(ts).formSNESJacobian if formSNESJacobian is not None: args = (SNES_(snes), Vec_(x), Mat_(A), Mat_(B), TS_(ts)) formSNESJacobian(*args) return FunctionEnd() # cdef PetscVec dx = NULL CHKERR( PetscObjectQuery( ts, b"@ts.vec_dot", &dx) ) # cdef PetscReal t = ts.ptime + ts.time_step cdef PetscReal a = 1.0/ts.time_step CHKERR( VecCopy(ts.vec_sol, dx) ) CHKERR( VecAXPBY(dx, +a, -a, x) ) CHKERR( TSComputeIJacobian(ts, t, x, dx, a, A, B, PETSC_FALSE) ) return FunctionEnd() cdef PetscErrorCode TSSolveStep_Python( PetscTS ts, PetscReal t, PetscVec x, ) \ except PETSC_ERR_PYTHON with gil: FunctionBegin(b"TSSolveStep_Python") # cdef solveStep = PyTS(ts).solveStep if solveStep is not None: solveStep(TS_(ts), t, Vec_(x)) return FunctionEnd() # cdef PetscInt nits = 0, lits = 0 CHKERR( SNESSolve(ts.snes, NULL, x) ) CHKERR( SNESGetIterationNumber(ts.snes, &nits) ) CHKERR( SNESGetLinearSolveIterations(ts.snes, &lits) ) ts.snes_its += nits ts.ksp_its += lits return FunctionEnd() cdef PetscErrorCode TSAdaptStep_Python( PetscTS ts, PetscReal t, PetscVec x, PetscReal *nextdt, PetscBool *stepok, ) \ except PETSC_ERR_PYTHON with gil: FunctionBegin(b"TSAdaptStep_Python") nextdt[0] = ts.time_step stepok[0] = PETSC_TRUE # cdef adaptStep = PyTS(ts).adaptStep if adaptStep is None: return FunctionEnd() cdef object retval cdef double dt cdef bint ok retval = adaptStep(TS_(ts), t, Vec_(x)) if retval is None: pass elif isinstance(retval, float): dt = retval nextdt[0] = dt stepok[0] = PETSC_TRUE elif isinstance(retval, bool): ok = retval nextdt[0] = ts.time_step stepok[0] = PETSC_TRUE if ok else PETSC_FALSE else: dt, ok = retval nextdt[0] = dt stepok[0] = PETSC_TRUE if ok else PETSC_FALSE return FunctionEnd() cdef PetscErrorCode TSStep_Python_default( PetscTS ts, ) \ except PETSC_ERR_PYTHON with gil: FunctionBegin(b"TSStep_Python_default") cdef PetscVec vec_update = NULL CHKERR( PetscObjectQuery( ts, b"@ts.vec_update", &vec_update) ) # cdef PetscInt r = 0 cdef PetscReal tt = ts.ptime cdef PetscReal dt = ts.time_step cdef PetscBool accept = PETSC_TRUE cdef PetscBool stageok = PETSC_TRUE for r from 0 <= r < ts.max_reject: tt = ts.ptime + ts.time_step CHKERR( VecCopy(ts.vec_sol, vec_update) ) CHKERR( TSPreStage(ts, tt+dt) ) TSSolveStep_Python(ts, tt, vec_update) CHKERR( TSPostStage(ts, tt+dt, 0, &vec_update) ); CHKERR( TSAdaptCheckStage(ts.adapt, ts, tt+dt, vec_update, &stageok) ); if not stageok: ts.reject += 1 continue TSAdaptStep_Python(ts, tt, vec_update, &dt, &accept) if not accept: ts.time_step = dt ts.reject += 1 continue CHKERR( VecCopy(vec_update, ts.vec_sol) ) ts.ptime += ts.time_step ts.time_step = dt break if (not stageok or not accept) and ts.reason == 0: ts.reason = TS_DIVERGED_STEP_REJECTED return FunctionEnd() # -------------------------------------------------------------------- cdef extern from * nogil: struct _TaoOps: PetscErrorCode (*destroy)(PetscTAO) except PETSC_ERR_PYTHON PetscErrorCode (*setup)(PetscTAO) except PETSC_ERR_PYTHON PetscErrorCode (*solve)(PetscTAO) except PETSC_ERR_PYTHON PetscErrorCode (*setfromoptions)(PetscTAO,PetscOptionItems*) except PETSC_ERR_PYTHON PetscErrorCode (*view)(PetscTAO,PetscViewer) except PETSC_ERR_PYTHON ctypedef _TaoOps *TaoOps struct _p_TAO: void *data TaoOps ops PetscInt niter, max_it PetscTAOConvergedReason reason PetscInt ksp_its, ksp_tot_its PetscKSP ksp PetscVec gradient PetscVec stepdirection PetscTAOLineSearch linesearch cdef extern from * nogil: # custom.h PetscErrorCode TaoConverged(PetscTAO,PetscTAOConvergedReason*) cdef extern from * nogil: # custom.h PetscErrorCode TaoGetVecs(PetscTAO,PetscVec*,PetscVec*,PetscVec*) PetscErrorCode TaoCheckReals(PetscTAO,PetscReal,PetscReal) PetscErrorCode TaoComputeUpdate(PetscTAO) PetscErrorCode TaoCreateDefaultLineSearch(PetscTAO) PetscErrorCode TaoCreateDefaultKSP(PetscTAO) PetscErrorCode TaoApplyLineSearch(PetscTAO,PetscReal*,PetscReal*,PetscTAOLineSearchConvergedReason*) @cython.internal cdef class _PyTao(_PyObj): pass cdef inline _PyTao PyTao(PetscTAO tao): if tao != NULL and tao.data != NULL: return <_PyTao>tao.data else: return _PyTao.__new__(_PyTao) cdef public PetscErrorCode TaoPythonGetContext(PetscTAO tao, void **ctx) \ except PETSC_ERR_PYTHON: FunctionBegin(b"TaoPythonGetContext") PyTao(tao).getcontext(ctx) return FunctionEnd() cdef public PetscErrorCode TaoPythonSetContext(PetscTAO tao, void *ctx) \ except PETSC_ERR_PYTHON: FunctionBegin(b"TaoPythonSetContext") PyTao(tao).setcontext(ctx, TAO_(tao)) return FunctionEnd() cdef PetscErrorCode TaoPythonSetType_PYTHON(PetscTAO tao, char name[]) \ except PETSC_ERR_PYTHON with gil: FunctionBegin(b"TaoPythonSetType_PYTHON") if name == NULL: return FunctionEnd() # XXX cdef object ctx = createcontext(name) TaoPythonSetContext(tao, ctx) PyTao(tao).setname(name) return FunctionEnd() cdef PetscErrorCode TaoPythonGetType_PYTHON(PetscTAO tao, const char *name[]) \ except PETSC_ERR_PYTHON with gil: FunctionBegin(b"TaoPythonGetType_PYTHON") name[0] = PyTao(tao).getname() return FunctionEnd() cdef PetscErrorCode TaoCreate_Python( PetscTAO tao, ) \ except PETSC_ERR_PYTHON with gil: FunctionBegin(b"TaoCreate_Python") # cdef TaoOps ops = tao.ops ops.destroy = TaoDestroy_Python ops.view = TaoView_Python ops.solve = TaoSolve_Python ops.setup = TaoSetUp_Python ops.setfromoptions = TaoSetFromOptions_Python # CHKERR( PetscObjectComposeFunction( tao, b"TaoPythonSetType_C", TaoPythonSetType_PYTHON) ) CHKERR( PetscObjectComposeFunction( tao, b"TaoPythonGetType_C", TaoPythonGetType_PYTHON) ) # CHKERR( TaoCreateDefaultLineSearch(tao) ) CHKERR( TaoCreateDefaultKSP(tao) ) # cdef ctx = PyTao(NULL) tao.data = ctx Py_INCREF(tao.data) return FunctionEnd() cdef inline PetscErrorCode TaoDestroy_Python_inner( PetscTAO tao, ) \ except PETSC_ERR_PYTHON with gil: try: addRef(tao) TaoPythonSetContext(tao, NULL) finally: delRef(tao) Py_DECREF(tao.data) tao.data = NULL return PETSC_SUCCESS cdef PetscErrorCode TaoDestroy_Python( PetscTAO tao, ) \ except PETSC_ERR_PYTHON nogil: FunctionBegin(b"TaoDestroy_Python") CHKERR( PetscObjectComposeFunction( tao, b"TaoPythonSetType_C", NULL) ) CHKERR( PetscObjectComposeFunction( tao, b"TaoPythonGetType_C", NULL) ) # if Py_IsInitialized(): TaoDestroy_Python_inner(tao) return FunctionEnd() cdef PetscErrorCode TaoSetUp_Python( PetscTAO tao, ) \ except PETSC_ERR_PYTHON with gil: FunctionBegin(b"TaoSetUp_Python") cdef char name[2048] cdef PetscBool found = PETSC_FALSE if PyTao(tao).self is None: CHKERR( PetscOptionsGetString(NULL, getPrefix(tao), b"-tao_python_type", name, sizeof(name), &found) ) if found and name[0]: CHKERR( TaoPythonSetType_PYTHON(tao, name) ) if PyTao(tao).self is None: return PetscSETERR(PETSC_ERR_USER, "Python context not set, call one of \n" " * TaoPythonSetType(tao, \"[package.]module.class\")\n" " * TaoSetFromOptions(tao) and pass option " "-tao_python_type [package.]module.class") # cdef setUp = PyTao(tao).setUp if setUp is not None: setUp(TAO_(tao)) return FunctionEnd() cdef PetscErrorCode TaoSetFromOptions_Python( PetscTAO tao, PetscOptionItems *PetscOptionsObject, ) \ except PETSC_ERR_PYTHON with gil: FunctionBegin(b"TaoSetFromOptions_Python") # cdef char name[2048], *defval = PyTao(tao).getname() cdef PetscBool found = PETSC_FALSE cdef PetscOptionItems *opts "PetscOptionsObject" = PetscOptionsObject CHKERR( PetscOptionsString( b"-tao_python_type", b"Python [package.]module[.{class|function}]", b"TaoPythonSetType", defval, name, sizeof(name), &found) ); opts; if found and name[0]: CHKERR( TaoPythonSetType_PYTHON(tao, name) ) # cdef setFromOptions = PyTao(tao).setFromOptions if setFromOptions is not None: setFromOptions(TAO_(tao)) CHKERR( KSPSetFromOptions(tao.ksp) ) return FunctionEnd() cdef PetscErrorCode TaoView_Python( PetscTAO tao, PetscViewer vwr, ) \ except PETSC_ERR_PYTHON with gil: FunctionBegin(b"TaoView_Python") viewcontext(PyTao(tao), vwr) cdef view = PyTao(tao).view if view is not None: view(TAO_(tao), Viewer_(vwr)) return FunctionEnd() cdef PetscErrorCode TaoSolve_Python( PetscTAO tao, ) \ except PETSC_ERR_PYTHON with gil: FunctionBegin(b"TaoSolve_Python") # tao.niter = 0 tao.ksp_its = 0 tao.reason = TAO_CONTINUE_ITERATING # cdef solve = PyTao(tao).solve if solve is not None: solve(TAO_(tao)) else: TaoSolve_Python_default(tao) # return FunctionEnd() cdef PetscErrorCode TaoSolve_Python_default( PetscTAO tao, ) \ except PETSC_ERR_PYTHON with gil: FunctionBegin(b"TaoSolve_Python_default") # cdef PetscVec X = NULL, G = NULL, S = NULL CHKERR( TaoGetVecs(tao, &X, &G, &S) ) # cdef PetscReal f = 0.0 cdef PetscReal gnorm = 0.0 cdef PetscReal step = 1.0 # if G != NULL: CHKERR( TaoComputeObjectiveAndGradient(tao, X, &f, G) ) CHKERR( VecNorm(G, PETSC_NORM_2, &gnorm) ) else: CHKERR( TaoComputeObjective(tao, X, &f) ) CHKERR( TaoCheckReals(tao, f, gnorm) ) CHKERR( TaoLogConvergenceHistory(tao, f, gnorm, 0.0, tao.ksp_its) ) CHKERR( TaoMonitor(tao, tao.niter, f, gnorm, 0.0, step) ) CHKERR( TaoConverged(tao, &tao.reason) ) cdef PetscObjectState ostate = -1 cdef PetscObjectState nstate = -1 cdef PetscInt its = 0 cdef PetscTAOLineSearchConvergedReason lsr = TAOLINESEARCH_SUCCESS for its from 0 <= its < tao.max_it: if tao.reason: break CHKERR( PetscObjectStateGet(X, &ostate) ) CHKERR( TaoComputeUpdate(tao) ) TaoPreStep_Python(tao) CHKERR( PetscObjectStateGet(X, &nstate) ) if ostate != nstate: if G != NULL: CHKERR( TaoComputeObjectiveAndGradient(tao, X, &f, G) ) CHKERR( VecNorm(G, PETSC_NORM_2, &gnorm) ) else: CHKERR( TaoComputeObjective(tao, X, &f) ) # tao.ksp_its = 0 TaoStep_Python(tao, X, G, S) CHKERR( KSPGetIterationNumber(tao.ksp, &tao.ksp_its) ) tao.ksp_tot_its += tao.ksp_its # if G != NULL: CHKERR( TaoApplyLineSearch(tao, &f, &step, &lsr) ) CHKERR( VecNorm(G, PETSC_NORM_2, &gnorm) ) if lsr < TAOLINESEARCH_CONTINUE_ITERATING: tao.reason = TAO_DIVERGED_LS_FAILURE else: CHKERR( TaoComputeObjective(tao, X, &f) ) CHKERR( TaoCheckReals(tao, f, gnorm) ) tao.niter += 1 # TaoPostStep_Python(tao) CHKERR( TaoLogConvergenceHistory(tao, f, gnorm, 0.0, tao.ksp_its) ) CHKERR( TaoMonitor(tao, tao.niter, f, gnorm, 0.0, step) ) CHKERR( TaoConverged(tao, &tao.reason) ) if tao.niter == tao.max_it: if tao.reason <= 0: tao.reason = TAO_DIVERGED_MAXITS # return FunctionEnd() cdef PetscErrorCode TaoStep_Python( PetscTAO tao, PetscVec X, PetscVec G, PetscVec S, ) \ except PETSC_ERR_PYTHON with gil: FunctionBegin(b"TaoStep_Python") cdef step = PyTao(tao).step if step is not None: step(TAO_(tao), Vec_(X), Vec_(G) if G != NULL else None, Vec_(S) if S != NULL else None) else: # TaoStep_Python_default(tao,X,G,S) CHKERR( TaoComputeGradient(tao, X, S) ) CHKERR( VecCopy(G, S) ) CHKERR( VecScale(S, -1.0) ) return FunctionEnd() cdef PetscErrorCode TaoPreStep_Python( PetscTAO tao, ) \ except PETSC_ERR_PYTHON with gil: FunctionBegin(b"TaoPreStep_Python") cdef preStep = PyTao(tao).preStep if preStep is not None: preStep(TAO_(tao)) return FunctionEnd() cdef PetscErrorCode TaoPostStep_Python( PetscTAO tao, ) \ except PETSC_ERR_PYTHON with gil: FunctionBegin(b"TaoPostStep_Python") cdef postStep = PyTao(tao).postStep if postStep is not None: postStep(TAO_(tao)) return FunctionEnd() # -------------------------------------------------------------------- cdef PetscErrorCode PetscPythonMonitorSet_Python( PetscObject obj_p, const char *url_p, ) \ except PETSC_ERR_PYTHON with gil: FunctionBegin(b"PetscPythonMonitorSet_Python") assert obj_p != NULL assert url_p != NULL assert url_p[0] != 0 # cdef PetscClassId classid = 0 CHKERR( PetscObjectGetClassId(obj_p, &classid) ) cdef type klass = PyPetscType_Lookup(classid) cdef Object ob = klass() ob.obj[0] = newRef(obj_p) # cdef url = bytes2str(url_p) if ':' in url: path, names = parse_url(url) else: path, names = url, 'monitor' module = load_module(path) for attr in names.split(','): monitor = getattr(module, attr) if isinstance(monitor, type): monitor = monitor(ob) ob.setMonitor(monitor) # return FunctionEnd() # -------------------------------------------------------------------- cdef extern from * nogil: ctypedef PetscErrorCode MatCreateFunction (PetscMat) except PETSC_ERR_PYTHON ctypedef PetscErrorCode PCCreateFunction (PetscPC) except PETSC_ERR_PYTHON ctypedef PetscErrorCode KSPCreateFunction (PetscKSP) except PETSC_ERR_PYTHON ctypedef PetscErrorCode SNESCreateFunction (PetscSNES) except PETSC_ERR_PYTHON ctypedef PetscErrorCode TSCreateFunction (PetscTS) except PETSC_ERR_PYTHON ctypedef PetscErrorCode TaoCreateFunction (PetscTAO) except PETSC_ERR_PYTHON PetscErrorCode MatRegister (const char[],MatCreateFunction* ) PetscErrorCode PCRegister (const char[],PCCreateFunction* ) PetscErrorCode KSPRegister (const char[],KSPCreateFunction* ) PetscErrorCode SNESRegister (const char[],SNESCreateFunction*) PetscErrorCode TSRegister (const char[],TSCreateFunction* ) PetscErrorCode TaoRegister (const char[],TaoCreateFunction* ) PetscErrorCode (*PetscPythonMonitorSet_C) \ (PetscObject, const char[]) except PETSC_ERR_PYTHON cdef public PetscErrorCode PetscPythonRegisterAll() except PETSC_ERR_PYTHON: FunctionBegin(b"PetscPythonRegisterAll") # Python subtypes CHKERR( MatRegister ( MATPYTHON, MatCreate_Python ) ) CHKERR( PCRegister ( PCPYTHON, PCCreate_Python ) ) CHKERR( KSPRegister ( KSPPYTHON, KSPCreate_Python ) ) CHKERR( SNESRegister( SNESPYTHON, SNESCreate_Python ) ) CHKERR( TSRegister ( TSPYTHON, TSCreate_Python ) ) CHKERR( TaoRegister ( TAOPYTHON, TaoCreate_Python ) ) # Python monitors global PetscPythonMonitorSet_C PetscPythonMonitorSet_C = PetscPythonMonitorSet_Python return FunctionEnd() # -------------------------------------------------------------------- ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/src/petsc4py/PETSc/petscao.pxi0000644000175000017500000000205414567251135020030 0ustar00balaybalaycdef extern from * nogil: ctypedef const char* PetscAOType "AOType" PetscAOType AOBASIC PetscAOType AOADVANCED PetscAOType AOMAPPING PetscAOType AOMEMORYSCALABLE PetscErrorCode AOView(PetscAO,PetscViewer) PetscErrorCode AODestroy(PetscAO*) PetscErrorCode AOCreateBasic(MPI_Comm,PetscInt,const PetscInt[],const PetscInt[],PetscAO*) PetscErrorCode AOCreateBasicIS(PetscIS,PetscIS,PetscAO*) PetscErrorCode AOCreateMemoryScalable(MPI_Comm,PetscInt,const PetscInt[],const PetscInt[],PetscAO*) PetscErrorCode AOCreateMemoryScalableIS(PetscIS,PetscIS,PetscAO*) PetscErrorCode AOCreateMapping(MPI_Comm,PetscInt,const PetscInt[],const PetscInt[],PetscAO*) PetscErrorCode AOCreateMappingIS(PetscIS,PetscIS,PetscAO*) PetscErrorCode AOGetType(PetscAO,PetscAOType*) PetscErrorCode AOApplicationToPetsc(PetscAO,PetscInt,PetscInt[]) PetscErrorCode AOApplicationToPetscIS(PetscAO,PetscIS) PetscErrorCode AOPetscToApplication(PetscAO,PetscInt,PetscInt[]) PetscErrorCode AOPetscToApplicationIS(PetscAO,PetscIS) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/src/petsc4py/PETSc/petscdef.pxi0000644000175000017500000000407614567251135020175 0ustar00balaybalaycdef extern from * nogil: enum: PETSC_DECIDE enum: PETSC_DEFAULT enum: PETSC_DETERMINE PetscReal PETSC_INFINITY PetscReal PETSC_NINFINITY ctypedef enum PetscBool: PETSC_FALSE PETSC_TRUE ctypedef enum PetscInsertMode "InsertMode": PETSC_NOT_SET_VALUES "NOT_SET_VALUES" PETSC_INSERT_VALUES "INSERT_VALUES" PETSC_ADD_VALUES "ADD_VALUES" PETSC_MAX_VALUES "MAX_VALUES" PETSC_INSERT_ALL_VALUES "INSERT_ALL_VALUES" PETSC_ADD_ALL_VALUES "ADD_ALL_VALUES" PETSC_INSERT_BC_VALUES "INSERT_BC_VALUES" PETSC_ADD_BC_VALUES "ADD_BC_VALUES" ctypedef enum PetscScatterMode "ScatterMode": PETSC_SCATTER_FORWARD "SCATTER_FORWARD" PETSC_SCATTER_REVERSE "SCATTER_REVERSE" PETSC_SCATTER_FORWARD_LOCAL "SCATTER_FORWARD_LOCAL" PETSC_SCATTER_REVERSE_LOCAL "SCATTER_REVERSE_LOCAL" ctypedef enum PetscNormType "NormType": PETSC_NORM_1 "NORM_1" PETSC_NORM_2 "NORM_2" PETSC_NORM_1_AND_2 "NORM_1_AND_2" PETSC_NORM_FROBENIUS "NORM_FROBENIUS" PETSC_NORM_INFINITY "NORM_INFINITY" PETSC_NORM_MAX "NORM_MAX" ctypedef enum PetscCopyMode: PETSC_COPY_VALUES PETSC_OWN_POINTER PETSC_USE_POINTER cdef inline PetscInsertMode insertmode(object mode) \ except (-1): if mode is None: return PETSC_INSERT_VALUES elif mode is True: return PETSC_ADD_VALUES elif mode is False: return PETSC_INSERT_VALUES else: return mode cdef inline PetscScatterMode scattermode(object mode) \ except (-1): if mode is None: return PETSC_SCATTER_FORWARD if mode is False: return PETSC_SCATTER_FORWARD if mode is True: return PETSC_SCATTER_REVERSE if isinstance(mode, str): if mode == 'forward': return PETSC_SCATTER_FORWARD if mode == 'reverse': return PETSC_SCATTER_REVERSE else: raise ValueError("unknown scatter mode: %s" % mode) return mode ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/src/petsc4py/PETSc/petscdevice.pxi0000644000175000017500000001121214567251135020664 0ustar00balaybalay# -------------------------------------------------------------------- cdef extern from * nogil: ctypedef enum PetscOffloadMask: PETSC_OFFLOAD_UNALLOCATED PETSC_OFFLOAD_CPU PETSC_OFFLOAD_GPU PETSC_OFFLOAD_BOTH PETSC_OFFLOAD_KOKKOS ctypedef enum PetscMemType: PETSC_MEMTYPE_HOST PETSC_MEMTYPE_CUDA PETSC_MEMTYPE_HIP PETSC_MEMTYPE_SYCL ctypedef enum PetscDeviceType: PETSC_DEVICE_HOST PETSC_DEVICE_CUDA PETSC_DEVICE_HIP PETSC_DEVICE_SYCL ctypedef enum PetscStreamType: PETSC_STREAM_GLOBAL_BLOCKING PETSC_STREAM_DEFAULT_BLOCKING PETSC_STREAM_GLOBAL_NONBLOCKING ctypedef enum PetscDeviceContextJoinMode: PETSC_DEVICE_CONTEXT_JOIN_DESTROY PETSC_DEVICE_CONTEXT_JOIN_SYNC PETSC_DEVICE_CONTEXT_JOIN_NO_SYNC PetscErrorCode PetscDeviceCreate(PetscDeviceType, PetscInt, PetscDevice *) PetscErrorCode PetscDeviceDestroy(PetscDevice *) PetscErrorCode PetscDeviceConfigure(PetscDevice) PetscErrorCode PetscDeviceView(PetscDevice, PetscViewer) PetscErrorCode PetscDeviceGetType(PetscDevice, PetscDeviceType *) PetscErrorCode PetscDeviceGetDeviceId(PetscDevice, PetscInt *) PetscDeviceType PETSC_DEVICE_DEFAULT() PetscErrorCode PetscDeviceSetDefaultDeviceType(PetscDeviceType) PetscErrorCode PetscDeviceInitialize(PetscDeviceType) PetscBool PetscDeviceInitialized(PetscDeviceType) PetscErrorCode PetscDeviceContextCreate(PetscDeviceContext *) PetscErrorCode PetscDeviceContextDestroy(PetscDeviceContext *) PetscErrorCode PetscDeviceContextSetStreamType(PetscDeviceContext, PetscStreamType) PetscErrorCode PetscDeviceContextGetStreamType(PetscDeviceContext, PetscStreamType *) PetscErrorCode PetscDeviceContextSetDevice(PetscDeviceContext, PetscDevice) PetscErrorCode PetscDeviceContextGetDevice(PetscDeviceContext, PetscDevice *) PetscErrorCode PetscDeviceContextGetDeviceType(PetscDeviceContext, PetscDeviceType *) PetscErrorCode PetscDeviceContextSetUp(PetscDeviceContext) PetscErrorCode PetscDeviceContextDuplicate(PetscDeviceContext, PetscDeviceContext *) PetscErrorCode PetscDeviceContextQueryIdle(PetscDeviceContext, PetscBool *) PetscErrorCode PetscDeviceContextWaitForContext(PetscDeviceContext, PetscDeviceContext) PetscErrorCode PetscDeviceContextForkWithStreamType(PetscDeviceContext, PetscStreamType, PetscInt, PetscDeviceContext **) PetscErrorCode PetscDeviceContextFork(PetscDeviceContext, PetscInt, PetscDeviceContext **) PetscErrorCode PetscDeviceContextJoin(PetscDeviceContext, PetscInt, PetscDeviceContextJoinMode, PetscDeviceContext **) PetscErrorCode PetscDeviceContextSynchronize(PetscDeviceContext) PetscErrorCode PetscDeviceContextSetFromOptions(MPI_Comm, PetscDeviceContext) PetscErrorCode PetscDeviceContextView(PetscDeviceContext, PetscViewer) PetscErrorCode PetscDeviceContextViewFromOptions(PetscDeviceContext, PetscObject, const char name[]) PetscErrorCode PetscDeviceContextGetCurrentContext(PetscDeviceContext *) PetscErrorCode PetscDeviceContextSetCurrentContext(PetscDeviceContext) cdef inline PetscDeviceType asDeviceType(object dtype) except (-1): if isinstance(dtype, str): dtype = dtype.upper() try: return getattr(Device.Type, dtype) except AttributeError: raise ValueError("unknown device type: %s" % dtype) return dtype cdef inline str toDeviceType(PetscDeviceType dtype): try: return Device.Type.__enum2str[dtype] except KeyError: raise NotImplementedError("unhandled PetscDeviceType %d" % dtype) cdef inline PetscStreamType asStreamType(object stype) except (-1): if isinstance(stype, str): stype = stype.upper() try: return getattr(DeviceContext.StreamType, stype) except AttributeError: raise ValueError("unknown stream type: %s" % stype) return stype cdef inline str toStreamType(PetscStreamType stype): try: return DeviceContext.StreamType.__enum2str[stype] except KeyError: raise NotImplementedError("unhandled PetscStreamType %d" % stype) cdef inline PetscDeviceContextJoinMode asJoinMode(object jmode) except (-1): if isinstance(jmode, str): jmode = jmode.upper() try: return getattr(DeviceContext.JoinMode, jmode) except AttributeError: raise ValueError("unknown join mode: %s" % jmode) return jmode cdef inline str toJoinMode(PetscDeviceContextJoinMode jmode): try: return DeviceContext.JoinMode.__enum2str[jmode] except KeyError: raise NotImplementedError("unhandled PetscDeviceContextJoinMode %d" % jmode) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/src/petsc4py/PETSc/petscdm.pxi0000644000175000017500000003016414567251135020034 0ustar00balaybalay# -------------------------------------------------------------------- cdef extern from * nogil: ctypedef const char* PetscDMType "DMType" PetscDMType DMDA_type "DMDA" PetscDMType DMCOMPOSITE PetscDMType DMSLICED PetscDMType DMSHELL PetscDMType DMPLEX PetscDMType DMREDUNDANT PetscDMType DMPATCH PetscDMType DMMOAB PetscDMType DMNETWORK PetscDMType DMFOREST PetscDMType DMP4EST PetscDMType DMP8EST PetscDMType DMSWARM PetscDMType DMPRODUCT PetscDMType DMSTAG ctypedef enum PetscDMBoundaryType"DMBoundaryType": DM_BOUNDARY_NONE DM_BOUNDARY_GHOSTED DM_BOUNDARY_MIRROR DM_BOUNDARY_PERIODIC DM_BOUNDARY_TWIST ctypedef enum PetscDMPolytopeType "DMPolytopeType": DM_POLYTOPE_POINT DM_POLYTOPE_SEGMENT DM_POLYTOPE_POINT_PRISM_TENSOR DM_POLYTOPE_TRIANGLE DM_POLYTOPE_QUADRILATERAL DM_POLYTOPE_SEG_PRISM_TENSOR DM_POLYTOPE_TETRAHEDRON DM_POLYTOPE_HEXAHEDRON DM_POLYTOPE_TRI_PRISM DM_POLYTOPE_TRI_PRISM_TENSOR DM_POLYTOPE_QUAD_PRISM_TENSOR DM_POLYTOPE_PYRAMID DM_POLYTOPE_FV_GHOST DM_POLYTOPE_INTERIOR_GHOST DM_POLYTOPE_UNKNOWN DM_NUM_POLYTOPES ctypedef PetscErrorCode (*PetscDMCoarsenHook)(PetscDM, PetscDM, void*) except PETSC_ERR_PYTHON ctypedef PetscErrorCode (*PetscDMRestrictHook)(PetscDM, PetscMat, PetscVec, PetscMat, PetscDM, void*) except PETSC_ERR_PYTHON PetscErrorCode DMCreate(MPI_Comm,PetscDM*) PetscErrorCode DMClone(PetscDM,PetscDM*) PetscErrorCode DMDestroy(PetscDM*) PetscErrorCode DMView(PetscDM,PetscViewer) PetscErrorCode DMLoad(PetscDM,PetscViewer) PetscErrorCode DMSetType(PetscDM,PetscDMType) PetscErrorCode DMGetType(PetscDM,PetscDMType*) PetscErrorCode DMGetDimension(PetscDM,PetscInt*) PetscErrorCode DMSetDimension(PetscDM,PetscInt) PetscErrorCode DMSetOptionsPrefix(PetscDM,char[]) PetscErrorCode DMGetOptionsPrefix(PetscDM,char*[]) PetscErrorCode DMAppendOptionsPrefix(PetscDM,char[]) PetscErrorCode DMSetFromOptions(PetscDM) PetscErrorCode DMViewFromOptions(PetscDM,PetscObject,char[]) PetscErrorCode DMSetUp(PetscDM) PetscErrorCode DMGetAdjacency(PetscDM,PetscInt,PetscBool*,PetscBool*) PetscErrorCode DMSetAdjacency(PetscDM,PetscInt,PetscBool,PetscBool) PetscErrorCode DMGetBasicAdjacency(PetscDM,PetscBool*,PetscBool*) PetscErrorCode DMSetBasicAdjacency(PetscDM,PetscBool,PetscBool) PetscErrorCode DMSetNumFields(PetscDM,PetscInt) PetscErrorCode DMGetNumFields(PetscDM,PetscInt*) PetscErrorCode DMSetField(PetscDM,PetscInt,PetscDMLabel,PetscObject) PetscErrorCode DMAddField(PetscDM,PetscDMLabel,PetscObject) PetscErrorCode DMGetField(PetscDM,PetscInt,PetscDMLabel*,PetscObject*) PetscErrorCode DMClearFields(PetscDM) PetscErrorCode DMCopyFields(PetscDM,PetscDM) PetscErrorCode DMCreateDS(PetscDM) PetscErrorCode DMClearDS(PetscDM) PetscErrorCode DMGetDS(PetscDM,PetscDS*) PetscErrorCode DMCopyDS(PetscDM,PetscDM) PetscErrorCode DMCopyDisc(PetscDM,PetscDM) PetscErrorCode DMGetBlockSize(PetscDM,PetscInt*) PetscErrorCode DMSetVecType(PetscDM,PetscVecType) PetscErrorCode DMCreateLocalVector(PetscDM,PetscVec*) PetscErrorCode DMCreateGlobalVector(PetscDM,PetscVec*) PetscErrorCode DMGetLocalVector(PetscDM,PetscVec*) PetscErrorCode DMRestoreLocalVector(PetscDM,PetscVec*) PetscErrorCode DMGetGlobalVector(PetscDM,PetscVec*) PetscErrorCode DMRestoreGlobalVector(PetscDM,PetscVec*) PetscErrorCode DMSetMatType(PetscDM,PetscMatType) PetscErrorCode DMCreateMatrix(PetscDM,PetscMat*) PetscErrorCode DMCreateMassMatrix(PetscDM,PetscDM,PetscMat*) PetscErrorCode DMGetCoordinateDM(PetscDM,PetscDM*) PetscErrorCode DMGetCoordinateSection(PetscDM,PetscSection*) PetscErrorCode DMSetCoordinates(PetscDM,PetscVec) PetscErrorCode DMGetCoordinates(PetscDM,PetscVec*) PetscErrorCode DMSetCoordinatesLocal(PetscDM,PetscVec) PetscErrorCode DMGetCoordinatesLocal(PetscDM,PetscVec*) PetscErrorCode DMGetCoordinateDim(PetscDM,PetscInt*) PetscErrorCode DMSetCoordinateDim(PetscDM,PetscInt) PetscErrorCode DMLocalizeCoordinates(PetscDM) PetscErrorCode DMProjectCoordinates(PetscDM, PetscFE) PetscErrorCode DMCreateInterpolation(PetscDM,PetscDM,PetscMat*,PetscVec*) PetscErrorCode DMCreateInjection(PetscDM,PetscDM,PetscMat*) PetscErrorCode DMCreateRestriction(PetscDM,PetscDM,PetscMat*) PetscErrorCode DMConvert(PetscDM,PetscDMType,PetscDM*) PetscErrorCode DMRefine(PetscDM,MPI_Comm,PetscDM*) PetscErrorCode DMCoarsen(PetscDM,MPI_Comm,PetscDM*) PetscErrorCode DMRefineHierarchy(PetscDM,PetscInt,PetscDM[]) PetscErrorCode DMCoarsenHierarchy(PetscDM,PetscInt,PetscDM[]) PetscErrorCode DMGetRefineLevel(PetscDM,PetscInt*) PetscErrorCode DMSetRefineLevel(PetscDM,PetscInt) PetscErrorCode DMGetCoarsenLevel(PetscDM,PetscInt*) PetscErrorCode DMGetCoarseDM(PetscDM,PetscDM*) PetscErrorCode DMSetCoarseDM(PetscDM,PetscDM) PetscErrorCode DMAdaptLabel(PetscDM,PetscDMLabel,PetscDM*) PetscErrorCode DMAdaptMetric(PetscDM,PetscVec,PetscDMLabel,PetscDMLabel,PetscDM*) PetscErrorCode DMGlobalToLocalBegin(PetscDM,PetscVec,PetscInsertMode,PetscVec) PetscErrorCode DMGlobalToLocalEnd(PetscDM,PetscVec,PetscInsertMode,PetscVec) PetscErrorCode DMLocalToGlobalBegin(PetscDM,PetscVec,PetscInsertMode,PetscVec) PetscErrorCode DMLocalToGlobalEnd(PetscDM,PetscVec,PetscInsertMode,PetscVec) PetscErrorCode DMLocalToLocalBegin(PetscDM,PetscVec,PetscInsertMode,PetscVec) PetscErrorCode DMLocalToLocalEnd(PetscDM,PetscVec,PetscInsertMode,PetscVec) PetscErrorCode DMGetLocalToGlobalMapping(PetscDM,PetscLGMap*) PetscErrorCode DMSetSection(PetscDM,PetscSection) PetscErrorCode DMGetSection(PetscDM,PetscSection*) PetscErrorCode DMSetLocalSection(PetscDM,PetscSection) PetscErrorCode DMGetLocalSection(PetscDM,PetscSection*) PetscErrorCode DMSetGlobalSection(PetscDM,PetscSection) PetscErrorCode DMGetGlobalSection(PetscDM,PetscSection*) PetscErrorCode DMCreateSectionSF(PetscDM,PetscSection,PetscSection) PetscErrorCode DMGetSectionSF(PetscDM,PetscSF*) PetscErrorCode DMSetSectionSF(PetscDM,PetscSF) PetscErrorCode DMGetPointSF(PetscDM,PetscSF*) PetscErrorCode DMSetPointSF(PetscDM,PetscSF) PetscErrorCode DMCreateSubDM(PetscDM, PetscInt, const PetscInt[], PetscIS*, PetscDM*) PetscErrorCode DMSetAuxiliaryVec(PetscDM, PetscDMLabel, PetscInt, PetscInt, PetscVec) PetscErrorCode DMGetAuxiliaryVec(PetscDM, PetscDMLabel, PetscInt, PetscInt, PetscVec*) PetscErrorCode DMCreateLabel(PetscDM,const char[]) PetscErrorCode DMGetLabelValue(PetscDM,const char[],PetscInt,PetscInt*) PetscErrorCode DMSetLabelValue(PetscDM,const char[],PetscInt,PetscInt) PetscErrorCode DMHasLabel(PetscDM,const char[],PetscBool*) PetscErrorCode DMClearLabelValue(PetscDM,const char[],PetscInt,PetscInt) PetscErrorCode DMGetLabelSize(PetscDM,const char[],PetscInt*) PetscErrorCode DMGetLabelIdIS(PetscDM,const char[],PetscIS*) PetscErrorCode DMGetStratumSize(PetscDM,const char[],PetscInt,PetscInt*) PetscErrorCode DMGetStratumIS(PetscDM,const char[],PetscInt,PetscIS*) PetscErrorCode DMClearLabelStratum(PetscDM,const char[],PetscInt) PetscErrorCode DMSetLabelOutput(PetscDM,const char[],PetscBool) PetscErrorCode DMGetLabelOutput(PetscDM,const char[],PetscBool*) PetscErrorCode DMGetNumLabels(PetscDM,PetscInt*) PetscErrorCode DMGetLabelName(PetscDM,PetscInt,const char**) PetscErrorCode DMHasLabel(PetscDM,const char[],PetscBool*) PetscErrorCode DMGetLabel(PetscDM,const char*,PetscDMLabel*) PetscErrorCode DMAddLabel(PetscDM,PetscDMLabel) PetscErrorCode DMRemoveLabel(PetscDM,const char[],PetscDMLabel*) PetscErrorCode DMLabelDestroy(PetscDMLabel *) #int DMCopyLabels(PetscDM,PetscDM) PetscErrorCode DMShellSetGlobalVector(PetscDM,PetscVec) PetscErrorCode DMShellSetLocalVector(PetscDM,PetscVec) PetscErrorCode DMKSPSetComputeOperators(PetscDM,PetscKSPComputeOpsFunction,void*) PetscErrorCode DMCreateFieldDecomposition(PetscDM,PetscInt*,char***,PetscIS**,PetscDM**) PetscErrorCode DMSNESSetFunction(PetscDM,PetscSNESFunctionFunction,void*) PetscErrorCode DMSNESSetJacobian(PetscDM,PetscSNESJacobianFunction,void*) PetscErrorCode DMCoarsenHookAdd(PetscDM,PetscDMCoarsenHook,PetscDMRestrictHook,void*) # -------------------------------------------------------------------- cdef inline PetscDMBoundaryType asBoundaryType(object boundary) \ except (-1): if boundary is None: return DM_BOUNDARY_NONE if boundary is False: return DM_BOUNDARY_NONE if boundary is True: return DM_BOUNDARY_PERIODIC if isinstance(boundary, str): if boundary == 'none': return DM_BOUNDARY_NONE elif boundary == 'ghosted': return DM_BOUNDARY_GHOSTED elif boundary == 'mirror': return DM_BOUNDARY_MIRROR elif boundary == 'periodic': return DM_BOUNDARY_PERIODIC elif boundary == 'twist': return DM_BOUNDARY_TWIST else: raise ValueError("unknown boundary type: %s" % boundary) return boundary cdef inline PetscInt asBoundary(object boundary, PetscDMBoundaryType *_x, PetscDMBoundaryType *_y, PetscDMBoundaryType *_z) except -1: cdef PetscInt dim = 0 cdef object x=None, y=None, z=None if (boundary is None or isinstance(boundary, str) or isinstance(boundary, int)): _x[0] = _y[0] = _z[0] = asBoundaryType(boundary) else: _x[0] = _y[0] = _z[0] = DM_BOUNDARY_NONE boundary = tuple(boundary) dim = len(boundary) if dim == 0: pass elif dim == 1: (x,) = boundary elif dim == 2: (x, y) = boundary elif dim == 3: (x, y, z) = boundary if dim >= 1: _x[0] = asBoundaryType(x) if dim >= 2: _y[0] = asBoundaryType(y) if dim >= 3: _z[0] = asBoundaryType(z) return dim cdef inline object toBoundary(PetscInt dim, PetscDMBoundaryType x, PetscDMBoundaryType y, PetscDMBoundaryType z): if dim == 0: return () elif dim == 1: return (x,) elif dim == 2: return (x, y) elif dim == 3: return (x, y, z) # ----------------------------------------------------------------------------- cdef inline DM ref_DM(PetscDM dm): cdef DM ob = DM() ob.dm = dm CHKERR( PetscINCREF(ob.obj) ) return ob # -------------------------------------------------------------------- cdef PetscErrorCode DM_PyCoarsenHook( PetscDM fine, PetscDM coarse, void* ctx, ) except PETSC_ERR_PYTHON with gil: cdef DM Fine = ref_DM(fine) cdef DM Coarse = ref_DM(coarse) cdef object hooks = Fine.get_attr('__coarsenhooks__') assert hooks is not None and type(hooks) is list for hook in hooks: (hookop, args, kargs) = hook hookop(Fine, Coarse, *args, **kargs) return PETSC_SUCCESS cdef PetscErrorCode DM_PyRestrictHook( PetscDM fine, PetscMat mrestrict, PetscVec rscale, PetscMat inject, PetscDM coarse, void* ctx, ) except PETSC_ERR_PYTHON with gil: cdef DM Fine = ref_DM(fine) cdef Mat Mrestrict = ref_Mat(mrestrict) cdef Vec Rscale = ref_Vec(rscale) cdef Mat Inject = ref_Mat(inject) cdef DM Coarse = ref_DM(coarse) cdef object hooks = Fine.get_attr('__restricthooks__') assert hooks is not None and type(hooks) is list for hook in hooks: (hookop, args, kargs) = hook hookop(Fine, Mrestrict, Rscale, Inject, Coarse, *args, **kargs) return PETSC_SUCCESS # ----------------------------------------------------------------------------- ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/src/petsc4py/PETSc/petscdmcomposite.pxi0000644000175000017500000000436114567251135021757 0ustar00balaybalay# -------------------------------------------------------------------- cdef extern from * nogil: PetscErrorCode DMCompositeCreate(MPI_Comm,PetscDM*) PetscErrorCode DMCompositeAddDM(PetscDM,PetscDM) PetscErrorCode DMCompositeGetNumberDM(PetscDM,PetscInt*) PetscErrorCode DMCompositeScatterArray(PetscDM,PetscVec,PetscVec*) PetscErrorCode DMCompositeGatherArray(PetscDM,PetscInsertMode,PetscVec,PetscVec*) PetscErrorCode DMCompositeGetEntriesArray(PetscDM,PetscDM*) PetscErrorCode DMCompositeGetAccessArray(PetscDM,PetscVec,PetscInt,const PetscInt*,PetscVec*) PetscErrorCode DMCompositeRestoreAccessArray(PetscDM,PetscVec,PetscInt,const PetscInt*,PetscVec*) PetscErrorCode DMCompositeGetGlobalISs(PetscDM,PetscIS**) PetscErrorCode DMCompositeGetLocalISs(PetscDM,PetscIS**) PetscErrorCode DMCompositeGetISLocalToGlobalMappings(PetscDM,PetscLGMap**) cdef class _DMComposite_access: cdef PetscDM dm cdef PetscVec gvec cdef PetscInt nlocs cdef PetscInt *locs cdef PetscVec *vecs cdef object locs_mem cdef object vecs_mem cdef object access def __cinit__(self, DM dm, Vec gvec, locs=None): self.dm = dm.dm CHKERR( PetscINCREF(&self.dm) ) self.gvec = gvec.vec CHKERR( PetscINCREF(&self.gvec) ) if locs is None: CHKERR( DMCompositeGetNumberDM(self.dm, &self.nlocs) ) locs = arange(0, self.nlocs, 1) self.locs_mem = iarray_i(locs, &self.nlocs, &self.locs) self.vecs_mem = oarray_p(empty_p(self.nlocs), NULL, &self.vecs) self.access = None def __dealloc__(self): CHKERR( DMDestroy(&self.dm) ) CHKERR( VecDestroy(&self.gvec) ) def __enter__(self): cdef Py_ssize_t i, n = self.nlocs CHKERR( DMCompositeGetAccessArray(self.dm, self.gvec, self.nlocs, self.locs, self.vecs) ) self.access = [ref_Vec(self.vecs[i]) for i from 0 <= i < n] return tuple(self.access) def __exit__(self, *exc): cdef Py_ssize_t i, n = self.nlocs for i from 0 <= i < n: (self.access[i]).vec = NULL CHKERR( DMCompositeRestoreAccessArray(self.dm, self.gvec, self.nlocs, self.locs, self.vecs) ) self.access = None ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/src/petsc4py/PETSc/petscdmda.pxi0000644000175000017500000003036714567251135020346 0ustar00balaybalay# -------------------------------------------------------------------- cdef extern from * nogil: ctypedef enum PetscDMDAStencilType"DMDAStencilType": DMDA_STENCIL_STAR DMDA_STENCIL_BOX ctypedef enum PetscDMDAInterpolationType"DMDAInterpolationType": DMDA_INTERPOLATION_Q0 "DMDA_Q0" DMDA_INTERPOLATION_Q1 "DMDA_Q1" ctypedef enum PetscDMDAElementType"DMDAElementType": DMDA_ELEMENT_P1 DMDA_ELEMENT_Q1 PetscErrorCode DMDACreateND(MPI_Comm, PetscInt,PetscInt, # dim, dof PetscInt,PetscInt,PetscInt, # M, N, P PetscInt,PetscInt,PetscInt, # m, n, p PetscInt[],PetscInt[],PetscInt[], # lx, ly, lz PetscDMBoundaryType, # bx PetscDMBoundaryType, # by PetscDMBoundaryType, # bz PetscDMDAStencilType, # stencil type PetscInt, # stencil width PetscDM*) PetscErrorCode DMDASetDof(PetscDM,PetscInt) PetscErrorCode DMDASetSizes(PetscDM,PetscInt,PetscInt,PetscInt) PetscErrorCode DMDASetNumProcs(PetscDM,PetscInt,PetscInt,PetscInt) PetscErrorCode DMDASetBoundaryType(PetscDM,PetscDMBoundaryType,PetscDMBoundaryType,PetscDMBoundaryType) PetscErrorCode DMDASetStencilType(PetscDM,PetscDMDAStencilType) PetscErrorCode DMDASetStencilWidth(PetscDM,PetscInt) PetscErrorCode DMDAGetInfo(PetscDM, PetscInt*, PetscInt*,PetscInt*,PetscInt*, PetscInt*,PetscInt*,PetscInt*, PetscInt*,PetscInt*, PetscDMBoundaryType*, PetscDMBoundaryType*, PetscDMBoundaryType*, PetscDMDAStencilType*) PetscErrorCode DMDAGetCorners(PetscDM, PetscInt*,PetscInt*,PetscInt*, PetscInt*,PetscInt*,PetscInt*) PetscErrorCode DMDAGetGhostCorners(PetscDM, PetscInt*,PetscInt*,PetscInt*, PetscInt*,PetscInt*,PetscInt*) PetscErrorCode DMDAGetOwnershipRanges(PetscDM, const PetscInt*[], const PetscInt*[], const PetscInt*[]) PetscErrorCode DMDASetUniformCoordinates(PetscDM, PetscReal,PetscReal, PetscReal,PetscReal, PetscReal,PetscReal) PetscErrorCode DMGetBoundingBox(PetscDM,PetscReal[],PetscReal[]) PetscErrorCode DMGetLocalBoundingBox(PetscDM,PetscReal[],PetscReal[]) PetscErrorCode DMDACreateNaturalVector(PetscDM,PetscVec*) PetscErrorCode DMDAGlobalToNaturalBegin(PetscDM,PetscVec,PetscInsertMode,PetscVec) PetscErrorCode DMDAGlobalToNaturalEnd(PetscDM,PetscVec,PetscInsertMode,PetscVec) PetscErrorCode DMDANaturalToGlobalBegin(PetscDM,PetscVec,PetscInsertMode,PetscVec) PetscErrorCode DMDANaturalToGlobalEnd(PetscDM,PetscVec,PetscInsertMode,PetscVec) PetscErrorCode DMDAGetAO(PetscDM,PetscAO*) PetscErrorCode DMDAGetScatter(PetscDM,PetscScatter*,PetscScatter*) PetscErrorCode DMDASetRefinementFactor(PetscDM,PetscInt,PetscInt,PetscInt) PetscErrorCode DMDAGetRefinementFactor(PetscDM,PetscInt*,PetscInt*,PetscInt*) PetscErrorCode DMDASetInterpolationType(PetscDM,PetscDMDAInterpolationType) PetscErrorCode DMDAGetInterpolationType(PetscDM,PetscDMDAInterpolationType*) PetscErrorCode DMDASetElementType(PetscDM,PetscDMDAElementType) PetscErrorCode DMDAGetElementType(PetscDM,PetscDMDAElementType*) PetscErrorCode DMDAGetElements(PetscDM,PetscInt*,PetscInt*,const PetscInt**) PetscErrorCode DMDARestoreElements(PetscDM,PetscInt*,PetscInt*,const PetscInt**) PetscErrorCode DMDASetFieldName(PetscDM,PetscInt,const char[]) PetscErrorCode DMDAGetFieldName(PetscDM,PetscInt,const char*[]) PetscErrorCode DMDASetCoordinateName(PetscDM,PetscInt,const char[]) PetscErrorCode DMDAGetCoordinateName(PetscDM,PetscInt,const char*[]) # -------------------------------------------------------------------- cdef inline PetscDMDAStencilType asStencil(object stencil) \ except (-1): if isinstance(stencil, str): if stencil == "star": return DMDA_STENCIL_STAR elif stencil == "box": return DMDA_STENCIL_BOX else: raise ValueError("unknown stencil type: %s" % stencil) return stencil cdef inline object toStencil(PetscDMDAStencilType stype): if stype == DMDA_STENCIL_STAR: return "star" elif stype == DMDA_STENCIL_BOX: return "box" cdef inline PetscDMDAInterpolationType dainterpolationtype(object itype) \ except (-1): if (isinstance(itype, str)): if itype in ("q0", "Q0"): return DMDA_INTERPOLATION_Q0 if itype in ("q1", "Q1"): return DMDA_INTERPOLATION_Q1 else: raise ValueError("unknown interpolation type: %s" % itype) return itype cdef inline PetscDMDAElementType daelementtype(object etype) \ except (-1): if (isinstance(etype, str)): if etype in ("p1", "P1"): return DMDA_ELEMENT_P1 if etype in ("q1", "Q1"): return DMDA_ELEMENT_Q1 else: raise ValueError("unknown element type: %s" % etype) return etype cdef inline PetscErrorCode DMDAGetDim(PetscDM da, PetscInt *dim) noexcept nogil: return DMDAGetInfo(da, dim, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL) cdef inline PetscInt asDims(dims, PetscInt *_M, PetscInt *_N, PetscInt *_P) except? -1: cdef PetscInt dim = PETSC_DECIDE cdef object M=None, N=None, P=None dims = tuple(dims) dim = len(dims) if dim == 0: pass elif dim == 1: M, = dims elif dim == 2: M, N = dims elif dim == 3: M, N, P = dims if dim >= 1: _M[0] = asInt(M) if dim >= 2: _N[0] = asInt(N) if dim >= 3: _P[0] = asInt(P) return dim cdef inline tuple toDims(PetscInt dim, PetscInt M, PetscInt N, PetscInt P): if dim == 0: return () elif dim == 1: return (toInt(M),) elif dim == 2: return (toInt(M), toInt(N)) elif dim == 3: return (toInt(M), toInt(N), toInt(P)) cdef inline tuple asOwnershipRanges(object ownership_ranges, PetscInt dim, PetscInt *m, PetscInt *n, PetscInt *p, PetscInt **_x, PetscInt **_y, PetscInt **_z): cdef object ranges = list(ownership_ranges) cdef PetscInt rdim = len(ranges) cdef PetscInt nlx=0, nly=0, nlz=0 if dim == PETSC_DECIDE: dim = rdim elif dim != rdim: raise ValueError( "number of dimensions %d and number ownership ranges %d" % (toInt(dim), toInt(rdim))) if dim >= 1: ranges[0] = iarray_i(ranges[0], &nlx, _x) if m[0] == PETSC_DECIDE: m[0] = nlx elif m[0] != nlx: raise ValueError( "ownership range size %d and number or processors %d" % (toInt(nlx), toInt(m[0]))) if dim >= 2: ranges[1] = iarray_i(ranges[1], &nly, _y) if n[0] == PETSC_DECIDE: n[0] = nly elif n[0] != nly: raise ValueError( "ownership range size %d and number or processors %d" % (toInt(nly), toInt(n[0]))) if dim >= 3: ranges[2] = iarray_i(ranges[2], &nlz, _z) if p[0] == PETSC_DECIDE: p[0] = nlz elif p[0] != nlz: raise ValueError( "ownership range size %d and number or processors %d" % (toInt(nlz), toInt(p[0]))) return tuple(ranges) cdef inline tuple toOwnershipRanges(PetscInt dim, PetscInt m, PetscInt n, PetscInt p, const PetscInt *lx, const PetscInt *ly, const PetscInt *lz): # Returns tuple of arrays containing ownership ranges as Python arrays ranges = [array_i(m, lx)] if dim > 1: ranges.append(array_i(n, ly)) if dim > 2: ranges.append(array_i(p, lz)) return tuple(ranges) # -------------------------------------------------------------------- cdef class _DMDA_Vec_array(object): cdef _Vec_buffer vecbuf cdef readonly tuple starts, sizes cdef readonly tuple shape, strides cdef readonly ndarray array def __cinit__(self, DMDA da, Vec vec, bint DOF=False): # cdef PetscInt dim=0, dof=0 CHKERR( DMDAGetInfo(da.dm, &dim, NULL, NULL, NULL, NULL, NULL, NULL, &dof, NULL, NULL, NULL, NULL, NULL) ) cdef PetscInt lxs=0, lys=0, lzs=0 cdef PetscInt lxm=0, lym=0, lzm=0 CHKERR( DMDAGetCorners(da.dm, &lxs, &lys, &lzs, &lxm, &lym, &lzm) ) cdef PetscInt gxs=0, gys=0, gzs=0 cdef PetscInt gxm=0, gym=0, gzm=0 CHKERR( DMDAGetGhostCorners(da.dm, &gxs, &gys, &gzs, &gxm, &gym, &gzm) ) # cdef PetscInt n=0 CHKERR( VecGetLocalSize(vec.vec, &n) ) cdef PetscInt xs, ys, zs, xm, ym, zm if (n == lxm*lym*lzm*dof): xs, ys, zs = lxs, lys, lzs xm, ym, zm = lxm, lym, lzm elif (n == gxm*gym*gzm*dof): xs, ys, zs = gxs, gys, gzs xm, ym, zm = gxm, gym, gzm else: raise ValueError( "Vector local size %d is not compatible " "with DMDA local sizes %s" % (n, toDims(dim, lxm, lym, lzm))) # cdef tuple starts = toDims(dim, xs, ys, zs) cdef tuple sizes = toDims(dim, xm, ym, zm) cdef Py_ssize_t k = sizeof(PetscScalar) cdef Py_ssize_t f = dof cdef Py_ssize_t d = dim cdef tuple shape = toDims(dim, xm, ym, zm) cdef tuple strides = (k*f, k*f*xm, k*f*xm*ym)[:d] if DOF or f > 1: shape += (f,) if DOF or f > 1: strides += (k,) # self.vecbuf = _Vec_buffer(vec) self.starts = starts self.sizes = sizes self.shape = shape self.strides = strides cdef int acquire(self) except -1: self.vecbuf.acquire() if self.array is None: self.array = asarray(self.vecbuf) self.array.shape = self.shape self.array.strides = self.strides return 0 cdef int release(self) except -1: self.vecbuf.release() self.array = None return 0 # def __getitem__(self, index): self.acquire() index = adjust_index_exp(self.starts, index) return self.array[index] def __setitem__(self, index, value): self.acquire() index = adjust_index_exp(self.starts, index) self.array[index] = value # 'with' statement (PEP 343) def __enter__(self): self.acquire() return self def __exit__(self, *exc): self.release() return None cdef object adjust_index_exp(object starts, object index): if not isinstance(index, tuple): return adjust_index(starts[0], index) index = list(index) for i, start in enumerate(starts): index[i] = adjust_index(start, index[i]) index = tuple(index) return index cdef object adjust_index(object lbound, object index): if index is None: return index if index is Ellipsis: return index if isinstance(index, slice): start = index.start stop = index.stop step = index.step if start is not None: start -= lbound if stop is not None: stop -= lbound return slice(start, stop, step) try: return index - lbound except TypeError: return index # -------------------------------------------------------------------- ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/src/petsc4py/PETSc/petscdmlabel.pxi0000644000175000017500000000460514567251135021035 0ustar00balaybalay# -------------------------------------------------------------------- cdef extern from* nogil: PetscErrorCode DMLabelCreate(MPI_Comm,char[],PetscDMLabel*) PetscErrorCode DMLabelView(PetscDMLabel,PetscViewer) PetscErrorCode DMLabelReset(PetscDMLabel) PetscErrorCode DMLabelDestroy(PetscDMLabel*) PetscErrorCode DMLabelGetDefaultValue(PetscDMLabel,PetscInt*) PetscErrorCode DMLabelSetDefaultValue(PetscDMLabel,PetscInt) PetscErrorCode DMLabelDuplicate(PetscDMLabel,PetscDMLabel*) PetscErrorCode DMLabelGetValue(PetscDMLabel,PetscInt,PetscInt*) PetscErrorCode DMLabelSetValue(PetscDMLabel,PetscInt,PetscInt) PetscErrorCode DMLabelClearValue(PetscDMLabel,PetscInt,PetscInt) PetscErrorCode DMLabelAddStratum(PetscDMLabel,PetscInt) PetscErrorCode DMLabelAddStrata(PetscDMLabel,PetscInt,const PetscInt[]) PetscErrorCode DMLabelAddStrataIS(PetscDMLabel,PetscIS) PetscErrorCode DMLabelInsertIS(PetscDMLabel,PetscIS,PetscInt) PetscErrorCode DMLabelGetNumValues(PetscDMLabel,PetscInt*) PetscErrorCode DMLabelGetStratumBounds(PetscDMLabel,PetscInt,PetscInt*,PetscInt*) PetscErrorCode DMLabelGetValueIS(PetscDMLabel,PetscIS*) PetscErrorCode DMLabelStratumHasPoint(PetscDMLabel,PetscInt,PetscInt,PetscBool*) PetscErrorCode DMLabelHasStratum(PetscDMLabel,PetscInt,PetscBool*) PetscErrorCode DMLabelGetStratumSize(PetscDMLabel,PetscInt,PetscInt*) PetscErrorCode DMLabelGetStratumIS(PetscDMLabel,PetscInt,PetscIS*) PetscErrorCode DMLabelSetStratumIS(PetscDMLabel,PetscInt,PetscIS) PetscErrorCode DMLabelClearStratum(PetscDMLabel,PetscInt) PetscErrorCode DMLabelComputeIndex(PetscDMLabel) PetscErrorCode DMLabelCreateIndex(PetscDMLabel,PetscInt,PetscInt) PetscErrorCode DMLabelDestroyIndex(PetscDMLabel) PetscErrorCode DMLabelHasValue(PetscDMLabel,PetscInt,PetscBool*) PetscErrorCode DMLabelHasPoint(PetscDMLabel,PetscInt,PetscBool*) PetscErrorCode DMLabelGetBounds(PetscDMLabel,PetscInt*,PetscInt*) PetscErrorCode DMLabelFilter(PetscDMLabel,PetscInt,PetscInt) PetscErrorCode DMLabelPermute(PetscDMLabel,PetscIS,PetscDMLabel*) PetscErrorCode DMLabelDistribute(PetscDMLabel,PetscSF,PetscDMLabel*) PetscErrorCode DMLabelGather(PetscDMLabel,PetscSF,PetscDMLabel*) PetscErrorCode DMLabelConvertToSection(PetscDMLabel,PetscSection*,PetscIS*) PetscErrorCode DMLabelGetNonEmptyStratumValuesIS(PetscDMLabel, PetscIS*) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/src/petsc4py/PETSc/petscdmplex.pxi0000644000175000017500000003547614567251135020740 0ustar00balaybalay# -------------------------------------------------------------------- cdef extern from * nogil: ctypedef enum PetscDMPlexReorderDefaultFlag "DMPlexReorderDefaultFlag": DMPLEX_REORDER_DEFAULT_NOTSET DMPLEX_REORDER_DEFAULT_FALSE DMPLEX_REORDER_DEFAULT_TRUE ctypedef const char* PetscDMPlexTransformType "DMPlexTransformType" PetscDMPlexTransformType DMPLEXREFINEREGULAR PetscDMPlexTransformType DMPLEXREFINEALFELD PetscDMPlexTransformType DMPLEXREFINEPOWELLSABIN PetscDMPlexTransformType DMPLEXREFINEBOUNDARYLAYER PetscDMPlexTransformType DMPLEXREFINESBR PetscDMPlexTransformType DMPLEXREFINETOBOX PetscDMPlexTransformType DMPLEXREFINETOSIMPLEX PetscDMPlexTransformType DMPLEXREFINE1D PetscDMPlexTransformType DMPLEXEXTRUDE PetscDMPlexTransformType DMPLEXTRANSFORMFILTER PetscErrorCode DMPlexCreate(MPI_Comm,PetscDM*) PetscErrorCode DMPlexCreateCohesiveSubmesh(PetscDM,PetscBool,const char[],PetscInt,PetscDM*) PetscErrorCode DMPlexCreateFromCellListPetsc(MPI_Comm,PetscInt,PetscInt,PetscInt,PetscInt,PetscBool,PetscInt[],PetscInt,PetscReal[],PetscDM*) #int DMPlexCreateFromDAG(PetscDM,PetscInt,const PetscInt[],const PetscInt[],const PetscInt[],const PetscInt[],const PetscScalar[]) PetscErrorCode DMPlexGetChart(PetscDM,PetscInt*,PetscInt*) PetscErrorCode DMPlexSetChart(PetscDM,PetscInt,PetscInt) PetscErrorCode DMPlexGetConeSize(PetscDM,PetscInt,PetscInt*) PetscErrorCode DMPlexSetConeSize(PetscDM,PetscInt,PetscInt) PetscErrorCode DMPlexGetCone(PetscDM,PetscInt,const PetscInt*[]) PetscErrorCode DMPlexSetCone(PetscDM,PetscInt,const PetscInt[]) PetscErrorCode DMPlexInsertCone(PetscDM,PetscInt,PetscInt,PetscInt) PetscErrorCode DMPlexInsertConeOrientation(PetscDM,PetscInt,PetscInt,PetscInt) PetscErrorCode DMPlexGetConeOrientation(PetscDM,PetscInt,const PetscInt*[]) PetscErrorCode DMPlexSetConeOrientation(PetscDM,PetscInt,const PetscInt[]) PetscErrorCode DMPlexSetCellType(PetscDM,PetscInt,PetscDMPolytopeType) PetscErrorCode DMPlexGetCellType(PetscDM,PetscInt,PetscDMPolytopeType*) PetscErrorCode DMPlexGetCellTypeLabel(PetscDM,PetscDMLabel*) PetscErrorCode DMPlexGetSupportSize(PetscDM,PetscInt,PetscInt*) PetscErrorCode DMPlexSetSupportSize(PetscDM,PetscInt,PetscInt) PetscErrorCode DMPlexGetSupport(PetscDM,PetscInt,const PetscInt*[]) PetscErrorCode DMPlexSetSupport(PetscDM,PetscInt,const PetscInt[]) #int DMPlexInsertSupport(PetscDM,PetscInt,PetscInt,PetscInt) #int DMPlexGetConeSection(PetscDM,PetscSection*) #int DMPlexGetSupportSection(PetscDM,PetscSection*) #int DMPlexGetCones(PetscDM,PetscInt*[]) #int DMPlexGetConeOrientations(PetscDM,PetscInt*[]) PetscErrorCode DMPlexGetMaxSizes(PetscDM,PetscInt*,PetscInt*) PetscErrorCode DMPlexSymmetrize(PetscDM) PetscErrorCode DMPlexStratify(PetscDM) #int DMPlexEqual(PetscDM,PetscDM,PetscBool*) PetscErrorCode DMPlexOrient(PetscDM) PetscErrorCode DMPlexInterpolate(PetscDM,PetscDM*) PetscErrorCode DMPlexUninterpolate(PetscDM,PetscDM*) #int DMPlexLoad(PetscViewer,PetscDM) #int DMPlexSetPreallocationCenterDimension(PetscDM,PetscInt) #int DMPlexGetPreallocationCenterDimension(PetscDM,PetscInt*) #int DMPlexPreallocateOperator(PetscDM,PetscInt,PetscSection,PetscSection,PetscInt[],PetscInt[],PetscInt[],PetscInt[],Mat,PetscBool) PetscErrorCode DMPlexGetPointLocal(PetscDM,PetscInt,PetscInt*,PetscInt*) #int DMPlexPointLocalRef(PetscDM,PetscInt,PetscScalar*,void*) #int DMPlexPointLocalRead(PetscDM,PetscInt,const PetscScalar*,const void*) PetscErrorCode DMPlexGetPointGlobal(PetscDM,PetscInt,PetscInt*,PetscInt*) #int DMPlexPointGlobalRef(PetscDM,PetscInt,PetscScalar*,void*) #int DMPlexPointGlobalRead(PetscDM,PetscInt,const PetscScalar*,const void*) PetscErrorCode DMPlexGetPointLocalField(PetscDM,PetscInt,PetscInt,PetscInt*,PetscInt*) PetscErrorCode DMPlexGetPointGlobalField(PetscDM,PetscInt,PetscInt,PetscInt*,PetscInt*) PetscErrorCode DMPlexCreateClosureIndex(PetscDM,PetscSection) #int PetscSectionCreateGlobalSectionLabel(PetscSection,PetscSF,PetscBool,PetscDMLabel,PetscInt,PetscSection*) PetscErrorCode DMPlexGetCellNumbering(PetscDM,PetscIS*) PetscErrorCode DMPlexGetVertexNumbering(PetscDM,PetscIS*) PetscErrorCode DMPlexCreatePointNumbering(PetscDM,PetscIS*) PetscErrorCode DMPlexGetDepth(PetscDM,PetscInt*) #int DMPlexGetDepthLabel(PetscDM,PetscDMLabel*) PetscErrorCode DMPlexGetDepthStratum(PetscDM,PetscInt,PetscInt*,PetscInt*) PetscErrorCode DMPlexGetHeightStratum(PetscDM,PetscInt,PetscInt*,PetscInt*) PetscErrorCode DMPlexGetPointDepth(PetscDM,PetscInt,PetscInt*) PetscErrorCode DMPlexGetPointHeight(PetscDM,PetscInt,PetscInt*) PetscErrorCode DMPlexGetMeet(PetscDM,PetscInt,const PetscInt[],PetscInt*,const PetscInt**) #int DMPlexGetFullMeet(PetscDM,PetscInt,const PetscInt[],PetscInt*,const PetscInt**) PetscErrorCode DMPlexRestoreMeet(PetscDM,PetscInt,const PetscInt[],PetscInt*,const PetscInt**) PetscErrorCode DMPlexGetJoin(PetscDM,PetscInt,const PetscInt[],PetscInt*,const PetscInt**) PetscErrorCode DMPlexGetFullJoin(PetscDM,PetscInt,const PetscInt[],PetscInt*,const PetscInt**) PetscErrorCode DMPlexRestoreJoin(PetscDM,PetscInt,const PetscInt[],PetscInt*,const PetscInt**) PetscErrorCode DMPlexGetTransitiveClosure(PetscDM,PetscInt,PetscBool,PetscInt*,PetscInt*[]) PetscErrorCode DMPlexRestoreTransitiveClosure(PetscDM,PetscInt,PetscBool,PetscInt*,PetscInt*[]) PetscErrorCode DMPlexVecGetClosure(PetscDM,PetscSection,PetscVec,PetscInt,PetscInt*,PetscScalar*[]) PetscErrorCode DMPlexVecRestoreClosure(PetscDM,PetscSection,PetscVec,PetscInt,PetscInt*,PetscScalar*[]) PetscErrorCode DMPlexVecSetClosure(PetscDM,PetscSection,PetscVec,PetscInt,PetscScalar[],PetscInsertMode) PetscErrorCode DMPlexMatSetClosure(PetscDM,PetscSection,PetscSection,PetscMat,PetscInt,PetscScalar[],PetscInsertMode) PetscErrorCode DMPlexGenerate(PetscDM,const char[],PetscBool ,PetscDM*) PetscErrorCode DMPlexTriangleSetOptions(PetscDM,const char*) PetscErrorCode DMPlexTetgenSetOptions(PetscDM,const char*) #int DMPlexCopyCoordinates(PetscDM,PetscDM) #int DMPlexCreateDoublet(MPI_Comm,PetscInt,PetscBool,PetscBool,PetscBool,PetscReal,PetscDM*) PetscErrorCode DMPlexCreateBoxMesh(MPI_Comm,PetscInt,PetscBool,PetscInt[],PetscReal[],PetscReal[],PetscDMBoundaryType[],PetscBool,PetscDM*) PetscErrorCode DMPlexCreateBoxSurfaceMesh(MPI_Comm,PetscInt,PetscInt[],PetscReal[],PetscReal[],PetscBool,PetscDM*) PetscErrorCode DMPlexCreateFromFile(MPI_Comm,const char[],const char[],PetscBool,PetscDM*) PetscErrorCode DMPlexCreateCGNS(MPI_Comm,PetscInt,PetscBool,PetscDM*) PetscErrorCode DMPlexCreateCGNSFromFile(MPI_Comm,const char[],PetscBool,PetscDM*) PetscErrorCode DMPlexCreateExodus(MPI_Comm,PetscInt,PetscBool,PetscDM*) PetscErrorCode DMPlexCreateExodusFromFile(MPI_Comm,const char[],PetscBool,PetscDM*) PetscErrorCode DMPlexCreateGmsh(MPI_Comm,PetscViewer,PetscBool,PetscDM*) #int DMPlexInvertCell(PetscInt,PetscInt,int[]) #int DMPlexCheckSymmetry(PetscDM) #int DMPlexCheckSkeleton(PetscDM,PetscBool,PetscInt) #int DMPlexCheckFaces(PetscDM,PetscBool,PetscInt) PetscErrorCode DMPlexSetAdjacencyUseAnchors(PetscDM,PetscBool) PetscErrorCode DMPlexGetAdjacencyUseAnchors(PetscDM,PetscBool*) PetscErrorCode DMPlexGetAdjacency(PetscDM,PetscInt,PetscInt*,PetscInt*[]) #int DMPlexCreateNeighborCSR(PetscDM,PetscInt,PetscInt*,PetscInt**,PetscInt**) PetscErrorCode DMPlexRebalanceSharedPoints(PetscDM,PetscInt,PetscBool,PetscBool,PetscBool*) PetscErrorCode DMPlexDistribute(PetscDM,PetscInt,PetscSF*,PetscDM*) PetscErrorCode DMPlexDistributeOverlap(PetscDM,PetscInt,PetscSF*,PetscDM*) PetscErrorCode DMPlexDistributeGetDefault(PetscDM,PetscBool*) PetscErrorCode DMPlexDistributeSetDefault(PetscDM,PetscBool) PetscErrorCode DMPlexSetPartitioner(PetscDM,PetscPartitioner) PetscErrorCode DMPlexGetPartitioner(PetscDM,PetscPartitioner*) PetscErrorCode DMPlexDistributeField(PetscDM,PetscSF,PetscSection,PetscVec,PetscSection,PetscVec) #int DMPlexDistributeData(PetscDM,PetscSF,PetscSection,MPI_Datatype,void*,PetscSection,void**) PetscErrorCode DMPlexIsDistributed(PetscDM,PetscBool*) PetscErrorCode DMPlexIsSimplex(PetscDM,PetscBool*) PetscErrorCode DMPlexDistributionSetName(PetscDM,const char[]) PetscErrorCode DMPlexDistributionGetName(PetscDM,const char*[]) PetscErrorCode DMPlexGetOrdering(PetscDM,PetscMatOrderingType,PetscDMLabel,PetscIS*) PetscErrorCode DMPlexPermute(PetscDM,PetscIS,PetscDM*) PetscErrorCode DMPlexReorderGetDefault(PetscDM,PetscDMPlexReorderDefaultFlag*) PetscErrorCode DMPlexReorderSetDefault(PetscDM,PetscDMPlexReorderDefaultFlag) #int DMPlexCreateSubmesh(PetscDM,PetscDMLabel,PetscInt,PetscDM*) #int DMPlexCreateHybridMesh(PetscDM,PetscDMLabel,PetscDMLabel,PetscInt,PetscDMLabel*,PetscDMLabel*,PetscDM *,PetscDM *) #int DMPlexGetSubpointMap(PetscDM,PetscDMLabel*) #int DMPlexSetSubpointMap(PetscDM,PetscDMLabel) #int DMPlexCreateSubpointIS(PetscDM,PetscIS*) PetscErrorCode DMPlexCreateCoarsePointIS(PetscDM,PetscIS*) PetscErrorCode DMPlexMarkBoundaryFaces(PetscDM,PetscInt,PetscDMLabel) PetscErrorCode DMPlexLabelComplete(PetscDM,PetscDMLabel) PetscErrorCode DMPlexLabelCohesiveComplete(PetscDM,PetscDMLabel,PetscDMLabel,PetscInt,PetscBool,PetscDM) PetscErrorCode DMPlexGetRefinementLimit(PetscDM,PetscReal*) PetscErrorCode DMPlexSetRefinementLimit(PetscDM,PetscReal) PetscErrorCode DMPlexGetRefinementUniform(PetscDM,PetscBool*) PetscErrorCode DMPlexSetRefinementUniform(PetscDM,PetscBool) PetscErrorCode DMPlexGetMinRadius(PetscDM, PetscReal*) #int DMPlexGetNumFaceVertices(PetscDM,PetscInt,PetscInt,PetscInt*) #int DMPlexGetOrientedFace(PetscDM,PetscInt,PetscInt,const PetscInt[],PetscInt,PetscInt[],PetscInt[],PetscInt[],PetscBool*) PetscErrorCode DMPlexCreateSection(PetscDM,PetscDMLabel[],const PetscInt[],const PetscInt[],PetscInt,const PetscInt[],const PetscIS[],const PetscIS[],PetscIS,PetscSection*) PetscErrorCode DMPlexComputeCellGeometryFVM(PetscDM,PetscInt,PetscReal*,PetscReal[],PetscReal[]) PetscErrorCode DMPlexConstructGhostCells(PetscDM,const char[],PetscInt*,PetscDM*) PetscErrorCode DMPlexMetricSetFromOptions(PetscDM) PetscErrorCode DMPlexMetricSetUniform(PetscDM,PetscBool) PetscErrorCode DMPlexMetricIsUniform(PetscDM,PetscBool*) PetscErrorCode DMPlexMetricSetIsotropic(PetscDM,PetscBool) PetscErrorCode DMPlexMetricIsIsotropic(PetscDM,PetscBool*) PetscErrorCode DMPlexMetricSetRestrictAnisotropyFirst(PetscDM,PetscBool) PetscErrorCode DMPlexMetricRestrictAnisotropyFirst(PetscDM,PetscBool*) PetscErrorCode DMPlexMetricSetNoInsertion(PetscDM,PetscBool) PetscErrorCode DMPlexMetricNoInsertion(PetscDM,PetscBool*) PetscErrorCode DMPlexMetricSetNoSwapping(PetscDM,PetscBool) PetscErrorCode DMPlexMetricNoSwapping(PetscDM,PetscBool*) PetscErrorCode DMPlexMetricSetNoMovement(PetscDM,PetscBool) PetscErrorCode DMPlexMetricNoMovement(PetscDM,PetscBool*) PetscErrorCode DMPlexMetricSetNoSurf(PetscDM,PetscBool) PetscErrorCode DMPlexMetricNoSurf(PetscDM,PetscBool*) PetscErrorCode DMPlexMetricSetVerbosity(PetscDM,PetscInt) PetscErrorCode DMPlexMetricGetVerbosity(PetscDM,PetscInt*) PetscErrorCode DMPlexMetricSetNumIterations(PetscDM,PetscInt) PetscErrorCode DMPlexMetricGetNumIterations(PetscDM,PetscInt*) PetscErrorCode DMPlexMetricSetMinimumMagnitude(PetscDM,PetscReal) PetscErrorCode DMPlexMetricGetMinimumMagnitude(PetscDM,PetscReal*) PetscErrorCode DMPlexMetricSetMaximumMagnitude(PetscDM,PetscReal) PetscErrorCode DMPlexMetricGetMaximumMagnitude(PetscDM,PetscReal*) PetscErrorCode DMPlexMetricSetMaximumAnisotropy(PetscDM,PetscReal) PetscErrorCode DMPlexMetricGetMaximumAnisotropy(PetscDM,PetscReal*) PetscErrorCode DMPlexMetricSetTargetComplexity(PetscDM,PetscReal) PetscErrorCode DMPlexMetricGetTargetComplexity(PetscDM,PetscReal*) PetscErrorCode DMPlexMetricSetNormalizationOrder(PetscDM,PetscReal) PetscErrorCode DMPlexMetricGetNormalizationOrder(PetscDM,PetscReal*) PetscErrorCode DMPlexMetricSetGradationFactor(PetscDM,PetscReal) PetscErrorCode DMPlexMetricGetGradationFactor(PetscDM,PetscReal*) PetscErrorCode DMPlexMetricSetHausdorffNumber(PetscDM,PetscReal) PetscErrorCode DMPlexMetricGetHausdorffNumber(PetscDM,PetscReal*) PetscErrorCode DMPlexMetricCreate(PetscDM,PetscInt,PetscVec*) PetscErrorCode DMPlexMetricCreateUniform(PetscDM,PetscInt,PetscReal,PetscVec*) PetscErrorCode DMPlexMetricCreateIsotropic(PetscDM,PetscInt,PetscVec,PetscVec*) PetscErrorCode DMPlexMetricDeterminantCreate(PetscDM,PetscInt,PetscVec*,PetscDM*) PetscErrorCode DMPlexMetricEnforceSPD(PetscDM,PetscVec,PetscBool,PetscBool,PetscVec,PetscVec) PetscErrorCode DMPlexMetricNormalize(PetscDM,PetscVec,PetscBool,PetscBool,PetscVec,PetscVec) PetscErrorCode DMPlexMetricAverage2(PetscDM,PetscVec,PetscVec,PetscVec) PetscErrorCode DMPlexMetricAverage3(PetscDM,PetscVec,PetscVec,PetscVec,PetscVec) PetscErrorCode DMPlexMetricIntersection2(PetscDM,PetscVec,PetscVec,PetscVec) PetscErrorCode DMPlexMetricIntersection3(PetscDM,PetscVec,PetscVec,PetscVec,PetscVec) PetscErrorCode DMPlexComputeGradientClementInterpolant(PetscDM,PetscVec,PetscVec) PetscErrorCode DMPlexTopologyView(PetscDM,PetscViewer) PetscErrorCode DMPlexCoordinatesView(PetscDM,PetscViewer) PetscErrorCode DMPlexLabelsView(PetscDM,PetscViewer) PetscErrorCode DMPlexSectionView(PetscDM,PetscViewer,PetscDM) PetscErrorCode DMPlexGlobalVectorView(PetscDM,PetscViewer,PetscDM,PetscVec) PetscErrorCode DMPlexLocalVectorView(PetscDM,PetscViewer,PetscDM,PetscVec) PetscErrorCode DMPlexTopologyLoad(PetscDM,PetscViewer,PetscSF*) PetscErrorCode DMPlexCoordinatesLoad(PetscDM,PetscViewer,PetscSF) PetscErrorCode DMPlexLabelsLoad(PetscDM,PetscViewer,PetscSF) PetscErrorCode DMPlexSectionLoad(PetscDM,PetscViewer,PetscDM,PetscSF,PetscSF*,PetscSF*) PetscErrorCode DMPlexGlobalVectorLoad(PetscDM,PetscViewer,PetscDM,PetscSF,PetscVec) PetscErrorCode DMPlexLocalVectorLoad(PetscDM,PetscViewer,PetscDM,PetscSF,PetscVec) PetscErrorCode DMPlexTransformApply(PetscDMPlexTransform, PetscDM, PetscDM *); PetscErrorCode DMPlexTransformCreate(MPI_Comm, PetscDMPlexTransform *); PetscErrorCode DMPlexTransformDestroy(PetscDMPlexTransform*); PetscErrorCode DMPlexTransformGetType(PetscDMPlexTransform, PetscDMPlexTransformType *); PetscErrorCode DMPlexTransformSetType(PetscDMPlexTransform tr, PetscDMPlexTransformType method); PetscErrorCode DMPlexTransformSetFromOptions(PetscDMPlexTransform); PetscErrorCode DMPlexTransformSetDM(PetscDMPlexTransform, PetscDM); PetscErrorCode DMPlexTransformSetUp(PetscDMPlexTransform); PetscErrorCode DMPlexTransformView(PetscDMPlexTransform tr, PetscViewer v); ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/src/petsc4py/PETSc/petscdmshell.pxi0000644000175000017500000004522714567251135021072 0ustar00balaybalayctypedef PetscErrorCode (*PetscDMShellXToYFunction)(PetscDM, PetscVec, PetscInsertMode, PetscVec) except PETSC_ERR_PYTHON cdef extern from * nogil: ctypedef PetscErrorCode (*PetscDMShellCreateVectorFunction)(PetscDM, PetscVec*) except PETSC_ERR_PYTHON ctypedef PetscErrorCode (*PetscDMShellCreateMatrixFunction)(PetscDM, PetscMat*) except PETSC_ERR_PYTHON ctypedef PetscErrorCode (*PetscDMShellTransferFunction)(PetscDM, MPI_Comm, PetscDM*) except PETSC_ERR_PYTHON ctypedef PetscErrorCode (*PetscDMShellCreateInterpolationFunction)(PetscDM, PetscDM, PetscMat*, PetscVec*) except PETSC_ERR_PYTHON ctypedef PetscErrorCode (*PetscDMShellCreateInjectionFunction)(PetscDM, PetscDM, PetscMat*) except PETSC_ERR_PYTHON ctypedef PetscErrorCode (*PetscDMShellCreateRestrictionFunction)(PetscDM, PetscDM, PetscMat*) except PETSC_ERR_PYTHON ctypedef PetscErrorCode (*PetscDMShellCreateFieldDecompositionFunction)(PetscDM, PetscInt*, char***, PetscIS**, PetscDM**) except PETSC_ERR_PYTHON ctypedef PetscErrorCode (*PetscDMShellCreateDomainDecompositionFunction)(PetscDM, PetscInt*, char***, PetscIS**, PetscIS**, PetscDM**) except PETSC_ERR_PYTHON ctypedef PetscErrorCode (*PetscDMShellCreateDomainDecompositionScattersFunction)(PetscDM, PetscInt, PetscDM*, PetscScatter**, PetscScatter**, PetscScatter**) except PETSC_ERR_PYTHON ctypedef PetscErrorCode (*PetscDMShellCreateSubDM)(PetscDM, PetscInt, PetscInt[], PetscIS*, PetscDM*) except PETSC_ERR_PYTHON PetscErrorCode DMShellCreate(MPI_Comm,PetscDM*) PetscErrorCode DMShellSetMatrix(PetscDM,PetscMat) PetscErrorCode DMShellSetGlobalVector(PetscDM,PetscVec) PetscErrorCode DMShellSetLocalVector(PetscDM,PetscVec) PetscErrorCode DMShellSetCreateGlobalVector(PetscDM,PetscDMShellCreateVectorFunction) PetscErrorCode DMShellSetCreateLocalVector(PetscDM,PetscDMShellCreateVectorFunction) PetscErrorCode DMShellSetGlobalToLocal(PetscDM,PetscDMShellXToYFunction,PetscDMShellXToYFunction) PetscErrorCode DMShellSetGlobalToLocalVecScatter(PetscDM,PetscScatter) PetscErrorCode DMShellSetLocalToGlobal(PetscDM,PetscDMShellXToYFunction,PetscDMShellXToYFunction) PetscErrorCode DMShellSetLocalToGlobalVecScatter(PetscDM,PetscScatter) PetscErrorCode DMShellSetLocalToLocal(PetscDM,PetscDMShellXToYFunction,PetscDMShellXToYFunction) PetscErrorCode DMShellSetLocalToLocalVecScatter(PetscDM,PetscScatter) PetscErrorCode DMShellSetCreateMatrix(PetscDM,PetscDMShellCreateMatrixFunction) PetscErrorCode DMShellSetCoarsen(PetscDM,PetscDMShellTransferFunction) PetscErrorCode DMShellSetRefine(PetscDM,PetscDMShellTransferFunction) PetscErrorCode DMShellSetCreateInterpolation(PetscDM,PetscDMShellCreateInterpolationFunction) PetscErrorCode DMShellSetCreateInjection(PetscDM,PetscDMShellCreateInjectionFunction) PetscErrorCode DMShellSetCreateRestriction(PetscDM,PetscDMShellCreateRestrictionFunction) PetscErrorCode DMShellSetCreateFieldDecomposition(PetscDM,PetscDMShellCreateFieldDecompositionFunction) PetscErrorCode DMShellSetCreateDomainDecomposition(PetscDM,PetscDMShellCreateDomainDecompositionFunction) PetscErrorCode DMShellSetCreateDomainDecompositionScatters(PetscDM,PetscDMShellCreateDomainDecompositionScattersFunction) PetscErrorCode DMShellSetCreateSubDM(PetscDM,PetscDMShellCreateSubDM) PetscErrorCode VecGetDM(PetscVec,PetscDM*) PetscErrorCode VecSetDM(PetscVec,PetscDM) PetscErrorCode MatGetDM(PetscMat,PetscDM*) PetscErrorCode MatSetDM(PetscMat,PetscDM) cdef PetscErrorCode DMSHELL_CreateGlobalVector( PetscDM dm, PetscVec *v) except PETSC_ERR_PYTHON with gil: cdef DM Dm = subtype_DM(dm)() cdef Vec vec Dm.dm = dm CHKERR( PetscINCREF(Dm.obj) ) context = Dm.get_attr('__create_global_vector__') assert context is not None and type(context) is tuple (create_gvec, args, kargs) = context vec = create_gvec(Dm, *args, **kargs) CHKERR( PetscINCREF(vec.obj) ) v[0] = vec.vec cdef PetscDM odm = NULL CHKERR( VecGetDM(v[0], &odm) ) if odm == NULL: CHKERR( VecSetDM(v[0], dm) ) return PETSC_SUCCESS cdef PetscErrorCode DMSHELL_CreateLocalVector( PetscDM dm, PetscVec *v) except PETSC_ERR_PYTHON with gil: cdef DM Dm = subtype_DM(dm)() cdef Vec vec Dm.dm = dm CHKERR( PetscINCREF(Dm.obj) ) context = Dm.get_attr('__create_local_vector__') assert context is not None and type(context) is tuple (create_lvec, args, kargs) = context vec = create_lvec(Dm, *args, **kargs) CHKERR( PetscINCREF(vec.obj) ) v[0] = vec.vec cdef PetscDM odm = NULL CHKERR( VecGetDM(v[0], &odm) ) if odm == NULL: CHKERR( VecSetDM(v[0], dm) ) return PETSC_SUCCESS cdef PetscErrorCode DMSHELL_GlobalToLocalBegin( PetscDM dm, PetscVec g, PetscInsertMode mode, PetscVec l) except PETSC_ERR_PYTHON with gil: cdef DM Dm = subtype_DM(dm)() cdef Vec gvec = ref_Vec(g) cdef Vec lvec = ref_Vec(l) Dm.dm = dm CHKERR( PetscINCREF(Dm.obj) ) context = Dm.get_attr('__g2l_begin__') assert context is not None and type(context) is tuple (begin, args, kargs) = context begin(Dm, gvec, mode, lvec, *args, **kargs) return PETSC_SUCCESS cdef PetscErrorCode DMSHELL_GlobalToLocalEnd( PetscDM dm, PetscVec g, PetscInsertMode mode, PetscVec l) except PETSC_ERR_PYTHON with gil: cdef DM Dm = subtype_DM(dm)() cdef Vec gvec = ref_Vec(g) cdef Vec lvec = ref_Vec(l) Dm.dm = dm CHKERR( PetscINCREF(Dm.obj) ) context = Dm.get_attr('__g2l_end__') assert context is not None and type(context) is tuple (end, args, kargs) = context end(Dm, gvec, mode, lvec, *args, **kargs) return PETSC_SUCCESS cdef PetscErrorCode DMSHELL_LocalToGlobalBegin( PetscDM dm, PetscVec g, PetscInsertMode mode, PetscVec l) except PETSC_ERR_PYTHON with gil: cdef DM Dm = subtype_DM(dm)() cdef Vec gvec = ref_Vec(g) cdef Vec lvec = ref_Vec(l) Dm.dm = dm CHKERR( PetscINCREF(Dm.obj) ) context = Dm.get_attr('__l2g_begin__') assert context is not None and type(context) is tuple (begin, args, kargs) = context begin(Dm, gvec, mode, lvec, *args, **kargs) return PETSC_SUCCESS cdef PetscErrorCode DMSHELL_LocalToGlobalEnd( PetscDM dm, PetscVec g, PetscInsertMode mode, PetscVec l) except PETSC_ERR_PYTHON with gil: cdef DM Dm = subtype_DM(dm)() cdef Vec gvec = ref_Vec(g) cdef Vec lvec = ref_Vec(l) Dm.dm = dm CHKERR( PetscINCREF(Dm.obj) ) context = Dm.get_attr('__l2g_end__') assert context is not None and type(context) is tuple (end, args, kargs) = context end(Dm, gvec, mode, lvec, *args, **kargs) return PETSC_SUCCESS cdef PetscErrorCode DMSHELL_LocalToLocalBegin( PetscDM dm, PetscVec g, PetscInsertMode mode, PetscVec l) except PETSC_ERR_PYTHON with gil: cdef DM Dm = subtype_DM(dm)() cdef Vec gvec = ref_Vec(g) cdef Vec lvec = ref_Vec(l) Dm.dm = dm CHKERR( PetscINCREF(Dm.obj) ) context = Dm.get_attr('__l2l_begin__') assert context is not None and type(context) is tuple (begin, args, kargs) = context begin(Dm, gvec, mode, lvec, *args, **kargs) return PETSC_SUCCESS cdef PetscErrorCode DMSHELL_LocalToLocalEnd( PetscDM dm, PetscVec g, PetscInsertMode mode, PetscVec l) except PETSC_ERR_PYTHON with gil: cdef DM Dm = subtype_DM(dm)() cdef Vec gvec = ref_Vec(g) cdef Vec lvec = ref_Vec(l) Dm.dm = dm CHKERR( PetscINCREF(Dm.obj) ) context = Dm.get_attr('__l2l_end__') assert context is not None and type(context) is tuple (end, args, kargs) = context end(Dm, gvec, mode, lvec, *args, **kargs) return PETSC_SUCCESS cdef PetscErrorCode DMSHELL_CreateMatrix( PetscDM dm, PetscMat *cmat) except PETSC_ERR_PYTHON with gil: cdef DM Dm = subtype_DM(dm)() cdef Mat mat Dm.dm = dm CHKERR( PetscINCREF(Dm.obj) ) context = Dm.get_attr('__create_matrix__') assert context is not None and type(context) is tuple (matrix, args, kargs) = context mat = matrix(Dm, *args, **kargs) CHKERR( PetscINCREF(mat.obj) ) cmat[0] = mat.mat cdef PetscDM odm = NULL CHKERR( MatGetDM(cmat[0], &odm) ) if odm == NULL: CHKERR( MatSetDM(cmat[0], dm) ) return PETSC_SUCCESS cdef PetscErrorCode DMSHELL_Coarsen( PetscDM dm, MPI_Comm comm, PetscDM *dmc) except PETSC_ERR_PYTHON with gil: cdef DM Dm = subtype_DM(dm)() cdef DM Dmc cdef Comm Comm = new_Comm(comm) Dm.dm = dm CHKERR( PetscINCREF(Dm.obj) ) context = Dm.get_attr('__coarsen__') assert context is not None and type(context) is tuple (coarsen, args, kargs) = context Dmc = coarsen(Dm, Comm, *args, **kargs) CHKERR( PetscINCREF(Dmc.obj) ) dmc[0] = Dmc.dm return PETSC_SUCCESS cdef PetscErrorCode DMSHELL_Refine( PetscDM dm, MPI_Comm comm, PetscDM *dmf) except PETSC_ERR_PYTHON with gil: cdef DM Dm = subtype_DM(dm)() cdef DM Dmf cdef Comm Comm = new_Comm(comm) Dm.dm = dm CHKERR( PetscINCREF(Dm.obj) ) context = Dm.get_attr('__refine__') assert context is not None and type(context) is tuple (refine, args, kargs) = context Dmf = refine(Dm, Comm, *args, **kargs) CHKERR( PetscINCREF(Dmf.obj) ) dmf[0] = Dmf.dm return PETSC_SUCCESS cdef PetscErrorCode DMSHELL_CreateInterpolation( PetscDM dmc, PetscDM dmf, PetscMat *cmat, PetscVec *cvec) except PETSC_ERR_PYTHON with gil: cdef DM Dmc = subtype_DM(dmc)() cdef DM Dmf = subtype_DM(dmf)() cdef Mat mat cdef Vec vec Dmc.dm = dmc CHKERR( PetscINCREF(Dmc.obj) ) Dmf.dm = dmf CHKERR( PetscINCREF(Dmf.obj) ) context = Dmc.get_attr('__create_interpolation__') assert context is not None and type(context) is tuple (interpolation, args, kargs) = context mat, vec = interpolation(Dmc, Dmf, *args, **kargs) CHKERR( PetscINCREF(mat.obj) ) cmat[0] = mat.mat if cvec == NULL: return PETSC_SUCCESS if vec is None: cvec[0] = NULL else: CHKERR( PetscINCREF(vec.obj) ) cvec[0] = vec.vec return PETSC_SUCCESS cdef PetscErrorCode DMSHELL_CreateInjection( PetscDM dmc, PetscDM dmf, PetscMat *cmat) except PETSC_ERR_PYTHON with gil: cdef DM Dmc = subtype_DM(dmc)() cdef DM Dmf = subtype_DM(dmf)() cdef Mat mat Dmc.dm = dmc CHKERR( PetscINCREF(Dmc.obj) ) Dmf.dm = dmf CHKERR( PetscINCREF(Dmf.obj) ) context = Dmc.get_attr('__create_injection__') assert context is not None and type(context) is tuple (injection, args, kargs) = context mat = injection(Dmc, Dmf, *args, **kargs) CHKERR( PetscINCREF(mat.obj) ) cmat[0] = mat.mat return PETSC_SUCCESS cdef PetscErrorCode DMSHELL_CreateRestriction( PetscDM dmf, PetscDM dmc, PetscMat *cmat) except PETSC_ERR_PYTHON with gil: cdef DM Dmf = subtype_DM(dmf)() cdef DM Dmc = subtype_DM(dmc)() cdef Mat mat Dmf.dm = dmf CHKERR( PetscINCREF(Dmf.obj) ) Dmc.dm = dmc CHKERR( PetscINCREF(Dmc.obj) ) context = Dmf.get_attr('__create_restriction__') assert context is not None and type(context) is tuple (restriction, args, kargs) = context mat = restriction(Dmf, Dmc, *args, **kargs) CHKERR( PetscINCREF(mat.obj) ) cmat[0] = mat.mat return PETSC_SUCCESS cdef PetscErrorCode DMSHELL_CreateFieldDecomposition( PetscDM dm, PetscInt *clen, char ***namelist, PetscIS **islist, PetscDM **dmlist) except PETSC_ERR_PYTHON with gil: cdef DM Dm = subtype_DM(dm)() cdef int i cdef const char *cname = NULL Dm.dm = dm CHKERR( PetscINCREF(Dm.obj) ) context = Dm.get_attr('__create_field_decomp__') assert context is not None and type(context) is tuple (decomp, args, kargs) = context names, ises, dms = decomp(Dm, *args, **kargs) if clen != NULL: if names is not None: clen[0] = len(names) elif ises is not None: clen[0] = len(ises) elif dms is not None: clen[0] = len(dms) else: clen[0] = 0 if namelist != NULL and names is not None: CHKERR( PetscMalloc(len(names)*sizeof(char**), namelist) ) for i in range(len(names)): names[i] = str2bytes(names[i], &cname) CHKERR( PetscStrallocpy(cname, &(namelist[0][i])) ) if islist != NULL and ises is not None: CHKERR( PetscMalloc(len(ises)*sizeof(PetscIS), islist) ) for i in range(len(ises)): islist[0][i] = (ises[i]).iset CHKERR( PetscINCREF((ises[i]).obj) ) if dmlist != NULL and dms is not None: CHKERR( PetscMalloc(len(dms)*sizeof(PetscDM), dmlist) ) for i in range(len(dms)): dmlist[0][i] = (dms[i]).dm CHKERR( PetscINCREF((dms[i]).obj) ) return PETSC_SUCCESS cdef PetscErrorCode DMSHELL_CreateDomainDecomposition( PetscDM dm, PetscInt *clen, char ***namelist, PetscIS **innerislist, PetscIS **outerislist, PetscDM **dmlist) except PETSC_ERR_PYTHON with gil: cdef DM Dm = subtype_DM(dm)() cdef int i cdef const char *cname = NULL Dm.dm = dm CHKERR( PetscINCREF(Dm.obj) ) context = Dm.get_attr('__create_domain_decomp__') assert context is not None and type(context) is tuple (decomp, args, kargs) = context names, innerises, outerises, dms = decomp(Dm, *args, **kargs) if clen != NULL: if names is not None: clen[0] = len(names) elif innerises is not None: clen[0] = len(innerises) elif outerises is not None: clen[0] = len(outerises) elif dms is not None: clen[0] = len(dms) else: clen[0] = 0 if namelist != NULL and names is not None: CHKERR( PetscMalloc(len(names)*sizeof(char**), namelist) ) for i in range(len(names)): names[i] = str2bytes(names[i], &cname) CHKERR( PetscStrallocpy(cname, &(namelist[0][i])) ) if innerislist != NULL and innerises is not None: CHKERR( PetscMalloc(len(innerises)*sizeof(PetscIS), innerislist) ) for i in range(len(innerises)): innerislist[0][i] = (innerises[i]).iset CHKERR( PetscINCREF((innerises[i]).obj) ) if outerislist != NULL and outerises is not None: CHKERR( PetscMalloc(len(outerises)*sizeof(PetscIS), outerislist) ) for i in range(len(outerises)): outerislist[0][i] = (outerises[i]).iset CHKERR( PetscINCREF((outerises[i]).obj) ) if dmlist != NULL and dms is not None: CHKERR( PetscMalloc(len(dms)*sizeof(PetscDM), dmlist) ) for i in range(len(dms)): dmlist[0][i] = (dms[i]).dm CHKERR( PetscINCREF((dms[i]).obj) ) return PETSC_SUCCESS cdef PetscErrorCode DMSHELL_CreateDomainDecompositionScatters( PetscDM dm, PetscInt clen, PetscDM *subdms, PetscScatter** iscat, PetscScatter** oscat, PetscScatter** gscat) except PETSC_ERR_PYTHON with gil: cdef DM Dm = subtype_DM(dm)() cdef int i cdef const char *cname = NULL cdef DM subdm = None Dm.dm = dm CHKERR( PetscINCREF(Dm.obj) ) psubdms = [] for i from 0 <= i < clen: subdm = subtype_DM(subdms[i])() subdm.dm = subdms[i] CHKERR( PetscINCREF(subdm.obj) ) psubdms.append(subdm) context = Dm.get_attr('__create_domain_decomp_scatters__') assert context is not None and type(context) is tuple (scatters, args, kargs) = context (iscatter, oscatter, gscatter) = scatters(Dm, psubdms, *args, **kargs) assert len(iscatter) == clen assert len(oscatter) == clen assert len(gscatter) == clen CHKERR ( PetscMalloc(clen*sizeof(PetscScatter), iscat) ) CHKERR ( PetscMalloc(clen*sizeof(PetscScatter), oscat) ) CHKERR ( PetscMalloc(clen*sizeof(PetscScatter), gscat) ) for i in range(clen): iscat[0][i] = (iscatter[i]).sct CHKERR( PetscINCREF((iscatter[i]).obj) ) oscat[0][i] = (oscatter[i]).sct CHKERR( PetscINCREF((oscatter[i]).obj) ) gscat[0][i] = (gscatter[i]).sct CHKERR( PetscINCREF((gscatter[i]).obj) ) return PETSC_SUCCESS cdef PetscErrorCode DMSHELL_CreateSubDM( PetscDM cdm, PetscInt numFields, const PetscInt cfields[], PetscIS *ciset, PetscDM *csubdm) except PETSC_ERR_PYTHON with gil: cdef DM dm = subtype_DM(cdm)() cdef IS iset cdef DM subdm dm.dm = cdm CHKERR( PetscINCREF(dm.obj) ) context = dm.get_attr('__create_subdm__') assert context is not None and type(context) is tuple (create_subdm, args, kargs) = context fields = array_i(numFields, cfields) iset, subdm = create_subdm(dm, fields, *args, **kargs) CHKERR( PetscINCREF(iset.obj) ) CHKERR( PetscINCREF(subdm.obj) ) ciset[0] = iset.iset csubdm[0] = subdm.dm return PETSC_SUCCESS ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/src/petsc4py/PETSc/petscdmstag.pxi0000644000175000017500000002776614567251135020731 0ustar00balaybalay# -------------------------------------------------------------------- cdef extern from * nogil: ctypedef enum PetscDMStagStencilType"DMStagStencilType": DMSTAG_STENCIL_STAR DMSTAG_STENCIL_BOX DMSTAG_STENCIL_NONE ctypedef enum PetscDMStagStencilLocation"DMStagStencilLocation": DMSTAG_NULL_LOCATION DMSTAG_BACK_DOWN_LEFT DMSTAG_BACK_DOWN DMSTAG_BACK_DOWN_RIGHT DMSTAG_BACK_LEFT DMSTAG_BACK DMSTAG_BACK_RIGHT DMSTAG_BACK_UP_LEFT DMSTAG_BACK_UP DMSTAG_BACK_UP_RIGHT DMSTAG_DOWN_LEFT DMSTAG_DOWN DMSTAG_DOWN_RIGHT DMSTAG_LEFT DMSTAG_ELEMENT DMSTAG_RIGHT DMSTAG_UP_LEFT DMSTAG_UP DMSTAG_UP_RIGHT DMSTAG_FRONT_DOWN_LEFT DMSTAG_FRONT_DOWN DMSTAG_FRONT_DOWN_RIGHT DMSTAG_FRONT_LEFT DMSTAG_FRONT DMSTAG_FRONT_RIGHT DMSTAG_FRONT_UP_LEFT DMSTAG_FRONT_UP DMSTAG_FRONT_UP_RIGHT PetscErrorCode DMStagCreate1d(MPI_Comm,PetscDMBoundaryType,PetscInt,PetscInt,PetscInt,PetscDMStagStencilType,PetscInt,const PetscInt[],PetscDM*) PetscErrorCode DMStagCreate2d(MPI_Comm,PetscDMBoundaryType,PetscDMBoundaryType,PetscInt,PetscInt,PetscInt,PetscInt,PetscInt,PetscInt,PetscInt,PetscDMStagStencilType,PetscInt,const PetscInt[],const PetscInt[],PetscDM*) PetscErrorCode DMStagCreate3d(MPI_Comm,PetscDMBoundaryType,PetscDMBoundaryType,PetscDMBoundaryType,PetscInt,PetscInt,PetscInt,PetscInt,PetscInt,PetscInt,PetscInt,PetscInt,PetscInt,PetscInt,PetscDMStagStencilType,PetscInt,const PetscInt[],const PetscInt[],const PetscInt[],PetscDM*) PetscErrorCode DMStagGetCorners(PetscDM,PetscInt*,PetscInt*,PetscInt*,PetscInt*,PetscInt*,PetscInt*,PetscInt*,PetscInt*,PetscInt*) PetscErrorCode DMStagGetGhostCorners(PetscDM,PetscInt*,PetscInt*,PetscInt*,PetscInt*,PetscInt*,PetscInt*) PetscErrorCode DMStagGetLocalSizes(PetscDM,PetscInt*,PetscInt*,PetscInt*) PetscErrorCode DMStagGetEntriesPerElement(PetscDM,PetscInt*) PetscErrorCode DMStagGetDOF(PetscDM,PetscInt*,PetscInt*,PetscInt*,PetscInt*) PetscErrorCode DMStagGetNumRanks(PetscDM,PetscInt*,PetscInt*,PetscInt*) PetscErrorCode DMStagGetGlobalSizes(PetscDM,PetscInt*,PetscInt*,PetscInt*) PetscErrorCode DMStagGetBoundaryTypes(PetscDM,PetscDMBoundaryType*,PetscDMBoundaryType*,PetscDMBoundaryType*) PetscErrorCode DMStagGetStencilWidth(PetscDM,PetscInt*) PetscErrorCode DMStagGetStencilType(PetscDM,PetscDMStagStencilType*) PetscErrorCode DMStagGetOwnershipRanges(PetscDM,const PetscInt*[],const PetscInt*[],const PetscInt*[]) PetscErrorCode DMStagSetDOF(PetscDM,PetscInt,PetscInt,PetscInt,PetscInt) PetscErrorCode DMStagSetNumRanks(PetscDM,PetscInt,PetscInt,PetscInt) PetscErrorCode DMStagSetGlobalSizes(PetscDM,PetscInt,PetscInt,PetscInt) PetscErrorCode DMStagSetBoundaryTypes(PetscDM,PetscDMBoundaryType,PetscDMBoundaryType,PetscDMBoundaryType) PetscErrorCode DMStagSetStencilWidth(PetscDM,PetscInt) PetscErrorCode DMStagSetStencilType(PetscDM,PetscDMStagStencilType) PetscErrorCode DMStagSetOwnershipRanges(PetscDM,const PetscInt[],const PetscInt[],const PetscInt[]) PetscErrorCode DMStagGetLocationSlot(PetscDM,PetscDMStagStencilLocation,PetscInt,PetscInt*) PetscErrorCode DMStagGetLocationDOF(PetscDM,PetscDMStagStencilLocation,PetscInt*) PetscErrorCode DMStagGetProductCoordinateLocationSlot(PetscDM,PetscDMStagStencilLocation,PetscInt*) PetscErrorCode DMStagGetIsFirstRank(PetscDM,PetscBool*,PetscBool*,PetscBool*) PetscErrorCode DMStagGetIsLastRank(PetscDM,PetscBool*,PetscBool*,PetscBool*) PetscErrorCode DMStagSetUniformCoordinatesExplicit(PetscDM,PetscReal,PetscReal,PetscReal,PetscReal,PetscReal,PetscReal) PetscErrorCode DMStagSetUniformCoordinatesProduct(PetscDM,PetscReal,PetscReal,PetscReal,PetscReal,PetscReal,PetscReal) PetscErrorCode DMStagSetCoordinateDMType(PetscDM,PetscDMType) PetscErrorCode DMStagSetUniformCoordinates(PetscDM,PetscReal,PetscReal,PetscReal,PetscReal,PetscReal,PetscReal) PetscErrorCode DMStagCreateCompatibleDMStag(PetscDM,PetscInt,PetscInt,PetscInt,PetscInt,PetscDM*) PetscErrorCode DMStagVecSplitToDMDA(PetscDM,PetscVec,PetscDMStagStencilLocation,PetscInt,PetscDM*,PetscVec*) PetscErrorCode DMStagMigrateVec(PetscDM,PetscVec,PetscDM,PetscVec) # -------------------------------------------------------------------- cdef inline PetscDMStagStencilType asStagStencil(object stencil) \ except (-1): if isinstance(stencil, str): if stencil == "star": return DMSTAG_STENCIL_STAR elif stencil == "box": return DMSTAG_STENCIL_BOX elif stencil == "none": return DMSTAG_STENCIL_NONE else: raise ValueError("unknown stencil type: %s" % stencil) return stencil cdef inline object toStagStencil(PetscDMStagStencilType stype): if stype == DMSTAG_STENCIL_STAR: return "star" elif stype == DMSTAG_STENCIL_BOX: return "box" elif stype == DMSTAG_STENCIL_NONE: return "none" cdef inline PetscDMStagStencilLocation asStagStencilLocation(object stencil_location) \ except (-1): if isinstance(stencil_location, str): if stencil_location == "null": return DMSTAG_NULL_LOCATION elif stencil_location == "back_down_left": return DMSTAG_BACK_DOWN_LEFT elif stencil_location == "back_down": return DMSTAG_BACK_DOWN elif stencil_location == "back_down_right": return DMSTAG_BACK_DOWN_RIGHT elif stencil_location == "back_left": return DMSTAG_BACK_LEFT elif stencil_location == "back": return DMSTAG_BACK elif stencil_location == "back_right": return DMSTAG_BACK_RIGHT elif stencil_location == "back_up_left": return DMSTAG_BACK_UP_LEFT elif stencil_location == "back_up": return DMSTAG_BACK_UP elif stencil_location == "back_up_right": return DMSTAG_BACK_UP_RIGHT elif stencil_location == "down_left": return DMSTAG_DOWN_LEFT elif stencil_location == "down": return DMSTAG_DOWN elif stencil_location == "down_right": return DMSTAG_DOWN_RIGHT elif stencil_location == "left": return DMSTAG_LEFT elif stencil_location == "element": return DMSTAG_ELEMENT elif stencil_location == "right": return DMSTAG_RIGHT elif stencil_location == "up_left": return DMSTAG_UP_LEFT elif stencil_location == "up": return DMSTAG_UP elif stencil_location == "up_right": return DMSTAG_UP_RIGHT elif stencil_location == "front_down_left": return DMSTAG_FRONT_DOWN_LEFT elif stencil_location == "front_down": return DMSTAG_FRONT_DOWN elif stencil_location == "front_down_right": return DMSTAG_FRONT_DOWN_RIGHT elif stencil_location == "front_left": return DMSTAG_FRONT_LEFT elif stencil_location == "front": return DMSTAG_FRONT elif stencil_location == "front_right": return DMSTAG_FRONT_RIGHT elif stencil_location == "front_up_left": return DMSTAG_FRONT_UP_LEFT elif stencil_location == "front_up": return DMSTAG_FRONT_UP elif stencil_location == "front_up_right": return DMSTAG_FRONT_UP_RIGHT else: raise ValueError("unknown stencil location type: %s" % stencil_location) return stencil_location cdef inline PetscInt asStagDims(dims, PetscInt *_M, PetscInt *_N, PetscInt *_P) except? -1: cdef PetscInt dim = PETSC_DECIDE cdef object M=None, N=None, P=None dims = tuple(dims) dim = len(dims) if dim == 0: pass elif dim == 1: M, = dims elif dim == 2: M, N = dims elif dim == 3: M, N, P = dims if dim >= 1: _M[0] = asInt(M) if dim >= 2: _N[0] = asInt(N) if dim >= 3: _P[0] = asInt(P) return dim cdef inline tuple toStagDims(PetscInt dim, PetscInt M, PetscInt N, PetscInt P): if dim == 0: return () elif dim == 1: return (toInt(M),) elif dim == 2: return (toInt(M), toInt(N)) elif dim == 3: return (toInt(M), toInt(N), toInt(P)) cdef inline PetscInt asDofs(dofs, PetscInt *_dof0, PetscInt *_dof1, PetscInt *_dof2, PetscInt *_dof3) except? -1: cdef PetscInt ndofs = PETSC_DECIDE cdef object dof0=None, dof1=None, dof2=None, dof3=None dofs = tuple(dofs) ndofs = len(dofs) if ndofs == 2: dof0, dof1 = dofs elif ndofs == 3: dof0, dof1, dof2 = dofs elif ndofs == 4: dof0, dof1, dof2, dof3 = dofs if ndofs >= 2: _dof0[0] = asInt(dof0) if ndofs >= 2: _dof1[0] = asInt(dof1) if ndofs >= 3: _dof2[0] = asInt(dof2) if ndofs >= 4: _dof3[0] = asInt(dof3) return ndofs cdef inline tuple toDofs(PetscInt ndofs, PetscInt dof0, PetscInt dof1, PetscInt dof2, PetscInt dof3): if ndofs == 2: return (toInt(dof0), toInt(dof1)) elif ndofs == 3: return (toInt(dof0), toInt(dof1), toInt(dof2)) elif ndofs == 4: return (toInt(dof0), toInt(dof1), toInt(dof2), toInt(dof3)) cdef inline tuple asStagOwnershipRanges(object ownership_ranges, PetscInt dim, PetscInt *m, PetscInt *n, PetscInt *p, PetscInt **_x, PetscInt **_y, PetscInt **_z): cdef object ranges = list(ownership_ranges) cdef PetscInt rdim = len(ranges) cdef PetscInt nlx=0, nly=0, nlz=0 if dim == PETSC_DECIDE: dim = rdim elif dim != rdim: raise ValueError( "number of dimensions %d and number ownership ranges %d" % (toInt(dim), toInt(rdim))) if dim >= 1: ranges[0] = iarray_i(ranges[0], &nlx, _x) if m[0] == PETSC_DECIDE: m[0] = nlx elif m[0] != nlx: raise ValueError( "ownership range size %d and number or processors %d" % (toInt(nlx), toInt(m[0]))) if dim >= 2: ranges[1] = iarray_i(ranges[1], &nly, _y) if n[0] == PETSC_DECIDE: n[0] = nly elif n[0] != nly: raise ValueError( "ownership range size %d and number or processors %d" % (toInt(nly), toInt(n[0]))) if dim >= 3: ranges[2] = iarray_i(ranges[2], &nlz, _z) if p[0] == PETSC_DECIDE: p[0] = nlz elif p[0] != nlz: raise ValueError( "ownership range size %d and number or processors %d" % (toInt(nlz), toInt(p[0]))) return tuple(ranges) cdef inline tuple toStagOwnershipRanges(PetscInt dim, PetscInt m, PetscInt n, PetscInt p, const PetscInt *lx, const PetscInt *ly, const PetscInt *lz): # Returns tuple of arrays containing ownership ranges as Python arrays ranges = [array_i(m, lx)] if dim > 1: ranges.append(array_i(n, ly)) if dim > 2: ranges.append(array_i(p, lz)) return tuple(ranges) cdef inline object toStagBoundary(PetscDMBoundaryType btype): if btype == DM_BOUNDARY_NONE: return "none" elif btype == DM_BOUNDARY_PERIODIC: return "periodic" elif btype == DM_BOUNDARY_GHOSTED: return "ghosted" cdef inline tuple toStagBoundaryTypes(PetscInt dim, PetscDMBoundaryType btx, PetscDMBoundaryType bty, PetscDMBoundaryType btz): if dim == 1: return (toStagBoundary(btx), ) if dim == 2: return (toStagBoundary(btx), toStagBoundary(bty)) if dim == 3: return (toStagBoundary(btx), toStagBoundary(bty), toStagBoundary(btz)) # -------------------------------------------------------------------- ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/src/petsc4py/PETSc/petscdmswarm.pxi0000644000175000017500000000674214567251135021113 0ustar00balaybalay# -------------------------------------------------------------------- cdef extern from * nogil: ctypedef enum PetscDMSwarmType "DMSwarmType": DMSWARM_BASIC DMSWARM_PIC ctypedef enum PetscDMSwarmMigrateType "DMSwarmMigrateType": DMSWARM_MIGRATE_BASIC DMSWARM_MIGRATE_DMCELLNSCATTER DMSWARM_MIGRATE_DMCELLEXACT DMSWARM_MIGRATE_USER ctypedef enum PetscDMSwarmCollectType "DMSwarmCollectType": DMSWARM_COLLECT_BASIC DMSWARM_COLLECT_DMDABOUNDINGBOX DMSWARM_COLLECT_GENERAL DMSWARM_COLLECT_USER ctypedef enum PetscDMSwarmPICLayoutType 'DMSwarmPICLayoutType': DMSWARMPIC_LAYOUT_REGULAR DMSWARMPIC_LAYOUT_GAUSS DMSWARMPIC_LAYOUT_SUBDIVISION PetscErrorCode DMSwarmCreateGlobalVectorFromField(PetscDM,const char[],PetscVec*) PetscErrorCode DMSwarmDestroyGlobalVectorFromField(PetscDM,const char[],PetscVec*) PetscErrorCode DMSwarmCreateLocalVectorFromField(PetscDM,const char[],PetscVec*) PetscErrorCode DMSwarmDestroyLocalVectorFromField(PetscDM,const char[],PetscVec*) PetscErrorCode DMSwarmInitializeFieldRegister(PetscDM) PetscErrorCode DMSwarmFinalizeFieldRegister(PetscDM) PetscErrorCode DMSwarmSetLocalSizes(PetscDM,PetscInt,PetscInt) PetscErrorCode DMSwarmRegisterPetscDatatypeField(PetscDM,const char[],PetscInt,PetscDataType) # PetscErrorCode DMSwarmRegisterUserStructField(PetscDM,const char[],size_t) # PetscErrorCode DMSwarmRegisterUserDatatypeField(PetscDM,const char[],size_t,PetscInt) PetscErrorCode DMSwarmGetField(PetscDM,const char[],PetscInt*,PetscDataType*,void**) PetscErrorCode DMSwarmRestoreField(PetscDM,const char[],PetscInt*,PetscDataType*,void**) PetscErrorCode DMSwarmVectorDefineField(PetscDM,const char[]) PetscErrorCode DMSwarmAddPoint(PetscDM) PetscErrorCode DMSwarmAddNPoints(PetscDM,PetscInt) PetscErrorCode DMSwarmRemovePoint(PetscDM) PetscErrorCode DMSwarmRemovePointAtIndex(PetscDM,PetscInt) PetscErrorCode DMSwarmCopyPoint(PetscDM,PetscInt,PetscInt) PetscErrorCode DMSwarmGetLocalSize(PetscDM,PetscInt*) PetscErrorCode DMSwarmGetSize(PetscDM,PetscInt*) PetscErrorCode DMSwarmMigrate(PetscDM,PetscBool) PetscErrorCode DMSwarmCollectViewCreate(PetscDM) PetscErrorCode DMSwarmCollectViewDestroy(PetscDM) PetscErrorCode DMSwarmSetCellDM(PetscDM,PetscDM) PetscErrorCode DMSwarmGetCellDM(PetscDM,PetscDM*) PetscErrorCode DMSwarmSetType(PetscDM, PetscDMSwarmType) PetscErrorCode DMSwarmSetPointsUniformCoordinates(PetscDM,PetscReal[],PetscReal[],PetscInt[],PetscInsertMode) PetscErrorCode DMSwarmSetPointCoordinates(PetscDM,PetscInt,PetscReal*,PetscBool,PetscInsertMode) PetscErrorCode DMSwarmInsertPointsUsingCellDM(PetscDM,PetscDMSwarmPICLayoutType,PetscInt) PetscErrorCode DMSwarmSetPointCoordinatesCellwise(PetscDM,PetscInt,PetscReal*) PetscErrorCode DMSwarmViewFieldsXDMF(PetscDM,const char*,PetscInt,const char**) PetscErrorCode DMSwarmViewXDMF(PetscDM,const char*) PetscErrorCode DMSwarmSortGetAccess(PetscDM) PetscErrorCode DMSwarmSortRestoreAccess(PetscDM) PetscErrorCode DMSwarmSortGetPointsPerCell(PetscDM,PetscInt,PetscInt*,PetscInt**) PetscErrorCode DMSwarmSortGetNumberOfPointsPerCell(PetscDM,PetscInt,PetscInt*) PetscErrorCode DMSwarmSortGetIsValid(PetscDM,PetscBool*) PetscErrorCode DMSwarmSortGetSizes(PetscDM,PetscInt*,PetscInt*) PetscErrorCode DMSwarmProjectFields(PetscDM,PetscInt,const char**,PetscVec*,PetscScatterMode) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/src/petsc4py/PETSc/petscdmutils.pxi0000644000175000017500000000175414567251135021120 0ustar00balaybalay cdef extern from * nogil: struct _DMInterpolationInfo ctypedef _DMInterpolationInfo* PetscDMInterpolation "DMInterpolationInfo" PetscErrorCode DMInterpolationCreate(MPI_Comm, PetscDMInterpolation*) PetscErrorCode DMInterpolationDestroy(PetscDMInterpolation*) PetscErrorCode DMInterpolationEvaluate(PetscDMInterpolation, PetscDM, PetscVec, PetscVec) PetscErrorCode DMInterpolationGetCoordinates(PetscDMInterpolation, PetscVec*) PetscErrorCode DMInterpolationGetDim(PetscDMInterpolation, PetscInt*) PetscErrorCode DMInterpolationGetDof(PetscDMInterpolation, PetscInt*) PetscErrorCode DMInterpolationGetVector(PetscDMInterpolation, PetscVec*) PetscErrorCode DMInterpolationRestoreVector(PetscDMInterpolation, PetscVec*) PetscErrorCode DMInterpolationSetDim(PetscDMInterpolation, PetscInt) PetscErrorCode DMInterpolationSetDof(PetscDMInterpolation, PetscInt) PetscErrorCode DMInterpolationSetUp(PetscDMInterpolation, PetscDM, PetscBool, PetscBool) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/src/petsc4py/PETSc/petscds.pxi0000644000175000017500000000340314567251135020036 0ustar00balaybalaycdef extern from * nogil: ctypedef const char* PetscDSType PetscDSType PETSCDSBASIC PetscErrorCode PetscDSCreate(MPI_Comm,PetscDS*) PetscErrorCode PetscDSDestroy(PetscDS*) PetscErrorCode PetscDSView(PetscDS,PetscViewer) PetscErrorCode PetscDSSetType(PetscDS,PetscDSType) PetscErrorCode PetscDSGetType(PetscDS,PetscDSType*) PetscErrorCode PetscDSSetFromOptions(PetscDS) PetscErrorCode PetscDSSetUp(PetscDS) PetscErrorCode PetscDSGetHeightSubspace(PetscDS,PetscInt,PetscDS*) PetscErrorCode PetscDSGetSpatialDimension(PetscDS,PetscInt*) PetscErrorCode PetscDSGetCoordinateDimension(PetscDS,PetscInt*) PetscErrorCode PetscDSSetCoordinateDimension(PetscDS,PetscInt) PetscErrorCode PetscDSGetNumFields(PetscDS,PetscInt*) PetscErrorCode PetscDSGetTotalDimension(PetscDS,PetscInt*) PetscErrorCode PetscDSGetTotalComponents(PetscDS,PetscInt*) PetscErrorCode PetscDSGetFieldIndex(PetscDS,PetscObject,PetscInt*) PetscErrorCode PetscDSGetFieldSize(PetscDS,PetscInt,PetscInt*) PetscErrorCode PetscDSGetFieldOffset(PetscDS,PetscInt,PetscInt*) PetscErrorCode PetscDSGetDimensions(PetscDS,PetscInt*[]) PetscErrorCode PetscDSGetComponents(PetscDS,PetscInt*[]) PetscErrorCode PetscDSGetComponentOffset(PetscDS,PetscInt,PetscInt*) PetscErrorCode PetscDSGetComponentOffsets(PetscDS,PetscInt*[]) PetscErrorCode PetscDSGetComponentDerivativeOffsets(PetscDS,PetscInt*[]) PetscErrorCode PetscDSGetDiscretization(PetscDS,PetscInt,PetscObject*) PetscErrorCode PetscDSSetDiscretization(PetscDS,PetscInt,PetscObject) PetscErrorCode PetscDSAddDiscretization(PetscDS,PetscObject) PetscErrorCode PetscDSGetImplicit(PetscDS,PetscInt,PetscBool*) PetscErrorCode PetscDSSetImplicit(PetscDS,PetscInt,PetscBool) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/src/petsc4py/PETSc/petscdt.pxi0000644000175000017500000000666414567251135020053 0ustar00balaybalay# -------------------------------------------------------------------- cdef extern from * nogil: ctypedef enum int "PetscGaussLobattoLegendreCreateType": PETSCGAUSSLOBATTOLEGENDRE_VIA_LINEAR_ALGEBRA PETSCGAUSSLOBATTOLEGENDRE_VIA_NEWTON PetscErrorCode PetscFECreateDefault(MPI_Comm, PetscInt, PetscInt, PetscBool, const char [], PetscInt, PetscFE*) PetscErrorCode PetscQuadratureCreate(MPI_Comm, PetscQuadrature*) PetscErrorCode PetscQuadratureDuplicate(PetscQuadrature, PetscQuadrature*) PetscErrorCode PetscQuadratureGetOrder(PetscQuadrature, PetscInt*) PetscErrorCode PetscQuadratureSetOrder(PetscQuadrature, PetscInt) PetscErrorCode PetscQuadratureGetNumComponents(PetscQuadrature, PetscInt*) PetscErrorCode PetscQuadratureSetNumComponents(PetscQuadrature, PetscInt) PetscErrorCode PetscQuadratureGetData(PetscQuadrature, PetscInt*, PetscInt*, PetscInt*, const PetscReal *[], const PetscReal *[]) PetscErrorCode PetscQuadratureSetData(PetscQuadrature, PetscInt, PetscInt, PetscInt, const PetscReal [], const PetscReal []) PetscErrorCode PetscQuadratureView(PetscQuadrature, PetscViewer) PetscErrorCode PetscQuadratureDestroy(PetscQuadrature *) PetscErrorCode PetscQuadratureExpandComposite(PetscQuadrature, PetscInt, const PetscReal[], const PetscReal[], PetscQuadrature *) PetscErrorCode PetscDTLegendreEval(PetscInt,const PetscReal*,PetscInt,const PetscInt*,PetscReal*,PetscReal*,PetscReal*) PetscErrorCode PetscDTGaussQuadrature(PetscInt,PetscReal,PetscReal,PetscReal*,PetscReal*) PetscErrorCode PetscDTGaussLobattoLegendreQuadrature(PetscInt,PetscGaussLobattoLegendreCreateType,PetscReal*,PetscReal*) PetscErrorCode PetscDTReconstructPoly(PetscInt,PetscInt,const PetscReal*,PetscInt,const PetscReal*,PetscReal*) PetscErrorCode PetscDTGaussTensorQuadrature(PetscInt,PetscInt,PetscInt,PetscReal,PetscReal,PetscQuadrature*) PetscErrorCode PetscDTGaussJacobiQuadrature(PetscInt,PetscInt,PetscInt,PetscReal,PetscReal,PetscQuadrature*) PetscErrorCode PetscDTTanhSinhTensorQuadrature(PetscInt, PetscInt, PetscReal, PetscReal, PetscQuadrature *) PetscErrorCode PetscDTTanhSinhIntegrate(void (*)(PetscReal *, void *, PetscReal *), PetscReal, PetscReal, PetscInt, PetscReal *) PetscErrorCode PetscDTTanhSinhIntegrateMPFR(void (*)(PetscReal *, void *, PetscReal *), PetscReal, PetscReal, PetscInt, PetscReal *) PetscErrorCode PetscGaussLobattoLegendreIntegrate(PetscInt, PetscReal *, PetscReal *, const PetscReal *, PetscReal *) PetscErrorCode PetscGaussLobattoLegendreElementLaplacianCreate(PetscInt, PetscReal *, PetscReal *, PetscReal ***) PetscErrorCode PetscGaussLobattoLegendreElementLaplacianDestroy(PetscInt, PetscReal *, PetscReal *, PetscReal ***) PetscErrorCode PetscGaussLobattoLegendreElementGradientCreate(PetscInt, PetscReal *, PetscReal *, PetscReal ***, PetscReal ***) PetscErrorCode PetscGaussLobattoLegendreElementGradientDestroy(PetscInt, PetscReal *, PetscReal *, PetscReal ***, PetscReal ***) PetscErrorCode PetscGaussLobattoLegendreElementAdvectionCreate(PetscInt, PetscReal *, PetscReal *, PetscReal ***) PetscErrorCode PetscGaussLobattoLegendreElementAdvectionDestroy(PetscInt, PetscReal *, PetscReal *, PetscReal ***) PetscErrorCode PetscGaussLobattoLegendreElementMassCreate(PetscInt, PetscReal *, PetscReal *, PetscReal ***) PetscErrorCode PetscGaussLobattoLegendreElementMassDestroy(PetscInt, PetscReal *, PetscReal *, PetscReal ***) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/src/petsc4py/PETSc/petscfe.pxi0000644000175000017500000000346714567251135020034 0ustar00balaybalay# -------------------------------------------------------------------- cdef extern from * nogil: ctypedef const char* PetscFEType PetscFEType PETSCFEBASIC PetscFEType PETSCFEOPENCL PetscFEType PETSCFECOMPOSITE PetscErrorCode PetscFECreate(MPI_Comm, PetscFE*) PetscErrorCode PetscFECreateDefault(MPI_Comm, PetscInt, PetscInt, PetscBool, const char [], PetscInt, PetscFE*) PetscErrorCode PetscFECreateLagrange(MPI_Comm, PetscInt, PetscInt, PetscBool, PetscInt, PetscInt, PetscFE*) PetscErrorCode PetscFESetType(PetscFE, PetscFEType) PetscErrorCode PetscFEGetQuadrature(PetscFE, PetscQuadrature*) PetscErrorCode PetscFEGetFaceQuadrature(PetscFE, PetscQuadrature*) PetscErrorCode PetscFESetQuadrature(PetscFE, PetscQuadrature) PetscErrorCode PetscFESetFaceQuadrature(PetscFE, PetscQuadrature) PetscErrorCode PetscFEDestroy(PetscFE*) PetscErrorCode PetscFEGetBasisSpace(PetscFE, PetscSpace*) PetscErrorCode PetscFESetBasisSpace(PetscFE, PetscSpace) PetscErrorCode PetscFEGetDimension(PetscFE, PetscInt*) PetscErrorCode PetscFEGetNumComponents(PetscFE, PetscInt*) PetscErrorCode PetscFESetNumComponents(PetscFE, PetscInt) PetscErrorCode PetscFEGetNumDof(PetscFE, const PetscInt**) PetscErrorCode PetscFEGetSpatialDimension(PetscFE, PetscInt*) PetscErrorCode PetscFEGetTileSizes(PetscFE, PetscInt*, PetscInt*, PetscInt*, PetscInt*) PetscErrorCode PetscFESetTileSizes(PetscFE, PetscInt, PetscInt, PetscInt, PetscInt) PetscErrorCode PetscFEGetDualSpace(PetscFE, PetscDualSpace*) PetscErrorCode PetscFESetDualSpace(PetscFE, PetscDualSpace) PetscErrorCode PetscFESetFromOptions(PetscFE) PetscErrorCode PetscFESetUp(PetscFE) PetscErrorCode PetscFEView(PetscFE, PetscViewer) PetscErrorCode PetscFEViewFromOptions(PetscFE, PetscObject, char[]) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/src/petsc4py/PETSc/petscis.pxi0000644000175000017500000002052314567251135020045 0ustar00balaybalaycdef extern from * nogil: ctypedef const char* PetscISType "ISType" PetscISType ISGENERAL PetscISType ISSTRIDE PetscISType ISBLOCK PetscErrorCode ISView(PetscIS,PetscViewer) PetscErrorCode ISDestroy(PetscIS*) PetscErrorCode ISCreate(MPI_Comm,PetscIS*) PetscErrorCode ISSetType(PetscIS,PetscISType) PetscErrorCode ISGetType(PetscIS,PetscISType*) PetscErrorCode ISCreateGeneral(MPI_Comm,PetscInt,PetscInt[],PetscCopyMode,PetscIS*) PetscErrorCode ISCreateBlock(MPI_Comm,PetscInt,PetscInt,PetscInt[],PetscCopyMode,PetscIS*) PetscErrorCode ISCreateStride(MPI_Comm,PetscInt,PetscInt,PetscInt,PetscIS*) PetscErrorCode ISLoad(PetscIS,PetscViewer) PetscErrorCode ISDuplicate(PetscIS,PetscIS*) PetscErrorCode ISCopy(PetscIS,PetscIS) PetscErrorCode ISAllGather(PetscIS,PetscIS*) PetscErrorCode ISInvertPermutation(PetscIS,PetscInt,PetscIS*) PetscErrorCode ISGetSize(PetscIS,PetscInt*) PetscErrorCode ISGetLocalSize(PetscIS,PetscInt*) PetscErrorCode ISGetBlockSize(PetscIS,PetscInt*) PetscErrorCode ISSetBlockSize(PetscIS,PetscInt) PetscErrorCode ISGetIndices(PetscIS,const PetscInt*[]) PetscErrorCode ISRestoreIndices(PetscIS,const PetscInt*[]) PetscErrorCode ISEqual(PetscIS,PetscIS,PetscBool*) PetscErrorCode ISSetPermutation(PetscIS) PetscErrorCode ISPermutation(PetscIS,PetscBool*) PetscErrorCode ISSetIdentity(PetscIS) PetscErrorCode ISIdentity(PetscIS,PetscBool*) PetscErrorCode ISSort(PetscIS) PetscErrorCode ISSorted(PetscIS,PetscBool*) PetscErrorCode ISSum(PetscIS,PetscIS,PetscIS*) PetscErrorCode ISExpand(PetscIS,PetscIS,PetscIS*) PetscErrorCode ISDifference(PetscIS,PetscIS,PetscIS*) PetscErrorCode ISComplement(PetscIS,PetscInt,PetscInt,PetscIS*) PetscErrorCode ISEmbed(PetscIS,PetscIS,PetscBool,PetscIS*) PetscErrorCode ISRenumber(PetscIS,PetscIS,PetscInt*,PetscIS*) PetscErrorCode ISGeneralSetIndices(PetscIS,PetscInt,PetscInt[],PetscCopyMode) PetscErrorCode ISBlockSetIndices(PetscIS,PetscInt,PetscInt,PetscInt[],PetscCopyMode) PetscErrorCode ISBlockGetIndices(PetscIS,const PetscInt*[]) PetscErrorCode ISBlockRestoreIndices(PetscIS,const PetscInt*[]) PetscErrorCode ISStrideSetStride(PetscIS,PetscInt,PetscInt,PetscInt) PetscErrorCode ISStrideGetInfo(PetscIS,PetscInt*,PetscInt*) PetscErrorCode ISToGeneral(PetscIS) PetscErrorCode ISBuildTwoSided(PetscIS,PetscIS,PetscIS*) cdef extern from * nogil: ctypedef const char* PetscISLocalToGlobalMappingType "ISLocalToGlobalMappingType" PetscISLocalToGlobalMappingType ISLOCALTOGLOBALMAPPINGBASIC PetscISLocalToGlobalMappingType ISLOCALTOGLOBALMAPPINGHASH ctypedef enum PetscGLMapMode "ISGlobalToLocalMappingMode": PETSC_IS_GTOLM_MASK "IS_GTOLM_MASK" PETSC_IS_GTOLM_DROP "IS_GTOLM_DROP" PetscErrorCode ISLocalToGlobalMappingCreate(MPI_Comm,PetscInt,PetscInt,PetscInt[],PetscCopyMode,PetscLGMap*) PetscErrorCode ISLocalToGlobalMappingCreateIS(PetscIS,PetscLGMap*) PetscErrorCode ISLocalToGlobalMappingCreateSF(PetscSF,PetscInt,PetscLGMap*) PetscErrorCode ISLocalToGlobalMappingSetType(PetscLGMap,PetscISLocalToGlobalMappingType) PetscErrorCode ISLocalToGlobalMappingSetFromOptions(PetscLGMap) PetscErrorCode ISLocalToGlobalMappingView(PetscLGMap,PetscViewer) PetscErrorCode ISLocalToGlobalMappingDestroy(PetscLGMap*) PetscErrorCode ISLocalToGlobalMappingGetSize(PetscLGMap,PetscInt*) PetscErrorCode ISLocalToGlobalMappingGetBlockSize(PetscLGMap,PetscInt*) PetscErrorCode ISLocalToGlobalMappingGetIndices(PetscLGMap,const PetscInt*[]) PetscErrorCode ISLocalToGlobalMappingRestoreIndices(PetscLGMap,const PetscInt*[]) PetscErrorCode ISLocalToGlobalMappingGetBlockIndices(PetscLGMap,const PetscInt*[]) PetscErrorCode ISLocalToGlobalMappingRestoreBlockIndices(PetscLGMap,const PetscInt*[]) PetscErrorCode ISLocalToGlobalMappingGetInfo(PetscLGMap,PetscInt*,PetscInt*[],PetscInt*[],PetscInt**[]) PetscErrorCode ISLocalToGlobalMappingRestoreInfo(PetscLGMap,PetscInt*,PetscInt*[],PetscInt*[],PetscInt**[]) PetscErrorCode ISLocalToGlobalMappingGetBlockInfo(PetscLGMap,PetscInt*,PetscInt*[],PetscInt*[],PetscInt**[]) PetscErrorCode ISLocalToGlobalMappingRestoreBlockInfo(PetscLGMap,PetscInt*,PetscInt*[],PetscInt*[],PetscInt**[]) PetscErrorCode ISLocalToGlobalMappingApply(PetscLGMap,PetscInt,PetscInt[],PetscInt[]) PetscErrorCode ISLocalToGlobalMappingApplyBlock(PetscLGMap,PetscInt,PetscInt[],PetscInt[]) PetscErrorCode ISLocalToGlobalMappingApplyIS(PetscLGMap,PetscIS,PetscIS*) PetscErrorCode ISGlobalToLocalMappingApply(PetscLGMap,PetscGLMapMode,PetscInt,PetscInt[],PetscInt*,PetscInt[]) PetscErrorCode ISGlobalToLocalMappingApplyBlock(PetscLGMap,PetscGLMapMode,PetscInt,PetscInt[],PetscInt*,PetscInt[]) # -------------------------------------------------------------------- cdef inline IS ref_IS(PetscIS iset): cdef IS ob = IS() ob.iset = iset CHKERR( PetscINCREF(ob.obj) ) return ob cdef inline LGMap ref_LGMap(PetscLGMap lgm): cdef LGMap ob = LGMap() ob.lgm = lgm CHKERR( PetscINCREF(ob.obj) ) return ob # -------------------------------------------------------------------- cdef class _IS_buffer: cdef PetscIS iset cdef PetscInt size cdef const PetscInt *data cdef bint hasarray def __cinit__(self, IS iset): cdef PetscIS i = iset.iset CHKERR( PetscINCREF(&i) ) self.iset = i self.size = 0 self.data = NULL self.hasarray = 0 def __dealloc__(self): if self.hasarray and self.iset != NULL: CHKERR( ISRestoreIndices(self.iset, &self.data) ) CHKERR( ISDestroy(&self.iset) ) # cdef int acquire(self) except -1: if not self.hasarray and self.iset != NULL: CHKERR( ISGetLocalSize(self.iset, &self.size) ) CHKERR( ISGetIndices(self.iset, &self.data) ) self.hasarray = 1 return 0 cdef int release(self) except -1: if self.hasarray and self.iset != NULL: self.size = 0 CHKERR( ISRestoreIndices(self.iset, &self.data) ) self.hasarray = 0 self.data = NULL return 0 # buffer interface (PEP 3118) cdef int acquirebuffer(self, Py_buffer *view, int flags) except -1: self.acquire() PyPetscBuffer_FillInfo(view, self.data, self.size, c'i', 1, flags) view.obj = self return 0 cdef int releasebuffer(self, Py_buffer *view) except -1: PyPetscBuffer_Release(view) self.release() return 0 def __getbuffer__(self, Py_buffer *view, int flags): self.acquirebuffer(view, flags) def __releasebuffer__(self, Py_buffer *view): self.releasebuffer(view) # 'with' statement (PEP 343) cdef object enter(self): self.acquire() return asarray(self) cdef object exit(self): self.release() return None def __enter__(self): return self.enter() def __exit__(self, *exc): return self.exit() # buffer interface (legacy) cdef Py_ssize_t getbuffer(self, void **p) except -1: cdef PetscInt n = 0 if p != NULL: self.acquire() p[0] = self.data n = self.size elif self.iset != NULL: CHKERR( ISGetLocalSize(self.iset, &n) ) return (n*sizeof(PetscInt)) def __getsegcount__(self, Py_ssize_t *lenp): if lenp != NULL: lenp[0] = self.getbuffer(NULL) return 1 def __getreadbuffer__(self, Py_ssize_t idx, void **p): if idx != 0: raise SystemError( "accessing non-existent buffer segment") return self.getbuffer(p) # NumPy array interface (legacy) property __array_interface__: def __get__(self): cdef PetscInt n = 0 if self.iset != NULL: CHKERR( ISGetLocalSize(self.iset, &n) ) cdef object size = toInt(n) cdef dtype descr = PyArray_DescrFromType(NPY_PETSC_INT) cdef str typestr = "=%c%d" % (descr.kind, descr.itemsize) return dict(version=3, data=self, shape=(size,), typestr=typestr) # -------------------------------------------------------------------- ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/src/petsc4py/PETSc/petscksp.pxi0000644000175000017500000002646014567251135020235 0ustar00balaybalaycdef extern from * nogil: ctypedef const char* PetscKSPType "KSPType" PetscKSPType KSPRICHARDSON PetscKSPType KSPCHEBYSHEV PetscKSPType KSPCG PetscKSPType KSPGROPPCG PetscKSPType KSPPIPECG PetscKSPType KSPPIPECGRR PetscKSPType KSPPIPELCG PetscKSPType KSPPIPEPRCG PetscKSPType KSPPIPECG2 PetscKSPType KSPCGNE PetscKSPType KSPNASH PetscKSPType KSPSTCG PetscKSPType KSPGLTR PetscKSPType KSPFCG PetscKSPType KSPPIPEFCG PetscKSPType KSPGMRES PetscKSPType KSPPIPEFGMRES PetscKSPType KSPFGMRES PetscKSPType KSPLGMRES PetscKSPType KSPDGMRES PetscKSPType KSPPGMRES PetscKSPType KSPTCQMR PetscKSPType KSPBCGS PetscKSPType KSPIBCGS PetscKSPType KSPQMRCGS PetscKSPType KSPFBCGS PetscKSPType KSPFBCGSR PetscKSPType KSPBCGSL PetscKSPType KSPPIPEBCGS PetscKSPType KSPCGS PetscKSPType KSPTFQMR PetscKSPType KSPCR PetscKSPType KSPPIPECR PetscKSPType KSPLSQR PetscKSPType KSPPREONLY PetscKSPType KSPNONE PetscKSPType KSPQCG PetscKSPType KSPBICG PetscKSPType KSPMINRES PetscKSPType KSPSYMMLQ PetscKSPType KSPLCD PetscKSPType KSPPYTHON PetscKSPType KSPGCR PetscKSPType KSPPIPEGCR PetscKSPType KSPTSIRM PetscKSPType KSPCGLS PetscKSPType KSPFETIDP PetscKSPType KSPHPDDM ctypedef enum PetscKSPNormType "KSPNormType": KSP_NORM_DEFAULT KSP_NORM_NONE KSP_NORM_PRECONDITIONED KSP_NORM_UNPRECONDITIONED KSP_NORM_NATURAL ctypedef enum PetscKSPConvergedReason "KSPConvergedReason": # iterating KSP_CONVERGED_ITERATING # converged KSP_CONVERGED_RTOL_NORMAL KSP_CONVERGED_ATOL_NORMAL KSP_CONVERGED_RTOL KSP_CONVERGED_ATOL KSP_CONVERGED_ITS KSP_CONVERGED_NEG_CURVE KSP_CONVERGED_STEP_LENGTH KSP_CONVERGED_HAPPY_BREAKDOWN # diverged KSP_DIVERGED_NULL KSP_DIVERGED_MAX_IT "KSP_DIVERGED_ITS" KSP_DIVERGED_DTOL KSP_DIVERGED_BREAKDOWN KSP_DIVERGED_BREAKDOWN_BICG KSP_DIVERGED_NONSYMMETRIC KSP_DIVERGED_INDEFINITE_PC KSP_DIVERGED_NANORINF KSP_DIVERGED_INDEFINITE_MAT KSP_DIVERGED_PC_FAILED ctypedef enum PetscKSPHPDDMType "KSPHPDDMType": KSP_HPDDM_TYPE_GMRES KSP_HPDDM_TYPE_BGMRES KSP_HPDDM_TYPE_CG KSP_HPDDM_TYPE_BCG KSP_HPDDM_TYPE_GCRODR KSP_HPDDM_TYPE_BGCRODR KSP_HPDDM_TYPE_BFBCG KSP_HPDDM_TYPE_PREONLY ctypedef PetscErrorCode (*PetscKSPCtxDel)(void*) ctypedef PetscErrorCode (*PetscKSPConvergedFunction)(PetscKSP, PetscInt, PetscReal, PetscKSPConvergedReason*, void*) except PETSC_ERR_PYTHON ctypedef PetscErrorCode (*PetscKSPMonitorFunction)(PetscKSP, PetscInt, PetscReal, void*) except PETSC_ERR_PYTHON ctypedef PetscErrorCode (*PetscKSPComputeRHSFunction)(PetscKSP, PetscVec, void*) except PETSC_ERR_PYTHON ctypedef PetscErrorCode (*PetscKSPComputeOpsFunction)(PetscKSP, PetscMat, PetscMat, void*) except PETSC_ERR_PYTHON PetscErrorCode KSPCreate(MPI_Comm,PetscKSP*) PetscErrorCode KSPDestroy(PetscKSP*) PetscErrorCode KSPView(PetscKSP,PetscViewer) PetscErrorCode KSPSetType(PetscKSP,PetscKSPType) PetscErrorCode KSPGetType(PetscKSP,PetscKSPType*) PetscErrorCode KSPSetOptionsPrefix(PetscKSP,char[]) PetscErrorCode KSPAppendOptionsPrefix(PetscKSP,char[]) PetscErrorCode KSPGetOptionsPrefix(PetscKSP,char*[]) PetscErrorCode KSPSetFromOptions(PetscKSP) PetscErrorCode KSPSetTolerances(PetscKSP,PetscReal,PetscReal,PetscReal,PetscInt) PetscErrorCode KSPGetTolerances(PetscKSP,PetscReal*,PetscReal*,PetscReal*,PetscInt*) PetscErrorCode KSPSetNormType(PetscKSP,PetscKSPNormType) PetscErrorCode KSPGetNormType(PetscKSP,PetscKSPNormType*) PetscErrorCode KSPSetPCSide(PetscKSP,PetscPCSide) PetscErrorCode KSPGetPCSide(PetscKSP,PetscPCSide*) PetscErrorCode KSPSetSupportedNorm(PetscKSP,PetscKSPNormType,PetscPCSide,PetscInt) PetscErrorCode KSPSetConvergenceTest(PetscKSP,PetscKSPConvergedFunction,void*,PetscKSPCtxDel) PetscErrorCode KSPSetResidualHistory(PetscKSP,PetscReal[],PetscInt,PetscBool) PetscErrorCode KSPGetResidualHistory(PetscKSP,PetscReal*[],PetscInt*) PetscErrorCode KSPLogResidualHistory(PetscKSP,PetscReal) PetscErrorCode KSPConvergedDefaultCreate(void**) PetscErrorCode KSPConvergedDefaultDestroy(void*) PetscErrorCode KSPConvergedDefault(PetscKSP,PetscInt,PetscReal,PetscKSPConvergedReason*,void*) except PETSC_ERR_PYTHON PetscErrorCode KSPConvergedSkip(PetscKSP,PetscInt,PetscReal,PetscKSPConvergedReason*,void*) except PETSC_ERR_PYTHON PetscErrorCode KSPMonitorSet(PetscKSP,PetscKSPMonitorFunction,void*,PetscKSPCtxDel) PetscErrorCode KSPMonitorCancel(PetscKSP) PetscErrorCode KSPMonitor(PetscKSP,PetscInt,PetscReal) PetscErrorCode KSPSetInitialGuessNonzero(PetscKSP,PetscBool) PetscErrorCode KSPGetInitialGuessNonzero(PetscKSP,PetscBool*) PetscErrorCode KSPSetInitialGuessKnoll(PetscKSP,PetscBool) PetscErrorCode KSPGetInitialGuessKnoll(PetscKSP,PetscBool*) PetscErrorCode KSPSetUseFischerGuess(PetscKSP,PetscInt,PetscInt) PetscErrorCode KSPGetComputeEigenvalues(PetscKSP,PetscBool*) PetscErrorCode KSPSetComputeEigenvalues(PetscKSP,PetscBool) PetscErrorCode KSPGetComputeSingularValues(PetscKSP,PetscBool*) PetscErrorCode KSPSetComputeSingularValues(PetscKSP,PetscBool) PetscErrorCode KSPSetComputeRHS(PetscKSP,PetscKSPComputeRHSFunction,void*) PetscErrorCode KSPSetComputeOperators(PetscKSP,PetscKSPComputeOpsFunction,void*) PetscErrorCode KSPSetOperators(PetscKSP,PetscMat,PetscMat) PetscErrorCode KSPGetOperators(PetscKSP,PetscMat*,PetscMat*) PetscErrorCode KSPGetOperatorsSet(PetscKSP,PetscBool*,PetscBool*) PetscErrorCode KSPSetPC(PetscKSP,PetscPC) PetscErrorCode KSPGetPC(PetscKSP,PetscPC*) PetscErrorCode KSPGetDM(PetscKSP,PetscDM*) PetscErrorCode KSPSetDM(PetscKSP,PetscDM) PetscErrorCode KSPSetDMActive(PetscKSP,PetscBool) PetscErrorCode KSPSetUp(PetscKSP) PetscErrorCode KSPReset(PetscKSP) PetscErrorCode KSPSetUpOnBlocks(PetscKSP) PetscErrorCode KSPSolve(PetscKSP,PetscVec,PetscVec) PetscErrorCode KSPSolveTranspose(PetscKSP,PetscVec,PetscVec) PetscErrorCode KSPMatSolve(PetscKSP,PetscMat,PetscMat) PetscErrorCode KSPMatSolveTranspose(PetscKSP,PetscMat,PetscMat) PetscErrorCode KSPGetRhs(PetscKSP,PetscVec*) PetscErrorCode KSPGetSolution(PetscKSP,PetscVec*) PetscErrorCode KSPGetConvergedReason(PetscKSP,PetscKSPConvergedReason*) PetscErrorCode KSPGetIterationNumber(PetscKSP,PetscInt*) PetscErrorCode KSPGetResidualNorm(PetscKSP,PetscReal*) PetscErrorCode KSPSetErrorIfNotConverged(PetscKSP,PetscBool); PetscErrorCode KSPGetErrorIfNotConverged(PetscKSP,PetscBool*); PetscErrorCode KSPBuildSolution(PetscKSP,PetscVec,PetscVec*) PetscErrorCode KSPBuildSolutionDefault(PetscKSP,PetscVec,PetscVec*) PetscErrorCode KSPBuildResidual(PetscKSP,PetscVec,PetscVec,PetscVec*) PetscErrorCode KSPBuildResidualDefault(PetscKSP,PetscVec,PetscVec,PetscVec*) PetscErrorCode KSPSetDiagonalScale(PetscKSP,PetscBool) PetscErrorCode KSPGetDiagonalScale(PetscKSP,PetscBool*) PetscErrorCode KSPSetDiagonalScaleFix(PetscKSP,PetscBool) PetscErrorCode KSPGetDiagonalScaleFix(PetscKSP,PetscBool*) PetscErrorCode KSPComputeExplicitOperator(PetscKSP,PetscMat*) PetscErrorCode KSPComputeEigenvalues(PetscKSP,PetscInt,PetscReal[],PetscReal[],PetscInt*) PetscErrorCode KSPComputeExtremeSingularValues(PetscKSP,PetscReal*,PetscReal*) PetscErrorCode KSPCreateVecs(PetscKSP,PetscInt,PetscVec**,PetscInt,PetscVec**) PetscErrorCode KSPGMRESSetRestart(PetscKSP,PetscInt) PetscErrorCode KSPPythonSetType(PetscKSP,char[]) PetscErrorCode KSPPythonGetType(PetscKSP,char*[]) PetscErrorCode KSPHPDDMSetType(PetscKSP,PetscKSPHPDDMType) PetscErrorCode KSPHPDDMGetType(PetscKSP,PetscKSPHPDDMType*) cdef extern from * nogil: # custom.h PetscErrorCode KSPSetIterationNumber(PetscKSP,PetscInt) PetscErrorCode KSPSetResidualNorm(PetscKSP,PetscReal) PetscErrorCode KSPConvergenceTestCall(PetscKSP,PetscInt,PetscReal,PetscKSPConvergedReason*) PetscErrorCode KSPSetConvergedReason(PetscKSP,PetscKSPConvergedReason) # ----------------------------------------------------------------------------- cdef inline KSP ref_KSP(PetscKSP ksp): cdef KSP ob = KSP() ob.ksp = ksp CHKERR( PetscINCREF(ob.obj) ) return ob # ----------------------------------------------------------------------------- cdef PetscErrorCode KSP_Converged( PetscKSP ksp, PetscInt its, PetscReal rnm, PetscKSPConvergedReason *r, void* ctx, ) except PETSC_ERR_PYTHON with gil: cdef KSP Ksp = ref_KSP(ksp) (converged, args, kargs) = Ksp.get_attr('__converged__') reason = converged(Ksp, toInt(its), toReal(rnm), *args, **kargs) if reason is None: r[0] = KSP_CONVERGED_ITERATING elif reason is False: r[0] = KSP_CONVERGED_ITERATING elif reason is True: r[0] = KSP_CONVERGED_ITS # XXX ? else: r[0] = reason return PETSC_SUCCESS # ----------------------------------------------------------------------------- cdef PetscErrorCode KSP_Monitor( PetscKSP ksp, PetscInt its, PetscReal rnm, void* ctx, ) except PETSC_ERR_PYTHON with gil: cdef KSP Ksp = ref_KSP(ksp) cdef object monitorlist = Ksp.get_attr('__monitor__') if monitorlist is None: return PETSC_SUCCESS for (monitor, args, kargs) in monitorlist: monitor(Ksp, toInt(its), toReal(rnm), *args, **kargs) return PETSC_SUCCESS # ----------------------------------------------------------------------------- cdef PetscErrorCode KSP_ComputeRHS( PetscKSP ksp, PetscVec rhs, void* ctx, ) except PETSC_ERR_PYTHON with gil: cdef KSP Ksp = ref_KSP(ksp) cdef Vec Rhs = ref_Vec(rhs) cdef object context = Ksp.get_attr('__rhs__') if context is None and ctx != NULL: context = ctx assert context is not None and type(context) is tuple # sanity check (computerhs, args, kargs) = context computerhs(Ksp, Rhs, *args, **kargs) return PETSC_SUCCESS cdef PetscErrorCode KSP_ComputeOps( PetscKSP ksp, PetscMat A, PetscMat B, void* ctx, ) except PETSC_ERR_PYTHON with gil: cdef KSP Ksp = ref_KSP(ksp) cdef Mat Amat = ref_Mat(A) cdef Mat Bmat = ref_Mat(B) cdef object context = Ksp.get_attr('__operators__') if context is None and ctx != NULL: context = ctx assert context is not None and type(context) is tuple # sanity check (computeops, args, kargs) = context computeops(Ksp, Amat, Bmat, *args, **kargs) return PETSC_SUCCESS # ----------------------------------------------------------------------------- ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/src/petsc4py/PETSc/petsclayout.pxi0000644000175000017500000000103714567251135020746 0ustar00balaybalay# -------------------------------------------------------------------- cdef extern from * nogil: struct _n_PetscLayout ctypedef _n_PetscLayout* PetscLayout PetscErrorCode PetscLayoutSetLocalSize(PetscLayout,PetscInt) PetscErrorCode PetscLayoutSetSize(PetscLayout,PetscInt) PetscErrorCode PetscLayoutGetBlockSize(PetscLayout,PetscInt*) PetscErrorCode PetscLayoutSetBlockSize(PetscLayout,PetscInt) PetscErrorCode PetscLayoutSetUp(PetscLayout) # -------------------------------------------------------------------- ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/src/petsc4py/PETSc/petsclog.pxi0000644000175000017500000000567414567251135020225 0ustar00balaybalaycdef extern from * nogil: ctypedef double PetscLogDouble ctypedef struct PetscEventPerfInfo: int count PetscLogDouble flops, time PetscLogDouble numMessages PetscLogDouble messageLength PetscLogDouble numReductions PetscErrorCode PetscLogDefaultBegin() PetscErrorCode PetscLogView(PetscViewer) PetscErrorCode PetscLogIsActive(PetscBool*) PetscErrorCode PetscLogFlops(PetscLogDouble) PetscErrorCode PetscGetFlops(PetscLogDouble*) PetscErrorCode PetscGetCPUTime(PetscLogDouble*) PetscErrorCode PetscMallocGetCurrentUsage(PetscLogDouble*) PetscErrorCode PetscMemoryGetCurrentUsage(PetscLogDouble*) PetscErrorCode PetscTime(PetscLogDouble*) PetscErrorCode PetscTimeSubtract(PetscLogDouble*) PetscErrorCode PetscTimeAdd(PetscLogDouble*) ctypedef int PetscLogStage PetscErrorCode PetscLogStageRegister(char[],PetscLogStage*) PetscErrorCode PetscLogStagePush(PetscLogStage) PetscErrorCode PetscLogStagePop() PetscErrorCode PetscLogStageSetActive(PetscLogStage,PetscBool) PetscErrorCode PetscLogStageGetActive(PetscLogStage,PetscBool*) PetscErrorCode PetscLogStageSetVisible(PetscLogStage,PetscBool) PetscErrorCode PetscLogStageGetVisible(PetscLogStage,PetscBool*) PetscErrorCode PetscLogStageGetId(char[],PetscLogStage*) ctypedef int PetscLogClass "PetscClassId" PetscErrorCode PetscLogClassRegister"PetscClassIdRegister"(char[],PetscLogClass*) PetscErrorCode PetscLogClassActivate"PetscLogEventActivateClass"(PetscLogClass) PetscErrorCode PetscLogClassDeactivate"PetscLogEventDeactivateClass"(PetscLogClass) ctypedef int PetscLogEvent PetscErrorCode PetscLogEventRegister(char[],PetscLogClass,PetscLogEvent*) PetscErrorCode PetscLogEventBegin(PetscLogEvent,PetscObject,PetscObject,PetscObject,PetscObject) PetscErrorCode PetscLogEventEnd(PetscLogEvent,PetscObject,PetscObject,PetscObject,PetscObject) PetscErrorCode PetscLogEventActivate(PetscLogEvent) PetscErrorCode PetscLogEventDeactivate(PetscLogEvent) PetscErrorCode PetscLogEventSetActiveAll(PetscLogEvent,PetscBool) PetscErrorCode PetscLogEventGetPerfInfo(PetscLogStage,PetscLogEvent,PetscEventPerfInfo*) cdef extern from * nogil: # custom.h PetscErrorCode PetscLogStageFindId(char[],PetscLogStage*) PetscErrorCode PetscLogClassFindId(char[],PetscLogClass*) PetscErrorCode PetscLogEventFindId(char[],PetscLogEvent*) PetscErrorCode PetscLogStageFindName(PetscLogStage,char*[]) PetscErrorCode PetscLogClassFindName(PetscLogClass,char*[]) PetscErrorCode PetscLogEventFindName(PetscLogEvent,char*[]) cdef inline int event_args2objs(object args, PetscObject o[4]) except -1: o[0] = o[1] = o[2] = o[3] = NULL cdef Py_ssize_t i=0, n = len(args) cdef Object tmp = None if n > 4: n = 4 for 0 <= i < n: tmp = args[i] if tmp is not None: o[i] = tmp.obj[0] return 0 ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/src/petsc4py/PETSc/petscmat.pxi0000644000175000017500000014445214567251135020223 0ustar00balaybalaycdef extern from * nogil: ctypedef const char* PetscMatType "MatType" PetscMatType MATSAME PetscMatType MATMAIJ PetscMatType MATSEQMAIJ PetscMatType MATMPIMAIJ PetscMatType MATKAIJ PetscMatType MATSEQKAIJ PetscMatType MATMPIKAIJ PetscMatType MATIS PetscMatType MATAIJ PetscMatType MATSEQAIJ PetscMatType MATMPIAIJ PetscMatType MATAIJCRL PetscMatType MATSEQAIJCRL PetscMatType MATMPIAIJCRL PetscMatType MATAIJCUSPARSE PetscMatType MATSEQAIJCUSPARSE PetscMatType MATMPIAIJCUSPARSE PetscMatType MATAIJVIENNACL PetscMatType MATSEQAIJVIENNACL PetscMatType MATMPIAIJVIENNACL PetscMatType MATAIJPERM PetscMatType MATSEQAIJPERM PetscMatType MATMPIAIJPERM PetscMatType MATAIJSELL PetscMatType MATSEQAIJSELL PetscMatType MATMPIAIJSELL PetscMatType MATAIJMKL PetscMatType MATSEQAIJMKL PetscMatType MATMPIAIJMKL PetscMatType MATBAIJMKL PetscMatType MATSEQBAIJMKL PetscMatType MATMPIBAIJMKL PetscMatType MATSHELL PetscMatType MATDENSE PetscMatType MATSEQDENSE PetscMatType MATMPIDENSE PetscMatType MATDENSECUDA PetscMatType MATSEQDENSECUDA PetscMatType MATMPIDENSECUDA PetscMatType MATELEMENTAL PetscMatType MATBAIJ PetscMatType MATSEQBAIJ PetscMatType MATMPIBAIJ PetscMatType MATMPIADJ PetscMatType MATSBAIJ PetscMatType MATSEQSBAIJ PetscMatType MATMPISBAIJ PetscMatType MATMFFD PetscMatType MATNORMAL PetscMatType MATNORMALHERMITIAN PetscMatType MATLRC PetscMatType MATSCATTER PetscMatType MATBLOCKMAT PetscMatType MATCOMPOSITE PetscMatType MATFFT PetscMatType MATFFTW PetscMatType MATSEQCUFFT PetscMatType MATTRANSPOSEVIRTUAL PetscMatType MATHERMITIANTRANSPOSEVIRTUAL PetscMatType MATSCHURCOMPLEMENT PetscMatType MATPYTHON PetscMatType MATHYPRE PetscMatType MATHYPRESTRUCT PetscMatType MATHYPRESSTRUCT PetscMatType MATSUBMATRIX PetscMatType MATLOCALREF PetscMatType MATNEST PetscMatType MATPREALLOCATOR PetscMatType MATSELL PetscMatType MATSEQSELL PetscMatType MATMPISELL PetscMatType MATDUMMY PetscMatType MATLMVM PetscMatType MATLMVMDFP PetscMatType MATLMVMBFGS PetscMatType MATLMVMSR1 PetscMatType MATLMVMBROYDEN PetscMatType MATLMVMBADBROYDEN PetscMatType MATLMVMSYMBROYDEN PetscMatType MATLMVMSYMBADBROYDEN PetscMatType MATLMVMDIAGBROYDEN PetscMatType MATCONSTANTDIAGONAL PetscMatType MATDIAGONAL PetscMatType MATH2OPUS ctypedef const char* PetscMatOrderingType "MatOrderingType" PetscMatOrderingType MATORDERINGNATURAL PetscMatOrderingType MATORDERINGND PetscMatOrderingType MATORDERING1WD PetscMatOrderingType MATORDERINGRCM PetscMatOrderingType MATORDERINGQMD PetscMatOrderingType MATORDERINGROWLENGTH PetscMatOrderingType MATORDERINGWBM PetscMatOrderingType MATORDERINGSPECTRAL PetscMatOrderingType MATORDERINGAMD PetscMatOrderingType MATORDERINGMETISND ctypedef const char* PetscMatSolverType "MatSolverType" PetscMatSolverType MATSOLVERSUPERLU PetscMatSolverType MATSOLVERSUPERLU_DIST PetscMatSolverType MATSOLVERSTRUMPACK PetscMatSolverType MATSOLVERUMFPACK PetscMatSolverType MATSOLVERCHOLMOD PetscMatSolverType MATSOLVERKLU PetscMatSolverType MATSOLVERELEMENTAL PetscMatSolverType MATSOLVERSCALAPACK PetscMatSolverType MATSOLVERESSL PetscMatSolverType MATSOLVERLUSOL PetscMatSolverType MATSOLVERMUMPS PetscMatSolverType MATSOLVERMKL_PARDISO PetscMatSolverType MATSOLVERMKL_CPARDISO PetscMatSolverType MATSOLVERPASTIX PetscMatSolverType MATSOLVERMATLAB PetscMatSolverType MATSOLVERPETSC PetscMatSolverType MATSOLVERBAS PetscMatSolverType MATSOLVERCUSPARSE PetscMatSolverType MATSOLVERCUDA PetscMatSolverType MATSOLVERSPQR ctypedef enum PetscMatReuse "MatReuse": MAT_INITIAL_MATRIX MAT_REUSE_MATRIX MAT_IGNORE_MATRIX MAT_INPLACE_MATRIX ctypedef enum PetscMatDuplicateOption "MatDuplicateOption": MAT_DO_NOT_COPY_VALUES MAT_COPY_VALUES MAT_SHARE_NONZERO_PATTERN ctypedef enum PetscMatSORType "MatSORType": SOR_FORWARD_SWEEP SOR_BACKWARD_SWEEP SOR_SYMMETRIC_SWEEP SOR_LOCAL_FORWARD_SWEEP SOR_LOCAL_BACKWARD_SWEEP SOR_LOCAL_SYMMETRIC_SWEEP SOR_ZERO_INITIAL_GUESS SOR_EISENSTAT SOR_APPLY_UPPER SOR_APPLY_LOWER ctypedef enum PetscMatProductType "MatProductType": MATPRODUCT_UNSPECIFIED MATPRODUCT_AB MATPRODUCT_AtB MATPRODUCT_ABt MATPRODUCT_PtAP MATPRODUCT_RARt MATPRODUCT_ABC ctypedef enum PetscMatAssemblyType "MatAssemblyType": MAT_FLUSH_ASSEMBLY MAT_FINAL_ASSEMBLY ctypedef enum PetscMatInfoType "MatInfoType": MAT_LOCAL MAT_GLOBAL_MAX MAT_GLOBAL_SUM ctypedef enum PetscMatStructure "MatStructure": MAT_SAME_NONZERO_PATTERN "SAME_NONZERO_PATTERN" MAT_DIFFERENT_NONZERO_PATTERN "DIFFERENT_NONZERO_PATTERN" MAT_SUBSET_NONZERO_PATTERN "SUBSET_NONZERO_PATTERN" MAT_UNKNOWN_NONZERO_PATTERN "UNKNOWN_NONZERO_PATTERN" ctypedef enum PetscMatOption "MatOption": MAT_OPTION_MIN MAT_UNUSED_NONZERO_LOCATION_ERR MAT_ROW_ORIENTED MAT_SYMMETRIC MAT_STRUCTURALLY_SYMMETRIC MAT_FORCE_DIAGONAL_ENTRIES MAT_IGNORE_OFF_PROC_ENTRIES MAT_USE_HASH_TABLE MAT_KEEP_NONZERO_PATTERN MAT_IGNORE_ZERO_ENTRIES MAT_USE_INODES MAT_HERMITIAN MAT_SYMMETRY_ETERNAL MAT_NEW_NONZERO_LOCATION_ERR MAT_IGNORE_LOWER_TRIANGULAR MAT_ERROR_LOWER_TRIANGULAR MAT_GETROW_UPPERTRIANGULAR MAT_SPD MAT_NO_OFF_PROC_ZERO_ROWS MAT_NO_OFF_PROC_ENTRIES MAT_NEW_NONZERO_LOCATIONS MAT_NEW_NONZERO_ALLOCATION_ERR MAT_SUBSET_OFF_PROC_ENTRIES MAT_SUBMAT_SINGLEIS MAT_STRUCTURE_ONLY MAT_SORTED_FULL MAT_OPTION_MAX ctypedef enum PetscMatOperation "MatOperation": pass PetscErrorCode MatView(PetscMat,PetscViewer) PetscErrorCode MatDestroy(PetscMat*) PetscErrorCode MatCreate(MPI_Comm,PetscMat*) PetscErrorCode MatCreateDenseCUDA(MPI_Comm,PetscInt,PetscInt,PetscInt,PetscInt,PetscScalar[],PetscMat*) PetscErrorCode MatCreateIS(MPI_Comm,PetscInt,PetscInt,PetscInt,PetscInt,PetscInt,PetscLGMap,PetscLGMap,PetscMat*) PetscErrorCode MatISGetLocalMat(PetscMat,PetscMat*) PetscErrorCode MatISGetMPIXAIJ(PetscMat,PetscMatReuse,PetscMat*) PetscErrorCode MatCreateScatter(MPI_Comm,PetscScatter,PetscMat*) PetscErrorCode MatScatterSetVecScatter(PetscMat,PetscScatter) PetscErrorCode MatScatterGetVecScatter(PetscMat,PetscScatter*) PetscErrorCode MatCreateNormal(PetscMat,PetscMat*) PetscErrorCode MatCreateTranspose(PetscMat,PetscMat*) PetscErrorCode MatCreateNormalHermitian(PetscMat,PetscMat*) PetscErrorCode MatCreateHermitianTranspose(PetscMat,PetscMat*) PetscErrorCode MatCreateLRC(PetscMat,PetscMat,PetscVec,PetscMat,PetscMat*) PetscErrorCode MatCreateSubMatrixVirtual(PetscMat,PetscIS,PetscIS,PetscMat*) PetscErrorCode MatCreateRedundantMatrix(PetscMat,PetscInt,MPI_Comm,PetscMatReuse,PetscMat*) PetscErrorCode MatCreateNest(MPI_Comm,PetscInt,PetscIS[],PetscInt,PetscIS[],PetscMat[],PetscMat*) PetscErrorCode MatCreateShell(MPI_Comm,PetscInt,PetscInt,PetscInt,PetscInt,void*,PetscMat*) PetscErrorCode MatCreateH2OpusFromMat(PetscMat,PetscInt,const PetscReal[],PetscBool,PetscReal,PetscInt,PetscInt,PetscInt,PetscReal,PetscMat*) PetscErrorCode MatCreateSeqAIJWithArrays(MPI_Comm,PetscInt,PetscInt,PetscInt[],PetscInt[],PetscScalar[],PetscMat*) PetscErrorCode MatCreateMPIAIJWithArrays(MPI_Comm,PetscInt,PetscInt,PetscInt,PetscInt,PetscInt[],PetscInt[],PetscScalar[],PetscMat*) PetscErrorCode MatCreateMPIAIJWithSplitArrays(MPI_Comm,PetscInt,PetscInt,PetscInt,PetscInt,PetscInt[],PetscInt[],PetscScalar[],PetscInt[],PetscInt[],PetscScalar[],PetscMat*) PetscErrorCode MatCreateDiagonal(PetscVec,PetscMat*) PetscErrorCode MatCreateConstantDiagonal(MPI_Comm,PetscInt,PetscInt,PetscInt,PetscInt,PetscScalar,PetscMat*) PetscErrorCode MatSetSizes(PetscMat,PetscInt,PetscInt,PetscInt,PetscInt) PetscErrorCode MatSetBlockSize(PetscMat,PetscInt) PetscErrorCode MatSetBlockSizes(PetscMat,PetscInt,PetscInt) PetscErrorCode MatSetType(PetscMat,PetscMatType) PetscErrorCode MatSetVecType(PetscMat,PetscVecType) PetscErrorCode MatGetVecType(PetscMat,PetscVecType*) PetscErrorCode MatSetOption(PetscMat,PetscMatOption,PetscBool) PetscErrorCode MatGetOption(PetscMat,PetscMatOption,PetscBool*) enum: MAT_SKIP_ALLOCATION PetscErrorCode MatSeqAIJSetPreallocation (PetscMat,PetscInt,PetscInt[]) PetscErrorCode MatMPIAIJSetPreallocation (PetscMat,PetscInt,PetscInt[],PetscInt,PetscInt[]) PetscErrorCode MatSeqBAIJSetPreallocation (PetscMat,PetscInt,PetscInt,PetscInt[]) PetscErrorCode MatMPIBAIJSetPreallocation (PetscMat,PetscInt,PetscInt,PetscInt[],PetscInt,PetscInt[]) PetscErrorCode MatSeqSBAIJSetPreallocation(PetscMat,PetscInt,PetscInt,PetscInt[]) PetscErrorCode MatMPISBAIJSetPreallocation(PetscMat,PetscInt,PetscInt,PetscInt[],PetscInt,PetscInt[]) PetscErrorCode MatSeqAIJSetPreallocationCSR (PetscMat, PetscInt[],PetscInt[],PetscScalar[]) PetscErrorCode MatMPIAIJSetPreallocationCSR (PetscMat, PetscInt[],PetscInt[],PetscScalar[]) PetscErrorCode MatSeqBAIJSetPreallocationCSR (PetscMat,PetscInt,PetscInt[],PetscInt[],PetscScalar[]) PetscErrorCode MatMPIBAIJSetPreallocationCSR (PetscMat,PetscInt,PetscInt[],PetscInt[],PetscScalar[]) PetscErrorCode MatSeqSBAIJSetPreallocationCSR(PetscMat,PetscInt,PetscInt[],PetscInt[],PetscScalar[]) PetscErrorCode MatMPISBAIJSetPreallocationCSR(PetscMat,PetscInt,PetscInt[],PetscInt[],PetscScalar[]) PetscErrorCode MatSeqDenseSetPreallocation(PetscMat,PetscScalar[]) PetscErrorCode MatMPIDenseSetPreallocation(PetscMat,PetscScalar[]) PetscErrorCode MatISSetPreallocation(PetscMat,PetscInt,PetscInt[],PetscInt,PetscInt[]) PetscErrorCode MatSetOptionsPrefix(PetscMat,char[]) PetscErrorCode MatAppendOptionsPrefix(PetscMat,char[]) PetscErrorCode MatGetOptionsPrefix(PetscMat,char*[]) PetscErrorCode MatSetFromOptions(PetscMat) PetscErrorCode MatSetUp(PetscMat) PetscErrorCode MatGetType(PetscMat,PetscMatType*) PetscErrorCode MatGetSize(PetscMat,PetscInt*,PetscInt*) PetscErrorCode MatGetLocalSize(PetscMat,PetscInt*,PetscInt*) PetscErrorCode MatGetBlockSize(PetscMat,PetscInt*) PetscErrorCode MatGetBlockSizes(PetscMat,PetscInt*,PetscInt*) PetscErrorCode MatGetOwnershipRange(PetscMat,PetscInt*,PetscInt*) PetscErrorCode MatGetOwnershipRanges(PetscMat,const PetscInt*[]) PetscErrorCode MatGetOwnershipRangeColumn(PetscMat,PetscInt*,PetscInt*) PetscErrorCode MatGetOwnershipRangesColumn(PetscMat,const PetscInt*[]) PetscErrorCode MatGetOwnershipIS(PetscMat,PetscIS*,PetscIS*) PetscErrorCode MatNestGetISs(PetscMat,PetscIS*,PetscIS*) PetscErrorCode MatNestGetLocalISs(PetscMat,PetscIS*,PetscIS*) PetscErrorCode MatNestGetSize(PetscMat,PetscInt*,PetscInt*) PetscErrorCode MatNestGetSubMat(PetscMat,PetscInt,PetscInt,PetscMat*) PetscErrorCode MatNestSetVecType(PetscMat,PetscVecType) PetscErrorCode MatEqual(PetscMat,PetscMat,PetscBool*) PetscErrorCode MatLoad(PetscMat,PetscViewer) PetscErrorCode MatDuplicate(PetscMat,PetscMatDuplicateOption,PetscMat*) PetscErrorCode MatCopy(PetscMat,PetscMat,PetscMatStructure) PetscErrorCode MatTranspose(PetscMat,PetscMatReuse,PetscMat*) PetscErrorCode MatTransposeSetPrecursor(PetscMat,PetscMat) PetscErrorCode MatHermitianTranspose(PetscMat,PetscMatReuse,PetscMat*) PetscErrorCode MatConvert(PetscMat,PetscMatType,PetscMatReuse,PetscMat*) PetscErrorCode MatIsSymmetric(PetscMat,PetscReal,PetscBool*) PetscErrorCode MatIsStructurallySymmetric(PetscMat,PetscBool*) PetscErrorCode MatIsHermitian(PetscMat,PetscReal,PetscBool*) PetscErrorCode MatIsSymmetricKnown(PetscMat,PetscBool*,PetscBool*) PetscErrorCode MatIsHermitianKnown(PetscMat,PetscBool*,PetscBool*) PetscErrorCode MatIsTranspose(PetscMat,PetscMat,PetscReal,PetscBool*) PetscErrorCode MatCreateVecs(PetscMat,PetscVec*,PetscVec*) PetscErrorCode MatSetValue(PetscMat,PetscInt,PetscInt,PetscScalar,PetscInsertMode) PetscErrorCode MatSetValues(PetscMat,PetscInt,const PetscInt[],PetscInt,const PetscInt[],const PetscScalar[],PetscInsertMode) PetscErrorCode MatSetValuesBlocked(PetscMat,PetscInt,const PetscInt[],PetscInt,const PetscInt[],const PetscScalar[],PetscInsertMode) PetscErrorCode MatSetLocalToGlobalMapping(PetscMat,PetscLGMap,PetscLGMap) PetscErrorCode MatGetLocalToGlobalMapping(PetscMat,PetscLGMap*,PetscLGMap*) PetscErrorCode MatSetValueLocal(PetscMat,PetscInt,PetscInt,PetscScalar,PetscInsertMode) PetscErrorCode MatSetValuesLocal(PetscMat,PetscInt,const PetscInt[],PetscInt,const PetscInt[],const PetscScalar[],PetscInsertMode) PetscErrorCode MatSetValuesBlockedLocal(PetscMat,PetscInt,const PetscInt[],PetscInt,const PetscInt[],const PetscScalar[],PetscInsertMode) PetscErrorCode MatSetStencil(PetscMat,PetscInt,const PetscInt[],const PetscInt[],PetscInt) ctypedef struct PetscMatStencil "MatStencil": PetscInt k,j,i,c PetscErrorCode MatSetValuesStencil(PetscMat,PetscInt,const PetscMatStencil[],PetscInt,const PetscMatStencil[],const PetscScalar[],PetscInsertMode) PetscErrorCode MatSetValuesBlockedStencil(PetscMat,PetscInt,const PetscMatStencil[],PetscInt,const PetscMatStencil[],const PetscScalar[],PetscInsertMode) PetscErrorCode MatGetValues(PetscMat,PetscInt,const PetscInt[],PetscInt,const PetscInt[],PetscScalar[]) PetscErrorCode MatGetRow(PetscMat,PetscInt,PetscInt*,const PetscInt*[],const PetscScalar*[]) PetscErrorCode MatRestoreRow(PetscMat,PetscInt,PetscInt*,const PetscInt*[],const PetscScalar*[]) PetscErrorCode MatGetRowIJ(PetscMat,PetscInt,PetscBool,PetscBool,PetscInt*,const PetscInt*[],const PetscInt*[],PetscBool*) PetscErrorCode MatRestoreRowIJ(PetscMat,PetscInt,PetscBool,PetscBool,PetscInt*,const PetscInt*[],const PetscInt*[],PetscBool*) PetscErrorCode MatGetColumnIJ(PetscMat,PetscInt,PetscBool,PetscBool,PetscInt*,const PetscInt*[],const PetscInt*[],PetscBool*) PetscErrorCode MatRestoreColumnIJ(PetscMat,PetscInt,PetscBool,PetscBool,PetscInt*,const PetscInt*[],const PetscInt*[],PetscBool*) PetscErrorCode MatZeroEntries(PetscMat) PetscErrorCode MatStoreValues(PetscMat) PetscErrorCode MatRetrieveValues(PetscMat) PetscErrorCode MatAssemblyBegin(PetscMat,PetscMatAssemblyType) PetscErrorCode MatAssemblyEnd(PetscMat,PetscMatAssemblyType) PetscErrorCode MatAssembled(PetscMat,PetscBool*) PetscErrorCode MatDiagonalSet(PetscMat,PetscVec,PetscInsertMode) PetscErrorCode MatDiagonalScale(PetscMat,PetscVec,PetscVec) PetscErrorCode MatScale(PetscMat,PetscScalar) PetscErrorCode MatShift(PetscMat,PetscScalar) PetscErrorCode MatFilter(PetscMat,PetscReal,PetscBool,PetscBool) PetscErrorCode MatSetRandom(PetscMat,PetscRandom) PetscErrorCode MatAXPY(PetscMat,PetscScalar,PetscMat,PetscMatStructure) PetscErrorCode MatAYPX(PetscMat,PetscScalar,PetscMat,PetscMatStructure) PetscErrorCode MatMatMult(PetscMat,PetscMat,PetscMatReuse,PetscReal,PetscMat*) PetscErrorCode MatMatTransposeMult(PetscMat,PetscMat,PetscMatReuse,PetscReal,PetscMat*) PetscErrorCode MatTransposeMatMult(PetscMat,PetscMat,PetscMatReuse,PetscReal,PetscMat*) PetscErrorCode MatPtAP(PetscMat,PetscMat,PetscMatReuse,PetscReal,PetscMat*) PetscErrorCode MatRARt(PetscMat,PetscMat,PetscMatReuse,PetscReal,PetscMat*) PetscErrorCode MatMatMatMult(PetscMat,PetscMat,PetscMat,PetscMatReuse,PetscReal,PetscMat*) PetscErrorCode MatSeqAIJKron(PetscMat,PetscMat,PetscMatReuse,PetscMat*) PetscErrorCode MatInterpolate(PetscMat,PetscVec,PetscVec) PetscErrorCode MatInterpolateAdd(PetscMat,PetscVec,PetscVec,PetscVec) PetscErrorCode MatRestrict(PetscMat,PetscVec,PetscVec) PetscErrorCode MatPermute(PetscMat,PetscIS,PetscIS,PetscMat*) PetscErrorCode MatPermuteSparsify(PetscMat,PetscInt,PetscReal,PetscReal,PetscIS,PetscIS,PetscMat*) PetscErrorCode MatMerge(MPI_Comm,PetscMat,PetscInt,PetscMatReuse,PetscMat*) PetscErrorCode MatCreateSubMatrix(PetscMat,PetscIS,PetscIS,PetscMatReuse,PetscMat*) PetscErrorCode MatCreateSubMatrices(PetscMat,PetscInt,PetscIS[],PetscIS[],PetscMatReuse,PetscMat*[]) PetscErrorCode MatIncreaseOverlap(PetscMat,PetscInt,PetscIS[],PetscInt) PetscErrorCode MatGetDiagonalBlock(PetscMat,PetscMat*) PetscErrorCode MatGetLocalSubMatrix(PetscMat,PetscIS,PetscIS,PetscMat*) PetscErrorCode MatRestoreLocalSubMatrix(PetscMat,PetscIS,PetscIS,PetscMat*) PetscErrorCode MatDestroyMatrices(PetscInt,PetscMat*[]) PetscErrorCode MatConjugate(PetscMat) PetscErrorCode MatRealPart(PetscMat) PetscErrorCode MatImaginaryPart(PetscMat) PetscErrorCode MatZeroRows(PetscMat,PetscInt,PetscInt[],PetscScalar,PetscVec,PetscVec) PetscErrorCode MatZeroRowsLocal(PetscMat,PetscInt,PetscInt[],PetscScalar,PetscVec,PetscVec) PetscErrorCode MatZeroRowsIS(PetscMat,PetscIS,PetscScalar,PetscVec,PetscVec) PetscErrorCode MatZeroRowsLocalIS(PetscMat,PetscIS,PetscScalar,PetscVec,PetscVec) PetscErrorCode MatFindZeroRows(PetscMat,PetscIS*) PetscErrorCode MatZeroRowsColumns(PetscMat,PetscInt,PetscInt[],PetscScalar,PetscVec,PetscVec) PetscErrorCode MatZeroRowsColumnsLocal(PetscMat,PetscInt,PetscInt[],PetscScalar,PetscVec,PetscVec) PetscErrorCode MatZeroRowsColumnsIS(PetscMat,PetscIS,PetscScalar,PetscVec,PetscVec) PetscErrorCode MatZeroRowsColumnsLocalIS(PetscMat,PetscIS,PetscScalar,PetscVec,PetscVec) PetscErrorCode MatZeroRowsColumnsStencil(PetscMat,PetscInt,const PetscMatStencil[],PetscScalar,PetscVec,PetscVec) PetscErrorCode MatGetDiagonal(PetscMat,PetscVec) PetscErrorCode MatGetRowSum(PetscMat,PetscVec) PetscErrorCode MatInvertBlockDiagonal(PetscMat,const PetscScalar**) PetscErrorCode MatGetRowMax(PetscMat,PetscVec,PetscInt[]) PetscErrorCode MatGetRowMaxAbs(PetscMat,PetscVec,PetscInt[]) PetscErrorCode MatGetColumnVector(PetscMat,PetscVec,PetscInt) PetscErrorCode MatNorm(PetscMat,PetscNormType,PetscReal*) PetscErrorCode MatMult(PetscMat,PetscVec,PetscVec) PetscErrorCode MatMultAdd(PetscMat,PetscVec,PetscVec,PetscVec) PetscErrorCode MatMultTranspose(PetscMat,PetscVec,PetscVec) PetscErrorCode MatMultTransposeAdd(PetscMat,PetscVec,PetscVec,PetscVec) # FIXME: Why? PetscErrorCode MatMultHermitian"MatMultHermitianTranspose"(PetscMat,PetscVec,PetscVec) PetscErrorCode MatMultHermitianAdd"MatMultHermitianTransposeAdd"(PetscMat,PetscVec,PetscVec,PetscVec) PetscErrorCode MatBindToCPU(PetscMat,PetscBool) PetscErrorCode MatBoundToCPU(PetscMat,PetscBool*) PetscErrorCode MatSOR(PetscMat,PetscVec,PetscReal,PetscMatSORType,PetscReal,PetscInt,PetscInt,PetscVec) PetscErrorCode MatGetOrdering(PetscMat,PetscMatOrderingType,PetscIS*,PetscIS*) PetscErrorCode MatReorderForNonzeroDiagonal(PetscMat,PetscReal,PetscIS,PetscIS) PetscErrorCode MatISFixLocalEmpty(PetscMat,PetscBool) PetscErrorCode MatISGetLocalMat(PetscMat,PetscMat*) PetscErrorCode MatISRestoreLocalMat(PetscMat,PetscMat*) PetscErrorCode MatISSetLocalMat(PetscMat,PetscMat) PetscErrorCode MatH2OpusOrthogonalize(PetscMat) PetscErrorCode MatH2OpusCompress(PetscMat,PetscReal) PetscErrorCode MatH2OpusLowRankUpdate(PetscMat,PetscMat,PetscMat,PetscScalar) PetscErrorCode MatMissingDiagonal(Mat,PetscBool*,PetscInt*) ctypedef enum PetscMatFactorShiftType "MatFactorShiftType": MAT_SHIFT_NONE MAT_SHIFT_NONZERO MAT_SHIFT_POSITIVE_DEFINITE MAT_SHIFT_INBLOCKS ctypedef struct PetscMatFactorInfo "MatFactorInfo": PetscReal fill PetscReal levels, diagonal_fill PetscReal usedt, dt, dtcol, dtcount PetscReal zeropivot, pivotinblocks PetscReal shifttype, shiftamount ctypedef struct PetscMatInfo "MatInfo": PetscLogDouble block_size PetscLogDouble nz_allocated, nz_used, nz_unneeded PetscLogDouble memory PetscLogDouble assemblies PetscLogDouble mallocs PetscLogDouble fill_ratio_given, fill_ratio_needed PetscLogDouble factor_mallocs PetscErrorCode MatGetInfo(PetscMat,PetscMatInfoType,PetscMatInfo*) PetscErrorCode MatFactorInfoInitialize(PetscMatFactorInfo*) PetscErrorCode MatCholeskyFactor(PetscMat,PetscIS,PetscMatFactorInfo*) PetscErrorCode MatCholeskyFactorSymbolic(PetscMat,PetscIS,PetscMatFactorInfo*,PetscMat*) PetscErrorCode MatCholeskyFactorNumeric(PetscMat,PetscMatFactorInfo*,PetscMat*) PetscErrorCode MatLUFactor(PetscMat,PetscIS,PetscIS,PetscMatFactorInfo*) PetscErrorCode MatILUFactor(PetscMat,PetscIS,PetscIS,PetscMatFactorInfo*) PetscErrorCode MatICCFactor(PetscMat,PetscIS,PetscMatFactorInfo*) PetscErrorCode MatLUFactorSymbolic(PetscMat,PetscIS,PetscIS,PetscMatFactorInfo*,PetscMat*) PetscErrorCode MatILUFactorSymbolic(PetscMat,PetscIS,PetscIS,PetscMatFactorInfo*,PetscMat*) PetscErrorCode MatICCFactorSymbolic(PetscMat,PetscIS,PetscMatFactorInfo*,PetscMat*) PetscErrorCode MatLUFactorNumeric(PetscMat,PetscMatFactorInfo*,PetscMat*) PetscErrorCode MatILUDTFactor(PetscMat,PetscIS,PetscIS,PetscMatFactorInfo*,PetscMat*) PetscErrorCode MatGetInertia(PetscMat,PetscInt*,PetscInt*,PetscInt*) PetscErrorCode MatSetUnfactored(PetscMat) PetscErrorCode MatLRCGetMats(PetscMat,PetscMat*,PetscMat*,PetscVec*,PetscMat*) PetscErrorCode MatLRCSetMats(PetscMat,PetscMat,PetscMat,PetscVec,PetscMat) PetscErrorCode MatMumpsSetIcntl(PetscMat,PetscInt,PetscInt) PetscErrorCode MatMumpsGetIcntl(PetscMat,PetscInt,PetscInt*) PetscErrorCode MatMumpsSetCntl(PetscMat,PetscInt,PetscReal) PetscErrorCode MatMumpsGetCntl(PetscMat,PetscInt,PetscReal*) PetscErrorCode MatMumpsGetInfo(PetscMat,PetscInt,PetscInt*) PetscErrorCode MatMumpsGetInfog(PetscMat,PetscInt,PetscInt*) PetscErrorCode MatMumpsGetRinfo(PetscMat,PetscInt,PetscReal*) PetscErrorCode MatMumpsGetRinfog(PetscMat,PetscInt,PetscReal*) PetscErrorCode MatForwardSolve(PetscMat,PetscVec,PetscVec) PetscErrorCode MatBackwardSolve(PetscMat,PetscVec,PetscVec) PetscErrorCode MatSolve(PetscMat,PetscVec,PetscVec) PetscErrorCode MatSolveTranspose(PetscMat,PetscVec,PetscVec) PetscErrorCode MatSolveAdd(PetscMat,PetscVec,PetscVec,PetscVec) PetscErrorCode MatSolveTransposeAdd(PetscMat,PetscVec,PetscVec,PetscVec) PetscErrorCode MatMatSolve(PetscMat,PetscMat,PetscMat) PetscErrorCode MatComputeExplicitOperator(PetscMat,PetscMat*) PetscErrorCode MatUseScaledForm(PetscMat,PetscBool) PetscErrorCode MatScaleSystem(PetscMat,PetscVec,PetscVec) PetscErrorCode MatUnScaleSystem(PetscMat,PetscVec,PetscVec) PetscErrorCode MatDenseSetLDA(PetscMat,PetscInt) PetscErrorCode MatDenseGetLDA(PetscMat,PetscInt*) PetscErrorCode MatDenseGetLocalMatrix(PetscMat,PetscMat*) PetscErrorCode MatDenseGetArray(PetscMat,PetscScalar*[]) PetscErrorCode MatDenseRestoreArray(PetscMat,PetscScalar*[]) PetscErrorCode MatDenseGetArrayWrite(PetscMat,PetscScalar*[]) PetscErrorCode MatDenseRestoreArrayWrite(PetscMat,PetscScalar*[]) PetscErrorCode MatDenseGetArrayRead(PetscMat,const PetscScalar*[]) PetscErrorCode MatDenseRestoreArrayRead(PetscMat,const PetscScalar*[]) PetscErrorCode MatDenseGetColumnVec(PetscMat,PetscInt,PetscVec*) PetscErrorCode MatDenseRestoreColumnVec(PetscMat,PetscInt,PetscVec*) PetscErrorCode MatDenseGetColumnVecRead(PetscMat,PetscInt,PetscVec*) PetscErrorCode MatDenseRestoreColumnVecRead(PetscMat,PetscInt,PetscVec*) PetscErrorCode MatDenseGetColumnVecWrite(PetscMat,PetscInt,PetscVec*) PetscErrorCode MatDenseRestoreColumnVecWrite(PetscMat,PetscInt,PetscVec*) PetscErrorCode MatDenseCUDAGetArray(PetscMat,PetscScalar*[]) PetscErrorCode MatDenseCUDARestoreArray(PetscMat,PetscScalar*[]) PetscErrorCode MatDenseCUDAGetArrayWrite(PetscMat,PetscScalar*[]) PetscErrorCode MatDenseCUDARestoreArrayWrite(PetscMat,PetscScalar*[]) PetscErrorCode MatDenseCUDAGetArrayRead(PetscMat,const PetscScalar*[]) PetscErrorCode MatDenseCUDARestoreArrayRead(PetscMat,const PetscScalar*[]) PetscErrorCode MatProductGetType(PetscMat,PetscMatProductType*) PetscErrorCode MatProductGetMats(PetscMat,PetscMat*,PetscMat*,PetscMat*) PetscErrorCode MatPythonSetType(PetscMat,char[]) PetscErrorCode MatPythonGetType(PetscMat,char*[]) cdef extern from * nogil: # custom.h PetscErrorCode MatGetCurrentMemType(PetscMat,PetscMemType*) PetscErrorCode MatIsPreallocated(PetscMat,PetscBool*) PetscErrorCode MatHasPreallocationAIJ(PetscMat,PetscBool*,PetscBool*,PetscBool*,PetscBool*) # ----------------------------------------------------------------------------- cdef extern from * nogil: PetscErrorCode MatNullSpaceDestroy(PetscNullSpace*) PetscErrorCode MatNullSpaceView(PetscNullSpace,PetscViewer) PetscErrorCode MatNullSpaceCreate(MPI_Comm,PetscBool,PetscInt,PetscVec[], PetscNullSpace*) PetscErrorCode MatNullSpaceCreateRigidBody(PetscVec,PetscNullSpace*) PetscErrorCode MatNullSpaceGetVecs(PetscNullSpace,PetscBool*,PetscInt*,const PetscVec*[]) PetscErrorCode MatNullSpaceRemove(PetscNullSpace,PetscVec) PetscErrorCode MatNullSpaceTest(PetscNullSpace,PetscMat,PetscBool*) ctypedef PetscErrorCode MatNullSpaceFunction(PetscNullSpace, PetscVec, void*) except PETSC_ERR_PYTHON PetscErrorCode MatNullSpaceSetFunction(PetscNullSpace,MatNullSpaceFunction*,void*) PetscErrorCode MatSetNullSpace(PetscMat,PetscNullSpace) PetscErrorCode MatGetNullSpace(PetscMat,PetscNullSpace*) PetscErrorCode MatSetTransposeNullSpace(PetscMat,PetscNullSpace) PetscErrorCode MatGetTransposeNullSpace(PetscMat,PetscNullSpace*) PetscErrorCode MatSetNearNullSpace(PetscMat,PetscNullSpace) PetscErrorCode MatGetNearNullSpace(PetscMat,PetscNullSpace*) cdef inline NullSpace ref_NullSpace(PetscNullSpace nsp): cdef NullSpace ob = NullSpace() ob.nsp = nsp CHKERR( PetscINCREF(ob.obj) ) return ob cdef PetscErrorCode NullSpace_Function( PetscNullSpace n, PetscVec v, void * ctx, ) except PETSC_ERR_PYTHON with gil: cdef NullSpace nsp = ref_NullSpace(n) cdef Vec vec = ref_Vec(v) (function, args, kargs) = nsp.get_attr('__function__') function(nsp, vec, *args, **kargs) return PETSC_SUCCESS # ----------------------------------------------------------------------------- cdef inline Mat ref_Mat(PetscMat mat): cdef Mat ob = Mat() ob.mat = mat CHKERR( PetscINCREF(ob.obj) ) return ob # ----------------------------------------------------------------------------- # unary operations cdef Mat mat_pos(Mat self): cdef Mat mat = type(self)() CHKERR( MatDuplicate(self.mat, MAT_COPY_VALUES, &mat.mat) ) return mat cdef Mat mat_neg(Mat self): cdef Mat mat = mat_pos(self) CHKERR( MatScale(mat.mat, -1) ) return mat # inplace binary operations cdef Mat mat_iadd(Mat self, other): if isinstance(other, Mat): self.axpy(1, other) elif isinstance(other, (tuple, list)): alpha, mat = other self.axpy(alpha, mat) elif isinstance(other, Vec): self.setDiagonal(other, PETSC_ADD_VALUES) else: self.shift(other) return self cdef Mat mat_isub(Mat self, other): if isinstance(other, Mat): self.axpy(-1, other) elif isinstance(other, (tuple, list)): alpha, mat = other self.axpy(-alpha, mat) elif isinstance(other, Vec): diag = other.copy() diag.scale(-1) self.setDiagonal(diag, PETSC_ADD_VALUES) diag.destroy() else: self.shift(-other) return self cdef Mat mat_imul(Mat self, other): if isinstance(other, (tuple, list)): L, R = other self.diagonalScale(L, R) else: self.scale(other) return self cdef Mat mat_idiv(Mat self, other): if isinstance(other, (tuple, list)): L, R = other if isinstance(L, Vec): L = L.copy() L.reciprocal() if isinstance(R, Vec): R = R.copy() R.reciprocal() self.diagonalScale(L, R) else: other = 1/other self.scale(other) return self # binary operations cdef Mat mat_add(Mat self, other): return mat_iadd(mat_pos(self), other) cdef Mat mat_sub(Mat self, other): return mat_isub(mat_pos(self), other) cdef Vec mat_mul_vec(Mat self, Vec other): #CHKERR( MatMult(self.mat, other.vec, result.vec) ) cdef Vec result = self.createVecLeft() self.mult(other, result) return result cdef Mat mat_mul_mat(Mat self, Mat other): return self.matMult(other) cdef object mat_mul(Mat self, other): if isinstance(other, Vec): return mat_mul_vec(self, other) elif isinstance(other, Mat): return mat_mul_mat(self, other) else: return mat_imul(mat_pos(self), other) cdef Mat mat_div(Mat self, other): return mat_idiv(mat_pos(self), other) cdef object mat_matmul(Mat self, other): if isinstance(other, Vec): return mat_mul_vec(self, other) if isinstance(other, Mat): return mat_mul_mat(self, other) return NotImplemented # reflected binary operations cdef Mat mat_radd(Mat self, other): return mat_add(self, other) cdef Mat mat_rsub(Mat self, other): cdef Mat mat = mat_sub(self, other) mat.scale(-1) return mat cdef Mat mat_rmul(Mat self, other): return mat_mul(self, other) cdef Mat mat_rdiv(Mat self, other): self; other; # unused return NotImplemented # ----------------------------------------------------------------------------- cdef inline PetscMatStructure matstructure(object structure) \ except (-1): if structure is None: return MAT_DIFFERENT_NONZERO_PATTERN elif structure is False: return MAT_DIFFERENT_NONZERO_PATTERN elif structure is True: return MAT_SAME_NONZERO_PATTERN else: return structure cdef inline PetscMatAssemblyType assemblytype(object assembly) \ except (-1): if assembly is None: return MAT_FINAL_ASSEMBLY elif assembly is False: return MAT_FINAL_ASSEMBLY elif assembly is True: return MAT_FLUSH_ASSEMBLY else: return assembly cdef inline PetscMatInfoType infotype(object info) \ except (-1): if info is None: return MAT_GLOBAL_SUM else: return info # ----------------------------------------------------------------------------- cdef inline PetscErrorCode Mat_Sizes( object size, object bsize, PetscInt *r, PetscInt *c, PetscInt *m, PetscInt *n, PetscInt *M, PetscInt *N, ) except PETSC_ERR_PYTHON: # unpack row and column sizes cdef object rsize, csize try: rsize , csize = size except (TypeError, ValueError): rsize = csize = size # unpack row and column block sizes cdef object rbsize, cbsize try: rbsize , cbsize = bsize except (TypeError, ValueError): rbsize = cbsize = bsize # split row and column sizes Sys_Sizes(rsize, rbsize, r, m, M) Sys_Sizes(csize, cbsize, c, n, N) return PETSC_SUCCESS cdef inline PetscErrorCode Mat_Create( PetscMatType mtype, object comm, object size, object bsize, PetscMat *A, ) except PETSC_ERR_PYTHON: # communicator cdef MPI_Comm ccomm = def_Comm(comm, PETSC_COMM_DEFAULT) # sizes and block sizes cdef PetscInt rbs = 0, cbs = 0, m = 0, n = 0, M = 0, N = 0 Mat_Sizes(size, bsize, &rbs, &cbs, &m, &n, &M, &N) if rbs == PETSC_DECIDE: rbs = 1 if cbs == PETSC_DECIDE: cbs = rbs Sys_Layout(ccomm, rbs, &m, &M) Sys_Layout(ccomm, cbs, &n, &N) # create matrix and set sizes cdef PetscMat mat = NULL CHKERR( MatCreate(ccomm, &mat) ) CHKERR( MatSetSizes(mat, m, n, M, N) ) CHKERR( MatSetBlockSizes(mat, rbs, cbs) ) CHKERR( MatSetType(mat, mtype) ) A[0] = mat return PETSC_SUCCESS cdef inline PetscErrorCode Mat_AllocAIJ_NNZ( PetscMat A, object NNZ) except PETSC_ERR_PYTHON: # cdef PetscBool aij=PETSC_FALSE, baij=PETSC_FALSE, sbaij=PETSC_FALSE, aijis=PETSC_FALSE CHKERR( MatHasPreallocationAIJ(A, &aij, &baij, &sbaij, &aijis)) # local row size and block size cdef PetscInt m=0, bs=1 CHKERR( MatGetLocalSize(A, &m, NULL) ) if baij == PETSC_TRUE or sbaij == PETSC_TRUE: CHKERR( MatGetBlockSize(A, &bs) ) assert bs > 0, "block size not set" # unpack NNZ argument cdef object od_nnz, oo_nnz try: od_nnz, oo_nnz = NNZ except (TypeError, ValueError): od_nnz, oo_nnz = NNZ, None # diagonal and off-diagonal number of nonzeros cdef PetscInt d_nz=PETSC_DECIDE, d_n=0, *d_nnz=NULL if od_nnz is not None: od_nnz = iarray_i(od_nnz, &d_n, &d_nnz) if d_n == 0: d_nnz = NULL # just in case elif d_n == 1: d_nz = d_nnz[0]; d_n=0; d_nnz = NULL cdef PetscInt o_nz=PETSC_DECIDE, o_n=0, *o_nnz=NULL if oo_nnz is not None: oo_nnz = iarray_i(oo_nnz, &o_n, &o_nnz) if o_n == 0: o_nnz = NULL # just in case elif o_n == 1: o_nz = o_nnz[0]; o_n=0; o_nnz = NULL if m == PETSC_DECIDE: if d_n > 1 and d_n*bs > m: m = d_n*bs if o_n > 1 and o_n*bs > m: m = o_n*bs # check array sizes if d_n > 1 and d_n*bs != m: raise ValueError( "size(d_nnz) is %d, expected %d" % (toInt(d_n), toInt(m//bs)) ) if o_n > 1 and o_n*bs != m: raise ValueError( "size(o_nnz) is %d, expected %d" % (toInt(o_n), toInt(m//bs)) ) # preallocate if aij == PETSC_TRUE: CHKERR( MatSeqAIJSetPreallocation(A, d_nz, d_nnz) ) CHKERR( MatMPIAIJSetPreallocation(A, d_nz, d_nnz, o_nz, o_nnz) ) if baij == PETSC_TRUE: CHKERR( MatSeqBAIJSetPreallocation(A, bs, d_nz, d_nnz) ) CHKERR( MatMPIBAIJSetPreallocation(A, bs, d_nz, d_nnz, o_nz, o_nnz) ) if sbaij == PETSC_TRUE: CHKERR( MatSeqSBAIJSetPreallocation(A, bs, d_nz, d_nnz) ) CHKERR( MatMPISBAIJSetPreallocation(A, bs, d_nz, d_nnz, o_nz, o_nnz) ) if aijis == PETSC_TRUE: CHKERR( MatISSetPreallocation(A, d_nz, d_nnz, o_nz, o_nnz) ) return PETSC_SUCCESS cdef inline PetscErrorCode Mat_AllocAIJ_CSR(PetscMat A, object CSR) except PETSC_ERR_PYTHON: # cdef PetscBool aij=PETSC_FALSE, baij=PETSC_FALSE, sbaij=PETSC_FALSE, aijis=PETSC_FALSE CHKERR( MatHasPreallocationAIJ(A, &aij, &baij, &sbaij, &aijis)) # local row size and block size cdef PetscInt m=0, bs = 1 CHKERR( MatGetLocalSize(A, &m, NULL) ) if baij == PETSC_TRUE or sbaij == PETSC_TRUE: CHKERR( MatGetBlockSize(A, &bs) ) assert bs > 0, "block size not set" # unpack CSR argument cdef object oi, oj, ov try: oi, oj, ov = CSR except (TypeError, ValueError): oi, oj = CSR; ov = None # rows, cols, and values cdef PetscInt ni=0, *i=NULL cdef PetscInt nj=0, *j=NULL cdef PetscInt nv=0 cdef PetscScalar *v=NULL oi = iarray_i(oi, &ni, &i) oj = iarray_i(oj, &nj, &j) if ov is not None: ov = iarray_s(ov, &nv, &v) if m == PETSC_DECIDE: m = (ni-1)*bs # check array sizes if ((ni-1)*bs != m): raise ValueError("size(I) is %d, expected %d" % (toInt(ni), toInt(m//bs+1)) ) if (i[0] != 0): raise ValueError("I[0] is %d, expected %d" % (toInt(i[0]), toInt(0)) ) if (i[ni-1] != nj): raise ValueError("size(J) is %d, expected %d" % (toInt(nj), toInt(i[ni-1])) ) if v != NULL and (nj*bs*bs != nv): raise ValueError("size(V) is %d, expected %d" % (toInt(nv), toInt(nj*bs*bs)) ) # preallocate if aij == PETSC_TRUE: CHKERR( MatSeqAIJSetPreallocationCSR(A, i, j, v) ) CHKERR( MatMPIAIJSetPreallocationCSR(A, i, j, v) ) if baij == PETSC_TRUE: CHKERR( MatSeqBAIJSetPreallocationCSR(A, bs, i, j, v) ) CHKERR( MatMPIBAIJSetPreallocationCSR(A, bs, i, j, v) ) if sbaij == PETSC_TRUE: CHKERR( MatSeqSBAIJSetPreallocationCSR(A, bs, i, j, v) ) CHKERR( MatMPISBAIJSetPreallocationCSR(A, bs, i, j, v) ) return PETSC_SUCCESS cdef inline PetscErrorCode Mat_AllocAIJ(PetscMat A,object NNZ, object CSR) except PETSC_ERR_PYTHON: if CSR is not None: return Mat_AllocAIJ_CSR(A, CSR) if NNZ is not None: return Mat_AllocAIJ_NNZ(A, NNZ) return PETSC_SUCCESS cdef inline object Mat_AllocDense(PetscMat A, object array): cdef PetscInt m=0, N=0 CHKERR( MatGetLocalSize(A, &m, NULL) ) CHKERR( MatGetSize(A, NULL, &N) ) cdef PetscInt size=0 cdef PetscScalar *data=NULL if array is not None: array = ofarray_s(array, &size, &data) if m*N != size: raise ValueError( "size(array) is %d, expected %dx%d=%d" % (toInt(size), toInt(m), toInt(N), toInt(m*N)) ) CHKERR( MatSeqDenseSetPreallocation(A, data) ) CHKERR( MatMPIDenseSetPreallocation(A, data) ) return array # ----------------------------------------------------------------------------- ctypedef PetscErrorCode MatSetValuesFcn(PetscMat, PetscInt,const PetscInt*, PetscInt,const PetscInt*, const PetscScalar*,PetscInsertMode) cdef inline MatSetValuesFcn* matsetvalues_fcn(int blocked, int local): cdef MatSetValuesFcn *setvalues = NULL if blocked and local: setvalues = MatSetValuesBlockedLocal elif blocked: setvalues = MatSetValuesBlocked elif local: setvalues = MatSetValuesLocal else: setvalues = MatSetValues return setvalues cdef inline PetscErrorCode matsetvalues(PetscMat A, object oi, object oj, object ov, object oaddv, int blocked, int local) except PETSC_ERR_PYTHON: # block size cdef PetscInt rbs=1, cbs=1 if blocked: CHKERR( MatGetBlockSizes(A, &rbs, &cbs) ) if rbs < 1: rbs = 1 if cbs < 1: cbs = 1 # rows, cols, and values cdef PetscInt ni=0, *i=NULL cdef PetscInt nj=0, *j=NULL cdef PetscInt nv=0 cdef PetscScalar *v=NULL oi = iarray_i(oi, &ni, &i) oj = iarray_i(oj, &nj, &j) ov = iarray_s(ov, &nv, &v) if ni*nj*rbs*cbs != nv: raise ValueError( "incompatible array sizes: ni=%d, nj=%d, nv=%d" % (toInt(ni), toInt(nj), toInt(nv)) ) # MatSetValuesXXX function and insert mode cdef MatSetValuesFcn *setvalues = matsetvalues_fcn(blocked, local) cdef PetscInsertMode addv = insertmode(oaddv) # actual call CHKERR( setvalues(A, ni, i, nj, j, v, addv) ) return PETSC_SUCCESS cdef inline PetscErrorCode matsetvalues_rcv(PetscMat A, object oi, object oj, object ov, object oaddv, int blocked, int local) except PETSC_ERR_PYTHON: # block size cdef PetscInt rbs=1, cbs=1 if blocked: CHKERR( MatGetBlockSizes(A, &rbs, &cbs) ) if rbs < 1: rbs = 1 if cbs < 1: cbs = 1 # rows, cols, and values cdef PetscInt ni=0, *i=NULL cdef PetscInt nj=0, *j=NULL cdef PetscInt nv=0 cdef PetscScalar *v=NULL cdef ndarray ai = iarray_i(oi, &ni, &i) cdef ndarray aj = iarray_i(oj, &nj, &j) cdef ndarray av = iarray_s(ov, &nv, &v) # check various dimensions if PyArray_NDIM(ai) != 2: raise ValueError( ("row indices must have two dimensions: " "rows.ndim=%d") % (PyArray_NDIM(ai)) ) elif not PyArray_ISCONTIGUOUS(ai): raise ValueError( "expecting a C-contiguous array") if PyArray_NDIM(aj) != 2: raise ValueError( ("column indices must have two dimensions: " "cols.ndim=%d") % (PyArray_NDIM(aj)) ) elif not PyArray_ISCONTIGUOUS(aj): raise ValueError( "expecting a C-contiguous array") if PyArray_NDIM(av) < 2: raise ValueError( ("values must have two or more dimensions: " "vals.ndim=%d") % (PyArray_NDIM(av)) ) elif not PyArray_ISCONTIGUOUS(av): raise ValueError( "expecting a C-contiguous array") # check various shapes cdef Py_ssize_t nm = PyArray_DIM(ai, 0) cdef Py_ssize_t si = PyArray_DIM(ai, 1) cdef Py_ssize_t sj = PyArray_DIM(aj, 1) cdef Py_ssize_t sv = PyArray_MultiplyList(PyArray_DIMS(av)+1, PyArray_NDIM(av)-1) if ((nm != PyArray_DIM(aj, 0)) or (nm != PyArray_DIM(av, 0)) or (si*rbs * sj*cbs != sv)): raise ValueError( ("input arrays have incompatible shapes: " "rows.shape=%s, cols.shape=%s, vals.shape=%s") % (ai.shape, aj.shape, av.shape)) # MatSetValuesXXX function and insert mode cdef MatSetValuesFcn *setvalues = \ matsetvalues_fcn(blocked, local) cdef PetscInsertMode addv = insertmode(oaddv) # actual calls cdef Py_ssize_t k=0 for k from 0 <= k < nm: CHKERR( setvalues(A, si, &i[k*si], sj, &j[k*sj], &v[k*sv], addv) ) return PETSC_SUCCESS cdef inline PetscErrorCode matsetvalues_ijv(PetscMat A, object oi, object oj, object ov, object oaddv, object om, int blocked, int local) except PETSC_ERR_PYTHON: # block size cdef PetscInt rbs=1, cbs=1 if blocked: CHKERR( MatGetBlockSizes(A, &rbs, &cbs) ) if rbs < 1: rbs = 1 if cbs < 1: cbs = 1 # column pointers, column indices, and values cdef PetscInt ni=0, *i=NULL cdef PetscInt nj=0, *j=NULL cdef PetscInt nv=0 cdef PetscScalar *v=NULL oi = iarray_i(oi, &ni, &i) oj = iarray_i(oj, &nj, &j) ov = iarray_s(ov, &nv, &v) # row indices cdef PetscInt nm=0, *m=NULL cdef PetscInt rs=0, re=ni-1 if om is not None: om = iarray_i(om, &nm, &m) else: if not local: CHKERR( MatGetOwnershipRange(A, &rs, &re) ) rs //= rbs; re //= rbs nm = re - rs # check various sizes if (ni-1 != nm): raise ValueError( "size(I) is %d, expected %d" % (toInt(ni), toInt(nm+1)) ) if (i[0] != 0):raise ValueError( "I[0] is %d, expected %d" % (toInt(i[0]), 0) ) if (i[ni-1] != nj): raise ValueError( "size(J) is %d, expected %d" % (toInt(nj), toInt(i[ni-1])) ) if (nj*rbs*cbs != nv): raise ValueError( "size(V) is %d, expected %d" % (toInt(nv), toInt(nj*rbs*cbs)) ) # MatSetValuesXXX function and insert mode cdef MatSetValuesFcn *setvalues = \ matsetvalues_fcn(blocked, local) cdef PetscInsertMode addv = insertmode(oaddv) # actual call cdef PetscInt k=0, l=0 cdef PetscInt irow=0, ncol=0, *icol=NULL cdef PetscScalar *sval=NULL for k from 0 <= k < nm: irow = m[k] if m!=NULL else rs+k ncol = i[k+1] - i[k] icol = j + i[k] if blocked: sval = v + i[k]*rbs*cbs for l from 0 <= l < ncol: CHKERR( setvalues(A, 1, &irow, 1, &icol[l], &sval[l*rbs*cbs], addv) ) else: sval = v + i[k] CHKERR( setvalues(A, 1, &irow, ncol, icol, sval, addv) ) return PETSC_SUCCESS cdef inline PetscErrorCode matsetvalues_csr(PetscMat A, object oi, object oj, object ov, object oaddv, int blocked, int local) except PETSC_ERR_PYTHON: matsetvalues_ijv(A, oi, oj, ov, oaddv, None, blocked, local) return PETSC_SUCCESS cdef inline matgetvalues(PetscMat mat, object orows, object ocols, object values): cdef PetscInt ni=0, nj=0, nv=0 cdef PetscInt *i=NULL, *j=NULL cdef PetscScalar *v=NULL cdef ndarray rows = iarray_i(orows, &ni, &i) cdef ndarray cols = iarray_i(ocols, &nj, &j) if values is None: values = empty_s(ni*nj) values.shape = rows.shape + cols.shape values = oarray_s(values, &nv, &v) if (ni*nj != nv): raise ValueError( "incompatible array sizes: ni=%d, nj=%d, nv=%d" % (toInt(ni), toInt(nj), toInt(nv))) CHKERR( MatGetValues(mat, ni, i, nj, j, v) ) return values # ----------------------------------------------------------------------------- cdef extern from * nogil: # custom.h PetscErrorCode MatFactorInfoDefaults(PetscBool,PetscBool,PetscMatFactorInfo*) cdef inline PetscMatFactorShiftType matfactorshifttype(object st) \ except (-1): if isinstance(st, str): if st == "none": return MAT_SHIFT_NONE if st == "nonzero": return MAT_SHIFT_NONZERO if st == "positive_definite": return MAT_SHIFT_POSITIVE_DEFINITE if st == "inblocks": return MAT_SHIFT_INBLOCKS if st == "na": return MAT_SHIFT_NONZERO if st == "pd": return MAT_SHIFT_POSITIVE_DEFINITE else: raise ValueError("unknown shift type: %s" % st) return st cdef PetscErrorCode matfactorinfo(PetscBool inc, PetscBool chol, object opts, PetscMatFactorInfo *info) except PETSC_ERR_PYTHON: CHKERR( MatFactorInfoDefaults(inc,chol,info) ) if opts is None: return PETSC_SUCCESS cdef dict options = dict(opts) # cdef fill = options.pop('fill', None) if fill is not None: info.fill = asReal(fill) # cdef zeropivot = options.pop('zeropivot', None) if zeropivot is not None: info.zeropivot = asReal(zeropivot) # cdef levels = options.pop('levels', None) if levels is not None: info.levels = asInt(levels) cdef diagonal_fill = options.pop('diagonal_fill', None) if diagonal_fill is not None: info.diagonal_fill = (diagonal_fill) # cdef dt = options.pop('dt', None) if dt is not None: info.dt = asReal(dt) cdef dtcol = options.pop('dtcol', None) if dtcol is not None: info.dtcol = asReal(dtcol) cdef dtcount = options.pop('dtcount', None) if dtcount is not None: info.dtcount = asInt(dtcount) if ((dt is not None) or (dtcol is not None) or (dtcount is not None)): info.usedt = PETSC_TRUE # cdef shifttype = options.pop('shifttype', None) if shifttype is not None: info.shifttype = matfactorshifttype(shifttype) cdef shiftamount = options.pop('shiftamount', None) if shiftamount is not None: info.shiftamount = asReal(shiftamount) # if options: raise ValueError("unknown options: %s" % list(options.keys())) return PETSC_SUCCESS # ----------------------------------------------------------------------------- cdef object mat_getitem(Mat self, object ij): cdef PetscInt M=0, N=0 rows, cols = ij if isinstance(rows, slice): CHKERR( MatGetSize(self.mat, &M, NULL) ) start, stop, stride = rows.indices(toInt(M)) rows = arange(start, stop, stride) if isinstance(cols, slice): CHKERR( MatGetSize(self.mat, NULL, &N) ) start, stop, stride = cols.indices(toInt(N)) cols = arange(start, stop, stride) return matgetvalues(self.mat, rows, cols, None) cdef PetscErrorCode mat_setitem(Mat self, object ij, object v) except PETSC_ERR_PYTHON: cdef PetscInt M=0, N=0 rows, cols = ij if isinstance(rows, slice): CHKERR( MatGetSize(self.mat, &M, NULL) ) start, stop, stride = rows.indices(toInt(M)) rows = arange(start, stop, stride) if isinstance(cols, slice): CHKERR( MatGetSize(self.mat, NULL, &N) ) start, stop, stride = cols.indices(toInt(N)) cols = arange(start, stop, stride) matsetvalues(self.mat, rows, cols, v, None, 0, 0) return PETSC_SUCCESS # ----------------------------------------------------------------------------- cdef matsetvaluestencil(PetscMat A, MatStencil r, MatStencil c, object value, PetscInsertMode im, int blocked): # block size cdef PetscInt rbs=1, cbs=1 if blocked: CHKERR( MatGetBlockSizes(A, &rbs, &cbs) ) if rbs < 1: rbs = 1 if cbs < 1: cbs = 1 # values cdef PetscInt nv = 1 cdef PetscScalar *v = NULL value = iarray_s(value, &nv, &v) if rbs*cbs != nv: raise ValueError( "incompatible array sizes: nv=%d" % toInt(nv) ) if blocked: CHKERR( MatSetValuesBlockedStencil(A, 1, &r.stencil, 1, &c.stencil, v, im) ) else: CHKERR( MatSetValuesStencil(A, 1, &r.stencil, 1, &c.stencil, v, im) ) return 0 cdef mat_get_dlpack_ctx(Mat self): if 'dense' not in self.getType(): raise NotImplementedError("Not for type {}".format(self.getType())) cdef object ctx0 = self.get_attr('__dltensor_ctx__') cdef PetscInt n = 0, m = 0, lda = 0 cdef int64_t ndim = 2 cdef int64_t* shape_arr = NULL cdef int64_t* strides_arr = NULL cdef object s1 = None cdef object s2 = None cdef PetscInt devId = 0 cdef PetscMemType mtype = PETSC_MEMTYPE_HOST if ctx0 is None: # First time in, create a linear memory view s1 = oarray_p(empty_p(ndim), NULL, &shape_arr) s2 = oarray_p(empty_p(ndim), NULL, &strides_arr) CHKERR( MatGetSize(self.mat, NULL, &n) ) CHKERR( MatGetLocalSize(self.mat, &m, NULL) ) CHKERR( MatDenseGetLDA(self.mat, &lda) ) shape_arr[0] = m shape_arr[1] = n strides_arr[0] = 1 strides_arr[1] = lda else: (_, _, ndim, s1, s2) = ctx0 devType_ = { PETSC_MEMTYPE_HOST : kDLCPU, PETSC_MEMTYPE_CUDA : kDLCUDA } CHKERR( MatGetCurrentMemType(self.mat, &mtype) ) dtype = devType_.get(mtype, kDLCPU) if dtype != kDLCPU: CHKERR( PetscObjectGetDeviceId(self.mat, &devId) ) ctx0 = (dtype, devId, ndim, s1, s2) self.set_attr('__dltensor_ctx__', ctx0) return ctx0 # ----------------------------------------------------------------------------- ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/src/petsc4py/PETSc/petscmatpartitioning.pxi0000644000175000017500000000214614567251135022644 0ustar00balaybalaycdef extern from * nogil: ctypedef const char* PetscMatPartitioningType "MatPartitioningType" PetscMatPartitioningType MATPARTITIONINGCURRENT PetscMatPartitioningType MATPARTITIONINGAVERAGE PetscMatPartitioningType MATPARTITIONINGSQUARE PetscMatPartitioningType MATPARTITIONINGPARMETIS PetscMatPartitioningType MATPARTITIONINGCHACO PetscMatPartitioningType MATPARTITIONINGPARTY PetscMatPartitioningType MATPARTITIONINGPTSCOTCH PetscMatPartitioningType MATPARTITIONINGHIERARCH PetscErrorCode MatPartitioningCreate(MPI_Comm,PetscMatPartitioning*) PetscErrorCode MatPartitioningDestroy(PetscMatPartitioning*) PetscErrorCode MatPartitioningView(PetscMatPartitioning,PetscViewer) PetscErrorCode MatPartitioningSetType(PetscMatPartitioning,PetscMatPartitioningType) PetscErrorCode MatPartitioningGetType(PetscMatPartitioning,PetscMatPartitioningType*) PetscErrorCode MatPartitioningSetFromOptions(PetscMatPartitioning) PetscErrorCode MatPartitioningSetAdjacency(PetscMatPartitioning,PetscMat) PetscErrorCode MatPartitioningApply(PetscMatPartitioning,PetscIS*) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/src/petsc4py/PETSc/petscmem.pxi0000644000175000017500000000057014567251135020210 0ustar00balaybalaycdef extern from * nogil: PetscErrorCode PetscMalloc(size_t,void*) PetscErrorCode PetscFree(void*) PetscErrorCode PetscMemcpy(void*,void*,size_t) PetscErrorCode PetscMemmove(void*,void*,size_t) PetscErrorCode PetscMemzero(void*,size_t) PetscErrorCode PetscMemcmp(void*,void*,size_t,PetscBool*) PetscErrorCode PetscStrallocpy(const char[],char*[]) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/src/petsc4py/PETSc/petscmpi.pxi0000644000175000017500000001011314567251135020211 0ustar00balaybalay# -------------------------------------------------------------------- cdef extern from * nogil: const MPI_Comm MPI_COMM_NULL const MPI_Comm MPI_COMM_SELF const MPI_Comm MPI_COMM_WORLD const MPI_Datatype MPI_DATATYPE_NULL const MPI_Op MPI_OP_NULL enum: MPI_IDENT enum: MPI_CONGRUENT int MPI_Comm_compare(MPI_Comm,MPI_Comm,int*) int MPI_Comm_size(MPI_Comm,int*) int MPI_Comm_rank(MPI_Comm,int*) int MPI_Barrier(MPI_Comm) int MPI_Initialized(int*) int MPI_Finalized(int*) ctypedef int MPI_Fint MPI_Fint MPI_Comm_c2f(MPI_Comm) cdef extern from * nogil: MPI_Comm PETSC_COMM_SELF MPI_Comm PETSC_COMM_WORLD PetscErrorCode PetscCommDuplicate(MPI_Comm,MPI_Comm*,int*) PetscErrorCode PetscCommDestroy(MPI_Comm*) # -------------------------------------------------------------------- cdef extern from "cython.h": void *Cython_ImportFunction(object, char[], char[]) except? NULL ctypedef MPI_Comm* PyMPICommGet(object) except NULL ctypedef object PyMPICommNew(MPI_Comm) ctypedef MPI_Datatype* PyMPIDatatypeGet(object) except NULL ctypedef MPI_Op* PyMPIOpGet(object) except NULL cdef inline MPI_Comm mpi4py_Comm_Get( object comm, ) except? MPI_COMM_NULL: from mpi4py import MPI cdef PyMPICommGet *commget = \ Cython_ImportFunction( MPI, b"PyMPIComm_Get", b"MPI_Comm *(PyObject *)") if commget == NULL: return MPI_COMM_NULL cdef MPI_Comm *ptr = commget(comm) if ptr == NULL: return MPI_COMM_NULL return ptr[0] cdef inline object mpi4py_Comm_New(MPI_Comm comm): from mpi4py import MPI cdef PyMPICommNew *commnew = \ Cython_ImportFunction( MPI, b"PyMPIComm_New", b"PyObject *(MPI_Comm)") if commnew == NULL: return None return commnew(comm) cdef inline MPI_Datatype mpi4py_Datatype_Get( object datatype, ) except? MPI_DATATYPE_NULL: from mpi4py import MPI cdef PyMPIDatatypeGet *datatypeget = \ Cython_ImportFunction( MPI, b"PyMPIDatatype_Get", b"MPI_Datatype *(PyObject *)") if datatypeget == NULL: return MPI_DATATYPE_NULL cdef MPI_Datatype *ptr = datatypeget(datatype) if ptr == NULL: return MPI_DATATYPE_NULL return ptr[0] cdef inline MPI_Op mpi4py_Op_Get( object op, ) except? MPI_OP_NULL: from mpi4py import MPI cdef PyMPIOpGet *opget = \ Cython_ImportFunction( MPI, b"PyMPIOp_Get", b"MPI_Op *(PyObject *)") if opget == NULL: return MPI_OP_NULL cdef MPI_Op *ptr = opget(op) if ptr == NULL: return MPI_OP_NULL return ptr[0] # -------------------------------------------------------------------- cdef inline PetscErrorCode PetscCommDEALLOC(MPI_Comm* comm): if comm == NULL: return PETSC_SUCCESS cdef MPI_Comm tmp = comm[0] if tmp == MPI_COMM_NULL: return PETSC_SUCCESS comm[0] = MPI_COMM_NULL if not (PetscInitializeCalled): return PETSC_SUCCESS if (PetscFinalizeCalled): return PETSC_SUCCESS return PetscCommDestroy(&tmp) cdef inline MPI_Comm def_Comm( object comm, MPI_Comm defv, ) except? MPI_COMM_NULL: cdef MPI_Comm retv = MPI_COMM_NULL if comm is None: retv = defv elif isinstance(comm, Comm): retv = (comm).comm elif type(comm).__module__ == 'mpi4py.MPI': retv = mpi4py_Comm_Get(comm) else: retv = (comm).comm return retv cdef inline Comm new_Comm(MPI_Comm comm): cdef Comm ob = Comm() ob.comm = comm return ob # -------------------------------------------------------------------- cdef inline int comm_size(MPI_Comm comm) except ? -1: if comm == MPI_COMM_NULL: raise ValueError("null communicator") cdef int size = 0 CHKERR( MPI_Comm_size(comm, &size) ) return size cdef inline int comm_rank(MPI_Comm comm) except ? -1: if comm == MPI_COMM_NULL: raise ValueError("null communicator") cdef int rank = 0 CHKERR( MPI_Comm_rank(comm, &rank) ) return rank # -------------------------------------------------------------------- ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/src/petsc4py/PETSc/petscobj.pxi0000644000175000017500000001543314567251135020210 0ustar00balaybalay# -------------------------------------------------------------------- cdef extern from * nogil: ctypedef int PetscClassId ctypedef int PetscObjectState PetscErrorCode PetscObjectView(PetscObject,PetscViewer) PetscErrorCode PetscObjectDestroy(PetscObject*) PetscErrorCode PetscObjectGetReference(PetscObject,PetscInt*) PetscErrorCode PetscObjectReference(PetscObject) PetscErrorCode PetscObjectDereference(PetscObject) PetscErrorCode PetscObjectSetOptionsPrefix(PetscObject,char[]) PetscErrorCode PetscObjectAppendOptionsPrefix(PetscObject,char[]) PetscErrorCode PetscObjectGetOptionsPrefix(PetscObject,char*[]) PetscErrorCode PetscObjectSetFromOptions(PetscObject) PetscErrorCode PetscObjectViewFromOptions(PetscObject,PetscObject,char[]) PetscErrorCode PetscObjectGetComm(PetscObject,MPI_Comm*) PetscErrorCode PetscObjectGetClassId(PetscObject,PetscClassId*) PetscErrorCode PetscObjectGetType(PetscObject,char*[]) PetscErrorCode PetscObjectGetClassName(PetscObject,char*[]) PetscErrorCode PetscObjectSetName(PetscObject,char[]) PetscErrorCode PetscObjectGetName(PetscObject,char*[]) PetscErrorCode PetscObjectStateIncrease(PetscObject) PetscErrorCode PetscObjectStateSet(PetscObject,PetscObjectState) PetscErrorCode PetscObjectStateGet(PetscObject,PetscObjectState*) PetscErrorCode PetscObjectTypeCompare(PetscObject,char[],PetscBool*) PetscErrorCode PetscObjectChangeTypeName(PetscObject,char[]) PetscErrorCode PetscObjectCompose(PetscObject,char[],PetscObject) PetscErrorCode PetscObjectQuery(PetscObject,char[],PetscObject*) ctypedef void (*PetscVoidFunction)() PetscErrorCode PetscObjectComposeFunction(PetscObject,char[],PetscVoidFunction) PetscErrorCode PetscObjectQueryFunction(PetscObject,char[],PetscVoidFunction*) PetscErrorCode PetscObjectIncrementTabLevel(PetscObject,PetscObject,PetscInt) PetscErrorCode PetscObjectGetTabLevel(PetscObject,PetscInt*) PetscErrorCode PetscObjectSetTabLevel(PetscObject,PetscInt) cdef extern from * nogil: # custom.h PetscErrorCode PetscObjectGetDeviceId(PetscObject,PetscInt*) cdef extern from "" nogil: PetscErrorCode PetscObjectDelayedDestroy(PetscObject*) # -------------------------------------------------------------------- cdef inline PetscErrorCode PetscINCREF(PetscObject *obj) noexcept nogil: if obj == NULL: return PETSC_SUCCESS if obj[0] == NULL: return PETSC_SUCCESS return PetscObjectReference(obj[0]) cdef inline PetscErrorCode PetscCLEAR(PetscObject* obj) noexcept nogil: if obj == NULL: return PETSC_SUCCESS if obj[0] == NULL: return PETSC_SUCCESS cdef PetscObject tmp tmp = obj[0]; obj[0] = NULL return PetscObjectDestroy(&tmp) cdef inline PetscErrorCode PetscDEALLOC(PetscObject* obj) noexcept nogil: if obj == NULL: return PETSC_SUCCESS if obj[0] == NULL: return PETSC_SUCCESS cdef PetscObject tmp tmp = obj[0]; obj[0] = NULL if not (PetscInitializeCalled): return PETSC_SUCCESS if (PetscFinalizeCalled): return PETSC_SUCCESS return PetscObjectDelayedDestroy(&tmp) cdef inline PetscErrorCode PetscINCSTATE(PetscObject *obj) noexcept nogil: if obj == NULL: return PETSC_SUCCESS if obj[0] == NULL: return PETSC_SUCCESS return PetscObjectStateIncrease(obj[0]) # -------------------------------------------------------------------- cdef extern from *: ctypedef struct PyObject void _Py_DecRef"Py_DECREF"(PyObject*) PyObject* PyDict_New() except NULL PyObject* PyDict_GetItem(PyObject*, PyObject*) except * int PyDict_SetItem(PyObject*, PyObject*, PyObject*) except -1 int PyDict_DelItem(PyObject*, PyObject*) except -1 cdef extern from * nogil: ctypedef struct _p_PetscObject: MPI_Comm comm const char *prefix PetscInt refct void *python_context PetscErrorCode (*python_destroy)(void*) noexcept nogil cdef inline void Py_DecRef(PyObject *ob) noexcept with gil: _Py_DecRef(ob) cdef PetscErrorCode PetscDelPyDict(void* ptr) noexcept nogil: if ptr != NULL and Py_IsInitialized(): Py_DecRef(ptr) return PETSC_SUCCESS cdef object PetscGetPyDict(PetscObject obj, bint create): if obj.python_context != NULL: return obj.python_context if create: obj.python_destroy = PetscDelPyDict obj.python_context = PyDict_New() return obj.python_context return None cdef inline object PetscGetPyObj(PetscObject o, char name[]): cdef object dct = PetscGetPyDict(o, False) if dct is None: return None cdef object key = bytes2str(name) cdef PyObject *d = dct cdef PyObject *k = key cdef PyObject *v = NULL v = PyDict_GetItem(d, k) if v != NULL: return v return None cdef inline object PetscSetPyObj(PetscObject o, char name[], object p): cdef object dct if p is not None: dct = PetscGetPyDict(o, True) else: dct = PetscGetPyDict(o, False) if dct is None: return None cdef str key = bytes2str(name) cdef PyObject *d = dct cdef PyObject *k = key cdef PyObject *v = p PyDict_SetItem(d, k, v) if v == None: PyDict_DelItem(d, k) return None # -------------------------------------------------------------------- cdef extern from *: object PyLong_FromVoidPtr(void*) cdef inline Py_intptr_t Object_toFortran(PetscObject o) nogil: return o # -------------------------------------------------------------------- cdef inline type subtype_DM(PetscDM dm): cdef PetscObject obj = dm if obj == NULL: return DM # --- cdef PetscBool match = PETSC_FALSE CHKERR( PetscObjectTypeCompare(obj, b"da", &match) ) if match == PETSC_TRUE: return DMDA CHKERR( PetscObjectTypeCompare(obj, b"plex", &match) ) if match == PETSC_TRUE: return DMPlex CHKERR( PetscObjectTypeCompare(obj, b"composite", &match) ) if match == PETSC_TRUE: return DMComposite CHKERR( PetscObjectTypeCompare(obj, b"shell", &match) ) if match == PETSC_TRUE: return DMShell CHKERR( PetscObjectTypeCompare(obj, b"stag", &match) ) if match == PETSC_TRUE: return DMStag CHKERR( PetscObjectTypeCompare(obj, b"swarm", &match) ) if match == PETSC_TRUE: return DMSwarm # --- return DM cdef inline type subtype_Object(PetscObject obj): cdef type klass = Object if obj == NULL: return klass cdef PetscClassId classid = 0 CHKERR( PetscObjectGetClassId(obj,&classid) ) if classid == PETSC_DM_CLASSID: klass = subtype_DM(obj) else: klass = PyPetscType_Lookup(classid) return klass # -------------------------------------------------------------------- ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/src/petsc4py/PETSc/petscopt.pxi0000644000175000017500000001535414567251135020242 0ustar00balaybalaycdef extern from * nogil: ctypedef struct _n_PetscOptions ctypedef _n_PetscOptions* PetscOptions PetscErrorCode PetscOptionsCreate(PetscOptions*) PetscErrorCode PetscOptionsDestroy(PetscOptions*) PetscErrorCode PetscOptionsView(PetscOptions,PetscViewer) PetscErrorCode PetscOptionsClear(PetscOptions) PetscErrorCode PetscOptionsPrefixPush(PetscOptions,char[]) PetscErrorCode PetscOptionsPrefixPop(PetscOptions) PetscErrorCode PetscOptionsHasName(PetscOptions,char[],char[],PetscBool*) PetscErrorCode PetscOptionsSetAlias(PetscOptions,char[],char[]) PetscErrorCode PetscOptionsSetValue(PetscOptions,char[],char[]) PetscErrorCode PetscOptionsClearValue(PetscOptions,char[]) PetscErrorCode PetscOptionsInsertString(PetscOptions,char[]) PetscErrorCode PetscOptionsInsertFile(PetscOptions,char[]) PetscErrorCode PetscOptionsGetAll(PetscOptions,char*[]) PetscErrorCode PetscOptionsGetBool(PetscOptions,char[],char[],PetscBool*,PetscBool*) PetscErrorCode PetscOptionsGetInt(PetscOptions,char[],char[],PetscInt*,PetscBool*) PetscErrorCode PetscOptionsGetReal(PetscOptions,char[],char[],PetscReal*,PetscBool*) PetscErrorCode PetscOptionsGetScalar(PetscOptions,char[],char[],PetscScalar*,PetscBool*) PetscErrorCode PetscOptionsGetString(PetscOptions,char[],char[],char[],size_t,PetscBool*) ctypedef struct _p_PetscToken ctypedef _p_PetscToken* PetscToken PetscErrorCode PetscTokenCreate(char[],char,PetscToken*) PetscErrorCode PetscTokenDestroy(PetscToken*) PetscErrorCode PetscTokenFind(PetscToken,char*[]) PetscErrorCode PetscOptionsValidKey(char[],PetscBool*) # cdef getprefix(prefix, deft=None): if prefix is None: prefix = deft elif isinstance(prefix, Options): prefix = prefix.prefix elif isinstance(prefix, Object): prefix = prefix.getOptionsPrefix() elif not isinstance(prefix, str): raise TypeError('option prefix must be string') if not prefix: return None if prefix.count(' '): raise ValueError('option prefix should not have spaces') if prefix.startswith('-'): raise ValueError('option prefix should not start with a hyphen') return prefix # cdef opt2str(const char *pre, const char *name): p = bytes2str(pre) if pre!=NULL else None n = bytes2str(name) if name[0]!=c'-' else bytes2str(&name[1]) return '(prefix:%s, name:%s)' % (p, n) cdef getopt_Bool(PetscOptions opt, const char *pre, const char *name, object deft): cdef PetscBool value = PETSC_FALSE cdef PetscBool flag = PETSC_FALSE CHKERR( PetscOptionsGetBool(opt, pre, name, &value, &flag) ) if flag==PETSC_TRUE: return toBool(value) if deft is not None: return deft raise KeyError(opt2str(pre, name)) cdef getopt_Int(PetscOptions opt, const char *pre, const char *name, object deft): cdef PetscInt value = 0 cdef PetscBool flag = PETSC_FALSE CHKERR( PetscOptionsGetInt(opt, pre, name, &value, &flag) ) if flag==PETSC_TRUE: return toInt(value) if deft is not None: return deft raise KeyError(opt2str(pre, name)) cdef getopt_Real(PetscOptions opt, const char *pre, const char *name, object deft): cdef PetscReal value = 0 cdef PetscBool flag = PETSC_FALSE CHKERR( PetscOptionsGetReal(opt, pre, name, &value, &flag) ) if flag==PETSC_TRUE: return toReal(value) if deft is not None: return deft raise KeyError(opt2str(pre, name)) cdef getopt_Scalar(PetscOptions opt, const char *pre, const char *name, object deft): cdef PetscScalar value = 0 cdef PetscBool flag = PETSC_FALSE CHKERR( PetscOptionsGetScalar(opt, pre, name, &value, &flag) ) if flag==PETSC_TRUE: return toScalar(value) if deft is not None: return deft raise KeyError(opt2str(pre, name)) cdef getopt_String(PetscOptions opt, const char *pre, const char *name, object deft): cdef char value[1024+1] cdef PetscBool flag = PETSC_FALSE CHKERR( PetscOptionsGetString(opt, pre, name, value, 1024, &flag) ) if flag==PETSC_TRUE: return bytes2str(value) if deft is not None: return deft raise KeyError(opt2str(pre, name)) cdef enum PetscOptType: OPT_BOOL OPT_INT OPT_REAL OPT_SCALAR OPT_STRING cdef getpair(prefix, name, const char **pr, const char **nm): # -- cdef const char *p = NULL prefix = str2bytes(prefix, &p) if p != NULL and p[0] == c'-': p = &p[1] # -- cdef const char *n = NULL name = str2bytes(name, &n) if n != NULL and n[0] != c'-': name = b'-' + name name = str2bytes(name, &n) # -- pr[0] = p nm[0] = n return (prefix, name) cdef getopt(PetscOptions opt, PetscOptType otype, prefix, name, deft): cdef const char *pr = NULL cdef const char *nm = NULL tmp = getpair(prefix, name, &pr, &nm) if otype == OPT_BOOL : return getopt_Bool (opt, pr, nm, deft) if otype == OPT_INT : return getopt_Int (opt, pr, nm, deft) if otype == OPT_REAL : return getopt_Real (opt, pr, nm, deft) if otype == OPT_SCALAR : return getopt_Scalar (opt, pr, nm, deft) if otype == OPT_STRING : return getopt_String (opt, pr, nm, deft) # simple minded options parser cdef tokenize(options): cdef PetscToken t = NULL cdef const char *s = NULL cdef const char *p = NULL options = str2bytes(options, &s) cdef list tokens = [] CHKERR( PetscTokenCreate(s, c' ', &t) ) try: CHKERR( PetscTokenFind(t, &p) ) while p != NULL: tokens.append(bytes2str(p)) CHKERR( PetscTokenFind(t, &p) ) finally: CHKERR( PetscTokenDestroy(&t) ) return tokens cdef bint iskey(key): cdef const char *k = NULL cdef PetscBool b = PETSC_FALSE if key: key = str2bytes(key, &k) CHKERR( PetscOptionsValidKey(k, &b) ) if b == PETSC_TRUE: return True return False cdef gettok(tokens): if tokens: return tokens.pop(0) else: return None cdef getkey(key, prefix): if not iskey(key): return None key = key[1:] if key[0] == '-': key = key[1:] if not key.startswith(prefix): return None return key.replace(prefix, '', 1) cdef parseopt(options, prefix): if isinstance(options, str): tokens = tokenize(options) else: tokens = list(options) prefix = prefix or '' # parser loop opts = {} first = gettok(tokens) while first: key = getkey(first, prefix) if not key: first = gettok(tokens) else: second = gettok(tokens) if getkey(second, prefix): value = None first = second else: value = second first = gettok(tokens) opts[key] = value # we are done return opts # ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/src/petsc4py/PETSc/petscpartitioner.pxi0000644000175000017500000000206314567251135021771 0ustar00balaybalaycdef extern from * nogil: ctypedef const char* PetscPartitionerType PetscPartitionerType PETSCPARTITIONERPARMETIS PetscPartitionerType PETSCPARTITIONERPTSCOTCH PetscPartitionerType PETSCPARTITIONERCHACO PetscPartitionerType PETSCPARTITIONERSIMPLE PetscPartitionerType PETSCPARTITIONERSHELL PetscPartitionerType PETSCPARTITIONERGATHER PetscPartitionerType PETSCPARTITIONERMATPARTITIONING PetscErrorCode PetscPartitionerCreate(MPI_Comm,PetscPartitioner*) PetscErrorCode PetscPartitionerDestroy(PetscPartitioner*) PetscErrorCode PetscPartitionerView(PetscPartitioner,PetscViewer) PetscErrorCode PetscPartitionerSetType(PetscPartitioner,PetscPartitionerType) PetscErrorCode PetscPartitionerGetType(PetscPartitioner,PetscPartitionerType*) PetscErrorCode PetscPartitionerSetFromOptions(PetscPartitioner) PetscErrorCode PetscPartitionerSetUp(PetscPartitioner) PetscErrorCode PetscPartitionerReset(PetscPartitioner) PetscErrorCode PetscPartitionerShellSetPartition(PetscPartitioner,PetscInt,PetscInt*,PetscInt*) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/src/petsc4py/PETSc/petscpc.pxi0000644000175000017500000005077014567251135020043 0ustar00balaybalaycdef extern from * nogil: ctypedef const char* PetscPCType "PCType" PetscPCType PCNONE PetscPCType PCJACOBI PetscPCType PCSOR PetscPCType PCLU PetscPCType PCQR PetscPCType PCSHELL PetscPCType PCBJACOBI PetscPCType PCMG PetscPCType PCEISENSTAT PetscPCType PCILU PetscPCType PCICC PetscPCType PCASM PetscPCType PCGASM PetscPCType PCKSP PetscPCType PCCOMPOSITE PetscPCType PCREDUNDANT PetscPCType PCSPAI PetscPCType PCNN PetscPCType PCCHOLESKY PetscPCType PCPBJACOBI PetscPCType PCVPBJACOBI PetscPCType PCMAT PetscPCType PCHYPRE PetscPCType PCPARMS PetscPCType PCFIELDSPLIT PetscPCType PCTFS PetscPCType PCML PetscPCType PCGALERKIN PetscPCType PCEXOTIC PetscPCType PCCP PetscPCType PCBFBT PetscPCType PCLSC PetscPCType PCPYTHON PetscPCType PCPFMG PetscPCType PCSYSPFMG PetscPCType PCREDISTRIBUTE PetscPCType PCSVD PetscPCType PCGAMG PetscPCType PCCHOWILUVIENNACL PetscPCType PCROWSCALINGVIENNACL PetscPCType PCSAVIENNACL PetscPCType PCBDDC PetscPCType PCKACZMARZ PetscPCType PCTELESCOPE PetscPCType PCPATCH PetscPCType PCLMVM PetscPCType PCHMG PetscPCType PCDEFLATION PetscPCType PCHPDDM PetscPCType PCH2OPUS ctypedef enum PetscPCSide "PCSide": PC_SIDE_DEFAULT PC_LEFT PC_RIGHT PC_SYMMETRIC ctypedef enum PetscPCASMType "PCASMType": PC_ASM_BASIC PC_ASM_RESTRICT PC_ASM_INTERPOLATE PC_ASM_NONE ctypedef enum PetscPCGASMType "PCGASMType": PC_GASM_BASIC PC_GASM_RESTRICT PC_GASM_INTERPOLATE PC_GASM_NONE ctypedef enum PetscPCMGType "PCMGType": PC_MG_MULTIPLICATIVE PC_MG_ADDITIVE PC_MG_FULL PC_MG_KASKADE ctypedef enum PetscPCMGCycleType "PCMGCycleType": PC_MG_CYCLE_V PC_MG_CYCLE_W ctypedef const char* PetscPCGAMGType "PCGAMGType" PetscPCGAMGType PCGAMGAGG PetscPCGAMGType PCGAMGGEO PetscPCGAMGType PCGAMGCLASSICAL ctypedef const char* PetscPCHYPREType "const char*" ctypedef enum PetscPCCompositeType "PCCompositeType": PC_COMPOSITE_ADDITIVE PC_COMPOSITE_MULTIPLICATIVE PC_COMPOSITE_SYMMETRIC_MULTIPLICATIVE PC_COMPOSITE_SPECIAL PC_COMPOSITE_SCHUR ctypedef enum PetscPCFieldSplitSchurPreType "PCFieldSplitSchurPreType": PC_FIELDSPLIT_SCHUR_PRE_SELF PC_FIELDSPLIT_SCHUR_PRE_SELFP PC_FIELDSPLIT_SCHUR_PRE_A11 PC_FIELDSPLIT_SCHUR_PRE_USER PC_FIELDSPLIT_SCHUR_PRE_FULL ctypedef enum PetscPCFieldSplitSchurFactType "PCFieldSplitSchurFactType": PC_FIELDSPLIT_SCHUR_FACT_DIAG PC_FIELDSPLIT_SCHUR_FACT_LOWER PC_FIELDSPLIT_SCHUR_FACT_UPPER PC_FIELDSPLIT_SCHUR_FACT_FULL ctypedef enum PetscPCPatchConstructType "PCPatchConstructType": PC_PATCH_STAR PC_PATCH_VANKA PC_PATCH_PARDECOMP PC_PATCH_USER PC_PATCH_PYTHON ctypedef enum PetscPCHPDDMCoarseCorrectionType "PCHPDDMCoarseCorrectionType": PC_HPDDM_COARSE_CORRECTION_DEFLATED PC_HPDDM_COARSE_CORRECTION_ADDITIVE PC_HPDDM_COARSE_CORRECTION_BALANCED ctypedef enum PetscPCDeflationSpaceType "PCDeflationSpaceType": PC_DEFLATION_SPACE_HAAR PC_DEFLATION_SPACE_DB2 PC_DEFLATION_SPACE_DB4 PC_DEFLATION_SPACE_DB8 PC_DEFLATION_SPACE_DB16 PC_DEFLATION_SPACE_BIORTH22 PC_DEFLATION_SPACE_MEYER PC_DEFLATION_SPACE_AGGREGATION PC_DEFLATION_SPACE_USER ctypedef enum PetscPCFailedReason "PCFailedReason": PC_SETUP_ERROR PC_NOERROR PC_FACTOR_STRUCT_ZEROPIVOT PC_FACTOR_NUMERIC_ZEROPIVOT PC_FACTOR_OUTMEMORY PC_FACTOR_OTHER PC_SUBPC_ERROR PetscErrorCode PCCreate(MPI_Comm,PetscPC*) PetscErrorCode PCDestroy(PetscPC*) PetscErrorCode PCView(PetscPC,PetscViewer) PetscErrorCode PCSetType(PetscPC,PetscPCType) PetscErrorCode PCGetType(PetscPC,PetscPCType*) PetscErrorCode PCSetOptionsPrefix(PetscPC,char[]) PetscErrorCode PCAppendOptionsPrefix(PetscPC,char[]) PetscErrorCode PCGetOptionsPrefix(PetscPC,char*[]) PetscErrorCode PCSetFromOptions(PetscPC) PetscErrorCode PCSetFailedReason(PetscPC,PetscPCFailedReason) PetscErrorCode PCGetFailedReason(PetscPC,PetscPCFailedReason*) PetscErrorCode PCGetFailedReasonRank(PetscPC,PetscPCFailedReason*) PetscErrorCode PCSetUp(PetscPC) PetscErrorCode PCReset(PetscPC) PetscErrorCode PCSetUpOnBlocks(PetscPC) PetscErrorCode PCApply(PetscPC,PetscVec,PetscVec) PetscErrorCode PCMatApply(PetscPC,PetscMat,PetscMat) PetscErrorCode PCApplyTranspose(PetscPC,PetscVec,PetscVec) PetscErrorCode PCApplySymmetricLeft(PetscPC,PetscVec,PetscVec) PetscErrorCode PCApplySymmetricRight(PetscPC,PetscVec,PetscVec) PetscErrorCode PCApplyRichardson(PetscPC,PetscVec,PetscVec,PetscVec,PetscReal,PetscReal,PetscReal,PetscInt) PetscErrorCode PCApplyBAorAB(PetscPC,PetscPCSide,PetscVec,PetscVec,PetscVec) PetscErrorCode PCApplyBAorABTranspose(PetscPC,PetscPCSide,PetscVec,PetscVec,PetscVec) #int PCApplyTransposeExists(PetscPC,PetscBool*) #int PCApplyRichardsonExists(PetscPC,PetscBool*) PetscErrorCode PCGetDM(PetscPC,PetscDM*) PetscErrorCode PCSetDM(PetscPC,PetscDM) PetscErrorCode PCSetOperators(PetscPC,PetscMat,PetscMat) PetscErrorCode PCGetOperators(PetscPC,PetscMat*,PetscMat*) PetscErrorCode PCGetOperatorsSet(PetscPC,PetscBool*,PetscBool*) PetscErrorCode PCSetCoordinates(PetscPC,PetscInt,PetscInt,PetscReal[]) PetscErrorCode PCSetUseAmat(PetscPC,PetscBool) PetscErrorCode PCGetUseAmat(PetscPC,PetscBool*) PetscErrorCode PCComputeExplicitOperator(PetscPC,PetscMat*) PetscErrorCode PCDiagonalScale(PetscPC,PetscBool*) PetscErrorCode PCDiagonalScaleLeft(PetscPC,PetscVec,PetscVec) PetscErrorCode PCDiagonalScaleRight(PetscPC,PetscVec,PetscVec) PetscErrorCode PCDiagonalScaleSet(PetscPC,PetscVec) PetscErrorCode PCASMSetType(PetscPC,PetscPCASMType) PetscErrorCode PCASMSetOverlap(PetscPC,PetscInt) PetscErrorCode PCASMSetLocalSubdomains(PetscPC,PetscInt,PetscIS[],PetscIS[]) PetscErrorCode PCASMSetTotalSubdomains(PetscPC,PetscInt,PetscIS[],PetscIS[]) PetscErrorCode PCASMGetSubKSP(PetscPC,PetscInt*,PetscInt*,PetscKSP*[]) PetscErrorCode PCASMSetSortIndices(PetscPC,PetscBool) PetscErrorCode PCGASMSetType(PetscPC,PetscPCGASMType) PetscErrorCode PCGASMSetOverlap(PetscPC,PetscInt) PetscErrorCode PCGAMGSetType(PetscPC,PetscPCGAMGType) PetscErrorCode PCGAMGSetNlevels(PetscPC,PetscInt) PetscErrorCode PCGAMGSetNSmooths(PetscPC,PetscInt) PetscErrorCode PCHYPREGetType(PetscPC,PetscPCHYPREType*) PetscErrorCode PCHYPRESetType(PetscPC,PetscPCHYPREType) PetscErrorCode PCHYPRESetDiscreteCurl(PetscPC,PetscMat); PetscErrorCode PCHYPRESetDiscreteGradient(PetscPC,PetscMat); PetscErrorCode PCHYPRESetAlphaPoissonMatrix(PetscPC,PetscMat); PetscErrorCode PCHYPRESetBetaPoissonMatrix(PetscPC,PetscMat); PetscErrorCode PCHYPRESetEdgeConstantVectors(PetscPC,PetscVec,PetscVec,PetscVec); PetscErrorCode PCHYPRESetInterpolations(PetscPC, PetscInt, PetscMat, PetscMat[], PetscMat, PetscMat[]); PetscErrorCode PCHYPREAMSSetInteriorNodes(PetscPC, PetscVec); PetscErrorCode PCFactorGetMatrix(PetscPC,PetscMat*) PetscErrorCode PCFactorSetZeroPivot(PetscPC,PetscReal) PetscErrorCode PCFactorSetShiftType(PetscPC,PetscMatFactorShiftType) PetscErrorCode PCFactorSetShiftAmount(PetscPC,PetscReal) PetscErrorCode PCFactorSetMatSolverType(PetscPC,PetscMatSolverType) PetscErrorCode PCFactorGetMatSolverType(PetscPC,PetscMatSolverType*) PetscErrorCode PCFactorSetUpMatSolverType(PetscPC) PetscErrorCode PCFactorSetFill(PetscPC,PetscReal) PetscErrorCode PCFactorSetColumnPivot(PetscPC,PetscReal) PetscErrorCode PCFactorReorderForNonzeroDiagonal(PetscPC,PetscReal) PetscErrorCode PCFactorSetMatOrderingType(PetscPC,PetscMatOrderingType) PetscErrorCode PCFactorSetReuseOrdering(PetscPC,PetscBool ) PetscErrorCode PCFactorSetReuseFill(PetscPC,PetscBool ) PetscErrorCode PCFactorSetUseInPlace(PetscPC) PetscErrorCode PCFactorSetAllowDiagonalFill(PetscPC) PetscErrorCode PCFactorSetPivotInBlocks(PetscPC,PetscBool ) PetscErrorCode PCFactorSetLevels(PetscPC,PetscInt) PetscErrorCode PCFactorSetDropTolerance(PetscPC,PetscReal,PetscReal,PetscInt) PetscErrorCode PCFieldSplitSetType(PetscPC,PetscPCCompositeType) PetscErrorCode PCFieldSplitSetBlockSize(PetscPC,PetscInt) PetscErrorCode PCFieldSplitSetFields(PetscPC,char[],PetscInt,PetscInt*,PetscInt*) PetscErrorCode PCFieldSplitSetIS(PetscPC,char[],PetscIS) PetscErrorCode PCFieldSplitGetSubKSP(PetscPC,PetscInt*,PetscKSP*[]) PetscErrorCode PCFieldSplitSchurGetSubKSP(PetscPC,PetscInt*,PetscKSP*[]) PetscErrorCode PCFieldSplitSetSchurPre(PetscPC,PetscPCFieldSplitSchurPreType,PetscMat) PetscErrorCode PCFieldSplitSetSchurFactType(PetscPC,PetscPCFieldSplitSchurFactType) #int PCFieldSplitGetSchurBlocks(PetscPC,PetscMat*,PetscMat*,PetscMat*,PetscMat*) PetscErrorCode PCCompositeSetType(PetscPC,PetscPCCompositeType) PetscErrorCode PCCompositeGetPC(PetscPC,PetscInt,PetscPC*) PetscErrorCode PCCompositeAddPCType(PetscPC,PetscPCType) PetscErrorCode PCCompositeAddPC(PetscPC,PetscPC) PetscErrorCode PCKSPGetKSP(PetscPC,PetscKSP*) PetscErrorCode PCSetReusePreconditioner(PetscPC,PetscBool) # --- MG --- PetscErrorCode PCMGSetType(PetscPC,PetscPCMGType) PetscErrorCode PCMGGetType(PetscPC,PetscPCMGType*) PetscErrorCode PCMGSetInterpolation(PetscPC,PetscInt,PetscMat) PetscErrorCode PCMGGetInterpolation(PetscPC,PetscInt,PetscMat*) PetscErrorCode PCMGSetRestriction(PetscPC,PetscInt,PetscMat) PetscErrorCode PCMGGetRestriction(PetscPC,PetscInt,PetscMat*) PetscErrorCode PCMGSetRScale(PetscPC,PetscInt,PetscVec) PetscErrorCode PCMGGetRScale(PetscPC,PetscInt,PetscVec*) PetscErrorCode PCMGGetSmoother(PetscPC,PetscInt,PetscKSP*) PetscErrorCode PCMGGetSmootherUp(PetscPC,PetscInt,PetscKSP*) PetscErrorCode PCMGGetSmootherDown(PetscPC,PetscInt,PetscKSP*) PetscErrorCode PCMGGetCoarseSolve(PetscPC,PetscKSP*) PetscErrorCode PCMGSetRhs(PetscPC,PetscInt,PetscVec) PetscErrorCode PCMGSetX(PetscPC,PetscInt,PetscVec) PetscErrorCode PCMGSetR(PetscPC,PetscInt,PetscVec) PetscErrorCode PCMGSetLevels(PetscPC,PetscInt,MPI_Comm*) PetscErrorCode PCMGGetLevels(PetscPC,PetscInt*) PetscErrorCode PCMGSetCycleType(PetscPC,PetscPCMGCycleType) PetscErrorCode PCMGSetCycleTypeOnLevel(PetscPC,PetscInt,PetscPCMGCycleType) PetscErrorCode PCBDDCSetDiscreteGradient(PetscPC,PetscMat,PetscInt,PetscInt,PetscBool,PetscBool) PetscErrorCode PCBDDCSetDivergenceMat(PetscPC,PetscMat,PetscBool,PetscIS) PetscErrorCode PCBDDCSetChangeOfBasisMat(PetscPC,PetscMat,PetscBool) PetscErrorCode PCBDDCSetPrimalVerticesIS(PetscPC,PetscIS) PetscErrorCode PCBDDCSetPrimalVerticesLocalIS(PetscPC,PetscIS) PetscErrorCode PCBDDCSetCoarseningRatio(PetscPC,PetscInt) PetscErrorCode PCBDDCSetLevels(PetscPC,PetscInt) PetscErrorCode PCBDDCSetDirichletBoundaries(PetscPC,PetscIS) PetscErrorCode PCBDDCSetDirichletBoundariesLocal(PetscPC,PetscIS) PetscErrorCode PCBDDCSetNeumannBoundaries(PetscPC,PetscIS) PetscErrorCode PCBDDCSetNeumannBoundariesLocal(PetscPC,PetscIS) PetscErrorCode PCBDDCSetDofsSplitting(PetscPC,PetscInt,PetscIS[]) PetscErrorCode PCBDDCSetDofsSplittingLocal(PetscPC,PetscInt,PetscIS[]) # --- Patch --- ctypedef PetscErrorCode (*PetscPCPatchComputeOperator)(PetscPC, PetscInt, PetscVec, PetscMat, PetscIS, PetscInt, const PetscInt*, const PetscInt*, void*) except PETSC_ERR_PYTHON ctypedef PetscErrorCode (*PetscPCPatchComputeFunction)(PetscPC, PetscInt, PetscVec, PetscVec, PetscIS, PetscInt, const PetscInt*, const PetscInt*, void*) except PETSC_ERR_PYTHON ctypedef PetscErrorCode (*PetscPCPatchConstructOperator)(PetscPC, PetscInt*, PetscIS**, PetscIS*, void*) except PETSC_ERR_PYTHON PetscErrorCode PCPatchSetCellNumbering(PetscPC, PetscSection) PetscErrorCode PCPatchSetDiscretisationInfo(PetscPC, PetscInt, PetscDM*, PetscInt*, PetscInt*, const PetscInt**, const PetscInt*, PetscInt, const PetscInt*, PetscInt, const PetscInt*) PetscErrorCode PCPatchSetComputeOperator(PetscPC, PetscPCPatchComputeOperator, void*) PetscErrorCode PCPatchSetComputeOperatorInteriorFacets(PetscPC, PetscPCPatchComputeOperator, void*) PetscErrorCode PCPatchSetComputeFunction(PetscPC, PetscPCPatchComputeFunction, void*) PetscErrorCode PCPatchSetComputeFunctionInteriorFacets(PetscPC, PetscPCPatchComputeFunction, void*) PetscErrorCode PCPatchSetConstructType(PetscPC, PetscPCPatchConstructType, PetscPCPatchConstructOperator, void*) ctypedef PetscErrorCode (*PetscPCHPDDMAuxiliaryMat)(PetscMat, PetscReal, PetscVec, PetscVec, PetscReal, PetscIS, void*) except PETSC_ERR_PYTHON PetscErrorCode PCHPDDMSetAuxiliaryMat(PetscPC,PetscIS,PetscMat,PetscPCHPDDMAuxiliaryMat,void*) PetscErrorCode PCHPDDMSetRHSMat(PetscPC,PetscMat) PetscErrorCode PCHPDDMHasNeumannMat(PetscPC,PetscBool) PetscErrorCode PCHPDDMSetCoarseCorrectionType(PetscPC,PetscPCHPDDMCoarseCorrectionType) PetscErrorCode PCHPDDMGetCoarseCorrectionType(PetscPC,PetscPCHPDDMCoarseCorrectionType*) PetscErrorCode PCHPDDMGetSTShareSubKSP(PetscPC,PetscBool*) PetscErrorCode PCHPDDMSetDeflationMat(PetscPC,PetscIS,PetscMat) # --- SPAI --- PetscErrorCode PCSPAISetEpsilon(PetscPC,PetscReal) PetscErrorCode PCSPAISetNBSteps(PetscPC,PetscInt) PetscErrorCode PCSPAISetMax(PetscPC,PetscInt) PetscErrorCode PCSPAISetMaxNew(PetscPC,PetscInt) PetscErrorCode PCSPAISetBlockSize(PetscPC,PetscInt) PetscErrorCode PCSPAISetCacheSize(PetscPC,PetscInt) PetscErrorCode PCSPAISetVerbose(PetscPC,PetscInt) PetscErrorCode PCSPAISetSp(PetscPC,PetscInt) # --- DEFLATION --- PetscErrorCode PCDeflationSetInitOnly(PetscPC,PetscBool) PetscErrorCode PCDeflationSetLevels(PetscPC,PetscInt) PetscErrorCode PCDeflationSetReductionFactor(PetscPC,PetscInt) PetscErrorCode PCDeflationSetCorrectionFactor(PetscPC,PetscScalar) PetscErrorCode PCDeflationSetSpaceToCompute(PetscPC,PetscPCDeflationSpaceType,PetscInt) PetscErrorCode PCDeflationSetSpace(PetscPC,PetscMat,PetscBool) PetscErrorCode PCDeflationSetProjectionNullSpaceMat(PetscPC,PetscMat) PetscErrorCode PCDeflationSetCoarseMat(PetscPC,PetscMat) PetscErrorCode PCDeflationGetCoarseKSP(PetscPC,PetscKSP*) PetscErrorCode PCDeflationGetPC(PetscPC,PetscPC*) # --- PYTHON --- PetscErrorCode PCPythonSetType(PetscPC,char[]) PetscErrorCode PCPythonGetType(PetscPC,char*[]) # -------------------------------------------------------------------- cdef inline PC ref_PC(PetscPC pc): cdef PC ob = PC() ob.pc = pc CHKERR( PetscINCREF(ob.obj) ) return ob cdef PetscErrorCode PCPatch_ComputeOperator( PetscPC pc, PetscInt point, PetscVec vec, PetscMat mat, PetscIS cells, PetscInt ndof, const PetscInt *dofmap, const PetscInt *dofmapWithAll, void *ctx) except PETSC_ERR_PYTHON with gil: cdef Vec Vec = ref_Vec(vec) cdef Mat Mat = ref_Mat(mat) cdef PC Pc = ref_PC(pc) cdef IS Is = ref_IS(cells) cdef object context = Pc.get_attr("__patch_compute_operator__") if context is None and ctx != NULL: context = ctx assert context is not None and type(context) is tuple (op, args, kargs) = context cdef PetscInt[:] pydofs = dofmap cdef PetscInt[:] pydofsWithAll if dofmapWithAll != NULL: pydofsWithAll = dofmapWithAll dofsall = asarray(pydofsWithAll) else: dofsall = None op(Pc, toInt(point), Vec, Mat, Is, asarray(pydofs), dofsall, *args, **kargs) return PETSC_SUCCESS cdef PetscErrorCode PCPatch_ComputeFunction( PetscPC pc, PetscInt point, PetscVec vec, PetscVec out, PetscIS cells, PetscInt ndof, const PetscInt *dofmap, const PetscInt *dofmapWithAll, void *ctx) except PETSC_ERR_PYTHON with gil: cdef Vec Out = ref_Vec(out) cdef Vec Vec = ref_Vec(vec) cdef PC Pc = ref_PC(pc) cdef IS Is = ref_IS(cells) cdef object context = Pc.get_attr("__patch_compute_function__") if context is None and ctx != NULL: context = ctx assert context is not None and type(context) is tuple (op, args, kargs) = context cdef PetscInt[:] pydofs = dofmap cdef PetscInt[:] pydofsWithAll = dofmapWithAll op(Pc, toInt(point), Vec, Out, Is, asarray(pydofs), asarray(pydofsWithAll), *args, **kargs) return PETSC_SUCCESS cdef PetscErrorCode PCPatch_ComputeOperatorInteriorFacets( PetscPC pc, PetscInt point, PetscVec vec, PetscMat mat, PetscIS facets, PetscInt ndof, const PetscInt *dofmap, const PetscInt *dofmapWithAll, void *ctx) except PETSC_ERR_PYTHON with gil: cdef Vec Vec = ref_Vec(vec) cdef Mat Mat = ref_Mat(mat) cdef PC Pc = ref_PC(pc) cdef IS Is = ref_IS(facets) cdef object context = Pc.get_attr("__patch_compute_operator_interior_facets__") if context is None and ctx != NULL: context = ctx assert context is not None and type(context) is tuple (op, args, kargs) = context cdef PetscInt[:] pydofs = dofmap cdef PetscInt[:] pydofsWithAll if dofmapWithAll != NULL: pydofsWithAll = dofmapWithAll dofsall = asarray(pydofsWithAll) else: dofsall = None op(Pc, toInt(point), Vec, Mat, Is, asarray(pydofs), dofsall, *args, **kargs) return PETSC_SUCCESS cdef PetscErrorCode PCPatch_ComputeFunctionInteriorFacets( PetscPC pc, PetscInt point, PetscVec vec, PetscVec out, PetscIS facets, PetscInt ndof, const PetscInt *dofmap, const PetscInt *dofmapWithAll, void *ctx) except PETSC_ERR_PYTHON with gil: cdef Vec Out = ref_Vec(out) cdef Vec Vec = ref_Vec(vec) cdef PC Pc = ref_PC(pc) cdef IS Is = ref_IS(facets) cdef object context = Pc.get_attr("__patch_compute_function_interior_facets__") if context is None and ctx != NULL: context = ctx assert context is not None and type(context) is tuple (op, args, kargs) = context cdef PetscInt[:] pydofs = dofmap cdef PetscInt[:] pydofsWithAll = dofmapWithAll op(Pc, toInt(point), Vec, Out, Is, asarray(pydofs), asarray(pydofsWithAll), *args, **kargs) return PETSC_SUCCESS cdef PetscErrorCode PCPatch_UserConstructOperator( PetscPC pc, PetscInt *n, PetscIS **userIS, PetscIS *userIterationSet, void *ctx) except PETSC_ERR_PYTHON with gil: cdef PC Pc = ref_PC(pc) cdef PetscInt i cdef object context = Pc.get_attr("__patch_construction_operator__") if context is None and ctx != NULL: context = ctx assert context is not None and type(context) is tuple (op, args, kargs) = context (patches, iterationSet) = op(Pc, *args, **kargs) n[0] = len(patches) CHKERR(PetscMalloc(n[0]*sizeof(PetscIS), userIS)) for i in range(n[0]): userIS[0][i] = (patches[i]).iset CHKERR( PetscINCREF(&(userIS[0][i])) ) userIterationSet[0] = (iterationSet).iset CHKERR( PetscINCREF(&(userIterationSet[0])) ) return PETSC_SUCCESS ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/src/petsc4py/PETSc/petscpyappctx.pxi0000644000175000017500000000065314567251135021304 0ustar00balaybalaycdef set appctx_registry = set() cdef inline object registerAppCtx(void *appctx): cdef object key = appctx appctx_registry.add(key) cdef inline object toAppCtx(void *appctx): cdef object key = appctx if key in appctx_registry: return appctx else: if appctx != NULL: return PyLong_FromVoidPtr(appctx) else: return None ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/src/petsc4py/PETSc/petscrand.pxi0000644000175000017500000000216714567251135020362 0ustar00balaybalaycdef extern from * nogil: ctypedef const char* PetscRandomType PetscRandomType PETSCRAND PetscRandomType PETSCRAND48 PetscRandomType PETSCSPRNG PetscRandomType PETSCRANDER48 PetscRandomType PETSCRANDOM123 PetscErrorCode PetscRandomCreate(MPI_Comm,PetscRandom*) PetscErrorCode PetscRandomDestroy(PetscRandom*) PetscErrorCode PetscRandomView(PetscRandom,PetscViewer) PetscErrorCode PetscRandomSetType(PetscRandom,PetscRandomType) PetscErrorCode PetscRandomGetType(PetscRandom,PetscRandomType*) PetscErrorCode PetscRandomSetFromOptions(PetscRandom) PetscErrorCode PetscRandomGetValue(PetscRandom,PetscScalar*) PetscErrorCode PetscRandomGetValueReal(PetscRandom,PetscReal*) PetscErrorCode PetscRandomGetValueImaginary(PetscRandom,PetscScalar*) PetscErrorCode PetscRandomGetInterval(PetscRandom,PetscScalar*,PetscScalar*) PetscErrorCode PetscRandomSetInterval(PetscRandom,PetscScalar,PetscScalar) PetscErrorCode PetscRandomSetSeed(PetscRandom,unsigned long) PetscErrorCode PetscRandomGetSeed(PetscRandom,unsigned long*) PetscErrorCode PetscRandomSeed(PetscRandom) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/src/petsc4py/PETSc/petscsct.pxi0000644000175000017500000000207514567251135020225 0ustar00balaybalay# -------------------------------------------------------------------- cdef extern from * nogil: ctypedef PetscSFType PetscScatterType "VecScatterType" PetscErrorCode VecScatterView(PetscScatter,PetscViewer) PetscErrorCode VecScatterDestroy(PetscScatter*) PetscErrorCode VecScatterSetUp(PetscScatter) PetscErrorCode VecScatterCreate(PetscVec,PetscIS,PetscVec,PetscIS,PetscScatter*) PetscErrorCode VecScatterSetFromOptions(PetscScatter) PetscErrorCode VecScatterSetType(PetscScatter,PetscScatterType) PetscErrorCode VecScatterGetType(PetscScatter,PetscScatterType*) PetscErrorCode VecScatterCopy(PetscScatter, PetscScatter*) PetscErrorCode VecScatterCreateToAll(PetscVec,PetscScatter*,PetscVec*) PetscErrorCode VecScatterCreateToZero(PetscVec,PetscScatter*,PetscVec*) PetscErrorCode VecScatterBegin(PetscScatter,PetscVec,PetscVec,PetscInsertMode,PetscScatterMode) PetscErrorCode VecScatterEnd(PetscScatter,PetscVec,PetscVec,PetscInsertMode,PetscScatterMode) # -------------------------------------------------------------------- ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/src/petsc4py/PETSc/petscsec.pxi0000644000175000017500000000732114567251135020205 0ustar00balaybalay# -------------------------------------------------------------------- cdef extern from * nogil: PetscErrorCode PetscSectionCreate(MPI_Comm,PetscSection*) PetscErrorCode PetscSectionClone(PetscSection,PetscSection*) PetscErrorCode PetscSectionSetUp(PetscSection) PetscErrorCode PetscSectionSetUpBC(PetscSection) PetscErrorCode PetscSectionView(PetscSection,PetscViewer) PetscErrorCode PetscSectionReset(PetscSection) PetscErrorCode PetscSectionDestroy(PetscSection*) PetscErrorCode PetscSectionGetNumFields(PetscSection,PetscInt*) PetscErrorCode PetscSectionSetNumFields(PetscSection,PetscInt) PetscErrorCode PetscSectionGetFieldName(PetscSection,PetscInt,const char*[]) PetscErrorCode PetscSectionSetFieldName(PetscSection,PetscInt,const char[]) PetscErrorCode PetscSectionGetFieldComponents(PetscSection,PetscInt,PetscInt*) PetscErrorCode PetscSectionSetFieldComponents(PetscSection,PetscInt,PetscInt) PetscErrorCode PetscSectionGetChart(PetscSection,PetscInt*,PetscInt*) PetscErrorCode PetscSectionSetChart(PetscSection,PetscInt,PetscInt) PetscErrorCode PetscSectionGetPermutation(PetscSection,PetscIS*) PetscErrorCode PetscSectionSetPermutation(PetscSection,PetscIS) PetscErrorCode PetscSectionGetDof(PetscSection,PetscInt,PetscInt*) PetscErrorCode PetscSectionSetDof(PetscSection,PetscInt,PetscInt) PetscErrorCode PetscSectionAddDof(PetscSection,PetscInt,PetscInt) PetscErrorCode PetscSectionGetFieldDof(PetscSection,PetscInt,PetscInt,PetscInt*) PetscErrorCode PetscSectionSetFieldDof(PetscSection,PetscInt,PetscInt,PetscInt) PetscErrorCode PetscSectionAddFieldDof(PetscSection,PetscInt,PetscInt,PetscInt) PetscErrorCode PetscSectionGetConstraintDof(PetscSection,PetscInt,PetscInt*) PetscErrorCode PetscSectionSetConstraintDof(PetscSection,PetscInt,PetscInt) PetscErrorCode PetscSectionAddConstraintDof(PetscSection,PetscInt,PetscInt) PetscErrorCode PetscSectionGetFieldConstraintDof(PetscSection,PetscInt,PetscInt,PetscInt*) PetscErrorCode PetscSectionSetFieldConstraintDof(PetscSection,PetscInt,PetscInt,PetscInt) PetscErrorCode PetscSectionAddFieldConstraintDof(PetscSection,PetscInt,PetscInt,PetscInt) PetscErrorCode PetscSectionGetConstraintIndices(PetscSection,PetscInt,const PetscInt**) PetscErrorCode PetscSectionSetConstraintIndices(PetscSection,PetscInt,const PetscInt*) PetscErrorCode PetscSectionGetFieldConstraintIndices(PetscSection,PetscInt,PetscInt,const PetscInt**) PetscErrorCode PetscSectionSetFieldConstraintIndices(PetscSection,PetscInt,PetscInt,const PetscInt*) PetscErrorCode PetscSectionGetMaxDof(PetscSection,PetscInt*) PetscErrorCode PetscSectionGetStorageSize(PetscSection,PetscInt*) PetscErrorCode PetscSectionGetConstrainedStorageSize(PetscSection,PetscInt*) PetscErrorCode PetscSectionGetOffset(PetscSection,PetscInt,PetscInt*) PetscErrorCode PetscSectionSetOffset(PetscSection,PetscInt,PetscInt) PetscErrorCode PetscSectionGetFieldOffset(PetscSection,PetscInt,PetscInt,PetscInt*) PetscErrorCode PetscSectionSetFieldOffset(PetscSection,PetscInt,PetscInt,PetscInt) PetscErrorCode PetscSectionGetOffsetRange(PetscSection,PetscInt*,PetscInt*) PetscErrorCode PetscSectionCreateGlobalSection(PetscSection,PetscSF,PetscBool,PetscBool,PetscSection*) #int PetscSectionCreateGlobalSectionCensored(PetscSection,PetscSF,PetscBool,PetscInt,const PetscInt[],PetscSection*) PetscErrorCode PetscSectionCreateSubsection(PetscSection,PetscInt,PetscInt[],PetscSection*) PetscErrorCode PetscSectionCreateSubmeshSection(PetscSection,IS,PetscSection*) #int PetscSectionGetPointLayout(MPI_Comm,PetscSection,PetscLayout*) #int PetscSectionGetValueLayout(MPI_Comm,PetscSection,PetscLayout*) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/src/petsc4py/PETSc/petscsf.pxi0000644000175000017500000000513714567251135020046 0ustar00balaybalay# -------------------------------------------------------------------- cdef extern from * nogil: ctypedef const char* PetscSFType PetscSFType PETSCSFBASIC PetscSFType PETSCSFNEIGHBOR PetscSFType PETSCSFALLGATHERV PetscSFType PETSCSFALLGATHER PetscSFType PETSCSFGATHERV PetscSFType PETSCSFGATHER PetscSFType PETSCSFALLTOALL PetscSFType PETSCSFWINDOW PetscErrorCode PetscSFCreate(MPI_Comm,PetscSF*) PetscErrorCode PetscSFSetType(PetscSF,PetscSFType) PetscErrorCode PetscSFGetType(PetscSF,PetscSFType*) PetscErrorCode PetscSFSetFromOptions(PetscSF) PetscErrorCode PetscSFSetUp(PetscSF) PetscErrorCode PetscSFView(PetscSF,PetscViewer) PetscErrorCode PetscSFReset(PetscSF) PetscErrorCode PetscSFDestroy(PetscSF*) ctypedef struct PetscSFNode: PetscInt rank PetscInt index PetscErrorCode PetscSFGetGraph(PetscSF,PetscInt*,PetscInt*,const PetscInt**,const PetscSFNode**) PetscErrorCode PetscSFSetGraph(PetscSF,PetscInt,PetscInt,const PetscInt*,PetscCopyMode,PetscSFNode*,PetscCopyMode) PetscErrorCode PetscSFSetRankOrder(PetscSF,PetscBool) PetscErrorCode PetscSFComputeDegreeBegin(PetscSF,const PetscInt**) PetscErrorCode PetscSFComputeDegreeEnd(PetscSF,const PetscInt**) PetscErrorCode PetscSFGetMultiSF(PetscSF,PetscSF*) PetscErrorCode PetscSFCreateInverseSF(PetscSF,PetscSF*) PetscErrorCode PetscSFCreateEmbeddedRootSF(PetscSF,PetscInt,const PetscInt*,PetscSF*) PetscErrorCode PetscSFCreateEmbeddedLeafSF(PetscSF,PetscInt,const PetscInt*,PetscSF*) PetscErrorCode PetscSFDistributeSection(PetscSF,PetscSection,PetscInt**,PetscSection) PetscErrorCode PetscSFCreateSectionSF(PetscSF,PetscSection,PetscInt*,PetscSection, PetscSF*) PetscErrorCode PetscSFCompose(PetscSF,PetscSF,PetscSF*) PetscErrorCode PetscSFBcastBegin(PetscSF,MPI_Datatype,const void*,void*,MPI_Op) PetscErrorCode PetscSFBcastEnd(PetscSF,MPI_Datatype,const void*,void*,MPI_Op) PetscErrorCode PetscSFReduceBegin(PetscSF,MPI_Datatype,const void*,void*,MPI_Op) PetscErrorCode PetscSFReduceEnd(PetscSF,MPI_Datatype,const void*,void*,MPI_Op) PetscErrorCode PetscSFScatterBegin(PetscSF,MPI_Datatype,const void*,void*) PetscErrorCode PetscSFScatterEnd(PetscSF,MPI_Datatype,const void*,void*) PetscErrorCode PetscSFGatherBegin(PetscSF,MPI_Datatype,const void*,void*) PetscErrorCode PetscSFGatherEnd(PetscSF,MPI_Datatype,const void*,void*) PetscErrorCode PetscSFFetchAndOpBegin(PetscSF,MPI_Datatype,void*,const void*,void*,MPI_Op) PetscErrorCode PetscSFFetchAndOpEnd(PetscSF,MPI_Datatype,void*,const void*,void*,MPI_Op) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/src/petsc4py/PETSc/petscsnes.pxi0000644000175000017500000004617314567251135020413 0ustar00balaybalaycdef extern from * nogil: ctypedef const char* PetscSNESType "SNESType" PetscSNESType SNESNEWTONLS PetscSNESType SNESNEWTONTR PetscSNESType SNESPYTHON PetscSNESType SNESNRICHARDSON PetscSNESType SNESKSPONLY PetscSNESType SNESKSPTRANSPOSEONLY PetscSNESType SNESVINEWTONRSLS PetscSNESType SNESVINEWTONSSLS PetscSNESType SNESNGMRES PetscSNESType SNESQN PetscSNESType SNESSHELL PetscSNESType SNESNGS PetscSNESType SNESNCG PetscSNESType SNESFAS PetscSNESType SNESMS PetscSNESType SNESNASM PetscSNESType SNESANDERSON PetscSNESType SNESASPIN PetscSNESType SNESCOMPOSITE PetscSNESType SNESPATCH ctypedef enum PetscSNESNormSchedule "SNESNormSchedule": SNES_NORM_DEFAULT SNES_NORM_NONE SNES_NORM_ALWAYS SNES_NORM_INITIAL_ONLY SNES_NORM_FINAL_ONLY SNES_NORM_INITIAL_FINAL_ONLY ctypedef enum PetscSNESConvergedReason "SNESConvergedReason": # iterating SNES_CONVERGED_ITERATING # converged SNES_CONVERGED_FNORM_ABS SNES_CONVERGED_FNORM_RELATIVE SNES_CONVERGED_SNORM_RELATIVE SNES_CONVERGED_ITS # diverged SNES_DIVERGED_FUNCTION_DOMAIN SNES_DIVERGED_FUNCTION_COUNT SNES_DIVERGED_LINEAR_SOLVE SNES_DIVERGED_FNORM_NAN SNES_DIVERGED_MAX_IT SNES_DIVERGED_LINE_SEARCH SNES_DIVERGED_INNER SNES_DIVERGED_LOCAL_MIN SNES_DIVERGED_DTOL SNES_DIVERGED_JACOBIAN_DOMAIN SNES_DIVERGED_TR_DELTA ctypedef PetscErrorCode (*PetscSNESCtxDel)(void*) ctypedef PetscErrorCode (*PetscSNESInitialGuessFunction)(PetscSNES, PetscVec, void*) except PETSC_ERR_PYTHON ctypedef PetscErrorCode (*PetscSNESFunctionFunction)(PetscSNES, PetscVec, PetscVec, void*) except PETSC_ERR_PYTHON ctypedef PetscErrorCode (*PetscSNESUpdateFunction)(PetscSNES, PetscInt) except PETSC_ERR_PYTHON ctypedef PetscErrorCode (*PetscSNESJacobianFunction)(PetscSNES, PetscVec, PetscMat, PetscMat, void*) except PETSC_ERR_PYTHON ctypedef PetscErrorCode (*PetscSNESObjectiveFunction)(PetscSNES, PetscVec, PetscReal*, void*) except PETSC_ERR_PYTHON ctypedef PetscErrorCode (*PetscSNESConvergedFunction)(PetscSNES, PetscInt, PetscReal, PetscReal, PetscReal, PetscSNESConvergedReason*, void*) except PETSC_ERR_PYTHON ctypedef PetscErrorCode (*PetscSNESMonitorFunction)(PetscSNES, PetscInt, PetscReal, void*) except PETSC_ERR_PYTHON PetscErrorCode SNESCreate(MPI_Comm,PetscSNES*) PetscErrorCode SNESDestroy(PetscSNES*) PetscErrorCode SNESView(PetscSNES,PetscViewer) PetscErrorCode SNESSetType(PetscSNES,PetscSNESType) PetscErrorCode SNESGetType(PetscSNES,PetscSNESType*) PetscErrorCode SNESSetOptionsPrefix(PetscSNES,char[]) PetscErrorCode SNESAppendOptionsPrefix(PetscSNES,char[]) PetscErrorCode SNESGetOptionsPrefix(PetscSNES,char*[]) PetscErrorCode SNESSetFromOptions(PetscSNES) PetscErrorCode SNESSetApplicationContext(PetscSNES,void*) PetscErrorCode SNESGetApplicationContext(PetscSNES,void*) PetscErrorCode SNESGetKSP(PetscSNES,PetscKSP*) PetscErrorCode SNESSetKSP(PetscSNES,PetscKSP) PetscErrorCode SNESGetDM(PetscSNES,PetscDM*) PetscErrorCode SNESSetDM(PetscSNES,PetscDM) PetscErrorCode SNESFASSetInterpolation(PetscSNES,PetscInt,PetscMat) PetscErrorCode SNESFASGetInterpolation(PetscSNES,PetscInt,PetscMat*) PetscErrorCode SNESFASSetRestriction(PetscSNES,PetscInt,PetscMat) PetscErrorCode SNESFASGetRestriction(PetscSNES,PetscInt,PetscMat*) PetscErrorCode SNESFASSetInjection(PetscSNES,PetscInt,PetscMat) PetscErrorCode SNESFASGetInjection(PetscSNES,PetscInt,PetscMat*) PetscErrorCode SNESFASSetRScale(PetscSNES,PetscInt,PetscVec) PetscErrorCode SNESFASSetLevels(PetscSNES,PetscInt,MPI_Comm[]) PetscErrorCode SNESFASGetLevels(PetscSNES,PetscInt*) PetscErrorCode SNESFASGetCycleSNES(PetscSNES,PetscInt,PetscSNES*) PetscErrorCode SNESFASGetCoarseSolve(PetscSNES,PetscSNES*) PetscErrorCode SNESFASGetSmoother(PetscSNES,PetscInt,PetscSNES*) PetscErrorCode SNESFASGetSmootherDown(PetscSNES,PetscInt,PetscSNES*) PetscErrorCode SNESFASGetSmootherUp(PetscSNES,PetscInt,PetscSNES*) PetscErrorCode SNESGetNPC(PetscSNES,PetscSNES*) PetscErrorCode SNESHasNPC(PetscSNES,PetscBool*) PetscErrorCode SNESSetNPC(PetscSNES,PetscSNES) PetscErrorCode SNESSetNPCSide(PetscSNES,PetscPCSide) PetscErrorCode SNESGetNPCSide(PetscSNES,PetscPCSide*) PetscErrorCode SNESGetRhs(PetscSNES,PetscVec*) PetscErrorCode SNESGetSolution(PetscSNES,PetscVec*) PetscErrorCode SNESSetSolution(PetscSNES,PetscVec) PetscErrorCode SNESGetSolutionUpdate(PetscSNES,PetscVec*) PetscErrorCode SNESSetComputeInitialGuess(PetscSNES,PetscSNESInitialGuessFunction,void*) PetscErrorCode SNESSetFunction(PetscSNES,PetscVec,PetscSNESFunctionFunction,void*) PetscErrorCode SNESGetFunction(PetscSNES,PetscVec*,void*,void**) PetscErrorCode SNESSetUpdate(PetscSNES,PetscSNESUpdateFunction) PetscErrorCode SNESSetJacobian(PetscSNES,PetscMat,PetscMat,PetscSNESJacobianFunction,void*) PetscErrorCode SNESGetJacobian(PetscSNES,PetscMat*,PetscMat*,PetscSNESJacobianFunction*,void**) PetscErrorCode SNESSetObjective(PetscSNES,PetscSNESObjectiveFunction,void*) PetscErrorCode SNESGetObjective(PetscSNES,PetscSNESObjectiveFunction*,void**) PetscErrorCode SNESComputeFunction(PetscSNES,PetscVec,PetscVec) PetscErrorCode SNESComputeJacobian(PetscSNES,PetscVec,PetscMat,PetscMat) PetscErrorCode SNESComputeObjective(PetscSNES,PetscVec,PetscReal*) ctypedef PetscErrorCode (*PetscSNESNGSFunction)(PetscSNES, PetscVec, PetscVec, void*) except PETSC_ERR_PYTHON PetscErrorCode SNESSetNGS(PetscSNES,PetscSNESNGSFunction,void*) PetscErrorCode SNESGetNGS(PetscSNES,PetscSNESNGSFunction*,void**) PetscErrorCode SNESComputeNGS(PetscSNES,PetscVec,PetscVec) PetscErrorCode SNESSetNormSchedule(PetscSNES,PetscSNESNormSchedule) PetscErrorCode SNESGetNormSchedule(PetscSNES,PetscSNESNormSchedule*) PetscErrorCode SNESSetTolerances(PetscSNES,PetscReal,PetscReal,PetscReal,PetscInt,PetscInt) PetscErrorCode SNESGetTolerances(PetscSNES,PetscReal*,PetscReal*,PetscReal*,PetscInt*,PetscInt*) PetscErrorCode SNESConverged(PetscSNES,PetscInt,PetscReal,PetscReal,PetscReal) PetscErrorCode SNESSetConvergenceTest(PetscSNES,PetscSNESConvergedFunction,void*,PetscSNESCtxDel*) PetscErrorCode SNESConvergedDefault(PetscSNES,PetscInt,PetscReal,PetscReal,PetscReal, PetscSNESConvergedReason*,void*) except PETSC_ERR_PYTHON PetscErrorCode SNESConvergedSkip(PetscSNES,PetscInt,PetscReal,PetscReal,PetscReal, PetscSNESConvergedReason*,void*) except PETSC_ERR_PYTHON PetscErrorCode SNESSetConvergenceHistory(PetscSNES,PetscReal[],PetscInt[],PetscInt,PetscBool) PetscErrorCode SNESGetConvergenceHistory(PetscSNES,PetscReal*[],PetscInt*[],PetscInt*) PetscErrorCode SNESLogConvergenceHistory(PetscSNES,PetscReal,PetscInt) PetscErrorCode SNESMonitorSet(PetscSNES,PetscSNESMonitorFunction,void*,PetscSNESCtxDel) PetscErrorCode SNESMonitorCancel(PetscSNES) PetscErrorCode SNESMonitor(PetscSNES,PetscInt,PetscReal) PetscErrorCode SNESSetUp(PetscSNES) PetscErrorCode SNESSetUpMatrices(PetscSNES) PetscErrorCode SNESReset(PetscSNES) PetscErrorCode SNESSolve(PetscSNES,PetscVec,PetscVec) PetscErrorCode SNESSetConvergedReason(PetscSNES,PetscSNESConvergedReason) PetscErrorCode SNESGetConvergedReason(PetscSNES,PetscSNESConvergedReason*) PetscErrorCode SNESSetErrorIfNotConverged(PetscSNES,PetscBool); PetscErrorCode SNESGetErrorIfNotConverged(PetscSNES,PetscBool*); PetscErrorCode SNESSetIterationNumber(PetscSNES,PetscInt) PetscErrorCode SNESGetIterationNumber(PetscSNES,PetscInt*) PetscErrorCode SNESSetForceIteration(PetscSNES,PetscBool) PetscErrorCode SNESSetFunctionNorm(PetscSNES,PetscReal) PetscErrorCode SNESGetFunctionNorm(PetscSNES,PetscReal*) PetscErrorCode SNESGetLinearSolveIterations(PetscSNES,PetscInt*) PetscErrorCode SNESSetCountersReset(PetscSNES,PetscBool) PetscErrorCode SNESGetNumberFunctionEvals(PetscSNES,PetscInt*) PetscErrorCode SNESSetMaxNonlinearStepFailures(PetscSNES,PetscInt) PetscErrorCode SNESGetMaxNonlinearStepFailures(PetscSNES,PetscInt*) PetscErrorCode SNESGetNonlinearStepFailures(PetscSNES,PetscInt*) PetscErrorCode SNESSetMaxLinearSolveFailures(PetscSNES,PetscInt) PetscErrorCode SNESGetMaxLinearSolveFailures(PetscSNES,PetscInt*) PetscErrorCode SNESGetLinearSolveFailures(PetscSNES,PetscInt*) PetscErrorCode SNESKSPSetUseEW(PetscSNES,PetscBool) PetscErrorCode SNESKSPGetUseEW(PetscSNES,PetscBool*) PetscErrorCode SNESKSPSetParametersEW(PetscSNES,PetscInt,PetscReal,PetscReal, PetscReal,PetscReal,PetscReal,PetscReal) PetscErrorCode SNESKSPGetParametersEW(PetscSNES,PetscInt*,PetscReal*,PetscReal*, PetscReal*,PetscReal*,PetscReal*,PetscReal*) PetscErrorCode SNESVISetVariableBounds(PetscSNES,PetscVec,PetscVec) #ctypedef PetscErrorCode (*PetscSNESVariableBoundsFunction)(PetscSNES,PetscVec,PetscVec) #int SNESVISetComputeVariableBounds(PetscSNES,PetscSNESVariableBoundsFunction) PetscErrorCode SNESVIGetInactiveSet(PetscSNES, PetscIS*) PetscErrorCode SNESCompositeGetSNES(PetscSNES,PetscInt,PetscSNES*) PetscErrorCode SNESCompositeGetNumber(PetscSNES,PetscInt*) PetscErrorCode SNESNASMGetSNES(PetscSNES,PetscInt,PetscSNES*) PetscErrorCode SNESNASMGetNumber(PetscSNES,PetscInt*) PetscErrorCode SNESPatchSetCellNumbering(PetscSNES, PetscSection) PetscErrorCode SNESPatchSetDiscretisationInfo(PetscSNES, PetscInt, PetscDM*, PetscInt*, PetscInt*, const PetscInt**, const PetscInt*, PetscInt, const PetscInt*, PetscInt, const PetscInt*) PetscErrorCode SNESPatchSetComputeOperator(PetscSNES, PetscPCPatchComputeOperator, void*) PetscErrorCode SNESPatchSetComputeFunction(PetscSNES, PetscPCPatchComputeFunction, void*) PetscErrorCode SNESPatchSetConstructType(PetscSNES, PetscPCPatchConstructType, PetscPCPatchConstructOperator, void*) PetscErrorCode SNESPythonSetType(PetscSNES,char[]) PetscErrorCode SNESPythonGetType(PetscSNES,char*[]) cdef extern from * nogil: # custom.h PetscErrorCode SNESSetUseMFFD(PetscSNES,PetscBool) PetscErrorCode SNESGetUseMFFD(PetscSNES,PetscBool*) PetscErrorCode SNESSetUseFDColoring(PetscSNES,PetscBool) PetscErrorCode SNESGetUseFDColoring(PetscSNES,PetscBool*) PetscErrorCode SNESConvergenceTestCall(PetscSNES,PetscInt, PetscReal,PetscReal,PetscReal, PetscSNESConvergedReason*) ctypedef const char* PetscSNESLineSearchType "SNESLineSearchType" PetscSNESLineSearchType SNESLINESEARCHBT PetscSNESLineSearchType SNESLINESEARCHNLEQERR PetscSNESLineSearchType SNESLINESEARCHBASIC PetscSNESLineSearchType SNESLINESEARCHNONE PetscSNESLineSearchType SNESLINESEARCHL2 PetscSNESLineSearchType SNESLINESEARCHCP PetscSNESLineSearchType SNESLINESEARCHSHELL PetscSNESLineSearchType SNESLINESEARCHNCGLINEAR PetscErrorCode SNESGetLineSearch(PetscSNES,PetscSNESLineSearch*) PetscErrorCode SNESLineSearchSetFromOptions(PetscSNESLineSearch) PetscErrorCode SNESLineSearchApply(PetscSNESLineSearch,PetscVec,PetscVec,PetscReal*,PetscVec) PetscErrorCode SNESLineSearchGetNorms(PetscSNESLineSearch,PetscReal*,PetscReal*,PetscReal*) PetscErrorCode SNESLineSearchDestroy(PetscSNESLineSearch*) ctypedef PetscErrorCode (*PetscSNESPreCheckFunction)(PetscSNESLineSearch, PetscVec,PetscVec, PetscBool*, void*) except PETSC_ERR_PYTHON PetscErrorCode SNESLineSearchSetPreCheck(PetscSNESLineSearch,PetscSNESPreCheckFunction,void*) PetscErrorCode SNESLineSearchGetSNES(PetscSNESLineSearch,PetscSNES*) # ----------------------------------------------------------------------------- cdef inline SNES ref_SNES(PetscSNES snes): cdef SNES ob = SNES() ob.snes = snes CHKERR( PetscINCREF(ob.obj) ) return ob # ----------------------------------------------------------------------------- cdef PetscErrorCode SNES_InitialGuess( PetscSNES snes, PetscVec x, void* ctx, ) except PETSC_ERR_PYTHON with gil: cdef SNES Snes = ref_SNES(snes) cdef Vec Xvec = ref_Vec(x) cdef object context = Snes.get_attr('__initialguess__') if context is None and ctx != NULL: context = ctx assert context is not None and type(context) is tuple # sanity check (initialguess, args, kargs) = context initialguess(Snes, Xvec, *args, **kargs) return PETSC_SUCCESS # ----------------------------------------------------------------------------- cdef PetscErrorCode SNES_PreCheck( PetscSNESLineSearch linesearch, PetscVec x, PetscVec y, PetscBool *changed, void* ctx ) except PETSC_ERR_PYTHON with gil: cdef PetscSNES snes = NULL; CHKERR( SNESLineSearchGetSNES(linesearch, &snes) ); cdef object b = False cdef SNES Snes = ref_SNES(snes) cdef Vec Xvec = ref_Vec(x) cdef Vec Yvec = ref_Vec(y) cdef object context = Snes.get_attr('__precheck__') if context is None and ctx != NULL: context = ctx assert context is not None and type(context) is tuple # sanity check (precheck, args, kargs) = context b = precheck(Xvec, Yvec, *args, **kargs) changed[0] = asBool(b) return PETSC_SUCCESS # ----------------------------------------------------------------------------- cdef PetscErrorCode SNES_Function( PetscSNES snes, PetscVec x, PetscVec f, void* ctx, ) except PETSC_ERR_PYTHON with gil: cdef SNES Snes = ref_SNES(snes) cdef Vec Xvec = ref_Vec(x) cdef Vec Fvec = ref_Vec(f) cdef object context = Snes.get_attr('__function__') if context is None and ctx != NULL: context = ctx assert context is not None and type(context) is tuple # sanity check (function, args, kargs) = context function(Snes, Xvec, Fvec, *args, **kargs) return PETSC_SUCCESS # ----------------------------------------------------------------------------- cdef PetscErrorCode SNES_Update( PetscSNES snes, PetscInt its, ) except PETSC_ERR_PYTHON with gil: cdef SNES Snes = ref_SNES(snes) cdef object context = Snes.get_attr('__update__') assert context is not None and type(context) is tuple # sanity check (update, args, kargs) = context update(Snes, toInt(its), *args, **kargs) return PETSC_SUCCESS # ----------------------------------------------------------------------------- cdef PetscErrorCode SNES_Jacobian( PetscSNES snes, PetscVec x, PetscMat J, PetscMat P, void* ctx, ) except PETSC_ERR_PYTHON with gil: cdef SNES Snes = ref_SNES(snes) cdef Vec Xvec = ref_Vec(x) cdef Mat Jmat = ref_Mat(J) cdef Mat Pmat = ref_Mat(P) cdef object context = Snes.get_attr('__jacobian__') if context is None and ctx != NULL: context = ctx assert context is not None and type(context) is tuple # sanity check (jacobian, args, kargs) = context jacobian(Snes, Xvec, Jmat, Pmat, *args, **kargs) return PETSC_SUCCESS # ----------------------------------------------------------------------------- cdef PetscErrorCode SNES_Objective( PetscSNES snes, PetscVec x, PetscReal *o, void* ctx, ) except PETSC_ERR_PYTHON with gil: cdef SNES Snes = ref_SNES(snes) cdef Vec Xvec = ref_Vec(x) cdef object context = Snes.get_attr('__objective__') if context is None and ctx != NULL: context = ctx assert context is not None and type(context) is tuple # sanity check (objective, args, kargs) = context obj = objective(Snes, Xvec, *args, **kargs) o[0] = asReal(obj) return PETSC_SUCCESS # ----------------------------------------------------------------------------- cdef PetscErrorCode SNES_NGS( PetscSNES snes, PetscVec x, PetscVec b, void* ctx, ) except PETSC_ERR_PYTHON with gil: cdef SNES Snes = ref_SNES(snes) cdef Vec Xvec = ref_Vec(x) cdef Vec Bvec = ref_Vec(b) cdef object context = Snes.get_attr('__ngs__') if context is None and ctx != NULL: context = ctx assert context is not None and type(context) is tuple # sanity check (ngs, args, kargs) = context ngs(Snes, Xvec, Bvec, *args, **kargs) return PETSC_SUCCESS # ----------------------------------------------------------------------------- cdef PetscErrorCode SNES_Converged( PetscSNES snes, PetscInt iters, PetscReal xnorm, PetscReal gnorm, PetscReal fnorm, PetscSNESConvergedReason *r, void* ctx, ) except PETSC_ERR_PYTHON with gil: cdef SNES Snes = ref_SNES(snes) cdef object it = toInt(iters) cdef object xn = toReal(xnorm) cdef object gn = toReal(gnorm) cdef object fn = toReal(fnorm) cdef object context = Snes.get_attr('__converged__') if context is None and ctx != NULL: context = ctx assert context is not None and type(context) is tuple # sanity check (converged, args, kargs) = context reason = converged(Snes, it, (xn, gn, fn), *args, **kargs) if reason is None: r[0] = SNES_CONVERGED_ITERATING elif reason is False: r[0] = SNES_CONVERGED_ITERATING elif reason is True: r[0] = SNES_CONVERGED_ITS # XXX ? else: r[0] = reason return PETSC_SUCCESS # ----------------------------------------------------------------------------- cdef PetscErrorCode SNES_Monitor( PetscSNES snes, PetscInt iters, PetscReal rnorm, void* ctx, ) except PETSC_ERR_PYTHON with gil: cdef SNES Snes = ref_SNES(snes) cdef object monitorlist = Snes.get_attr('__monitor__') if monitorlist is None: return PETSC_SUCCESS cdef object it = toInt(iters) cdef object rn = toReal(rnorm) for (monitor, args, kargs) in monitorlist: monitor(Snes, it, rn, *args, **kargs) return PETSC_SUCCESS # ----------------------------------------------------------------------------- ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/src/petsc4py/PETSc/petscspace.pxi0000644000175000017500000001234214567251135020525 0ustar00balaybalay cdef extern from * nogil: ctypedef const char* PetscSpaceType PetscSpaceType PETSCSPACEPOLYNOMIAL PetscSpaceType PETSCSPACEPTRIMMED PetscSpaceType PETSCSPACETENSOR PetscSpaceType PETSCSPACESUM PetscSpaceType PETSCSPACEPOINT PetscSpaceType PETSCSPACESUBSPACE PetscSpaceType PETSCSPACEWXY PetscErrorCode PetscSpaceCreate(MPI_Comm, PetscSpace*) PetscErrorCode PetscSpaceSetUp(PetscSpace) PetscErrorCode PetscSpaceSetFromOptions(PetscSpace) PetscErrorCode PetscSpaceDestroy(PetscSpace*) PetscErrorCode PetscSpaceView(PetscSpace, PetscViewer) PetscErrorCode PetscSpaceSetType(PetscSpace, PetscSpaceType) PetscErrorCode PetscSpaceGetType(PetscSpace, PetscSpaceType*) #int PetscSpaceEvaluate(PetscSpace, PetscInt, const PetscReal [], PetscReal [], PetscReal []) PetscErrorCode PetscSpaceGetDimension(PetscSpace, PetscInt*) PetscErrorCode PetscSpaceGetDegree(PetscSpace, PetscInt*, PetscInt*) PetscErrorCode PetscSpaceGetNumVariables(PetscSpace, PetscInt*) PetscErrorCode PetscSpaceGetNumComponents(PetscSpace, PetscInt*) PetscErrorCode PetscSpaceSetDegree(PetscSpace, PetscInt, PetscInt) PetscErrorCode PetscSpaceSetNumComponents(PetscSpace, PetscInt) PetscErrorCode PetscSpaceSetNumVariables(PetscSpace, PetscInt) PetscErrorCode PetscSpaceSumGetConcatenate(PetscSpace, PetscBool*) PetscErrorCode PetscSpaceSumSetConcatenate(PetscSpace, PetscBool) PetscErrorCode PetscSpaceSumGetNumSubspaces(PetscSpace, PetscInt*) PetscErrorCode PetscSpaceSumGetSubspace(PetscSpace, PetscInt, PetscSpace*) PetscErrorCode PetscSpaceSumSetNumSubspaces(PetscSpace, PetscInt) PetscErrorCode PetscSpaceSumSetSubspace(PetscSpace,PetscInt, PetscSpace) PetscErrorCode PetscSpaceTensorGetNumSubspaces(PetscSpace, PetscInt*) PetscErrorCode PetscSpaceTensorGetSubspace(PetscSpace, PetscInt, PetscSpace*) PetscErrorCode PetscSpaceTensorSetNumSubspaces(PetscSpace, PetscInt) PetscErrorCode PetscSpaceTensorSetSubspace(PetscSpace, PetscInt, PetscSpace) PetscErrorCode PetscSpaceViewFromOptions(PetscSpace, PetscObject, char []) PetscErrorCode PetscSpacePolynomialSetTensor(PetscSpace, PetscBool) PetscErrorCode PetscSpacePolynomialGetTensor(PetscSpace, PetscBool*) PetscErrorCode PetscSpacePointSetPoints(PetscSpace, PetscQuadrature) PetscErrorCode PetscSpacePointGetPoints(PetscSpace, PetscQuadrature*) PetscErrorCode PetscSpacePTrimmedSetFormDegree(PetscSpace, PetscInt) PetscErrorCode PetscSpacePTrimmedGetFormDegree(PetscSpace, PetscInt*) # -------------------------------------------------------------------- cdef extern from * nogil: ctypedef const char* PetscDualSpaceType PetscDualSpaceType PETSCDUALSPACELAGRANGE PetscDualSpaceType PETSCDUALSPACESIMPLE PetscDualSpaceType PETSCDUALSPACEREFINED PetscDualSpaceType PETSCDUALSPACEBDM PetscErrorCode PetscDualSpaceCreate(MPI_Comm, PetscDualSpace*) PetscErrorCode PetscDualSpaceDestroy(PetscDualSpace*) PetscErrorCode PetscDualSpaceDuplicate(PetscDualSpace, PetscDualSpace*) PetscErrorCode PetscDualSpaceView(PetscDualSpace, PetscViewer) PetscErrorCode PetscDualSpaceGetDM(PetscDualSpace, PetscDM*) PetscErrorCode PetscDualSpaceSetDM(PetscDualSpace, PetscDM) PetscErrorCode PetscDualSpaceGetDimension(PetscDualSpace, PetscInt*) PetscErrorCode PetscDualSpaceGetNumComponents(PetscDualSpace, PetscInt*) PetscErrorCode PetscDualSpaceSetNumComponents(PetscDualSpace, PetscInt) PetscErrorCode PetscDualSpaceGetOrder(PetscDualSpace, PetscInt*) PetscErrorCode PetscDualSpaceSetOrder(PetscDualSpace, PetscInt) PetscErrorCode PetscDualSpaceGetNumDof(PetscDualSpace, const PetscInt**) PetscErrorCode PetscDualSpaceSetUp(PetscDualSpace) PetscErrorCode PetscDualSpaceViewFromOptions(PetscDualSpace,PetscObject, char[]) PetscErrorCode PetscDualSpaceGetFunctional(PetscDualSpace, PetscInt, PetscQuadrature*) PetscErrorCode PetscDualSpaceGetInteriorDimension(PetscDualSpace, PetscInt*) PetscErrorCode PetscDualSpaceLagrangeGetContinuity(PetscDualSpace, PetscBool*) PetscErrorCode PetscDualSpaceLagrangeGetTensor(PetscDualSpace, PetscBool*) PetscErrorCode PetscDualSpaceLagrangeGetTrimmed(PetscDualSpace, PetscBool*) PetscErrorCode PetscDualSpaceLagrangeSetContinuity(PetscDualSpace, PetscBool) PetscErrorCode PetscDualSpaceLagrangeSetTensor(PetscDualSpace, PetscBool) PetscErrorCode PetscDualSpaceLagrangeSetTrimmed(PetscDualSpace, PetscBool) PetscErrorCode PetscDualSpaceSimpleSetDimension(PetscDualSpace, PetscInt) PetscErrorCode PetscDualSpaceSimpleSetFunctional(PetscDualSpace, PetscInt, PetscQuadrature) PetscErrorCode PetscDualSpaceGetType(PetscDualSpace, PetscDualSpaceType*) PetscErrorCode PetscDualSpaceSetType(PetscDualSpace, PetscDualSpaceType) #int PetscDualSpaceSetFromOptions(PetscDualSpace) #int PetscDualSpaceRefinedSetCellSpaces(PetscDualSpace, const PetscDualSpace []) # Advanced #int PetscDualSpaceCreateAllDataDefault(PetscDualSpace, PetscQuadrature*, PetscMat*) #int PetscDualSpaceCreateInteriorDataDefault(PetscDualSpace, PetscQuadrature*, PetscMat*) #int PetscDualSpaceEqual(PetscDualSpace, PetscDualSpace, PetscBool*) #int PetscDualSpaceGetAllData(PetscDualSpace, PetscQuadrature*, PetscMat*)././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/src/petsc4py/PETSc/petscsys.pxi0000644000175000017500000000733414567251135020255 0ustar00balaybalaycdef extern from * nogil: ctypedef enum PetscDataType: PETSC_INT PETSC_REAL PETSC_SCALAR PETSC_COMPLEX PETSC_DATATYPE_UNKNOWN const char PETSC_AUTHOR_INFO[] PetscErrorCode PetscGetVersion(char[],size_t) PetscErrorCode PetscGetVersionNumber(PetscInt*,PetscInt*,PetscInt*,PetscInt*) PetscErrorCode PetscInitialize(int*,char***,char[],char[]) PetscErrorCode PetscInitializeNoArguments() PetscErrorCode PetscFinalize() PetscBool PetscInitializeCalled PetscBool PetscFinalizeCalled ctypedef PetscErrorCode (*PetscErrorHandlerFunction)( MPI_Comm,int,char*,char*,int,PetscErrorType,char*,void*) PetscErrorHandlerFunction PetscAttachDebuggerErrorHandler PetscErrorHandlerFunction PetscEmacsClientErrorHandler PetscErrorHandlerFunction PetscTraceBackErrorHandler PetscErrorHandlerFunction PetscMPIAbortErrorHandler PetscErrorHandlerFunction PetscAbortErrorHandler PetscErrorHandlerFunction PetscIgnoreErrorHandler PetscErrorCode PetscPushErrorHandler(PetscErrorHandlerFunction,void*) PetscErrorCode PetscPopErrorHandler() PetscErrorCode PetscPopSignalHandler() PetscErrorCode PetscInfoAllow(PetscBool) PetscErrorCode PetscInfoSetFile(char*,char*) PetscErrorCode PetscErrorMessage(int,char*[],char**) PetscErrorCode PetscSplitOwnership(MPI_Comm,PetscInt*,PetscInt*) PetscErrorCode PetscSplitOwnershipBlock(MPI_Comm,PetscInt,PetscInt*,PetscInt*) FILE *PETSC_STDOUT FILE *PETSC_STDERR PetscErrorCode PetscPrintf(MPI_Comm,char[],...) PetscErrorCode PetscVSNPrintf(char*,size_t,const char[],size_t *,va_list) PetscErrorCode PetscVFPrintfDefault(FILE*,const char[],va_list) PetscErrorCode PetscSynchronizedPrintf(MPI_Comm,char[],...) PetscErrorCode PetscSynchronizedFlush(MPI_Comm,FILE*) PetscErrorCode PetscSequentialPhaseBegin(MPI_Comm,int) PetscErrorCode PetscSequentialPhaseEnd(MPI_Comm,int) PetscErrorCode PetscSleep(PetscReal) PetscErrorCode PetscCitationsRegister(const char[],PetscBool*) PetscErrorCode PetscHasExternalPackage(const char[],PetscBool*) cdef inline PetscErrorCode Sys_Sizes( object size, object bsize, PetscInt *_b, PetscInt *_n, PetscInt *_N, ) except PETSC_ERR_PYTHON: # get block size cdef PetscInt bs=PETSC_DECIDE, b=PETSC_DECIDE if bsize is not None: bs = b = asInt(bsize) if bs == PETSC_DECIDE: bs = 1 # unpack and get local and global sizes cdef PetscInt n=PETSC_DECIDE, N=PETSC_DECIDE cdef object on, oN try: on, oN = size except (TypeError, ValueError): on = None; oN = size if on is not None: n = asInt(on) if oN is not None: N = asInt(oN) # check block, local, and and global sizes if (bs < 1): raise ValueError( "block size %d must be positive" % toInt(bs)) if n==PETSC_DECIDE and N==PETSC_DECIDE: raise ValueError( "local and global sizes cannot be both 'DECIDE'") if (n > 0) and (n % bs): raise ValueError( "local size %d not divisible by block size %d" % (toInt(n), toInt(bs)) ) if (N > 0) and (N % bs): raise ValueError( "global size %d not divisible by block size %d" % (toInt(N), toInt(bs)) ) # return result to the caller if _b != NULL: _b[0] = b if _n != NULL: _n[0] = n if _N != NULL: _N[0] = N return PETSC_SUCCESS cdef inline PetscErrorCode Sys_Layout( MPI_Comm comm, PetscInt bs, PetscInt *_n, PetscInt *_N, ) except PETSC_ERR_PYTHON: cdef PetscInt n = _n[0] cdef PetscInt N = _N[0] if bs < 0: bs = 1 if n > 0: n = n // bs if N > 0: N = N // bs CHKERR( PetscSplitOwnership(comm, &n, &N) ) _n[0] = n * bs _N[0] = N * bs return PETSC_SUCCESS ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/src/petsc4py/PETSc/petsctao.pxi0000644000175000017500000006147414567251135020227 0ustar00balaybalaycdef extern from * nogil: ctypedef const char* PetscTAOType "TaoType" PetscTAOType TAOLMVM PetscTAOType TAONLS PetscTAOType TAONTR PetscTAOType TAONTL PetscTAOType TAOCG PetscTAOType TAOTRON PetscTAOType TAOOWLQN PetscTAOType TAOBMRM PetscTAOType TAOBLMVM PetscTAOType TAOBQNLS PetscTAOType TAOBNCG PetscTAOType TAOBNLS PetscTAOType TAOBNTR PetscTAOType TAOBNTL PetscTAOType TAOBQNKLS PetscTAOType TAOBQNKTR PetscTAOType TAOBQNKTL PetscTAOType TAOBQPIP PetscTAOType TAOGPCG PetscTAOType TAONM PetscTAOType TAOPOUNDERS PetscTAOType TAOBRGN PetscTAOType TAOLCL PetscTAOType TAOSSILS PetscTAOType TAOSSFLS PetscTAOType TAOASILS PetscTAOType TAOASFLS PetscTAOType TAOIPM PetscTAOType TAOPDIPM PetscTAOType TAOSHELL PetscTAOType TAOADMM PetscTAOType TAOALMM PetscTAOType TAOPYTHON ctypedef enum PetscTAOConvergedReason "TaoConvergedReason": #iterating TAO_CONTINUE_ITERATING # converged TAO_CONVERGED_GATOL TAO_CONVERGED_GRTOL TAO_CONVERGED_GTTOL TAO_CONVERGED_STEPTOL TAO_CONVERGED_MINF TAO_CONVERGED_USER # diverged TAO_DIVERGED_MAXITS TAO_DIVERGED_NAN TAO_DIVERGED_MAXFCN TAO_DIVERGED_LS_FAILURE TAO_DIVERGED_TR_REDUCTION TAO_DIVERGED_USER ctypedef PetscErrorCode (*PetscTaoMonitorDestroy)(void**) ctypedef PetscErrorCode PetscTaoConvergenceTest(PetscTAO,void*) except PETSC_ERR_PYTHON ctypedef PetscErrorCode PetscTaoMonitor(PetscTAO,void*) except PETSC_ERR_PYTHON ctypedef PetscErrorCode PetscTaoObjective(PetscTAO,PetscVec,PetscReal*,void*) except PETSC_ERR_PYTHON ctypedef PetscErrorCode PetscTaoResidual(PetscTAO,PetscVec,PetscVec,void*) except PETSC_ERR_PYTHON ctypedef PetscErrorCode PetscTaoGradient(PetscTAO,PetscVec,PetscVec,void*) except PETSC_ERR_PYTHON ctypedef PetscErrorCode PetscTaoObjGrad(PetscTAO,PetscVec,PetscReal*,PetscVec,void*) except PETSC_ERR_PYTHON ctypedef PetscErrorCode PetscTaoRegularizerObjGrad(PetscTAO,PetscVec,PetscReal*,PetscVec,void*) except PETSC_ERR_PYTHON ctypedef PetscErrorCode PetscTaoVarBounds(PetscTAO,PetscVec,PetscVec,void*) except PETSC_ERR_PYTHON ctypedef PetscErrorCode PetscTaoConstraints(PetscTAO,PetscVec,PetscVec,void*) except PETSC_ERR_PYTHON ctypedef PetscErrorCode PetscTaoEqualityConstraints(PetscTAO,PetscVec,PetscVec,void*) except PETSC_ERR_PYTHON ctypedef PetscErrorCode PetscTaoHessian(PetscTAO,PetscVec,PetscMat,PetscMat,void*) except PETSC_ERR_PYTHON ctypedef PetscErrorCode PetscTaoRegularizerHessian(PetscTAO,PetscVec,PetscMat,void*) except PETSC_ERR_PYTHON ctypedef PetscErrorCode PetscTaoJacobian(PetscTAO,PetscVec,PetscMat,PetscMat,void*) except PETSC_ERR_PYTHON ctypedef PetscErrorCode PetscTaoJacobianResidual(PetscTAO,PetscVec,PetscMat,PetscMat,void*) except PETSC_ERR_PYTHON ctypedef PetscErrorCode PetscTaoJacobianState(PetscTAO,PetscVec,PetscMat,PetscMat,PetscMat,void*) except PETSC_ERR_PYTHON ctypedef PetscErrorCode PetscTaoJacobianDesign(PetscTAO,PetscVec,PetscMat,void*) except PETSC_ERR_PYTHON ctypedef PetscErrorCode PetscTaoJacobianEquality(PetscTAO,PetscVec,PetscMat,PetscMat,void*) except PETSC_ERR_PYTHON ctypedef PetscErrorCode PetscTaoUpdateFunction(PetscTAO,PetscInt,void*) except PETSC_ERR_PYTHON ctypedef enum PetscTAOBNCGType "TaoBNCGType": TAO_BNCG_GD TAO_BNCG_PCGD TAO_BNCG_HS TAO_BNCG_FR TAO_BNCG_PRP TAO_BNCG_PRP_PLUS TAO_BNCG_DY TAO_BNCG_HZ TAO_BNCG_DK TAO_BNCG_KD TAO_BNCG_SSML_BFGS TAO_BNCG_SSML_DFP TAO_BNCG_SSML_BRDN PetscErrorCode TaoMonitor(PetscTAO,PetscInt,PetscReal,PetscReal,PetscReal,PetscReal) PetscErrorCode TaoView(PetscTAO,PetscViewer) PetscErrorCode TaoDestroy(PetscTAO*) PetscErrorCode TaoCreate(MPI_Comm,PetscTAO*) PetscErrorCode TaoSetOptionsPrefix(PetscTAO,char[]) PetscErrorCode TaoAppendOptionsPrefix(PetscTAO,char[]) PetscErrorCode TaoGetOptionsPrefix(PetscTAO,char*[]) PetscErrorCode TaoSetFromOptions(PetscTAO) PetscErrorCode TaoSetType(PetscTAO,PetscTAOType) PetscErrorCode TaoGetType(PetscTAO,PetscTAOType*) PetscErrorCode TaoSetUp(PetscTAO) PetscErrorCode TaoSolve(PetscTAO) PetscErrorCode TaoSetTolerances(PetscTAO,PetscReal,PetscReal,PetscReal) PetscErrorCode TaoGetTolerances(PetscTAO,PetscReal*,PetscReal*,PetscReal*) PetscErrorCode TaoSetConstraintTolerances(PetscTAO,PetscReal,PetscReal) PetscErrorCode TaoGetConstraintTolerances(PetscTAO,PetscReal*,PetscReal*) PetscErrorCode TaoSetFunctionLowerBound(PetscTAO,PetscReal) PetscErrorCode TaoSetMaximumIterations(PetscTAO,PetscInt) PetscErrorCode TaoGetMaximumIterations(PetscTAO,PetscInt*) PetscErrorCode TaoSetMaximumFunctionEvaluations(PetscTAO,PetscInt) PetscErrorCode TaoGetMaximumFunctionEvaluations(PetscTAO,PetscInt*) PetscErrorCode TaoSetIterationNumber(PetscTAO,PetscInt) PetscErrorCode TaoGetIterationNumber(PetscTAO,PetscInt*) PetscErrorCode TaoSetTrustRegionTolerance(PetscTAO,PetscReal) PetscErrorCode TaoGetInitialTrustRegionRadius(PetscTAO,PetscReal*) PetscErrorCode TaoGetTrustRegionRadius(PetscTAO,PetscReal*) PetscErrorCode TaoSetTrustRegionRadius(PetscTAO,PetscReal) PetscErrorCode TaoDefaultConvergenceTest(PetscTAO,void*) except PETSC_ERR_PYTHON PetscErrorCode TaoSetConvergenceTest(PetscTAO,PetscTaoConvergenceTest*, void*) PetscErrorCode TaoSetConvergedReason(PetscTAO,PetscTAOConvergedReason) PetscErrorCode TaoGetConvergedReason(PetscTAO,PetscTAOConvergedReason*) PetscErrorCode TaoLogConvergenceHistory(PetscTAO,PetscReal,PetscReal,PetscReal,PetscInt) PetscErrorCode TaoGetSolutionStatus(PetscTAO,PetscInt*, PetscReal*,PetscReal*, PetscReal*,PetscReal*, PetscTAOConvergedReason*) PetscErrorCode TaoSetMonitor(PetscTAO,PetscTaoMonitor,void*,PetscTaoMonitorDestroy) PetscErrorCode TaoCancelMonitors(PetscTAO) PetscErrorCode TaoComputeObjective(PetscTAO,PetscVec,PetscReal*) PetscErrorCode TaoComputeResidual(PetscTAO,PetscVec,PetscVec) PetscErrorCode TaoComputeGradient(PetscTAO,PetscVec,PetscVec) PetscErrorCode TaoComputeObjectiveAndGradient(PetscTAO,PetscVec,PetscReal*,PetscVec) PetscErrorCode TaoComputeConstraints(PetscTAO,PetscVec,PetscVec) PetscErrorCode TaoComputeDualVariables(PetscTAO,PetscVec,PetscVec) PetscErrorCode TaoComputeVariableBounds(PetscTAO) PetscErrorCode TaoComputeHessian(PetscTAO,PetscVec,PetscMat,PetscMat) PetscErrorCode TaoComputeJacobian(PetscTAO,PetscVec,PetscMat,PetscMat) PetscErrorCode TaoSetSolution(PetscTAO,PetscVec) PetscErrorCode TaoSetConstraintsVec(PetscTAO,PetscVec) PetscErrorCode TaoSetVariableBounds(PetscTAO,PetscVec,PetscVec) PetscErrorCode TaoGetSolution(PetscTAO,PetscVec*) PetscErrorCode TaoSetGradientNorm(PetscTAO,PetscMat) PetscErrorCode TaoGetGradientNorm(PetscTAO,PetscMat*) PetscErrorCode TaoLMVMSetH0(PetscTAO,PetscMat) PetscErrorCode TaoLMVMGetH0(PetscTAO,PetscMat*) PetscErrorCode TaoLMVMGetH0KSP(PetscTAO,PetscKSP*) PetscErrorCode TaoBNCGGetType(PetscTAO,PetscTAOBNCGType*) PetscErrorCode TaoBNCGSetType(PetscTAO,PetscTAOBNCGType) PetscErrorCode TaoGetVariableBounds(PetscTAO,PetscVec*,PetscVec*) PetscErrorCode TaoSetObjective(PetscTAO,PetscTaoObjective*,void*) PetscErrorCode TaoSetGradient(PetscTAO,PetscVec,PetscTaoGradient*,void*) PetscErrorCode TaoSetObjectiveAndGradient(PetscTAO,PetscVec,PetscTaoObjGrad*,void*) PetscErrorCode TaoSetHessian(PetscTAO,PetscMat,PetscMat,PetscTaoHessian*,void*) PetscErrorCode TaoGetObjective(PetscTAO,PetscTaoObjective**,void**) PetscErrorCode TaoGetGradient(PetscTAO,PetscVec*,PetscTaoGradient**,void**) PetscErrorCode TaoGetObjectiveAndGradient(PetscTAO,PetscVec*,PetscTaoObjGrad**,void**) PetscErrorCode TaoGetHessian(PetscTAO,PetscMat*,PetscMat*,PetscTaoHessian**,void**) PetscErrorCode TaoSetResidualRoutine(PetscTAO,PetscVec,PetscTaoResidual,void*) PetscErrorCode TaoSetVariableBoundsRoutine(PetscTAO,PetscTaoVarBounds*,void*) PetscErrorCode TaoSetConstraintsRoutine(PetscTAO,PetscVec,PetscTaoConstraints*,void*) PetscErrorCode TaoSetJacobianRoutine(PetscTAO,PetscMat,PetscMat,PetscTaoJacobian*,void*) PetscErrorCode TaoSetJacobianResidualRoutine(PetscTAO,PetscMat,PetscMat,PetscTaoJacobianResidual*,void*) PetscErrorCode TaoSetStateDesignIS(PetscTAO,PetscIS,PetscIS) PetscErrorCode TaoSetJacobianStateRoutine(PetscTAO,PetscMat,PetscMat,PetscMat,PetscTaoJacobianState*,void*) PetscErrorCode TaoSetJacobianDesignRoutine(PetscTAO,PetscMat,PetscTaoJacobianDesign*,void*) PetscErrorCode TaoSetEqualityConstraintsRoutine(PetscTAO,PetscVec,PetscTaoEqualityConstraints*,void*) PetscErrorCode TaoSetJacobianEqualityRoutine(PetscTAO,PetscMat,PetscMat,PetscTaoJacobianEquality*,void*) PetscErrorCode TaoSetUpdate(PetscTAO,PetscTaoUpdateFunction*,void*) PetscErrorCode TaoSetInitialTrustRegionRadius(PetscTAO,PetscReal) PetscErrorCode TaoGetKSP(PetscTAO,PetscKSP*) PetscErrorCode TaoGetLineSearch(PetscTAO,PetscTAOLineSearch*) PetscErrorCode TaoBRGNGetSubsolver(PetscTAO,PetscTAO*) PetscErrorCode TaoBRGNSetRegularizerObjectiveAndGradientRoutine(PetscTAO,PetscTaoRegularizerObjGrad*,void*) PetscErrorCode TaoBRGNSetRegularizerHessianRoutine(PetscTAO,PetscMat,PetscTaoRegularizerHessian*,void*) PetscErrorCode TaoBRGNSetRegularizerWeight(PetscTAO,PetscReal) PetscErrorCode TaoBRGNSetL1SmoothEpsilon(PetscTAO,PetscReal) PetscErrorCode TaoBRGNSetDictionaryMatrix(PetscTAO,PetscMat) PetscErrorCode TaoBRGNGetDampingVector(PetscTAO,PetscVec*) PetscErrorCode TaoPythonSetType(PetscTAO,char[]) PetscErrorCode TaoPythonGetType(PetscTAO,char*[]) ctypedef const char* PetscTAOLineSearchType "TaoLineSearchType" PetscTAOLineSearchType TAOLINESEARCHUNIT PetscTAOLineSearchType TAOLINESEARCHARMIJO PetscTAOLineSearchType TAOLINESEARCHOWARMIJO PetscTAOLineSearchType TAOLINESEARCHGPCG PetscTAOLineSearchType TAOLINESEARCHMT PetscTAOLineSearchType TAOLINESEARCHIPM ctypedef enum PetscTAOLineSearchConvergedReason "TaoLineSearchConvergedReason": # failed TAOLINESEARCH_FAILED_INFORNAN TAOLINESEARCH_FAILED_BADPARAMETER TAOLINESEARCH_FAILED_ASCENT # continue TAOLINESEARCH_CONTINUE_ITERATING # success TAOLINESEARCH_SUCCESS TAOLINESEARCH_SUCCESS_USER # halted TAOLINESEARCH_HALTED_OTHER TAOLINESEARCH_HALTED_MAXFCN TAOLINESEARCH_HALTED_UPPERBOUND TAOLINESEARCH_HALTED_LOWERBOUND TAOLINESEARCH_HALTED_RTOL TAOLINESEARCH_HALTED_USER ctypedef PetscErrorCode PetscTaoLineSearchObjective(PetscTAOLineSearch,PetscVec,PetscReal*,void*) except PETSC_ERR_PYTHON ctypedef PetscErrorCode PetscTaoLineSearchGradient(PetscTAOLineSearch,PetscVec,PetscVec,void*) except PETSC_ERR_PYTHON ctypedef PetscErrorCode PetscTaoLineSearchObjGrad(PetscTAOLineSearch,PetscVec,PetscReal*,PetscVec,void*) except PETSC_ERR_PYTHON ctypedef PetscErrorCode PetscTaoLineSearchObjGTS(PetscTaoLineSearch,PetscVec,PetscVec,PetscReal*,PetscReal*,void*) except PETSC_ERR_PYTHON PetscErrorCode TaoLineSearchCreate(MPI_Comm,PetscTAOLineSearch*) PetscErrorCode TaoLineSearchDestroy(PetscTAOLineSearch*) PetscErrorCode TaoLineSearchView(PetscTAOLineSearch,PetscViewer) PetscErrorCode TaoLineSearchSetType(PetscTAOLineSearch,PetscTAOLineSearchType) PetscErrorCode TaoLineSearchGetType(PetscTAOLineSearch,PetscTAOLineSearchType*) PetscErrorCode TaoLineSearchSetOptionsPrefix(PetscTAOLineSearch,char[]) PetscErrorCode TaoLineSearchGetOptionsPrefix(PetscTAOLineSearch,char*[]) PetscErrorCode TaoLineSearchSetFromOptions(PetscTAOLineSearch) PetscErrorCode TaoLineSearchSetUp(PetscTAOLineSearch) PetscErrorCode TaoLineSearchUseTaoRoutines(PetscTAOLineSearch,PetscTAO) PetscErrorCode TaoLineSearchSetObjectiveRoutine(PetscTAOLineSearch,PetscTaoLineSearchObjective,void*) PetscErrorCode TaoLineSearchSetGradientRoutine(PetscTAOLineSearch,PetscTaoLineSearchGradient,void*) PetscErrorCode TaoLineSearchSetObjectiveAndGradientRoutine(PetscTAOLineSearch,PetscTaoLineSearchObjGrad,void*) PetscErrorCode TaoLineSearchApply(PetscTAOLineSearch,PetscVec,PetscReal*,PetscVec,PetscVec,PetscReal*,PetscTAOLineSearchConvergedReason*) # -------------------------------------------------------------------- cdef inline TAO ref_TAO(PetscTAO tao): cdef TAO ob = TAO() ob.tao = tao CHKERR( PetscINCREF(ob.obj) ) return ob # -------------------------------------------------------------------- cdef PetscErrorCode TAO_Objective(PetscTAO _tao, PetscVec _x, PetscReal *_f, void *ctx) except PETSC_ERR_PYTHON with gil: cdef TAO tao = ref_TAO(_tao) cdef Vec x = ref_Vec(_x) context = tao.get_attr("__objective__") if context is None and ctx != NULL: context = ctx assert context is not None and type(context) is tuple # sanity check (objective, args, kargs) = context retv = objective(tao, x, *args, **kargs) _f[0] = asReal(retv) return PETSC_SUCCESS cdef PetscErrorCode TAO_Residual(PetscTAO _tao, PetscVec _x, PetscVec _r, void *ctx) except PETSC_ERR_PYTHON with gil: cdef TAO tao = ref_TAO(_tao) cdef Vec x = ref_Vec(_x) cdef Vec r = ref_Vec(_r) context = tao.get_attr("__residual__") if context is None and ctx != NULL: context = ctx assert context is not None and type(context) is tuple # sanity check (residual, args, kargs) = context residual(tao, x, r, *args, **kargs) return PETSC_SUCCESS cdef PetscErrorCode TAO_Gradient(PetscTAO _tao, PetscVec _x, PetscVec _g, void *ctx) except PETSC_ERR_PYTHON with gil: cdef TAO tao = ref_TAO(_tao) cdef Vec x = ref_Vec(_x) cdef Vec g = ref_Vec(_g) context = tao.get_attr("__gradient__") if context is None and ctx != NULL: context = ctx assert context is not None and type(context) is tuple # sanity check (gradient, args, kargs) = context gradient(tao, x, g, *args, **kargs) return PETSC_SUCCESS cdef PetscErrorCode TAO_ObjGrad(PetscTAO _tao, PetscVec _x, PetscReal *_f, PetscVec _g, void *ctx) except PETSC_ERR_PYTHON with gil: cdef TAO tao = ref_TAO(_tao) cdef Vec x = ref_Vec(_x) cdef Vec g = ref_Vec(_g) context = tao.get_attr("__objgrad__") if context is None and ctx != NULL: context = ctx assert context is not None and type(context) is tuple # sanity check (objgrad, args, kargs) = context retv = objgrad(tao, x, g, *args, **kargs) _f[0] = asReal(retv) return PETSC_SUCCESS cdef PetscErrorCode TAO_BRGNRegObjGrad(PetscTAO _tao, PetscVec _x, PetscReal *_f, PetscVec _g, void *ctx) except PETSC_ERR_PYTHON with gil: cdef TAO tao = ref_TAO(_tao) cdef Vec x = ref_Vec(_x) cdef Vec g = ref_Vec(_g) context = tao.get_attr("__brgnregobjgrad__") if context is None and ctx != NULL: context = ctx assert context is not None and type(context) is tuple # sanity check (objgrad, args, kargs) = context retv = objgrad(tao, x, g, *args, **kargs) _f[0] = asReal(retv) return PETSC_SUCCESS cdef PetscErrorCode TAO_Constraints(PetscTAO _tao, PetscVec _x, PetscVec _r, void *ctx) except PETSC_ERR_PYTHON with gil: cdef TAO tao = ref_TAO(_tao) cdef Vec x = ref_Vec(_x) cdef Vec r = ref_Vec(_r) context = tao.get_attr("__constraints__") if context is None and ctx != NULL: context = ctx assert context is not None and type(context) is tuple # sanity check (constraints, args, kargs) = context constraints(tao, x, r, *args, **kargs) return PETSC_SUCCESS cdef PetscErrorCode TAO_VarBounds(PetscTAO _tao, PetscVec _xl, PetscVec _xu, void *ctx) except PETSC_ERR_PYTHON with gil: cdef TAO tao = ref_TAO(_tao) cdef Vec xl = ref_Vec(_xl) cdef Vec xu = ref_Vec(_xu) context = tao.get_attr("__varbounds__") if context is None and ctx != NULL: context = ctx assert context is not None and type(context) is tuple # sanity check (varbounds, args, kargs) = context varbounds(tao, xl, xu, *args, **kargs) return PETSC_SUCCESS cdef PetscErrorCode TAO_Hessian(PetscTAO _tao, PetscVec _x, PetscMat _H, PetscMat _P, void* ctx) except PETSC_ERR_PYTHON with gil: cdef TAO tao = ref_TAO(_tao) cdef Vec x = ref_Vec(_x) cdef Mat H = ref_Mat(_H) cdef Mat P = ref_Mat(_P) context = tao.get_attr("__hessian__") if context is None and ctx != NULL: context = ctx assert context is not None and type(context) is tuple # sanity check (hessian, args, kargs) = context hessian(tao, x, H, P, *args, **kargs) return PETSC_SUCCESS cdef PetscErrorCode TAO_BRGNRegHessian(PetscTAO _tao, PetscVec _x, PetscMat _H, void* ctx) except PETSC_ERR_PYTHON with gil: cdef TAO tao = ref_TAO(_tao) cdef Vec x = ref_Vec(_x) cdef Mat H = ref_Mat(_H) context = tao.get_attr("__brgnreghessian__") if context is None and ctx != NULL: context = ctx assert context is not None and type(context) is tuple # sanity check (hessian, args, kargs) = context hessian(tao, x, H, *args, **kargs) return PETSC_SUCCESS cdef PetscErrorCode TAO_Jacobian(PetscTAO _tao, PetscVec _x, PetscMat _J, PetscMat _P, void* ctx) except PETSC_ERR_PYTHON with gil: cdef TAO tao = ref_TAO(_tao) cdef Vec x = ref_Vec(_x) cdef Mat J = ref_Mat(_J) cdef Mat P = ref_Mat(_P) context = tao.get_attr("__jacobian__") if context is None and ctx != NULL: context = ctx assert context is not None and type(context) is tuple # sanity check (jacobian, args, kargs) = context jacobian(tao, x, J, P, *args, **kargs) return PETSC_SUCCESS cdef PetscErrorCode TAO_JacobianResidual(PetscTAO _tao, PetscVec _x, PetscMat _J, PetscMat _P, void* ctx) except PETSC_ERR_PYTHON with gil: cdef TAO tao = ref_TAO(_tao) cdef Vec x = ref_Vec(_x) cdef Mat J = ref_Mat(_J) cdef Mat P = ref_Mat(_P) context = tao.get_attr("__jacobian_residual__") if context is None and ctx != NULL: context = ctx assert context is not None and type(context) is tuple # sanity check (jacobian, args, kargs) = context jacobian(tao, x, J, P, *args, **kargs) return PETSC_SUCCESS cdef PetscErrorCode TAO_JacobianState(PetscTAO _tao, PetscVec _x, PetscMat _J, PetscMat _P, PetscMat _I, void* ctx) except PETSC_ERR_PYTHON with gil: cdef TAO tao = ref_TAO(_tao) cdef Vec x = ref_Vec(_x) cdef Mat J = ref_Mat(_J) cdef Mat P = ref_Mat(_P) cdef Mat I = ref_Mat(_I) context = tao.get_attr("__jacobian_state__") if context is None and ctx != NULL: context = ctx assert context is not None and type(context) is tuple # sanity check (jacobian, args, kargs) = context jacobian(tao, x, J, P, I, *args, **kargs) return PETSC_SUCCESS cdef PetscErrorCode TAO_JacobianDesign(PetscTAO _tao, PetscVec _x, PetscMat _J, void* ctx) except PETSC_ERR_PYTHON with gil: cdef TAO tao = ref_TAO(_tao) cdef Vec x = ref_Vec(_x) cdef Mat J = ref_Mat(_J) context = tao.get_attr("__jacobian_design__") if context is None and ctx != NULL: context = ctx assert context is not None and type(context) is tuple # sanity check (jacobian, args, kargs) = context jacobian(tao, x, J, *args, **kargs) return PETSC_SUCCESS cdef PetscErrorCode TAO_EqualityConstraints(PetscTAO _tao, PetscVec _x, PetscVec _c, void* ctx) except PETSC_ERR_PYTHON with gil: cdef TAO tao = ref_TAO(_tao) cdef Vec x = ref_Vec(_x) cdef Vec c = ref_Vec(_c) context = tao.get_attr("__equality_constraints__") if context is None and ctx != NULL: context = ctx assert context is not None and type(context) is tuple # sanity check (f, args, kargs) = context f(tao, x, c, *args, **kargs) return PETSC_SUCCESS cdef PetscErrorCode TAO_JacobianEquality(PetscTAO _tao, PetscVec _x, PetscMat _J, PetscMat _P, void* ctx) except PETSC_ERR_PYTHON with gil: cdef TAO tao = ref_TAO(_tao) cdef Vec x = ref_Vec(_x) cdef Mat J = ref_Mat(_J) cdef Mat P = ref_Mat(_P) context = tao.get_attr("__jacobian_equality__") if context is None and ctx != NULL: context = ctx assert context is not None and type(context) is tuple # sanity check (jacobian, args, kargs) = context jacobian(tao, x, J, P, *args, **kargs) return PETSC_SUCCESS # ctx is unused cdef PetscErrorCode TAO_Update( PetscTAO _tao, PetscInt its, void* ctx) except PETSC_ERR_PYTHON with gil: cdef TAO tao = ref_TAO(_tao) (update, args, kargs) = tao.get_attr('__update__') update(tao, toInt(its), *args, **kargs) return PETSC_SUCCESS cdef PetscErrorCode TAO_Converged(PetscTAO _tao, void* ctx) except PETSC_ERR_PYTHON with gil: # call first the default convergence test CHKERR( TaoDefaultConvergenceTest(_tao, NULL) ) # call next the user-provided convergence test cdef TAO tao = ref_TAO(_tao) (converged, args, kargs) = tao.get_attr('__converged__') reason = converged(tao, *args, **kargs) if reason is None: return PETSC_SUCCESS # handle value of convergence reason cdef PetscTAOConvergedReason creason = TAO_CONTINUE_ITERATING if reason is False or reason == -1: creason = TAO_DIVERGED_USER elif reason is True or reason == 1: creason = TAO_CONVERGED_USER else: creason = reason assert creason >= TAO_DIVERGED_USER assert creason <= TAO_CONVERGED_USER CHKERR( TaoSetConvergedReason(_tao, creason) ) return PETSC_SUCCESS cdef PetscErrorCode TAO_Monitor(PetscTAO _tao, void* ctx) except PETSC_ERR_PYTHON with gil: cdef TAO tao = ref_TAO(_tao) cdef object monitorlist = tao.get_attr('__monitor__') if monitorlist is None: return PETSC_SUCCESS for (monitor, args, kargs) in monitorlist: monitor(tao, *args, **kargs) return PETSC_SUCCESS # -------------------------------------------------------------------- cdef inline TAOLineSearch ref_TAOLS(PetscTAOLineSearch taols): cdef TAOLineSearch ob = TAOLineSearch() ob.taols = taols CHKERR( PetscINCREF(ob.obj) ) return ob # -------------------------------------------------------------------- cdef PetscErrorCode TAOLS_Objective(PetscTAOLineSearch _ls, PetscVec _x, PetscReal *_f, void *ctx) except PETSC_ERR_PYTHON with gil: cdef TAOLineSearch ls = ref_TAOLS(_ls) cdef Vec x = ref_Vec(_x) (objective, args, kargs) = ls.get_attr("__objective__") retv = objective(ls, x, *args, **kargs) _f[0] = asReal(retv) return PETSC_SUCCESS cdef PetscErrorCode TAOLS_Gradient(PetscTAOLineSearch _ls, PetscVec _x, PetscVec _g, void *ctx) except PETSC_ERR_PYTHON with gil: cdef TAOLineSearch ls = ref_TAOLS(_ls) cdef Vec x = ref_Vec(_x) cdef Vec g = ref_Vec(_g) (gradient, args, kargs) = ls.get_attr("__gradient__") gradient(ls, x, g, *args, **kargs) return PETSC_SUCCESS cdef PetscErrorCode TAOLS_ObjGrad(PetscTAOLineSearch _ls, PetscVec _x, PetscReal *_f, PetscVec _g, void *ctx) except PETSC_ERR_PYTHON with gil: cdef TAOLineSearch ls = ref_TAOLS(_ls) cdef Vec x = ref_Vec(_x) cdef Vec g = ref_Vec(_g) (objgrad, args, kargs) = ls.get_attr("__objgrad__") retv = objgrad(ls, x, g, *args, **kargs) _f[0] = asReal(retv) return PETSC_SUCCESS ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/src/petsc4py/PETSc/petscts.pxi0000644000175000017500000006005214567251135020061 0ustar00balaybalaycdef extern from * nogil: ctypedef const char* PetscTSType "TSType" PetscTSType TSEULER PetscTSType TSBEULER PetscTSType TSBASICSYMPLECTIC PetscTSType TSPSEUDO PetscTSType TSCN PetscTSType TSSUNDIALS PetscTSType TSRK PetscTSType TSPYTHON PetscTSType TSTHETA PetscTSType TSALPHA PetscTSType TSALPHA2 PetscTSType TSGLLE PetscTSType TSGLEE PetscTSType TSSSP PetscTSType TSARKIMEX PetscTSType TSDIRK PetscTSType TSROSW PetscTSType TSEIMEX PetscTSType TSMIMEX PetscTSType TSBDF PetscTSType TSRADAU5 PetscTSType TSMPRK PetscTSType TSDISCGRAD ctypedef enum PetscTSProblemType "TSProblemType": TS_LINEAR TS_NONLINEAR ctypedef enum PetscTSEquationType "TSEquationType": TS_EQ_UNSPECIFIED TS_EQ_EXPLICIT TS_EQ_ODE_EXPLICIT TS_EQ_DAE_SEMI_EXPLICIT_INDEX1 TS_EQ_DAE_SEMI_EXPLICIT_INDEX2 TS_EQ_DAE_SEMI_EXPLICIT_INDEX3 TS_EQ_DAE_SEMI_EXPLICIT_INDEXHI TS_EQ_IMPLICIT TS_EQ_ODE_IMPLICIT TS_EQ_DAE_IMPLICIT_INDEX1 TS_EQ_DAE_IMPLICIT_INDEX2 TS_EQ_DAE_IMPLICIT_INDEX3 TS_EQ_DAE_IMPLICIT_INDEXHI ctypedef enum PetscTSConvergedReason "TSConvergedReason": # iterating TS_CONVERGED_ITERATING # converged TS_CONVERGED_TIME TS_CONVERGED_ITS TS_CONVERGED_USER TS_CONVERGED_EVENT # diverged TS_DIVERGED_NONLINEAR_SOLVE TS_DIVERGED_STEP_REJECTED ctypedef enum PetscTSExactFinalTimeOption "TSExactFinalTimeOption": TS_EXACTFINALTIME_UNSPECIFIED TS_EXACTFINALTIME_STEPOVER TS_EXACTFINALTIME_INTERPOLATE TS_EXACTFINALTIME_MATCHSTEP ctypedef PetscErrorCode PetscTSCtxDel(void*) ctypedef PetscErrorCode (*PetscTSFunctionFunction)(PetscTS, PetscReal, PetscVec, PetscVec, void*) except PETSC_ERR_PYTHON ctypedef PetscErrorCode (*PetscTSJacobianFunction)(PetscTS, PetscReal, PetscVec, PetscMat, PetscMat, void*) except PETSC_ERR_PYTHON ctypedef PetscErrorCode (*PetscTSIFunctionFunction)(PetscTS, PetscReal, PetscVec, PetscVec, PetscVec, void*) except PETSC_ERR_PYTHON ctypedef PetscErrorCode (*PetscTSIJacobianFunction)(PetscTS, PetscReal, PetscVec, PetscVec, PetscReal, PetscMat, PetscMat, void*) except PETSC_ERR_PYTHON ctypedef PetscErrorCode (*PetscTSIJacobianPFunction)(PetscTS, PetscReal, PetscVec, PetscVec, PetscReal, PetscMat, void*) except PETSC_ERR_PYTHON ctypedef PetscErrorCode (*PetscTSI2FunctionFunction)(PetscTS, PetscReal, PetscVec, PetscVec, PetscVec, PetscVec, void*) except PETSC_ERR_PYTHON ctypedef PetscErrorCode (*PetscTSI2JacobianFunction)(PetscTS, PetscReal, PetscVec, PetscVec, PetscVec, PetscReal, PetscReal, PetscMat, PetscMat, void*) except PETSC_ERR_PYTHON ctypedef PetscErrorCode (*PetscTSMonitorFunction)(PetscTS, PetscInt, PetscReal, PetscVec, void*) except PETSC_ERR_PYTHON ctypedef PetscErrorCode (*PetscTSPreStepFunction) (PetscTS) except PETSC_ERR_PYTHON ctypedef PetscErrorCode (*PetscTSPostStepFunction) (PetscTS) except PETSC_ERR_PYTHON PetscErrorCode TSCreate(MPI_Comm comm,PetscTS*) PetscErrorCode TSClone(PetscTS,PetscTS*) PetscErrorCode TSDestroy(PetscTS*) PetscErrorCode TSView(PetscTS,PetscViewer) PetscErrorCode TSLoad(PetscTS,PetscViewer) PetscErrorCode TSSetProblemType(PetscTS,PetscTSProblemType) PetscErrorCode TSGetProblemType(PetscTS,PetscTSProblemType*) PetscErrorCode TSSetEquationType(PetscTS,PetscTSEquationType) PetscErrorCode TSGetEquationType(PetscTS,PetscTSEquationType*) PetscErrorCode TSSetType(PetscTS,PetscTSType) PetscErrorCode TSGetType(PetscTS,PetscTSType*) PetscErrorCode TSSetOptionsPrefix(PetscTS,char[]) PetscErrorCode TSAppendOptionsPrefix(PetscTS,char[]) PetscErrorCode TSGetOptionsPrefix(PetscTS,char*[]) PetscErrorCode TSSetFromOptions(PetscTS) PetscErrorCode TSSetSolution(PetscTS,PetscVec) PetscErrorCode TSGetSolution(PetscTS,PetscVec*) PetscErrorCode TS2SetSolution(PetscTS,PetscVec,PetscVec) PetscErrorCode TS2GetSolution(PetscTS,PetscVec*,PetscVec*) PetscErrorCode TSGetRHSFunction(PetscTS,PetscVec*,PetscTSFunctionFunction*,void*) PetscErrorCode TSGetRHSJacobian(PetscTS,PetscMat*,PetscMat*,PetscTSJacobianFunction*,void**) PetscErrorCode TSSetRHSFunction(PetscTS,PetscVec,PetscTSFunctionFunction,void*) PetscErrorCode TSSetRHSJacobian(PetscTS,PetscMat,PetscMat,PetscTSJacobianFunction,void*) PetscErrorCode TSSetIFunction(PetscTS,PetscVec,PetscTSIFunctionFunction,void*) PetscErrorCode TSSetIJacobian(PetscTS,PetscMat,PetscMat,PetscTSIJacobianFunction,void*) PetscErrorCode TSSetIJacobianP(PetscTS,PetscMat,PetscTSIJacobianPFunction,void*) PetscErrorCode TSGetIFunction(PetscTS,PetscVec*,PetscTSIFunctionFunction*,void*) PetscErrorCode TSGetIJacobian(PetscTS,PetscMat*,PetscMat*,PetscTSIJacobianFunction*,void**) PetscErrorCode TSSetI2Function(PetscTS,PetscVec,PetscTSI2FunctionFunction,void*) PetscErrorCode TSSetI2Jacobian(PetscTS,PetscMat,PetscMat,PetscTSI2JacobianFunction,void*) PetscErrorCode TSGetI2Function(PetscTS,PetscVec*,PetscTSI2FunctionFunction*,void**) PetscErrorCode TSGetI2Jacobian(PetscTS,PetscMat*,PetscMat*,PetscTSI2JacobianFunction*,void**) PetscErrorCode TSGetKSP(PetscTS,PetscKSP*) PetscErrorCode TSGetSNES(PetscTS,PetscSNES*) PetscErrorCode TSGetDM(PetscTS,PetscDM*) PetscErrorCode TSSetDM(PetscTS,PetscDM) PetscErrorCode TSComputeRHSFunction(PetscTS,PetscReal,PetscVec,PetscVec) PetscErrorCode TSComputeRHSFunctionLinear(PetscTS,PetscReal,PetscVec,PetscVec,void*) PetscErrorCode TSComputeRHSJacobian(PetscTS,PetscReal,PetscVec,PetscMat,PetscMat) PetscErrorCode TSComputeRHSJacobianConstant(PetscTS,PetscReal,PetscVec,PetscMat,PetscMat,void*) PetscErrorCode TSComputeIFunction(PetscTS,PetscReal,PetscVec,PetscVec,PetscVec,PetscBool) PetscErrorCode TSComputeIJacobian(PetscTS,PetscReal,PetscVec,PetscVec,PetscReal,PetscMat,PetscMat,PetscBool) PetscErrorCode TSComputeIJacobianP(PetscTS,PetscReal,PetscVec,PetscVec,PetscReal,PetscMat,PetscBool) PetscErrorCode TSComputeI2Function(PetscTS,PetscReal,PetscVec,PetscVec,PetscVec,PetscVec) PetscErrorCode TSComputeI2Jacobian(PetscTS,PetscReal,PetscVec,PetscVec,PetscVec,PetscReal,PetscReal,PetscMat,PetscMat) PetscErrorCode TSSetTime(PetscTS,PetscReal) PetscErrorCode TSGetTime(PetscTS,PetscReal*) PetscErrorCode TSGetPrevTime(PetscTS,PetscReal*) PetscErrorCode TSGetSolveTime(PetscTS,PetscReal*) PetscErrorCode TSSetTimeStep(PetscTS,PetscReal) PetscErrorCode TSGetTimeStep(PetscTS,PetscReal*) PetscErrorCode TSSetStepNumber(PetscTS,PetscInt) PetscErrorCode TSGetStepNumber(PetscTS,PetscInt*) PetscErrorCode TSSetMaxSteps(PetscTS,PetscInt) PetscErrorCode TSGetMaxSteps(PetscTS,PetscInt*) PetscErrorCode TSSetMaxTime(PetscTS,PetscReal) PetscErrorCode TSGetMaxTime(PetscTS,PetscReal*) PetscErrorCode TSSetExactFinalTime(PetscTS,PetscTSExactFinalTimeOption) PetscErrorCode TSSetTimeSpan(PetscTS,PetscInt,PetscReal*) PetscErrorCode TSGetTimeSpan(PetscTS,PetscInt*,const PetscReal**) PetscErrorCode TSGetTimeSpanSolutions(PetscTS,PetscInt*,PetscVec**) PetscErrorCode TSSetConvergedReason(PetscTS,PetscTSConvergedReason) PetscErrorCode TSGetConvergedReason(PetscTS,PetscTSConvergedReason*) PetscErrorCode TSGetSNESIterations(PetscTS,PetscInt*) PetscErrorCode TSGetKSPIterations(PetscTS,PetscInt*) PetscErrorCode TSGetStepRejections(PetscTS,PetscInt*) PetscErrorCode TSSetMaxStepRejections(PetscTS,PetscInt) PetscErrorCode TSGetSNESFailures(PetscTS,PetscInt*) PetscErrorCode TSSetMaxSNESFailures(PetscTS,PetscInt) PetscErrorCode TSSetErrorIfStepFails(PetscTS,PetscBool) PetscErrorCode TSSetTolerances(PetscTS,PetscReal,PetscVec,PetscReal,PetscVec) PetscErrorCode TSGetTolerances(PetscTS,PetscReal*,PetscVec*,PetscReal*,PetscVec*) PetscErrorCode TSMonitorSet(PetscTS,PetscTSMonitorFunction,void*,PetscTSCtxDel*) PetscErrorCode TSMonitorCancel(PetscTS) PetscErrorCode TSMonitor(PetscTS,PetscInt,PetscReal,PetscVec) ctypedef PetscErrorCode (*PetscTSEventHandler)(PetscTS,PetscReal,PetscVec,PetscScalar[],void*) except PETSC_ERR_PYTHON ctypedef PetscErrorCode (*PetscTSPostEvent)(PetscTS,PetscInt,PetscInt[],PetscReal,PetscVec, PetscBool, void*) except PETSC_ERR_PYTHON PetscErrorCode TSSetEventHandler(PetscTS, PetscInt, PetscInt[], PetscBool[], PetscTSEventHandler, PetscTSPostEvent, void*) PetscErrorCode TSSetEventTolerances(PetscTS, PetscReal, PetscReal[]) PetscErrorCode TSGetNumEvents(PetscTS, PetscInt*) ctypedef PetscErrorCode (*PetscTSAdjointR)(PetscTS,PetscReal,PetscVec,PetscVec,void*) except PETSC_ERR_PYTHON ctypedef PetscErrorCode (*PetscTSAdjointDRDY)(PetscTS,PetscReal,PetscVec,PetscVec[],void*) except PETSC_ERR_PYTHON ctypedef PetscErrorCode (*PetscTSAdjointDRDP)(PetscTS,PetscReal,PetscVec,PetscVec[],void*) except PETSC_ERR_PYTHON ctypedef PetscErrorCode (*PetscTSRHSJacobianP)(PetscTS,PetscReal,PetscVec,PetscMat,void*) except PETSC_ERR_PYTHON PetscErrorCode TSSetSaveTrajectory(PetscTS) PetscErrorCode TSRemoveTrajectory(PetscTS) PetscErrorCode TSSetCostGradients(PetscTS,PetscInt,PetscVec*,PetscVec*) PetscErrorCode TSGetCostGradients(PetscTS,PetscInt*,PetscVec**,PetscVec**) PetscErrorCode TSCreateQuadratureTS(PetscTS,PetscBool,PetscTS*) PetscErrorCode TSGetQuadratureTS(PetscTS,PetscBool*,PetscTS*) PetscErrorCode TSGetCostIntegral(PetscTS,PetscVec*) PetscErrorCode TSSetRHSJacobianP(PetscTS,PetscMat,PetscTSRHSJacobianP,void*) PetscErrorCode TSComputeRHSJacobianP(PetscTS,PetscReal,PetscVec,PetscMat) PetscErrorCode TSAdjointSolve(PetscTS) PetscErrorCode TSAdjointSetSteps(PetscTS,PetscInt) PetscErrorCode TSAdjointStep(PetscTS) PetscErrorCode TSAdjointSetUp(PetscTS) PetscErrorCode TSAdjointReset(PetscTS) PetscErrorCode TSAdjointComputeDRDPFunction(PetscTS,PetscReal,PetscVec,PetscVec*) PetscErrorCode TSAdjointComputeDRDYFunction(PetscTS,PetscReal,PetscVec,PetscVec*) PetscErrorCode TSAdjointCostIntegral(PetscTS) PetscErrorCode TSForwardSetSensitivities(PetscTS,PetscInt,PetscVec*,PetscInt,PetscVec*) PetscErrorCode TSForwardGetSensitivities(PetscTS,PetscInt*,PetscVec**,PetscInt*,PetscVec**) PetscErrorCode TSForwardSetIntegralGradients(PetscTS,PetscInt,PetscVec *,PetscVec *) PetscErrorCode TSForwardGetIntegralGradients(PetscTS,PetscInt*,PetscVec **,PetscVec **) PetscErrorCode TSForwardSetRHSJacobianP(PetscTS,PetscVec*,PetscTSCostIntegrandFunction,void*) PetscErrorCode TSForwardComputeRHSJacobianP(PetscTS,PetscReal,PetscVec,PetscVec*) PetscErrorCode TSForwardSetUp(PetscTS) PetscErrorCode TSForwardCostIntegral(PetscTS) PetscErrorCode TSForwardStep(PetscTS) PetscErrorCode TSSetPreStep(PetscTS, PetscTSPreStepFunction) PetscErrorCode TSSetPostStep(PetscTS, PetscTSPostStepFunction) PetscErrorCode TSSetUp(PetscTS) PetscErrorCode TSReset(PetscTS) PetscErrorCode TSStep(PetscTS) PetscErrorCode TSRestartStep(PetscTS) PetscErrorCode TSRollBack(PetscTS) PetscErrorCode TSSolve(PetscTS,PetscVec) PetscErrorCode TSInterpolate(PetscTS,PetscReal,PetscVec) PetscErrorCode TSPreStage(PetscTS,PetscReal) PetscErrorCode TSPostStage(PetscTS,PetscReal,PetscInt,PetscVec*) PetscErrorCode TSThetaSetTheta(PetscTS,PetscReal) PetscErrorCode TSThetaGetTheta(PetscTS,PetscReal*) PetscErrorCode TSThetaSetEndpoint(PetscTS,PetscBool) PetscErrorCode TSThetaGetEndpoint(PetscTS,PetscBool*) PetscErrorCode TSAlphaSetRadius(PetscTS,PetscReal) PetscErrorCode TSAlphaSetParams(PetscTS,PetscReal,PetscReal,PetscReal) PetscErrorCode TSAlphaGetParams(PetscTS,PetscReal*,PetscReal*,PetscReal*) ctypedef const char* PetscTSRKType "TSRKType" PetscTSRKType TSRK1FE PetscTSRKType TSRK2A PetscTSRKType TSRK2B PetscTSRKType TSRK3 PetscTSRKType TSRK3BS PetscTSRKType TSRK4 PetscTSRKType TSRK5F PetscTSRKType TSRK5DP PetscTSRKType TSRK5BS PetscTSRKType TSRK6VR PetscTSRKType TSRK7VR PetscTSRKType TSRK8VR PetscErrorCode TSRKGetType(PetscTS,PetscTSRKType*) PetscErrorCode TSRKSetType(PetscTS,PetscTSRKType) ctypedef const char* PetscTSARKIMEXType "TSARKIMEXType" PetscTSARKIMEXType TSARKIMEX1BEE PetscTSARKIMEXType TSARKIMEXA2 PetscTSARKIMEXType TSARKIMEXL2 PetscTSARKIMEXType TSARKIMEXARS122 PetscTSARKIMEXType TSARKIMEX2C PetscTSARKIMEXType TSARKIMEX2D PetscTSARKIMEXType TSARKIMEX2E PetscTSARKIMEXType TSARKIMEXPRSSP2 PetscTSARKIMEXType TSARKIMEX3 PetscTSARKIMEXType TSARKIMEXBPR3 PetscTSARKIMEXType TSARKIMEXARS443 PetscTSARKIMEXType TSARKIMEX4 PetscTSARKIMEXType TSARKIMEX5 PetscErrorCode TSARKIMEXGetType(PetscTS,PetscTSRKType*) PetscErrorCode TSARKIMEXSetType(PetscTS,PetscTSRKType) PetscErrorCode TSARKIMEXSetFullyImplicit(PetscTS,PetscBool) ctypedef const char* PetscTSDIRKType "TSDIRKType" PetscTSDIRKType TSDIRKS212 PetscTSDIRKType TSDIRKES122SAL PetscTSDIRKType TSDIRKES213SAL PetscTSDIRKType TSDIRKES324SAL PetscTSDIRKType TSDIRKES325SAL PetscTSDIRKType TSDIRK657A PetscTSDIRKType TSDIRKES648SA PetscTSDIRKType TSDIRK658A PetscTSDIRKType TSDIRKS659A PetscTSDIRKType TSDIRK7510SAL PetscTSDIRKType TSDIRKES7510SA PetscTSDIRKType TSDIRK759A PetscTSDIRKType TSDIRKS7511SAL PetscTSDIRKType TSDIRK8614A PetscTSDIRKType TSDIRK8616SAL PetscTSDIRKType TSDIRKES8516SAL PetscErrorCode TSDIRKGetType(PetscTS,PetscTSDIRKType*) PetscErrorCode TSDIRKSetType(PetscTS,PetscTSDIRKType) PetscErrorCode TSPythonSetType(PetscTS,char[]) PetscErrorCode TSPythonGetType(PetscTS,char*[]) cdef extern from * nogil: struct _p_TSAdapt ctypedef _p_TSAdapt *PetscTSAdapt "TSAdapt" PetscErrorCode TSGetAdapt(PetscTS,PetscTSAdapt*) PetscErrorCode TSAdaptGetStepLimits(PetscTSAdapt,PetscReal*,PetscReal*) PetscErrorCode TSAdaptSetStepLimits(PetscTSAdapt,PetscReal,PetscReal) PetscErrorCode TSAdaptCheckStage(PetscTSAdapt,PetscTS,PetscReal,PetscVec,PetscBool*) cdef extern from * nogil: # custom.h PetscErrorCode TSSetTimeStepNumber(PetscTS,PetscInt) # ----------------------------------------------------------------------------- cdef inline TS ref_TS(PetscTS ts): cdef TS ob = TS() ob.ts = ts CHKERR( PetscINCREF(ob.obj) ) return ob # ----------------------------------------------------------------------------- cdef PetscErrorCode TS_RHSFunction( PetscTS ts, PetscReal t, PetscVec x, PetscVec f, void* ctx, ) except PETSC_ERR_PYTHON with gil: cdef TS Ts = ref_TS(ts) cdef Vec Xvec = ref_Vec(x) cdef Vec Fvec = ref_Vec(f) cdef object context = Ts.get_attr('__rhsfunction__') if context is None and ctx != NULL: context = ctx assert context is not None and type(context) is tuple # sanity check (function, args, kargs) = context function(Ts, toReal(t), Xvec, Fvec, *args, **kargs) return PETSC_SUCCESS cdef PetscErrorCode TS_RHSJacobian( PetscTS ts, PetscReal t, PetscVec x, PetscMat J, PetscMat P, void* ctx, ) except PETSC_ERR_PYTHON with gil: cdef TS Ts = ref_TS(ts) cdef Vec Xvec = ref_Vec(x) cdef Mat Jmat = ref_Mat(J) cdef Mat Pmat = ref_Mat(P) cdef object context = Ts.get_attr('__rhsjacobian__') if context is None and ctx != NULL: context = ctx assert context is not None and type(context) is tuple # sanity check (jacobian, args, kargs) = context jacobian(Ts, toReal(t), Xvec, Jmat, Pmat, *args, **kargs) return PETSC_SUCCESS cdef PetscErrorCode TS_RHSJacobianP( PetscTS ts, PetscReal t, PetscVec x, PetscMat J, void* ctx, ) except PETSC_ERR_PYTHON with gil: cdef TS Ts = ref_TS(ts) cdef Vec Xvec = ref_Vec(x) cdef Mat Jmat = ref_Mat(J) cdef object context = Ts.get_attr('__rhsjacobianp__') if context is None and ctx != NULL: context = ctx assert context is not None and type(context) is tuple # sanity check (jacobianp, args, kargs) = context jacobianp(Ts, toReal(t), Xvec, Jmat, *args, **kargs) return PETSC_SUCCESS # ----------------------------------------------------------------------------- cdef PetscErrorCode TS_IFunction( PetscTS ts, PetscReal t, PetscVec x, PetscVec xdot, PetscVec f, void* ctx, ) except PETSC_ERR_PYTHON with gil: cdef TS Ts = ref_TS(ts) cdef Vec Xvec = ref_Vec(x) cdef Vec XDvec = ref_Vec(xdot) cdef Vec Fvec = ref_Vec(f) cdef object context = Ts.get_attr('__ifunction__') if context is None and ctx != NULL: context = ctx assert context is not None and type(context) is tuple # sanity check (function, args, kargs) = context function(Ts, toReal(t), Xvec, XDvec, Fvec, *args, **kargs) return PETSC_SUCCESS cdef PetscErrorCode TS_IJacobian( PetscTS ts, PetscReal t, PetscVec x, PetscVec xdot, PetscReal a, PetscMat J, PetscMat P, void* ctx, ) except PETSC_ERR_PYTHON with gil: cdef TS Ts = ref_TS(ts) cdef Vec Xvec = ref_Vec(x) cdef Vec XDvec = ref_Vec(xdot) cdef Mat Jmat = ref_Mat(J) cdef Mat Pmat = ref_Mat(P) cdef object context = Ts.get_attr('__ijacobian__') if context is None and ctx != NULL: context = ctx assert context is not None and type(context) is tuple # sanity check (jacobian, args, kargs) = context jacobian(Ts, toReal(t), Xvec, XDvec, toReal(a), Jmat, Pmat, *args, **kargs) return PETSC_SUCCESS cdef PetscErrorCode TS_IJacobianP( PetscTS ts, PetscReal t, PetscVec x, PetscVec xdot, PetscReal a, PetscMat J, void* ctx, ) except PETSC_ERR_PYTHON with gil: cdef TS Ts = ref_TS(ts) cdef Vec Xvec = ref_Vec(x) cdef Vec XDvec = ref_Vec(xdot) cdef Mat Jmat = ref_Mat(J) cdef object context = Ts.get_attr('__ijacobianp__') if context is None and ctx != NULL: context = ctx assert context is not None and type(context) is tuple # sanity check (jacobian, args, kargs) = context jacobian(Ts, toReal(t), Xvec, XDvec, toReal(a), Jmat, *args, **kargs) return PETSC_SUCCESS cdef PetscErrorCode TS_I2Function( PetscTS ts, PetscReal t, PetscVec x, PetscVec xdot, PetscVec xdotdot, PetscVec f, void* ctx, ) except PETSC_ERR_PYTHON with gil: cdef TS Ts = ref_TS(ts) cdef Vec Xvec = ref_Vec(x) cdef Vec XDvec = ref_Vec(xdot) cdef Vec XDDvec = ref_Vec(xdotdot) cdef Vec Fvec = ref_Vec(f) cdef object context = Ts.get_attr('__i2function__') if context is None and ctx != NULL: context = ctx assert context is not None and type(context) is tuple # sanity check (function, args, kargs) = context function(Ts, toReal(t), Xvec, XDvec, XDDvec, Fvec, *args, **kargs) return PETSC_SUCCESS cdef PetscErrorCode TS_I2Jacobian( PetscTS ts, PetscReal t, PetscVec x, PetscVec xdot, PetscVec xdotdot, PetscReal v, PetscReal a, PetscMat J, PetscMat P, void* ctx, ) except PETSC_ERR_PYTHON with gil: cdef TS Ts = ref_TS(ts) cdef Vec Xvec = ref_Vec(x) cdef Vec XDvec = ref_Vec(xdot) cdef Vec XDDvec = ref_Vec(xdotdot) cdef Mat Jmat = ref_Mat(J) cdef Mat Pmat = ref_Mat(P) cdef object context = Ts.get_attr('__i2jacobian__') if context is None and ctx != NULL: context = ctx assert context is not None and type(context) is tuple # sanity check (jacobian, args, kargs) = context jacobian(Ts, toReal(t), Xvec, XDvec, XDDvec, toReal(v), toReal(a), Jmat, Pmat, *args, **kargs) return PETSC_SUCCESS # ----------------------------------------------------------------------------- cdef PetscErrorCode TS_Monitor( PetscTS ts, PetscInt step, PetscReal time, PetscVec u, void* ctx, ) except PETSC_ERR_PYTHON with gil: cdef TS Ts = ref_TS(ts) cdef Vec Vu = ref_Vec(u) cdef object monitorlist = Ts.get_attr('__monitor__') if monitorlist is None: return PETSC_SUCCESS for (monitor, args, kargs) in monitorlist: monitor(Ts, toInt(step), toReal(time), Vu, *args, **kargs) return PETSC_SUCCESS # ----------------------------------------------------------------------------- cdef PetscErrorCode TS_EventHandler( PetscTS ts, PetscReal time, PetscVec u, PetscScalar fvalue[], void* ctx, ) except PETSC_ERR_PYTHON with gil: cdef TS Ts = ref_TS(ts) cdef Vec Vu = ref_Vec(u) cdef object context = Ts.get_attr('__eventhandler__') if context is None: return PETSC_SUCCESS (eventhandler, args, kargs) = context cdef PetscInt nevents = 0 CHKERR( TSGetNumEvents(ts, &nevents) ) cdef npy_intp s = nevents fvalue_array = PyArray_SimpleNewFromData(1, &s, NPY_PETSC_SCALAR, fvalue) eventhandler(Ts, toReal(time), Vu, fvalue_array, *args, **kargs) return PETSC_SUCCESS cdef PetscErrorCode TS_PostEvent( PetscTS ts, PetscInt nevents_zero, PetscInt events_zero[], PetscReal time, PetscVec u, PetscBool forward, void* ctx, ) except PETSC_ERR_PYTHON with gil: cdef TS Ts = ref_TS(ts) cdef Vec Vu = ref_Vec(u) cdef object context = Ts.get_attr('__postevent__') if context is None: return PETSC_SUCCESS (postevent, args, kargs) = context cdef npy_intp s = nevents_zero events_zero_array = PyArray_SimpleNewFromData(1, &s, NPY_PETSC_INT, events_zero) postevent(Ts, events_zero_array, toReal(time), Vu, toBool(forward), *args, **kargs) return PETSC_SUCCESS cdef PetscErrorCode TS_PreStep( PetscTS ts, ) except PETSC_ERR_PYTHON with gil: cdef TS Ts = ref_TS(ts) (prestep, args, kargs) = Ts.get_attr('__prestep__') prestep(Ts, *args, **kargs) return PETSC_SUCCESS cdef PetscErrorCode TS_PostStep( PetscTS ts, ) except PETSC_ERR_PYTHON with gil: cdef TS Ts = ref_TS(ts) (poststep, args, kargs) = Ts.get_attr('__poststep__') poststep(Ts, *args, **kargs) return PETSC_SUCCESS # ----------------------------------------------------------------------------- ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/src/petsc4py/PETSc/petscvec.pxi0000644000175000017500000006060314567251135020212 0ustar00balaybalay# -------------------------------------------------------------------- cdef extern from * nogil: ctypedef const char* PetscVecType "VecType" PetscVecType VECSEQ PetscVecType VECMPI PetscVecType VECSTANDARD PetscVecType VECSHARED PetscVecType VECSEQVIENNACL PetscVecType VECMPIVIENNACL PetscVecType VECVIENNACL PetscVecType VECSEQCUDA PetscVecType VECMPICUDA PetscVecType VECCUDA PetscVecType VECSEQHIP PetscVecType VECMPIHIP PetscVecType VECHIP PetscVecType VECNEST PetscVecType VECSEQKOKKOS PetscVecType VECMPIKOKKOS PetscVecType VECKOKKOS ctypedef enum PetscVecOption "VecOption": VEC_IGNORE_OFF_PROC_ENTRIES VEC_IGNORE_NEGATIVE_INDICES PetscErrorCode VecView(PetscVec,PetscViewer) PetscErrorCode VecDestroy(PetscVec*) PetscErrorCode VecCreate(MPI_Comm,PetscVec*) PetscErrorCode VecSetOptionsPrefix(PetscVec,char[]) PetscErrorCode VecAppendOptionsPrefix(PetscVec,char[]) PetscErrorCode VecGetOptionsPrefix(PetscVec,char*[]) PetscErrorCode VecSetFromOptions(PetscVec) PetscErrorCode VecSetUp(PetscVec) PetscErrorCode VecCreateSeq(MPI_Comm,PetscInt,PetscVec*) PetscErrorCode VecCreateSeqWithArray(MPI_Comm,PetscInt,PetscInt,PetscScalar[],PetscVec*) PetscErrorCode VecCreateSeqCUDAWithArrays(MPI_Comm,PetscInt,PetscInt,PetscScalar[],PetscScalar[],PetscVec*) PetscErrorCode VecCreateSeqHIPWithArrays(MPI_Comm,PetscInt,PetscInt,PetscScalar[],PetscScalar[],PetscVec*) PetscErrorCode VecCreateSeqViennaCLWithArrays(MPI_Comm,PetscInt,PetscInt,PetscScalar[],PetscScalar[],PetscVec*) PetscErrorCode VecCreateMPI(MPI_Comm,PetscInt,PetscInt,PetscVec*) PetscErrorCode VecCreateMPIWithArray(MPI_Comm,PetscInt,PetscInt,PetscInt,PetscScalar[],PetscVec*) PetscErrorCode VecCreateMPICUDAWithArrays(MPI_Comm,PetscInt,PetscInt,PetscInt,PetscScalar[],PetscScalar[],PetscVec*) PetscErrorCode VecCreateMPIHIPWithArrays(MPI_Comm,PetscInt,PetscInt,PetscInt,PetscScalar[],PetscScalar[],PetscVec*) PetscErrorCode VecCreateMPIViennaCLWithArrays(MPI_Comm,PetscInt,PetscInt,PetscInt,PetscScalar[],PetscScalar[],PetscVec*) PetscErrorCode VecCreateGhost(MPI_Comm,PetscInt,PetscInt,PetscInt,PetscInt[],PetscVec*) PetscErrorCode VecCreateGhostWithArray(MPI_Comm,PetscInt,PetscInt,PetscInt,PetscInt[],PetscScalar[],PetscVec*) PetscErrorCode VecCreateGhostBlock(MPI_Comm,PetscInt,PetscInt,PetscInt,PetscInt,PetscInt[],PetscVec*) PetscErrorCode VecCreateGhostBlockWithArray(MPI_Comm,PetscInt,PetscInt,PetscInt,PetscInt,PetscInt[],PetscScalar[],PetscVec*) PetscErrorCode VecCreateShared(MPI_Comm,PetscInt,PetscInt,PetscVec*) PetscErrorCode VecCreateNest(MPI_Comm,PetscInt,PetscIS[],PetscVec[],PetscVec*) PetscErrorCode VecGetType(PetscVec,PetscVecType*) PetscErrorCode VecSetType(PetscVec,PetscVecType) PetscErrorCode VecSetOption(PetscVec,PetscVecOption,PetscBool) PetscErrorCode VecSetSizes(PetscVec,PetscInt,PetscInt) PetscErrorCode VecGetSize(PetscVec,PetscInt*) PetscErrorCode VecGetLocalSize(PetscVec,PetscInt*) PetscErrorCode VecSetBlockSize(PetscVec,PetscInt) PetscErrorCode VecGetBlockSize(PetscVec,PetscInt*) PetscErrorCode VecGetOwnershipRange(PetscVec,PetscInt*,PetscInt*) PetscErrorCode VecGetOwnershipRanges(PetscVec,const PetscInt*[]) PetscErrorCode VecCreateLocalVector(PetscVec,PetscVec*) PetscErrorCode VecGetLocalVector(PetscVec,PetscVec) PetscErrorCode VecRestoreLocalVector(PetscVec,PetscVec) PetscErrorCode VecGetLocalVectorRead(PetscVec,PetscVec) PetscErrorCode VecRestoreLocalVectorRead(PetscVec,PetscVec) PetscErrorCode VecGetArrayWrite(PetscVec,PetscScalar*[]) PetscErrorCode VecRestoreArrayWrite(PetscVec,PetscScalar*[]) PetscErrorCode VecGetArrayRead(PetscVec,const PetscScalar*[]) PetscErrorCode VecRestoreArrayRead(PetscVec,const PetscScalar*[]) PetscErrorCode VecGetArray(PetscVec,PetscScalar*[]) PetscErrorCode VecRestoreArray(PetscVec,PetscScalar*[]) PetscErrorCode VecPlaceArray(PetscVec,PetscScalar[]) PetscErrorCode VecResetArray(PetscVec) PetscErrorCode VecGetArrayWriteAndMemType(PetscVec,PetscScalar*[],PetscMemType*) PetscErrorCode VecRestoreArrayWriteAndMemType(PetscVec,PetscScalar*[]) PetscErrorCode VecGetArrayReadAndMemType(PetscVec,const PetscScalar*[],PetscMemType*) PetscErrorCode VecRestoreArrayReadAndMemType(PetscVec,const PetscScalar*[]) PetscErrorCode VecGetArrayAndMemType(PetscVec,PetscScalar*[],PetscMemType*) PetscErrorCode VecRestoreArrayAndMemType(PetscVec,PetscScalar*[]) PetscErrorCode VecEqual(PetscVec,PetscVec,PetscBool*) PetscErrorCode VecLoad(PetscVec,PetscViewer) PetscErrorCode VecDuplicate(PetscVec,PetscVec*) PetscErrorCode VecCopy(PetscVec,PetscVec) PetscErrorCode VecFilter(PetscVec,PetscReal) PetscErrorCode VecDuplicateVecs(PetscVec,PetscInt,PetscVec*[]) PetscErrorCode VecDestroyVecs(PetscInt,PetscVec*[]) PetscErrorCode VecGetValues(PetscVec,PetscInt,PetscInt[],PetscScalar[]) PetscErrorCode VecSetValue(PetscVec,PetscInt,PetscScalar,PetscInsertMode) PetscErrorCode VecSetValues(PetscVec,PetscInt,const PetscInt[],const PetscScalar[],PetscInsertMode) PetscErrorCode VecSetValuesBlocked(PetscVec,PetscInt,const PetscInt[],const PetscScalar[],PetscInsertMode) PetscErrorCode VecSetLocalToGlobalMapping(PetscVec,PetscLGMap) PetscErrorCode VecGetLocalToGlobalMapping(PetscVec,PetscLGMap*) PetscErrorCode VecSetValueLocal(PetscVec,PetscInt,PetscScalar,PetscInsertMode) PetscErrorCode VecSetValuesLocal(PetscVec,PetscInt,const PetscInt[],const PetscScalar[],PetscInsertMode) PetscErrorCode VecSetValuesBlockedLocal(PetscVec,PetscInt,const PetscInt[],const PetscScalar[],PetscInsertMode) PetscErrorCode VecDot(PetscVec,PetscVec,PetscScalar*) PetscErrorCode VecDotBegin(PetscVec,PetscVec,PetscScalar*) PetscErrorCode VecDotEnd(PetscVec,PetscVec,PetscScalar*) PetscErrorCode VecTDot(PetscVec,PetscVec,PetscScalar*) PetscErrorCode VecTDotBegin(PetscVec,PetscVec,PetscScalar*) PetscErrorCode VecTDotEnd(PetscVec,PetscVec,PetscScalar*) PetscErrorCode VecMDot(PetscVec,PetscInt,PetscVec[],PetscScalar*) PetscErrorCode VecMDotBegin(PetscVec,PetscInt,PetscVec[],PetscScalar*) PetscErrorCode VecMDotEnd(PetscVec,PetscInt,PetscVec[],PetscScalar*) PetscErrorCode VecMTDot(PetscVec,PetscInt,PetscVec[],PetscScalar*) PetscErrorCode VecMTDotBegin(PetscVec,PetscInt,PetscVec[],PetscScalar*) PetscErrorCode VecMTDotEnd(PetscVec,PetscInt,PetscVec[],PetscScalar*) PetscErrorCode VecNorm(PetscVec,PetscNormType,PetscReal*) PetscErrorCode VecNormBegin(PetscVec,PetscNormType,PetscReal*) PetscErrorCode VecNormEnd(PetscVec,PetscNormType,PetscReal*) PetscErrorCode VecDotNorm2(PetscVec,PetscVec,PetscScalar*,PetscReal*) PetscErrorCode VecAssemblyBegin(PetscVec) PetscErrorCode VecAssemblyEnd(PetscVec) PetscErrorCode VecZeroEntries(PetscVec) PetscErrorCode VecConjugate(PetscVec) PetscErrorCode VecNormalize(PetscVec,PetscReal*) PetscErrorCode VecSum(PetscVec,PetscScalar*) PetscErrorCode VecMax(PetscVec,PetscInt*,PetscReal*) PetscErrorCode VecMin(PetscVec,PetscInt*,PetscReal*) PetscErrorCode VecScale(PetscVec,PetscScalar) PetscErrorCode VecCopy(PetscVec,PetscVec) PetscErrorCode VecSetRandom(PetscVec,PetscRandom) PetscErrorCode VecSet(PetscVec,PetscScalar) PetscErrorCode VecSwap(PetscVec,PetscVec) PetscErrorCode VecAXPY(PetscVec,PetscScalar,PetscVec) PetscErrorCode VecAXPBY(PetscVec,PetscScalar,PetscScalar,PetscVec) PetscErrorCode VecAYPX(PetscVec,PetscScalar,PetscVec) PetscErrorCode VecWAXPY(PetscVec,PetscScalar,PetscVec,PetscVec) PetscErrorCode VecMAXPY(PetscVec,PetscInt,PetscScalar[],PetscVec[]) PetscErrorCode VecPointwiseMax(PetscVec,PetscVec,PetscVec) PetscErrorCode VecPointwiseMaxAbs(PetscVec,PetscVec,PetscVec) PetscErrorCode VecPointwiseMin(PetscVec,PetscVec,PetscVec) PetscErrorCode VecPointwiseMult(PetscVec,PetscVec,PetscVec) PetscErrorCode VecPointwiseDivide(PetscVec,PetscVec,PetscVec) PetscErrorCode VecMaxPointwiseDivide(PetscVec,PetscVec,PetscReal*) PetscErrorCode VecShift(PetscVec,PetscScalar) PetscErrorCode VecFilter(PetscVec,PetscReal) PetscErrorCode VecReciprocal(PetscVec) PetscErrorCode VecPermute(PetscVec,PetscIS,PetscBool) PetscErrorCode VecExp(PetscVec) PetscErrorCode VecLog(PetscVec) PetscErrorCode VecSqrtAbs(PetscVec) PetscErrorCode VecAbs(PetscVec) PetscErrorCode VecStrideMin(PetscVec,PetscInt,PetscInt*,PetscReal*) PetscErrorCode VecStrideMax(PetscVec,PetscInt,PetscInt*,PetscReal*) PetscErrorCode VecStrideScale(PetscVec,PetscInt,PetscScalar) PetscErrorCode VecStrideGather(PetscVec,PetscInt,PetscVec,PetscInsertMode) PetscErrorCode VecStrideScatter(PetscVec,PetscInt,PetscVec,PetscInsertMode) PetscErrorCode VecStrideNorm(PetscVec,PetscInt,PetscNormType,PetscReal*) PetscErrorCode VecGhostGetLocalForm(PetscVec,PetscVec*) PetscErrorCode VecGhostRestoreLocalForm(PetscVec,PetscVec*) PetscErrorCode VecGhostUpdateBegin(PetscVec,PetscInsertMode,PetscScatterMode) PetscErrorCode VecGhostUpdateEnd(PetscVec,PetscInsertMode,PetscScatterMode) PetscErrorCode VecMPISetGhost(PetscVec,PetscInt,const PetscInt*) PetscErrorCode VecGetSubVector(PetscVec,PetscIS,PetscVec*) PetscErrorCode VecRestoreSubVector(PetscVec,PetscIS,PetscVec*) PetscErrorCode VecNestGetSubVecs(PetscVec,PetscInt*,PetscVec**) PetscErrorCode VecNestSetSubVecs(PetscVec,PetscInt,PetscInt*,PetscVec*) PetscErrorCode VecISAXPY(PetscVec,PetscIS,PetscScalar,PetscVec) PetscErrorCode VecISSet(PetscVec,PetscIS,PetscScalar) PetscErrorCode VecCUDAGetArrayRead(PetscVec,const PetscScalar*[]) PetscErrorCode VecCUDAGetArrayWrite(PetscVec,PetscScalar*[]) PetscErrorCode VecCUDAGetArray(PetscVec,PetscScalar*[]) PetscErrorCode VecCUDARestoreArrayRead(PetscVec,const PetscScalar*[]) PetscErrorCode VecCUDARestoreArrayWrite(PetscVec,PetscScalar*[]) PetscErrorCode VecCUDARestoreArray(PetscVec,PetscScalar*[]) PetscErrorCode VecHIPGetArrayRead(PetscVec,const PetscScalar*[]) PetscErrorCode VecHIPGetArrayWrite(PetscVec,PetscScalar*[]) PetscErrorCode VecHIPGetArray(PetscVec,PetscScalar*[]) PetscErrorCode VecHIPRestoreArrayRead(PetscVec,const PetscScalar*[]) PetscErrorCode VecHIPRestoreArrayWrite(PetscVec,PetscScalar*[]) PetscErrorCode VecHIPRestoreArray(PetscVec,PetscScalar*[]) PetscErrorCode VecBindToCPU(PetscVec,PetscBool) PetscErrorCode VecBoundToCPU(PetscVec,PetscBool*) PetscErrorCode VecGetOffloadMask(PetscVec,PetscOffloadMask*) PetscErrorCode VecViennaCLGetCLContext(PetscVec,Py_uintptr_t*) PetscErrorCode VecViennaCLGetCLQueue(PetscVec,Py_uintptr_t*) PetscErrorCode VecViennaCLGetCLMemRead(PetscVec,Py_uintptr_t*) PetscErrorCode VecViennaCLGetCLMemWrite(PetscVec,Py_uintptr_t*) PetscErrorCode VecViennaCLRestoreCLMemWrite(PetscVec) PetscErrorCode VecViennaCLGetCLMem(PetscVec,Py_uintptr_t*) PetscErrorCode VecViennaCLRestoreCLMem(PetscVec) PetscErrorCode VecCreateSeqCUDAWithArray(MPI_Comm,PetscInt,PetscInt,const PetscScalar*,PetscVec*) PetscErrorCode VecCreateMPICUDAWithArray(MPI_Comm,PetscInt,PetscInt,PetscInt,const PetscScalar*,PetscVec*) PetscErrorCode VecCreateSeqHIPWithArray(MPI_Comm,PetscInt,PetscInt,const PetscScalar*,PetscVec*) PetscErrorCode VecCreateMPIHIPWithArray(MPI_Comm,PetscInt,PetscInt,PetscInt,const PetscScalar*,PetscVec*) cdef extern from * nogil: # custom.h PetscErrorCode VecStrideSum(PetscVec,PetscInt,PetscScalar*) PetscErrorCode VecGetCurrentMemType(PetscVec,PetscMemType*) # -------------------------------------------------------------------- cdef inline Vec ref_Vec(PetscVec vec): cdef Vec ob = Vec() ob.vec = vec CHKERR( PetscINCREF(ob.obj) ) return ob # -------------------------------------------------------------------- # unary operations cdef Vec vec_pos(Vec self): cdef Vec vec = type(self)() CHKERR( VecDuplicate(self.vec, &vec.vec) ) CHKERR( VecCopy(self.vec, vec.vec) ) return vec cdef Vec vec_neg(Vec self): cdef Vec vec = vec_pos(self) CHKERR( VecScale(vec.vec, -1) ) return vec cdef Vec vec_abs(Vec self): cdef Vec vec = vec_pos(self) CHKERR( VecAbs(vec.vec) ) return vec # inplace binary operations cdef Vec vec_iadd(Vec self, other): cdef PetscScalar alpha = 1 cdef Vec vec if isinstance(other, Vec): alpha = 1; vec = other CHKERR( VecAXPY(self.vec, alpha, vec.vec) ) elif isinstance(other, (tuple, list)): other, vec = other alpha = asScalar(other) CHKERR( VecAXPY(self.vec, alpha, vec.vec) ) else: alpha = asScalar(other) CHKERR( VecShift(self.vec, alpha) ) return self cdef Vec vec_isub(Vec self, other): cdef PetscScalar alpha = 1 cdef Vec vec if isinstance(other, Vec): alpha = 1; vec = other CHKERR( VecAXPY(self.vec, -alpha, vec.vec) ) elif isinstance(other, (tuple, list)): other, vec = other alpha = asScalar(other) CHKERR( VecAXPY(self.vec, -alpha, vec.vec) ) else: alpha = asScalar(other) CHKERR( VecShift(self.vec, -alpha) ) return self cdef Vec vec_imul(Vec self, other): cdef PetscScalar alpha = 1 cdef Vec vec if isinstance(other, Vec): vec = other CHKERR( VecPointwiseMult(self.vec, self.vec, vec.vec) ) else: alpha = asScalar(other) CHKERR( VecScale(self.vec, alpha) ) return self cdef Vec vec_idiv(Vec self, other): cdef PetscScalar one = 1 cdef PetscScalar alpha = 1 cdef Vec vec if isinstance(other, Vec): vec = other CHKERR( VecPointwiseDivide(self.vec, self.vec, vec.vec) ) else: alpha = asScalar(other) CHKERR( VecScale(self.vec, one/alpha) ) return self # binary operations cdef Vec vec_add(Vec self, other): return vec_iadd(vec_pos(self), other) cdef Vec vec_sub(Vec self, other): return vec_isub(vec_pos(self), other) cdef Vec vec_mul(Vec self, other): return vec_imul(vec_pos(self), other) cdef Vec vec_div(Vec self, other): return vec_idiv(vec_pos(self), other) cdef object vec_matmul(Vec self, other): if isinstance(other, Vec): return self.dot(other) if isinstance(other, Mat): result = other.createVecRight() other.multTranspose(self, result) return result return NotImplemented # reflected binary operations cdef Vec vec_radd(Vec self, other): return vec_add(self, other) cdef Vec vec_rsub(Vec self, other): cdef Vec vec = vec_sub(self, other) CHKERR( VecScale(vec.vec, -1) ) return vec cdef Vec vec_rmul(Vec self, other): return vec_mul(self, other) cdef Vec vec_rdiv(Vec self, other): cdef Vec vec = vec_div(self, other) CHKERR( VecReciprocal(vec.vec) ) return vec # -------------------------------------------------------------------- cdef inline int Vec_Sizes(object size, object bsize, PetscInt *b, PetscInt *n, PetscInt *N) except -1: Sys_Sizes(size, bsize, b, n, N) return 0 # -------------------------------------------------------------------- ctypedef PetscErrorCode VecSetValuesFcn(PetscVec, PetscInt,const PetscInt*, const PetscScalar*,PetscInsertMode) cdef inline VecSetValuesFcn* vecsetvalues_fcn(int blocked, int local): cdef VecSetValuesFcn *setvalues = NULL if blocked and local: setvalues = VecSetValuesBlockedLocal elif blocked: setvalues = VecSetValuesBlocked elif local: setvalues = VecSetValuesLocal else: setvalues = VecSetValues return setvalues cdef inline int vecsetvalues(PetscVec V, object oi, object ov, object oim, int blocked, int local) except -1: # block size cdef PetscInt bs=1 if blocked: CHKERR( VecGetBlockSize(V, &bs) ) if bs < 1: bs = 1 # indices and values cdef PetscInt ni=0, nv=0 cdef PetscInt *i=NULL cdef PetscScalar *v=NULL cdef object tmp1 = iarray_i(oi, &ni, &i) cdef object tmp2 = iarray_s(ov, &nv, &v) if ni*bs != nv: raise ValueError( "incompatible array sizes: ni=%d, nv=%d, bs=%d" % (toInt(ni), toInt(nv), toInt(bs)) ) # VecSetValuesXXX function and insert mode cdef VecSetValuesFcn *setvalues = vecsetvalues_fcn(blocked, local) cdef PetscInsertMode addv = insertmode(oim) # actual call CHKERR( setvalues(V, ni, i, v, addv) ) return 0 cdef object vecgetvalues(PetscVec vec, object oindices, object values): cdef PetscInt ni=0, nv=0 cdef PetscInt *i=NULL cdef PetscScalar *v=NULL cdef object indices = iarray_i(oindices, &ni, &i) if values is None: values = empty_s(ni) values.shape = indices.shape values = oarray_s(values, &nv, &v) if (ni != nv): raise ValueError( ("incompatible array sizes: " "ni=%d, nv=%d") % (toInt(ni), toInt(nv))) CHKERR( VecGetValues(vec, ni, i, v) ) return values # -------------------------------------------------------------------- cdef inline _Vec_buffer vec_getbuffer_r(Vec self): cdef _Vec_buffer buf = _Vec_buffer(self) buf.readonly = 1 return buf cdef inline _Vec_buffer vec_getbuffer_w(Vec self): cdef _Vec_buffer buf = _Vec_buffer(self) buf.readonly = 0 return buf cdef inline ndarray vec_getarray_r(Vec self): return asarray(vec_getbuffer_r(self)) cdef inline ndarray vec_getarray_w(Vec self): return asarray(vec_getbuffer_w(self)) cdef inline int vec_setarray(Vec self, object o) except -1: cdef PetscInt na=0, nv=0, i=0 cdef PetscScalar *va=NULL, *vv=NULL cdef ndarray ary = iarray_s(o, &na, &va) CHKERR( VecGetLocalSize(self.vec, &nv) ) if (na != nv) and PyArray_NDIM(ary) > 0: raise ValueError( "array size %d incompatible with vector local size %d" % (toInt(na), toInt(nv)) ) CHKERR( VecGetArray(self.vec, &vv) ) try: if PyArray_NDIM(ary) == 0: for i from 0 <= i < nv: vv[i] = va[0] else: CHKERR( PetscMemcpy(vv, va, nv*sizeof(PetscScalar)) ) finally: CHKERR( VecRestoreArray(self.vec, &vv) ) return 0 cdef object vec_getitem(Vec self, object i): cdef PetscInt N=0 if i is Ellipsis: return asarray(self) if isinstance(i, slice): CHKERR( VecGetSize(self.vec, &N) ) start, stop, stride = i.indices(toInt(N)) i = arange(start, stop, stride) return vecgetvalues(self.vec, i, None) cdef int vec_setitem(Vec self, object i, object v) except -1: cdef PetscInt N=0 if i is Ellipsis: return vec_setarray(self, v) if isinstance(i, slice): CHKERR( VecGetSize(self.vec, &N) ) start, stop, stride = i.indices(toInt(N)) i = arange(start, stop, stride) vecsetvalues(self.vec, i, v, None, 0, 0) return 0 cdef vec_get_dlpack_ctx(Vec self): cdef object ctx0 = self.get_attr('__dltensor_ctx__') cdef PetscInt n = 0 cdef int64_t ndim = 1 cdef int64_t* shape_arr = NULL cdef int64_t* strides_arr = NULL cdef object s1 = None cdef object s2 = None cdef PetscInt devId = 0 cdef PetscMemType mtype = PETSC_MEMTYPE_HOST if ctx0 is None: # First time in, create a linear memory view s1 = oarray_p(empty_p(ndim), NULL, &shape_arr) s2 = oarray_p(empty_p(ndim), NULL, &strides_arr) CHKERR( VecGetLocalSize(self.vec, &n) ) shape_arr[0] = n strides_arr[0] = 1 else: (_, _, ndim, s1, s2) = ctx0 devType_ = { PETSC_MEMTYPE_HOST : kDLCPU, PETSC_MEMTYPE_CUDA : kDLCUDA, PETSC_MEMTYPE_HIP : kDLROCM } CHKERR( VecGetCurrentMemType(self.vec, &mtype) ) dtype = devType_.get(mtype, kDLCPU) if dtype != kDLCPU: CHKERR( PetscObjectGetDeviceId(self.vec, &devId) ) ctx0 = (dtype, devId, ndim, s1, s2) self.set_attr('__dltensor_ctx__', ctx0) return ctx0 # -------------------------------------------------------------------- cdef int Vec_AcquireArray(PetscVec v, PetscScalar *a[], int ro) except -1 nogil: if ro: CHKERR( VecGetArrayRead(v, a) ) else: CHKERR( VecGetArray(v, a) ) return 0 cdef int Vec_ReleaseArray(PetscVec v, PetscScalar *a[], int ro) except -1 nogil: if ro: CHKERR( VecRestoreArrayRead(v, a) ) else: CHKERR( VecRestoreArray(v, a) ) return 0 cdef class _Vec_buffer: cdef PetscVec vec cdef PetscInt size cdef PetscScalar *data cdef bint readonly cdef bint hasarray def __cinit__(self, Vec vec, bint readonly=0): cdef PetscVec v = vec.vec CHKERR( PetscINCREF(&v) ) self.vec = v self.size = 0 self.data = NULL self.readonly = 1 if readonly else 0 self.hasarray = 0 def __dealloc__(self): if self.hasarray and self.vec != NULL: Vec_ReleaseArray(self.vec, &self.data, self.readonly) CHKERR( VecDestroy(&self.vec) ) # cdef int acquire(self) except -1 nogil: if not self.hasarray and self.vec != NULL: CHKERR( VecGetLocalSize(self.vec, &self.size) ) Vec_AcquireArray(self.vec, &self.data, self.readonly) self.hasarray = 1 return 0 cdef int release(self) except -1 nogil: if self.hasarray and self.vec != NULL: self.size = 0 Vec_ReleaseArray(self.vec, &self.data, self.readonly) self.hasarray = 0 return 0 # buffer interface (PEP 3118) cdef int acquirebuffer(self, Py_buffer *view, int flags) except -1: self.acquire() PyPetscBuffer_FillInfo(view, self.data, self.size, c's', self.readonly, flags) view.obj = self return 0 cdef int releasebuffer(self, Py_buffer *view) except -1: PyPetscBuffer_Release(view) self.release() return 0 def __getbuffer__(self, Py_buffer *view, int flags): self.acquirebuffer(view, flags) def __releasebuffer__(self, Py_buffer *view): self.releasebuffer(view) # 'with' statement (PEP 343) cdef object enter(self): self.acquire() return asarray(self) cdef object exit(self): self.release() return None def __enter__(self): return self.enter() def __exit__(self, *exc): return self.exit() # buffer interface (legacy) cdef Py_ssize_t getbuffer(self, void **p) except -1: cdef PetscInt n = 0 if p != NULL: self.acquire() p[0] = self.data n = self.size elif self.vec != NULL: CHKERR( VecGetLocalSize(self.vec, &n) ) return (n*sizeof(PetscScalar)) def __getsegcount__(self, Py_ssize_t *lenp): if lenp != NULL: lenp[0] = self.getbuffer(NULL) return 1 def __getreadbuffer__(self, Py_ssize_t idx, void **p): if idx != 0: raise SystemError( "accessing non-existent buffer segment") return self.getbuffer(p) def __getwritebuffer__(self, Py_ssize_t idx, void **p): if idx != 0: raise SystemError( "accessing non-existent buffer segment") if self.readonly: raise TypeError( "Object is not writable.") return self.getbuffer(p) # NumPy array interface (legacy) property __array_interface__: def __get__(self): cdef PetscInt n = 0 if self.vec != NULL: CHKERR( VecGetLocalSize(self.vec, &n) ) cdef object size = toInt(n) cdef dtype descr = PyArray_DescrFromType(NPY_PETSC_SCALAR) cdef str typestr = "=%c%d" % (descr.kind, descr.itemsize) return dict(version=3, data=self, shape=(size,), typestr=typestr) # -------------------------------------------------------------------- cdef class _Vec_LocalForm: "Context manager for `Vec` local form" cdef Vec gvec cdef Vec lvec def __init__(self, Vec gvec): self.gvec = gvec self.lvec = Vec() def __enter__(self): cdef PetscVec gvec = self.gvec.vec CHKERR( VecGhostGetLocalForm(gvec, &self.lvec.vec) ) return self.lvec def __exit__(self, *exc): cdef PetscVec gvec = self.gvec.vec CHKERR( VecGhostRestoreLocalForm(gvec, &self.lvec.vec) ) self.lvec.vec = NULL ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/src/petsc4py/PETSc/petscvwr.pxi0000644000175000017500000001533014567251135020250 0ustar00balaybalaycdef extern from * nogil: ctypedef const char* PetscViewerType PetscViewerType PETSCVIEWERSOCKET PetscViewerType PETSCVIEWERASCII PetscViewerType PETSCVIEWERBINARY PetscViewerType PETSCVIEWERSTRING PetscViewerType PETSCVIEWERDRAW PetscViewerType PETSCVIEWERVU PetscViewerType PETSCVIEWERMATHEMATICA PetscViewerType PETSCVIEWERHDF5 PetscViewerType PETSCVIEWERVTK PetscViewerType PETSCVIEWERMATLAB PetscViewerType PETSCVIEWERSAWS PetscViewerType PETSCVIEWERGLVIS PetscViewerType PETSCVIEWERADIOS PetscViewerType PETSCVIEWEREXODUSII ctypedef enum PetscViewerFormat: PETSC_VIEWER_DEFAULT PETSC_VIEWER_ASCII_MATLAB PETSC_VIEWER_ASCII_MATHEMATICA PETSC_VIEWER_ASCII_IMPL PETSC_VIEWER_ASCII_INFO PETSC_VIEWER_ASCII_INFO_DETAIL PETSC_VIEWER_ASCII_COMMON PETSC_VIEWER_ASCII_SYMMODU PETSC_VIEWER_ASCII_INDEX PETSC_VIEWER_ASCII_DENSE PETSC_VIEWER_ASCII_MATRIXMARKET PETSC_VIEWER_ASCII_VTK_DEPRECATED PETSC_VIEWER_ASCII_VTK_CELL_DEPRECATED PETSC_VIEWER_ASCII_VTK_COORDS_DEPRECATED PETSC_VIEWER_ASCII_PCICE PETSC_VIEWER_ASCII_PYTHON PETSC_VIEWER_ASCII_FACTOR_INFO PETSC_VIEWER_ASCII_LATEX PETSC_VIEWER_ASCII_XML PETSC_VIEWER_ASCII_GLVIS PETSC_VIEWER_ASCII_CSV PETSC_VIEWER_DRAW_BASIC PETSC_VIEWER_DRAW_LG PETSC_VIEWER_DRAW_LG_XRANGE PETSC_VIEWER_DRAW_CONTOUR PETSC_VIEWER_DRAW_PORTS PETSC_VIEWER_VTK_VTS PETSC_VIEWER_VTK_VTR PETSC_VIEWER_VTK_VTU PETSC_VIEWER_BINARY_MATLAB PETSC_VIEWER_NATIVE PETSC_VIEWER_HDF5_PETSC PETSC_VIEWER_HDF5_VIZ PETSC_VIEWER_HDF5_XDMF PETSC_VIEWER_HDF5_MAT PETSC_VIEWER_NOFORMAT PETSC_VIEWER_LOAD_BALANCE PETSC_VIEWER_FAILED ctypedef enum PetscFileMode: PETSC_FILE_MODE_READ "FILE_MODE_READ" PETSC_FILE_MODE_WRITE "FILE_MODE_WRITE" PETSC_FILE_MODE_APPEND "FILE_MODE_APPEND" PETSC_FILE_MODE_UPDATE "FILE_MODE_UPDATE" PETSC_FILE_MODE_APPEND_UPDATE "FILE_MODE_APPEND_UPDATE" enum: PETSC_DRAW_FULL_SIZE enum: PETSC_DRAW_HALF_SIZE enum: PETSC_DRAW_THIRD_SIZE enum: PETSC_DRAW_QUARTER_SIZE PetscErrorCode PetscViewerView(PetscViewer,PetscViewer) PetscErrorCode PetscViewerDestroy(PetscViewer*) PetscErrorCode PetscViewerCreate(MPI_Comm,PetscViewer*) PetscErrorCode PetscViewerSetType(PetscViewer,PetscViewerType) PetscErrorCode PetscViewerGetType(PetscViewer,PetscViewerType*) PetscErrorCode PetscViewerSetOptionsPrefix(PetscViewer,char[]) PetscErrorCode PetscViewerAppendOptionsPrefix(PetscViewer,char[]) PetscErrorCode PetscViewerGetOptionsPrefix(PetscViewer,char*[]) PetscErrorCode PetscViewerSetFromOptions(PetscViewer) PetscErrorCode PetscViewerSetUp(PetscViewer) PetscErrorCode PetscViewerASCIIOpen(MPI_Comm,char[],PetscViewer*) PetscErrorCode PetscViewerBinaryCreate(MPI_Comm comm,PetscViewer*) PetscErrorCode PetscViewerBinaryOpen(MPI_Comm,char[],PetscFileMode,PetscViewer*) PetscErrorCode PetscViewerDrawOpen(MPI_Comm,char[],char[],int,int,int,int,PetscViewer*) PetscErrorCode PetscViewerBinarySetUseMPIIO(PetscViewer,PetscBool) PetscErrorCode PetscViewerSetFormat(PetscViewer,PetscViewerFormat) PetscErrorCode PetscViewerGetFormat(PetscViewer,PetscViewerFormat*) PetscErrorCode PetscViewerPushFormat(PetscViewer,PetscViewerFormat) PetscErrorCode PetscViewerPopFormat(PetscViewer) PetscErrorCode PetscViewerGetSubViewer(PetscViewer,MPI_Comm,PetscViewer*) PetscErrorCode PetscViewerRestoreSubViewer(PetscViewer,MPI_Comm,PetscViewer*) PetscErrorCode PetscViewerASCIISetTab(PetscViewer,PetscInt) PetscErrorCode PetscViewerASCIIGetTab(PetscViewer,PetscInt*) PetscErrorCode PetscViewerASCIIAddTab(PetscViewer,PetscInt) PetscErrorCode PetscViewerASCIISubtractTab(PetscViewer,PetscInt) PetscErrorCode PetscViewerASCIIPushSynchronized(PetscViewer) PetscErrorCode PetscViewerASCIIPopSynchronized(PetscViewer) PetscErrorCode PetscViewerASCIIPushTab(PetscViewer) PetscErrorCode PetscViewerASCIIPopTab(PetscViewer) PetscErrorCode PetscViewerASCIIUseTabs(PetscViewer,PetscBool) PetscErrorCode PetscViewerASCIIPrintf(PetscViewer,const char[],...) PetscErrorCode PetscViewerStringSPrintf(PetscViewer,char[],...) PetscErrorCode PetscViewerASCIISynchronizedPrintf(PetscViewer,const char[],...) PetscErrorCode PetscViewerFileGetName(PetscViewer,char*[]) PetscErrorCode PetscViewerFileSetName(PetscViewer,char[]) PetscErrorCode PetscViewerFileGetMode(PetscViewer,PetscFileMode*) PetscErrorCode PetscViewerFileSetMode(PetscViewer,PetscFileMode) PetscErrorCode PetscViewerFlush(PetscViewer) PetscErrorCode PetscViewerDrawClear(PetscViewer) PetscErrorCode PetscViewerDrawSetInfo(PetscViewer,char[],char[],int,int,int,int) PetscErrorCode PetscViewerHDF5PushTimestepping(PetscViewer) PetscErrorCode PetscViewerHDF5PopTimestepping(PetscViewer) PetscErrorCode PetscViewerHDF5GetTimestep(PetscViewer,PetscInt*) PetscErrorCode PetscViewerHDF5SetTimestep(PetscViewer,PetscInt) PetscErrorCode PetscViewerHDF5IncrementTimestep(PetscViewer) PetscErrorCode PetscViewerHDF5PushGroup(PetscViewer,char[]) PetscErrorCode PetscViewerHDF5PopGroup(PetscViewer) PetscErrorCode PetscViewerHDF5GetGroup(PetscViewer,char[],char*[]) PetscViewer PETSC_VIEWER_STDOUT_(MPI_Comm) except? NULL PetscViewer PETSC_VIEWER_STDOUT_SELF PetscViewer PETSC_VIEWER_STDOUT_WORLD PetscViewer PETSC_VIEWER_STDERR_(MPI_Comm) except? NULL PetscViewer PETSC_VIEWER_STDERR_SELF PetscViewer PETSC_VIEWER_STDERR_WORLD PetscViewer PETSC_VIEWER_BINARY_(MPI_Comm) except? NULL PetscViewer PETSC_VIEWER_BINARY_SELF PetscViewer PETSC_VIEWER_BINARY_WORLD PetscViewer PETSC_VIEWER_DRAW_(MPI_Comm) except? NULL PetscViewer PETSC_VIEWER_DRAW_SELF PetscViewer PETSC_VIEWER_DRAW_WORLD # --- cdef inline PetscFileMode filemode(object mode) except (-1): if mode is None: return PETSC_FILE_MODE_READ if isinstance(mode, str): if mode == 'r' : return PETSC_FILE_MODE_READ elif mode == 'w' : return PETSC_FILE_MODE_WRITE elif mode == 'a' : return PETSC_FILE_MODE_APPEND elif mode == 'r+' : return PETSC_FILE_MODE_UPDATE elif mode == 'w+' : return PETSC_FILE_MODE_UPDATE elif mode == 'a+' : return PETSC_FILE_MODE_APPEND_UPDATE elif mode == 'u' : return PETSC_FILE_MODE_UPDATE elif mode == 'au' : return PETSC_FILE_MODE_APPEND_UPDATE elif mode == 'ua' : return PETSC_FILE_MODE_APPEND_UPDATE return mode ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/src/petsc4py/PETSc/typing.pxi0000644000175000017500000000325714567251135017712 0ustar00balaybalaycdef Any cdef Self cdef Union cdef Literal cdef Optional cdef NoReturn cdef Callable cdef Hashable cdef Iterable cdef Iterator cdef Sequence cdef Mapping cdef PathLike cdef Scalar cdef ArrayInt cdef ArrayReal cdef ArrayComplex cdef ArrayScalar cdef DimsSpec cdef AccessModeSpec cdef InsertModeSpec cdef ScatterModeSpec cdef LayoutSizeSpec cdef NormTypeSpec # --- Mat --- cdef MatAssemblySpec cdef MatSizeSpec cdef MatBlockSizeSpec cdef CSRIndicesSpec cdef CSRSpec cdef NNZSpec # --- MatNullSpace --- cdef MatNullFunction # --- DM --- cdef DMCoarsenHookFunction cdef DMRestrictHookFunction # --- KSP --- cdef KSPRHSFunction cdef KSPOperatorsFunction cdef KSPConvergenceTestFunction cdef KSPMonitorFunction # --- TS --- cdef TSRHSFunction cdef TSRHSJacobian cdef TSRHSJacobianP cdef TSIFunction cdef TSIJacobian cdef TSIJacobianP cdef TSI2Function cdef TSI2Jacobian cdef TSMonitorFunction cdef TSEventHandlerFunction cdef TSPostEventFunction cdef TSPreStepFunction cdef TSPostStepFunction # --- SNES --- cdef SNESMonitorFunction cdef SNESObjFunction cdef SNESFunction cdef SNESJacobianFunction cdef SNESGuessFunction cdef SNESUpdateFunction cdef SNESLSPreFunction cdef SNESNGSFunction cdef SNESConvergedFunction # --- TAO --- cdef TAOObjectiveFunction cdef TAOGradientFunction cdef TAOObjectiveGradientFunction cdef TAOHessianFunction cdef TAOUpdateFunction cdef TAOMonitorFunction cdef TAOConvergedFunction cdef TAOJacobianFunction cdef TAOResidualFunction cdef TAOJacobianResidualFunction cdef TAOVariableBoundsFunction cdef TAOConstraintsFunction cdef TAOLSObjectiveFunction cdef TAOLSGradientFunction cdef TAOLSObjectiveGradientFunction # --- MPI --- cdef Intracomm cdef Datatype cdef Op ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/src/petsc4py/PETSc.pxd0000644000175000017500000001741614567251135016375 0ustar00balaybalay# Author: Lisandro Dalcin # Contact: dalcinl@gmail.com # -------------------------------------------------------------------- cdef extern from "": ctypedef struct _p_MPI_Comm ctypedef _p_MPI_Comm* MPI_Comm ctypedef struct _p_MPI_Op ctypedef _p_MPI_Op* MPI_Op ctypedef struct _p_MPI_Datatype ctypedef _p_MPI_Datatype* MPI_Datatype ctypedef struct _p_PetscObject ctypedef _p_PetscObject* PetscObject struct _p_PetscViewer ctypedef _p_PetscViewer* PetscViewer struct _p_PetscRandom ctypedef _p_PetscRandom* PetscRandom struct _n_PetscDevice ctypedef _n_PetscDevice* PetscDevice struct _p_PetscDeviceContext ctypedef _p_PetscDeviceContext* PetscDeviceContext struct _p_IS ctypedef _p_IS* PetscIS "IS" struct _p_ISLocalToGlobalMapping ctypedef _p_ISLocalToGlobalMapping* PetscLGMap "ISLocalToGlobalMapping" struct _p_PetscSF ctypedef _p_PetscSF* PetscSF "PetscSF" struct _p_Vec ctypedef _p_Vec* PetscVec "Vec" struct _p_VecScatter ctypedef _p_VecScatter* PetscScatter "VecScatter" struct _p_PetscSpace ctypedef _p_PetscSpace* PetscSpace "PetscSpace" struct _p_PetscDualSpace ctypedef _p_PetscDualSpace* PetscDualSpace "PetscDualSpace" struct _p_PetscFE ctypedef _p_PetscFE* PetscFE "PetscFE" struct _p_PetscQuadrature ctypedef _p_PetscQuadrature* PetscQuadrature "PetscQuadrature" struct _p_DMLabel ctypedef _p_DMLabel* PetscDMLabel "DMLabel" struct _p_PetscSection ctypedef _p_PetscSection* PetscSection struct _p_Mat ctypedef _p_Mat* PetscMat "Mat" struct _p_MatPartitioning ctypedef _p_Mat* PetscMatPartitioning "MatPartitioning" struct _p_MatNullSpace ctypedef _p_MatNullSpace* PetscNullSpace "MatNullSpace" struct _p_PC ctypedef _p_PC* PetscPC "PC" struct _p_KSP ctypedef _p_KSP* PetscKSP "KSP" struct _p_SNES ctypedef _p_SNES* PetscSNES "SNES" struct _p_SNESLineSearch ctypedef _p_SNESLineSearch* PetscSNESLineSearch "SNESLineSearch" struct _p_TS ctypedef _p_TS* PetscTS "TS" struct _p_TAO "_p_Tao" ctypedef _p_TAO* PetscTAO "Tao" struct _p_TAOLineSearch "_p_TaoLineSearch" ctypedef _p_TAOLineSearch* PetscTAOLineSearch "TaoLineSearch" struct _p_AO ctypedef _p_AO* PetscAO "AO" struct _p_DM ctypedef _p_DM* PetscDM "DM" struct _p_DMPlexTransform ctypedef _p_DMPlexTransform* PetscDMPlexTransform "DMPlexTransform" struct _p_PetscDS ctypedef _p_PetscDS* PetscDS struct _p_PetscPartitioner ctypedef _p_PetscPartitioner* PetscPartitioner "PetscPartitioner" # -------------------------------------------------------------------- ctypedef public api class Comm [ type PyPetscComm_Type, object PyPetscCommObject, ]: cdef MPI_Comm comm cdef int isdup cdef object base ctypedef public api class Object [ type PyPetscObject_Type, object PyPetscObjectObject, ]: cdef __weakref__ cdef __dummy__ cdef PetscObject oval cdef PetscObject *obj cdef object get_attr(self, char name[]) cdef object set_attr(self, char name[], object attr) cdef object get_dict(self) ctypedef public api class Viewer(Object) [ type PyPetscViewer_Type, object PyPetscViewerObject, ]: cdef PetscViewer vwr ctypedef public api class Random(Object) [ type PyPetscRandom_Type, object PyPetscRandomObject, ]: cdef PetscRandom rnd ctypedef public api class Device [ type PyPetscDevice_Type, object PyPetscDeviceObject, ]: cdef PetscDevice device cdef object __weakref__ ctypedef public api class DeviceContext(Object) [ type PyPetscDeviceContext_Type, object PyPetscDeviceContextObject, ]: cdef PetscDeviceContext dctx ctypedef public api class IS(Object) [ type PyPetscIS_Type, object PyPetscISObject, ]: cdef PetscIS iset ctypedef public api class LGMap(Object) [ type PyPetscLGMap_Type, object PyPetscLGMapObject, ]: cdef PetscLGMap lgm ctypedef public api class SF(Object) [ type PyPetscSF_Type, object PyPetscSFObject, ]: cdef PetscSF sf ctypedef public api class Vec(Object) [ type PyPetscVec_Type, object PyPetscVecObject, ]: cdef PetscVec vec ctypedef public api class Space(Object) [ type PyPetscSpace_Type, object PyPetscSpaceObject, ]: cdef PetscSpace space ctypedef public api class DualSpace(Object) [ type PyPetscDualSpace_Type, object PyPetscDualSpaceObject, ]: cdef PetscDualSpace dualspace ctypedef public api class FE(Object) [ type PyPetscFE_Type, object PyPetscFEObject, ]: cdef PetscFE fe ctypedef public api class Quad(Object) [ type PyPetscQuad_Type, object PyPetscQuadObject, ]: cdef PetscQuadrature quad ctypedef public api class Scatter(Object) [ type PyPetscScatter_Type, object PyPetscScatterObject, ]: cdef PetscScatter sct ctypedef public api class Section(Object) [ type PyPetscSection_Type, object PyPetscSectionObject, ]: cdef PetscSection sec ctypedef public api class Mat(Object) [ type PyPetscMat_Type, object PyPetscMatObject, ]: cdef PetscMat mat ctypedef public api class MatPartitioning(Object) [ type PyPetscMatPartitioning_Type, object PyPetscMatPartitioningObject, ]: cdef PetscMatPartitioning part ctypedef public api class NullSpace(Object) [ type PyPetscNullSpace_Type, object PyPetscNullSpaceObject, ]: cdef PetscNullSpace nsp ctypedef public api class PC(Object) [ type PyPetscPC_Type, object PyPetscPCObject, ]: cdef PetscPC pc ctypedef public api class KSP(Object) [ type PyPetscKSP_Type, object PyPetscKSPObject, ]: cdef PetscKSP ksp ctypedef public api class SNES(Object) [ type PyPetscSNES_Type, object PyPetscSNESObject, ]: cdef PetscSNES snes ctypedef public api class TS(Object) [ type PyPetscTS_Type, object PyPetscTSObject, ]: cdef PetscTS ts ctypedef public api class TAO(Object) [ type PyPetscTAO_Type, object PyPetscTAOObject, ]: cdef PetscTAO tao ctypedef public api class TAOLineSearch(Object) [ type PyPetscTAOLineSearch_Type, object PyPetscTAOLineSearchObject, ]: cdef PetscTAOLineSearch taols ctypedef public api class AO(Object) [ type PyPetscAO_Type, object PyPetscAOObject, ]: cdef PetscAO ao ctypedef public api class DM(Object) [ type PyPetscDM_Type, object PyPetscDMObject, ]: cdef PetscDM dm ctypedef public api class DMPlexTransform(Object) [ type PyPetscDMPlexTransform_Type, object PyPetscDMPlexTransformObject, ]: cdef PetscDMPlexTransform tr ctypedef public api class DS(Object) [ type PyPetscDS_Type, object PyPetscDSObject, ]: cdef PetscDS ds ctypedef public api class Partitioner(Object) [ type PyPetscPartitioner_Type, object PyPetscPartitionerObject, ]: cdef PetscPartitioner part ctypedef public api class DMLabel(Object) [ type PyPetscDMLabel_Type, object PyPetscDMLabelObject, ]: cdef PetscDMLabel dmlabel # -------------------------------------------------------------------- cdef MPI_Comm GetComm(object, MPI_Comm) except * cdef MPI_Comm GetCommDefault() cdef int PyPetscType_Register(int, type) except -1 cdef type PyPetscType_Lookup(int) # -------------------------------------------------------------------- cdef extern from * nogil: ctypedef enum PetscErrorCode: PETSC_SUCCESS PETSC_ERR_PLIB PETSC_ERR_SUP PETSC_ERR_USER PETSC_ERR_MEM PETSC_ERR_MPI PETSC_ERR_PYTHON ctypedef enum PetscErrorType: PETSC_ERROR_INITIAL PETSC_ERROR_REPEAT cdef PetscErrorCode CHKERR(PetscErrorCode) except PETSC_ERR_PYTHON nogil ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/src/petsc4py/PETSc.py0000644000175000017500000000022014567251135016213 0ustar00balaybalayARCH = None from petsc4py.lib import ImportPETSc # noqa: E402 PETSc = ImportPETSc(ARCH) PETSc._initialize() del PETSc del ImportPETSc del ARCH ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/src/petsc4py/PETSc.pyx0000644000175000017500000000072314567251135016413 0ustar00balaybalay#cython: language_level=3str #cython: embedsignature=True #cython: embedsignature.format=python #cython: annotation_typing=False #cython: cdivision=True #cython: auto_pickle=False #cython: always_allow_keywords=True #cython: allow_none_for_extension_args=False #cython: autotestdict=False #cython: warn.multiple_declarators=False #cython: optimize.use_switch=False #cython: binding=False #from __future__ import annotations cimport cython include "PETSc/PETSc.pyx" ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/src/petsc4py/__init__.pxd0000644000175000017500000000007014567251135017202 0ustar00balaybalay# Author: Lisandro Dalcin # Contact: dalcinl@gmail.com ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/src/petsc4py/__init__.py0000644000175000017500000000452614567251135017051 0ustar00balaybalay# Author: Lisandro Dalcin # Contact: dalcinl@gmail.com """The PETSc for Python package. This package is an interface to PETSc libraries. PETSc_ (the Portable, Extensible Toolkit for Scientific Computation) is a suite of data structures and routines for the scalable (parallel) solution of scientific applications modeled by partial differential equations. It employs the MPI_ standard for all message-passing communications. .. _PETSc: https://petsc.org .. _MPI: https://www.mpi-forum.org """ __author__ = 'Lisandro Dalcin' __version__ = '3.20.5' __credits__ = 'PETSc Team ' def init(args=None, arch=None, comm=None): """Initialize PETSc. Parameters ---------- args Command-line arguments, usually the `sys.argv` list arch Specific configuration to use comm MPI commmunicator Notes ----- This function should be called only once, typically at the very beginning of the bootstrap script of an application. """ import petsc4py.lib PETSc = petsc4py.lib.ImportPETSc(arch) args = petsc4py.lib.getInitArgs(args) PETSc._initialize(args, comm) def get_include(): """Return the directory in the package that contains header files. Extension modules that need to compile against petsc4py should use this function to locate the appropriate include directory. Example ------- Using Python distutils or NumPy distutils:: import petsc4py Extension('extension_name', ... include_dirs=[..., petsc4py.get_include()]) """ from os.path import dirname, join return join(dirname(__file__), 'include') def get_config(): """Return a dictionary with information about PETSc.""" import os import sys if sys.version_info[0] >= 3: from io import StringIO from configparser import ConfigParser else: from StringIO import StringIO from ConfigParser import ConfigParser pgkdir = os.path.dirname(__file__) filename = os.path.join(pgkdir, 'lib', 'petsc.cfg') with open(filename) as fp: stream = StringIO("[petsc]\n"+fp.read()) parser = ConfigParser() parser.optionxform = str if sys.version_info[0] >= 3: parser.read_file(stream, filename) else: parser.readfp(stream, filename) return dict(parser.items('petsc')) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/src/petsc4py/__init__.pyi0000644000175000017500000000041514567251135017213 0ustar00balaybalayfrom typing import Union from mpi4py.MPI import Intracomm __version__: str = ... def init(args: Union[str,list[str]] | None = ..., arch: str | None = ..., comm: Intracomm | None = ...) -> None: ... def get_include() -> str: ... def get_config() -> dict[str, str]: ... ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/src/petsc4py/__main__.py0000644000175000017500000000402114567251135017020 0ustar00balaybalay# Author: Lisandro Dalcin # Contact: dalcinl@gmail.com """ Command line access to the PETSc Options Database. This module provides command line access to PETSc Options Database. It outputs a listing of the many PETSc options indicating option names, default values and descriptions. Usage:: $ python -m petsc4py [vec|mat|pc|ksp|snes|ts|tao] [] """ def help(args=None): import shlex import sys # program name try: prog = sys.argv[0] except Exception: prog = getattr(sys, 'executable', 'python') # arguments if args is None: args = sys.argv[1:] elif isinstance(args, str): args = shlex.split(args) else: args = [str(a) for a in args] # import and initialize import petsc4py petsc4py.init([prog, '-help'] + args) from petsc4py import PETSc # help dispatcher COMM = PETSc.COMM_SELF if 'vec' in args: vec = PETSc.Vec().create(comm=COMM) vec.setSizes(0) vec.setFromOptions() vec.destroy() if 'mat' in args: mat = PETSc.Mat().create(comm=COMM) mat.setSizes([0, 0]) mat.setFromOptions() mat.destroy() if 'pc' in args: pc = PETSc.PC().create(comm=COMM) pc.setFromOptions() pc.destroy() if 'ksp' in args: ksp = PETSc.KSP().create(comm=COMM) ksp.setFromOptions() ksp.destroy() if 'snes' in args: snes = PETSc.SNES().create(comm=COMM) snes.setFromOptions() snes.destroy() if 'ts' in args: ts = PETSc.TS().create(comm=COMM) ts.setFromOptions() ts.destroy() if 'tao' in args: tao = PETSc.TAO().create(comm=COMM) tao.setFromOptions() tao.destroy() if 'dmda' in args: dmda = PETSc.DMDA().create(comm=COMM) dmda.setFromOptions() dmda.destroy() if 'dmplex' in args: dmplex = PETSc.DMPlex().create(comm=COMM) dmplex.setFromOptions() dmplex.destroy() if __name__ == '__main__': help() ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/src/petsc4py/__main__.pyi0000644000175000017500000000013114567251135017167 0ustar00balaybalayfrom typing import Union def help(args: Union[str,list[str]] | None = ...) -> None: ... ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1709010084.3663752 petsc4py-3.20.5/src/petsc4py/include/0000755000175000017500000000000014567266244016363 5ustar00balaybalay././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1709010084.4373753 petsc4py-3.20.5/src/petsc4py/include/petsc4py/0000755000175000017500000000000014567266244020136 5ustar00balaybalay././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/src/petsc4py/include/petsc4py/numpy.h0000644000175000017500000000173214567251135021453 0ustar00balaybalay#ifndef PETSC4PY_NUMPY_H #define PETSC4PY_NUMPY_H #include #include #include # define NPY_PETSC_BOOL NPY_INT #if defined(PETSC_USE_64BIT_INDICES) # define NPY_PETSC_INT NPY_INT64 #else # define NPY_PETSC_INT NPY_INT #endif #if defined(PETSC_USE_REAL_SINGLE) # define NPY_PETSC_REAL NPY_FLOAT # define NPY_PETSC_COMPLEX NPY_CFLOAT #elif defined(PETSC_USE_REAL_DOUBLE) # define NPY_PETSC_REAL NPY_DOUBLE # define NPY_PETSC_COMPLEX NPY_CDOUBLE #elif defined(PETSC_USE_REAL_LONG_DOUBLE) # define NPY_PETSC_REAL NPY_LONGDOUBLE # define NPY_PETSC_COMPLEX NPY_CLONGDOUBLE #elif defined(PETSC_USE_REAL___FLOAT128) # define NPY_PETSC_REAL NPY_FLOAT128 # define NPY_PETSC_COMPLEX NPY_COMPLEX256 #else # error "unsupported real precision" #endif #if defined(PETSC_USE_COMPLEX) # define NPY_PETSC_SCALAR NPY_PETSC_COMPLEX #else # define NPY_PETSC_SCALAR NPY_PETSC_REAL #endif #endif /* !PETSC4PY_NUMPY_H */ ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/src/petsc4py/include/petsc4py/petsc4py.h0000644000175000017500000000047414567251135022060 0ustar00balaybalay/* Author: Lisandro Dalcin */ /* Contact: dalcinl@gmail.com */ #ifndef PETSC4PY_H #define PETSC4PY_H #include #include #include "../../PETSc_api.h" static int import_petsc4py(void) { if (import_petsc4py__PETSc() < 0) goto bad; return 0; bad: return -1; } #endif /* !PETSC4PY_H */ ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/src/petsc4py/include/petsc4py/petsc4py.i0000644000175000017500000005055614567251135022067 0ustar00balaybalay/* Author: Lisandro Dalcin */ /* Contact: dalcinl@gmail.com */ /* ---------------------------------------------------------------- */ %header %{#include %} %init %{import_petsc4py();%} /* ---------------------------------------------------------------- */ %runtime %{ SWIGINTERNINLINE PyObject* SWIG_getattr_this(PyObject* obj) { if (!obj) return NULL; obj = PyObject_GetAttr(obj, SWIG_This()); if (!obj) PyErr_Clear(); return obj; } SWIGINTERNINLINE int SWIG_convert_ptr(PyObject *obj, void **ptr, swig_type_info *ty, int flags) { int res = SWIG_ConvertPtr(obj, ptr, ty, flags); if (!SWIG_IsOK(res)) { PyObject* _this = SWIG_getattr_this(obj); res = SWIG_ConvertPtr(_this, ptr, ty, flags); Py_XDECREF(_this); } return res; } #undef SWIG_ConvertPtr #define SWIG_ConvertPtr(obj, pptr, type, flags) \ SWIG_convert_ptr(obj, pptr, type, flags) %} /* ---------------------------------------------------------------- */ /* ---------------------------------------------------------------- */ /* PETSc Error Codes */ /* ---------------------------------------------------------------- */ %define %petsc4py_errt(Pkg, PyType, Type) %wrapper %{ #ifndef Py##Pkg##_ChkErrQ #define Py##Pkg##_ChkErrQ(ierr) \ do { \ if (ierr != PETSC_SUCCESS) { \ Py##Pkg##PyType##_Set((ierr)); SWIG_fail; \ } \ } while (0) #endif /* defined Py##Pkg##_ChkErrQ */ %} %typemap(out,noblock=1) Type { Py##Pkg##_ChkErrQ($1); %set_output(VOID_Object); } %enddef /* ---------------------------------------------------------------- */ /* ---------------------------------------------------------------- */ /* Numeric Types */ /* ---------------------------------------------------------------- */ %define SWIG_TYPECHECK_PETSC_INT SWIG_TYPECHECK_INT32 %enddef %define SWIG_TYPECHECK_PETSC_REAL SWIG_TYPECHECK_DOUBLE %enddef %define SWIG_TYPECHECK_PETSC_COMPLEX SWIG_TYPECHECK_CPLXDBL %enddef %define SWIG_TYPECHECK_PETSC_SCALAR SWIG_TYPECHECK_CPLXDBL %enddef /* PetscInt */ /* -------- */ %fragment(SWIG_From_frag(PetscInt64),"header", fragment=SWIG_From_frag(long long), fragment=SWIG_From_frag(long)) { SWIGINTERN SWIG_Object SWIG_From_dec(PetscInt64)(PetscInt64 val) { %#if PETSC_SIZEOF_LONG == 8 return SWIG_From(long)(%numeric_cast(val,long)); %#else return SWIG_From(long long)(%numeric_cast(val,long long)); %#endif } } %fragment(SWIG_AsVal_frag(PetscInt64),"header", fragment=SWIG_AsVal_frag(long long), fragment=SWIG_AsVal_frag(long)) { SWIGINTERN int SWIG_AsVal_dec(PetscInt64)(SWIG_Object obj, PetscInt64 *val) { %#if PETSC_SIZEOF_LONG == 8 long v; int res = SWIG_AsVal(long)(obj, &v); %#else long long v; int res = SWIG_AsVal(long long)(obj, &v); %#endif if (SWIG_IsOK(res) && val) if (val) *val = %numeric_cast(v,PetscInt64); return res; } } %fragment(SWIG_From_frag(PetscInt),"header", fragment=SWIG_From_frag(PetscInt64), fragment=SWIG_From_frag(int)) { %#if defined(PETSC_USE_64BIT_INDICES) %define_as(SWIG_From(PetscInt), SWIG_From(PetscInt64)) %#else %define_as(SWIG_From(PetscInt), SWIG_From(int)) %#endif } %fragment(SWIG_AsVal_frag(PetscInt),"header", fragment=SWIG_AsVal_frag(PetscInt64), fragment=SWIG_AsVal_frag(int)) { %#if defined(PETSC_USE_64BIT_INDICES) %define_as(SWIG_AsVal(PetscInt), SWIG_AsVal(PetscInt64)) %#else %define_as(SWIG_AsVal(PetscInt), SWIG_AsVal(int)) %#endif } /* PetscReal */ /* --------- */ %fragment(SWIG_From_frag(long double),"header", fragment=SWIG_From_frag(double)) { SWIGINTERN SWIG_Object SWIG_From_dec(long double)(long double val) { return SWIG_From(double)((double)val); } } %fragment(SWIG_AsVal_frag(long double),"header", fragment=SWIG_AsVal_frag(double)) { SWIGINTERN int SWIG_AsVal_dec(long double)(SWIG_Object obj, long double *val) { double v; int res = SWIG_AsVal(double)(obj, &v); if (SWIG_IsOK(res) && val) if (val) *val = %numeric_cast(v,long double); return res; } } %fragment(SWIG_From_frag(PetscReal),"header", fragment=SWIG_From_frag(long double), fragment=SWIG_From_frag(double), fragment=SWIG_From_frag(float)) { %#if defined(PETSC_USE_REAL_SINGLE) %define_as(SWIG_From(PetscReal), SWIG_From(float)) %#elif defined(PETSC_USE_REAL_DOUBLE) %define_as(SWIG_From(PetscReal), SWIG_From(double)) %#elif defined(PETSC_USE_REAL_LONG_DOUBLE) %define_as(SWIG_From(PetscReal), SWIG_From(long double)) %#endif } %fragment(SWIG_AsVal_frag(PetscReal),"header", fragment=SWIG_AsVal_frag(long double), fragment=SWIG_AsVal_frag(double), fragment=SWIG_AsVal_frag(float)) { %#if defined(PETSC_USE_REAL_SINGLE) %define_as(SWIG_AsVal(PetscReal), SWIG_AsVal(float)) %#elif defined(PETSC_USE_REAL_DOUBLE) %define_as(SWIG_AsVal(PetscReal), SWIG_AsVal(double)) %#elif defined(PETSC_USE_REAL_LONG_DOUBLE) %define_as(SWIG_AsVal(PetscReal), SWIG_AsVal(long double)) %#endif } /* PetscComplex */ /* ------------ */ %include complex.i %fragment(SWIG_From_frag(PetscComplex),"header", #ifdef __cplusplus fragment=SWIG_From_frag(std::complex), fragment=SWIG_From_frag(std::complex), fragment=SWIG_From_frag(std::complex)) #else fragment=SWIG_From_frag(long double complex), fragment=SWIG_From_frag(double complex), fragment=SWIG_From_frag(float complex)) #endif { %#if defined(PETSC_CLANGUAGE_CXX) %define_as(SWIG_From(PetscComplex), SWIG_From(std::complex)) %#else %define_as(SWIG_From(PetscComplex), SWIG_From(double complex)) %#endif } %fragment(SWIG_AsVal_frag(PetscComplex),"header", #ifdef __cplusplus fragment=SWIG_AsVal_frag(std::complex), fragment=SWIG_AsVal_frag(std::complex), fragment=SWIG_AsVal_frag(std::complex)) #else fragment=SWIG_AsVal_frag(long double complex), fragment=SWIG_AsVal_frag(double complex), fragment=SWIG_AsVal_frag(float complex)) #endif { %#if defined(PETSC_CLANGUAGE_CXX) %define_as(SWIG_AsVal(PetscComplex), SWIG_AsVal(std::complex)) %#else %define_as(SWIG_AsVal(PetscComplex), SWIG_AsVal(double complex)) %#endif } /* PetscScalar */ /* ----------- */ %fragment(SWIG_From_frag(PetscScalar), "header", fragment=SWIG_From_frag(PetscReal), fragment=SWIG_From_frag(PetscComplex)) { %#if defined(PETSC_USE_COMPLEX) %define_as(SWIG_From(PetscScalar), SWIG_From(PetscComplex)) %#else %define_as(SWIG_From(PetscScalar), SWIG_From(PetscReal)) %#endif } %fragment(SWIG_AsVal_frag(PetscScalar), "header", fragment=SWIG_AsVal_frag(PetscReal), fragment=SWIG_AsVal_frag(PetscComplex)) { %#if defined(PETSC_USE_COMPLEX) %define_as(SWIG_AsVal(PetscScalar), SWIG_AsVal(PetscComplex)) %#else %define_as(SWIG_AsVal(PetscScalar), SWIG_AsVal(PetscReal)) %#endif } %define %petsc4py_numt(Pkg, PyType, Type, CheckCode, UNUSED) %types(Type,Type*); %typemaps_primitive(%checkcode(CheckCode), Type); /* INPUT value typemap*/ %typemap(typecheck, precedence=%checkcode(CheckCode), fragment=SWIG_AsVal_frag(Type)) Type, const Type & { int res = SWIG_AsVal(Type)($input, 0); $1 = SWIG_CheckState(res); } %typemap(in,noblock=1,fragment=SWIG_AsVal_frag(Type)) Type (Type val, int ecode = 0) { ecode = SWIG_AsVal(Type)($input, &val); if (!SWIG_IsOK(ecode)) %argument_fail(ecode, "$ltype", $symname, $argnum); $1 = %static_cast(val,$ltype); } %typemap(in,noblock=1,fragment=SWIG_AsVal_frag(Type)) const Type & ($*ltype temp, Type val, int ecode = 0) { ecode = SWIG_AsVal(Type)($input, &val); if (!SWIG_IsOK(ecode)) %argument_fail(ecode, "$*ltype", $symname, $argnum); temp = %static_cast(val,$*ltype); $1 = &temp; } %typemap(freearg) Type, const Type & ""; /* INPUT pointer/reference typemap */ %typemap(typecheck, precedence=%checkcode(CheckCode), fragment=SWIG_AsVal_frag(Type)) Type *INPUT, Type &INPUT { int res = SWIG_AsVal(Type)($input, 0); $1 = SWIG_CheckState(res); } %typemap(in,noblock=1,fragment=SWIG_AsVal_frag(Type)) Type *INPUT ($*ltype temp, int res = 0) { res = SWIG_AsVal(Type)($input, &temp); if (!SWIG_IsOK(res)) %argument_fail(res, "$*ltype",$symname, $argnum); $1 = &temp; } %typemap(in,noblock=1,fragment=SWIG_AsVal_frag(Type)) Type &INPUT ($*ltype temp, int res = 0) { res = SWIG_AsVal(Type)($input, &temp); if (!SWIG_IsOK(res)) %argument_fail(res, "$*ltype",$symname, $argnum); $1 = &temp; } %typemap(freearg) Type *INPUT, Type &INPUT ""; /* OUTPUT pointer/reference typemap */ %typemap(in,numinputs=0,noblock=1) Type *OUTPUT ($*ltype temp=0) "$1 = &temp;"; %typemap(in,numinputs=0,noblock=1) Type &OUTPUT ($*ltype temp=0) "$1 = &temp;"; %typemap(argout,noblock=1,fragment=SWIG_From_frag(Type)) Type* OUTPUT, Type &OUTPUT { %append_output(SWIG_From(Type)((*$1))); } %typemap(freearg) Type *OUTPUT ""; /* INOUT pointer/reference typemap */ %typemap(typecheck) Type *INOUT = Type *INPUT; %typemap(in) Type *INOUT = Type *INPUT; %typemap(argout) Type *INOUT = Type *OUTPUT; %typemap(freearg) Type *INOUT ""; %typemap(typecheck) Type &INOUT = Type &INPUT; %typemap(in) Type &INOUT = Type &INPUT; %typemap(argout) Type &INOUT = Type &OUTPUT; %typemap(freearg) Type &INOUT ""; /* default typemap for pointer argument */ %apply Type *OUTPUT { Type * } %enddef /* %petsc4py_numt */ /* ---------------------------------------------------------------- */ /* ---------------------------------------------------------------- */ /* Enumerations */ /* ---------------------------------------------------------------- */ %define SWIG_TYPECHECK_PETSC_ENUM SWIG_TYPECHECK_INT32 %enddef %fragment(SWIG_From_frag(PetscEnum),"header", fragment=SWIG_From_frag(int)) { SWIGINTERN SWIG_Object SWIG_From_dec(PetscEnum)(PetscEnum val) { return SWIG_From(int)((PetscEnum)val); } } %fragment(SWIG_AsVal_frag(PetscEnum),"header", fragment=SWIG_AsVal_frag(int)) { SWIGINTERN int SWIG_AsVal_dec(PetscEnum)(SWIG_Object obj, PetscEnum *val) { int v; int res = SWIG_AsVal(int)(obj, &v); if (SWIG_IsOK(res) && val) *val = %static_cast(v,PetscEnum); return res; } } %typemaps_primitive(%checkcode(PETSC_ENUM), PetscEnum); %typemap(in,numinputs=0) PetscEnum *OUTPUT ($*ltype temp) "$1 = &temp;" %typemap(argout,noblock=1,fragment=SWIG_From_frag(PetscEnum)) PetscEnum *OUTPUT { %append_output(SWIG_From(PetscEnum)(%static_cast(*$1,PetscEnum))); } %apply PetscEnum *INPUT { PetscEnum const * } %typemap(argout) PetscEnum const* ""; %apply PetscEnum *OUTPUT { PetscEnum * } %define %petsc4py_enum(EnumType) %apply PetscEnum { EnumType } %apply PetscEnum * { EnumType * } %apply PetscEnum *INPUT { EnumType *INPUT } %apply PetscEnum *OUTPUT { EnumType *OUTPUT } %apply PetscEnum *INOUT { EnumType *INOUT } %enddef /* ---------------------------------------------------------------- */ %define %petsc4py_fragments(Pkg, PyType, Type, OBJECT_DEFAULT) /* AsVal */ /* ----- */ %fragment(SWIG_AsVal_frag(Type),"header") { SWIGINTERN int SWIG_AsVal_dec(Type)(SWIG_Object input, Type *v) { if (input == Py_None) { if (v) *v = OBJECT_DEFAULT; return SWIG_OK; } else if (PyObject_TypeCheck(input,&Py##Pkg##PyType##_Type)) { if (v) *v = Py##Pkg##PyType##_Get(input); return SWIG_OK; } else { void *argp = 0; int res = SWIG_ConvertPtr(input,&argp,%descriptor(p_##Type), 0); if (!SWIG_IsOK(res)) return res; if (!argp) return SWIG_ValueError; if (v) *v = *(%static_cast(argp,Type*)); return SWIG_OK; } } } /* AsPtr */ /* ----- */ %fragment(SWIG_AsPtr_frag(Type),"header", fragment=%fragment_name(GetPtr,Type)) { SWIGINTERN int SWIG_AsPtr_dec(Type)(SWIG_Object input, Type **p) { if (input == Py_None) { if (p) *p = 0; return SWIG_OK; } else if (PyObject_TypeCheck(input,&Py##Pkg##PyType##_Type)) { if (p) *p = Py##Pkg##PyType##_GetPtr(input); return SWIG_OK; } else { void *argp = 0; int res = SWIG_ConvertPtr(input,&argp,%descriptor(p_##Type), 0); if (!SWIG_IsOK(res)) return res; if (!argp) return SWIG_ValueError; if (p) *p = %static_cast(argp,Type*); return SWIG_OK; } } } /* From */ /* ---- */ %fragment(SWIG_From_frag(Type),"header") { SWIGINTERN SWIG_Object SWIG_From_dec(Type)(Type v) { return Py##Pkg##PyType##_New(v); } } %enddef /*petsc4py_fragments*/ /* ---------------------------------------------------------------- */ /* MPI Communicator */ /* ---------------------------------------------------------------- */ %define SWIG_TYPECHECK_MPI_COMM 600 %enddef %define %petsc4py_comm(Pkg, PyType, Type, CODE, OBJECT_NULL) /* pointer type */ %types(Type*); /* XXX find better way */ /* fragments */ %fragment(%fragment_name(GetPtr,MPI_Comm),"header") { } %petsc4py_fragments(Pkg, PyType, Type, PETSC_COMM_WORLD) /* base typemaps */ %typemaps_asvalfromn(%checkcode(MPI_COMM), Type); /* custom typemaps */ %typemap(check,noblock=1) Type { if ($1 == OBJECT_NULL) %argument_nullref("$ltype",$symname,$argnum); } %enddef /* %petsc4py_comm */ /* ---------------------------------------------------------------- */ /* PETSc Objects */ /* ---------------------------------------------------------------- */ %define SWIG_TYPECHECK_PETSC_OBJECT 500 %enddef %define SWIG_TYPECHECK_PETSC_VIEWER 501 %enddef %define SWIG_TYPECHECK_PETSC_RANDOM 502 %enddef %define SWIG_TYPECHECK_PETSC_DEVICE_CONTEXT 503 %enddef %define SWIG_TYPECHECK_PETSC_IS 510 %enddef %define SWIG_TYPECHECK_PETSC_IS_LTOGM 511 %enddef %define SWIG_TYPECHECK_PETSC_SF 512 %enddef %define SWIG_TYPECHECK_PETSC_VEC 513 %enddef %define SWIG_TYPECHECK_PETSC_VEC_SCATTER 514 %enddef %define SWIG_TYPECHECK_PETSC_SECTION 515 %enddef %define SWIG_TYPECHECK_PETSC_MAT 520 %enddef %define SWIG_TYPECHECK_PETSC_MAT_PARTITIONING 521 %enddef %define SWIG_TYPECHECK_PETSC_MAT_NULLSPACE 522 %enddef %define SWIG_TYPECHECK_PETSC_KSP 530 %enddef %define SWIG_TYPECHECK_PETSC_PC 531 %enddef %define SWIG_TYPECHECK_PETSC_SNES 532 %enddef %define SWIG_TYPECHECK_PETSC_TS 533 %enddef %define SWIG_TYPECHECK_PETSC_TAO 534 %enddef %define SWIG_TYPECHECK_PETSC_AO 540 %enddef %define SWIG_TYPECHECK_PETSC_DM 541 %enddef %define SWIG_TYPECHECK_PETSC_DS 542 %enddef %define SWIG_TYPECHECK_PETSC_PARTITIONER 543 %enddef %define SWIG_TYPECHECK_PETSC_FE 550 %enddef %define SWIG_TYPECHECK_PETSC_QUADRATURE 551 %enddef %define SWIG_TYPECHECK_PETSC_SPACE 552 %enddef %define SWIG_TYPECHECK_PETSC_DUALSPACE 553 %enddef %define SWIG_TYPECHECK_PETSC_DMLABEL 560 %enddef %define %petsc4py_objt(Pkg, PyType, Type, CODE) /* pointer type */ %types(Type*); /* XXX find better way */ /* fragments */ %fragment(%fragment_name(GetPtr,Type),"header") { /* XXX implement this better*/ %define_as(Py##Pkg##PyType##_GetPtr(ob), (Type *)PyPetscObject_GetPtr(ob)) } %petsc4py_fragments(Pkg, PyType, Type, NULL) /* base typemaps */ %typemaps_asptrfromn(%checkcode(CODE), Type); /* Custom Typemaps */ /* --------------- */ /* freearg */ %typemap(freearg) Type, Type*, Type& ""; /* check */ %typemap(check,noblock=1) Type INPUT { if ($1 == NULL) %argument_nullref("$type", $symname, $argnum); } /* input pointer */ %typemap(in,fragment=SWIG_AsPtr_frag(Type)) Type *INPUT (int res = SWIG_OLDOBJ) { Type *ptr = (Type *)0; res = SWIG_AsPtr(Type)($input, &ptr); if (!SWIG_IsOK(res)) { %argument_fail(res,"$type", $symname, $argnum); } $1 = ptr; } %typemap(check,noblock=1) Type *INPUT { if ($1 == NULL || (*$1) == NULL) %argument_nullref("$type", $symname, $argnum); } /* input reference */ %apply Type *INPUT { Type& } /* optional value */ %typemap(arginit) Type OPTIONAL "$1 = NULL;" %typemap(in,fragment=SWIG_AsPtr_frag(Type)) Type OPTIONAL (int res = 0) { Type *ptr = (Type *)0; res = SWIG_AsPtr(Type)($input, &ptr); if (!SWIG_IsOK(res)) { %argument_fail(res, "$type", $symname, $argnum); } if (ptr) $1 = *ptr; } /* optional reference */ %typemap(in,fragment=SWIG_AsPtr_frag(Type)) Type& OPTIONAL (int res = 0) { Type *ptr = (Type *)0; res = SWIG_AsPtr(Type)($input, &ptr); if (!SWIG_IsOK(res)) { %argument_fail(res, "$type", $symname, $argnum); } if (!ptr) %argument_nullref("$type", $symname, $argnum); $1 = ptr; if (SWIG_IsNewObj(res)) %delete(ptr); } %typemap(in,numinputs=0) Type* OUTREF, Type* OUTNEW ($*ltype temp = NULL) "$1 = &temp;"; %typemap(freearg) Type* OUTREF, Type* OUTNEW ""; %typemap(check) Type* OUTREF, Type* OUTNEW ""; %typemap(argout) Type* OUTREF { SWIG_Object o = Py##Pkg##PyType##_New(*$1); %append_output(o); } %typemap(argout) Type* OUTNEW { SWIG_Object o = Py##Pkg##PyType##_New(*$1); if (o!=NULL) PetscObjectDereference((PetscObject)(*$1)); %append_output(o); } %apply Type OPTIONAL { Type MAYBE } %apply Type& OPTIONAL { Type& MAYBE } %apply Type* OUTNEW { Type* NEWOBJ } %apply Type* OUTREF { Type* NEWREF } %enddef /* %petsc4py_objt */ /* ---------------------------------------------------------------- */ /* */ /* ---------------------------------------------------------------- */ %petsc4py_errt( Petsc , Error , PetscErrorCode ) %petsc4py_numt( Petsc , Int , PetscInt , PETSC_INT , 0 ) %petsc4py_numt( Petsc , Real , PetscReal , PETSC_REAL , 0 ) %petsc4py_numt( Petsc , Complex , PetscComplex , PETSC_COMPLEX , 0 ) %petsc4py_numt( Petsc , Scalar , PetscScalar , PETSC_SCALAR , 0 ) %petsc4py_comm( Petsc, Comm , MPI_Comm , MPI_COMM , MPI_COMM_NULL ) %petsc4py_objt( Petsc , Object , PetscObject , PETSC_OBJECT ) %petsc4py_objt( Petsc , Viewer , PetscViewer , PETSC_VIEWER ) %petsc4py_objt( Petsc , Random , PetscRandom , PETSC_RANDOM ) %petsc4py_objt( Petsc , DeviceContext , PetscDeviceContext , PETSC_DEVICE_CONTEXT ) %petsc4py_objt( Petsc , IS , IS , PETSC_IS ) %petsc4py_objt( Petsc , LGMap , ISLocalToGlobalMapping , PETSC_IS_LTOGM ) %petsc4py_objt( Petsc , SF , PetscSF , PETSC_SF ) %petsc4py_objt( Petsc , Vec , Vec , PETSC_VEC ) %petsc4py_objt( Petsc , Scatter , VecScatter , PETSC_VEC_SCATTER ) %petsc4py_objt( Petsc , Section , PetscSection , PETSC_SECTION ) %petsc4py_objt( Petsc , Mat , Mat , PETSC_MAT ) %petsc4py_objt( Petsc , MatPartitioning, MatPartitioning , PETSC_MAT_PARTITIONING ) %petsc4py_objt( Petsc , NullSpace , MatNullSpace , PETSC_MAT_NULLSPACE ) %petsc4py_objt( Petsc , KSP , KSP , PETSC_KSP ) %petsc4py_objt( Petsc , PC , PC , PETSC_PC ) %petsc4py_objt( Petsc , SNES , SNES , PETSC_SNES ) %petsc4py_objt( Petsc , TS , TS , PETSC_TS ) %petsc4py_objt( Petsc , TAO , Tao , PETSC_TAO ) %petsc4py_objt( Petsc , AO , AO , PETSC_AO ) %petsc4py_objt( Petsc , DM , DM , PETSC_DM ) %petsc4py_objt( Petsc , DS , PetscDS , PETSC_DS ) %petsc4py_objt( Petsc , Partitioner , PetscPartitioner , PETSC_PARTITIONER ) %petsc4py_objt( Petsc , FE , PetscFE , PETSC_FE ) %petsc4py_objt( Petsc , Quad , PetscQuadrature , PETSC_QUADRATURE ) %petsc4py_objt( Petsc , Space , PetscSpace , PETSC_SPACE ) %petsc4py_objt( Petsc , DualSpace , PetscDualSpace , PETSC_DUALSPACE ) %petsc4py_objt( Petsc , DMLabel , PetscDMLabel , PETSC_DMLABEL ) /* ---------------------------------------------------------------- */ /* * Local Variables: * mode: C * End: */ ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/src/petsc4py/include/petsc4py/pybuffer.h0000644000175000017500000000565414567251135022134 0ustar00balaybalay#ifndef PETSC4PY_PYBUFFER_H #define PETSC4PY_PYBUFFER_H #include #include #if defined(PETSC_USE_64BIT_INDICES) # define _PyPetsc_FMT_PETSC_INT "q" #else # define _PyPetsc_FMT_PETSC_INT "i" #endif #if defined(PETSC_USE_REAL_SINGLE) # define _PyPetsc_FMT_PETSC_REAL "f" # define _PyPetsc_FMT_PETSC_COMPLEX "Zf" #elif defined(PETSC_USE_REAL_DOUBLE) # define _PyPetsc_FMT_PETSC_REAL "d" # define _PyPetsc_FMT_PETSC_COMPLEX "Zd" #elif defined(PETSC_USE_REAL_LONG_DOUBLE) # define _PyPetsc_FMT_PETSC_REAL "g" # define _PyPetsc_FMT_PETSC_COMPLEX "Zg" #elif defined(PETSC_USE_REAL___FLOAT128) # define _PyPetsc_FMT_PETSC_REAL "g" # define _PyPetsc_FMT_PETSC_COMPLEX "Zg" #else # error "unsupported real precision" #endif #if defined(PETSC_USE_COMPLEX) # define _PyPetsc_FMT_PETSC_SCALAR _PyPetsc_FMT_PETSC_COMPLEX #else # define _PyPetsc_FMT_PETSC_SCALAR _PyPetsc_FMT_PETSC_REAL #endif static inline int PyPetscBuffer_FillInfo(Py_buffer *view, void *buf, PetscInt count, char typechar, int readonly, int flags) { if (view == NULL) return 0; if (((flags & PyBUF_WRITABLE) == PyBUF_WRITABLE) && (readonly == 1)) { PyErr_SetString(PyExc_BufferError, "Object is not writable."); return -1; } view->buf = buf; switch (typechar) { case 'i': view->itemsize = sizeof(PetscInt); break; case 'r': view->itemsize = sizeof(PetscReal); break; case 's': view->itemsize = sizeof(PetscScalar); break; case 'c': view->itemsize = sizeof(PetscReal)*2; break; default: view->itemsize = 1; } view->len = count*view->itemsize; view->readonly = readonly; view->format = NULL; if ((flags & PyBUF_FORMAT) == PyBUF_FORMAT) { switch (typechar) { case 'i': view->format = (char *) _PyPetsc_FMT_PETSC_INT; break; case 'r': view->format = (char *) _PyPetsc_FMT_PETSC_REAL; break; case 's': view->format = (char *) _PyPetsc_FMT_PETSC_SCALAR; break; case 'c': view->format = (char *) _PyPetsc_FMT_PETSC_COMPLEX; break; default: view->format = (char *) "B"; } } view->ndim = 0; view->shape = NULL; view->strides = NULL; view->suboffsets = NULL; view->internal = NULL; if ((flags & PyBUF_ND) == PyBUF_ND) { view->ndim = 1; view->internal = PyMem_Malloc(2*sizeof(Py_ssize_t)); if (!view->internal) { PyErr_NoMemory(); return -1; } view->shape = (Py_ssize_t *) view->internal; view->shape[0] = view->len/view->itemsize; if ((flags & PyBUF_STRIDES) == PyBUF_STRIDES) { view->strides = view->shape + 1; view->strides[0] = view->itemsize; } } return 0; } static inline void PyPetscBuffer_Release(Py_buffer *view) { if (view == NULL) return; if (view->internal) PyMem_Free(view->internal); view->internal = NULL; } #undef _PyPetsc_FMT_PETSC_INT #undef _PyPetsc_FMT_PETSC_REAL #undef _PyPetsc_FMT_PETSC_SCALAR #undef _PyPetsc_FMT_PETSC_COMPLEX #endif/*!PETSC4PY_PYBUFFER_H*/ ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/src/petsc4py/include/petsc4py/pyscalar.h0000644000175000017500000000132014567251135022112 0ustar00balaybalay#ifndef PETSC4PY_PYSCALAR_H #define PETSC4PY_PYSCALAR_H #include #include static inline PyObject *PyPetscScalar_FromPetscScalar(PetscScalar s) { #if defined(PETSC_USE_COMPLEX) double a = (double)PetscRealPart(s); double b = (double)PetscImaginaryPart(s); return PyComplex_FromDoubles(a, b); #else return PyFloat_FromDouble((double)s); #endif } static inline PetscScalar PyPetscScalar_AsPetscScalar(PyObject *o) { #if defined(PETSC_USE_COMPLEX) Py_complex cval = PyComplex_AsCComplex(o); PetscReal a = (PetscReal)cval.real; PetscReal b = (PetscReal)cval.imag; return a + b * PETSC_i; #else return (PetscScalar)PyFloat_AsDouble(o); #endif } #endif/*PETSC4PY_PYSCALAR_H*/ ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1709010084.4383752 petsc4py-3.20.5/src/petsc4py/lib/0000755000175000017500000000000014567266244015506 5ustar00balaybalay././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/src/petsc4py/lib/__init__.py0000644000175000017500000001424714567251135017620 0ustar00balaybalay# Author: Lisandro Dalcin # Contact: dalcinl@gmail.com # -------------------------------------------------------------------- """ Extension modules for different PETSc configurations. PETSc can be configured with different options (eg. debug/optimized, single/double precisionm, C/C++ compilers, external packages). Each configuration variant is associated to a name, frequently available as an environmental variable named ``PETSC_ARCH``. This package is a holds all the available variants of the PETSc extension module built against specific PETSc configurations. It also provides a convenience function using of the ``importlib`` module for easily importing any of the available extension modules depending on the value of a user-provided configuration name, the ``PETSC_ARCH`` environmental variable, or a configuration file. """ # -------------------------------------------------------------------- def ImportPETSc(arch=None): """ Import the PETSc extension module for a given configuration name. """ path, arch = getPathArchPETSc(arch) return Import('petsc4py', 'PETSc', path, arch) def getPathArchPETSc(arch=None): """ Undocumented. """ import os path = os.path.abspath(os.path.dirname(__file__)) rcvar, rcfile = 'PETSC_ARCH', 'petsc.cfg' path, arch = getPathArch(path, arch, rcvar, rcfile) return (path, arch) # -------------------------------------------------------------------- def Import(pkg, name, path, arch): """ Import helper for PETSc-based extension modules. """ import os import sys import warnings try: import importlib.machinery import importlib.util except ImportError: importlib = None import imp def get_ext_suffix(): if importlib: return importlib.machinery.EXTENSION_SUFFIXES[0] else: return imp.get_suffixes()[0][0] def import_module(pkg, name, path, arch): fullname = '{}.{}'.format(pkg, name) pathlist = [os.path.join(path, arch)] if importlib: finder = importlib.machinery.PathFinder() spec = finder.find_spec(fullname, pathlist) module = importlib.util.module_from_spec(spec) sys.modules[fullname] = module spec.loader.exec_module(module) return module else: f, fn, info = imp.find_module(name, pathlist) with f: return imp.load_module(fullname, f, fn, info) # test if extension module was already imported module = sys.modules.get('{}.{}'.format(pkg, name)) filename = getattr(module, '__file__', '') if filename.endswith(get_ext_suffix()): # if 'arch' is None, do nothing; otherwise this # call may be invalid if extension module for # other 'arch' has been already imported. if arch is not None and arch != module.__arch__: raise ImportError("%s already imported" % module) return module # silence annoying Cython warning warnings.filterwarnings("ignore", message="numpy.dtype size changed") warnings.filterwarnings("ignore", message="numpy.ndarray size changed") # import extension module from 'path/arch' directory module = import_module(pkg, name, path, arch) module.__arch__ = arch # save arch value setattr(sys.modules[pkg], name, module) return module def getPathArch(path, arch, rcvar='PETSC_ARCH', rcfile='petsc.cfg'): """ Undocumented. """ import os import warnings # path if not path: path = '.' elif os.path.isfile(path): path = os.path.dirname(path) elif not os.path.isdir(path): raise ValueError("invalid path: '%s'" % path) # arch if arch is not None: if not isinstance(arch, str): raise TypeError( "arch argument must be string") if not os.path.isdir(os.path.join(path, arch)): raise TypeError("invalid arch value: '%s'" % arch) return (path, arch) # helper function def arch_list(arch): arch = arch.strip().split(os.path.pathsep) arch = [a.strip() for a in arch if a] arch = [a for a in arch if a] return arch # try to get arch from the environment arch_env = arch_list(os.environ.get(rcvar, '')) for arch in arch_env: if os.path.isdir(os.path.join(path, arch)): return (path, arch) # configuration file if not os.path.isfile(rcfile): rcfile = os.path.join(path, rcfile) if not os.path.isfile(rcfile): # now point to continue return (path, '') # helper function def parse_rc(rcfile): with open(rcfile) as f: rcdata = f.read() lines = [ln.strip() for ln in rcdata.splitlines()] lines = [ln for ln in lines if not ln.startswith('#')] entries = [ln.split('=') for ln in lines if ln] entries = [(k.strip(), v.strip()) for k, v in entries] return dict(entries) # try to get arch from data in config file configrc = parse_rc(rcfile) arch_cfg = arch_list(configrc.get(rcvar, '')) for arch in arch_cfg: if arch.startswith('%(') and arch.endswith(')s'): arch = arch % os.environ if os.path.isdir(os.path.join(path, arch)): if arch_env: warnings.warn( "ignored arch: '%s', using: '%s'" % \ (os.path.pathsep.join(arch_env), arch)) return (path, arch) # nothing good found return (path, '') def getInitArgs(args): """ Undocumented. """ import shlex import sys if args is None: args = [] elif isinstance(args, str): args = shlex.split(args) else: args = [str(a) for a in args] args = [a for a in args if a] if args and args[0].startswith('-'): sys_argv = getattr(sys, 'argv', None) sys_exec = getattr(sys, 'executable', 'python') if (sys_argv and sys_argv[0] and sys_argv[0] != '-c'): prog_name = sys_argv[0] else: prog_name = sys_exec args.insert(0, prog_name) return args # -------------------------------------------------------------------- ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/src/petsc4py/lib/__init__.pyi0000644000175000017500000000061314567251135017761 0ustar00balaybalayfrom types import ModuleType def ImportPETSc(arch: str | None = ...) -> ModuleType: ... def getPathArchPETSc(arch: str | None = ...) -> tuple[str, str]: ... def Import(pkg: str, name: str, path: str, arch: str) -> ModuleType: ... def getPathArch(path: str, arch: str, rcvar: str = ..., rcfile: str = ...) -> tuple[str, str]: ... def getInitArgs(args: str | list[str] | None) -> list[str]: ... ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/src/petsc4py/lib/petsc.cfg0000644000175000017500000000006714567251135017301 0ustar00balaybalayPETSC_DIR = %(PETSC_DIR)s PETSC_ARCH = %(PETSC_ARCH)s ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/src/petsc4py/py.typed0000644000175000017500000000003314567251135016424 0ustar00balaybalay# Marker file for PEP 561. ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/src/petsc4py/typing.py0000644000175000017500000002502614567251135016622 0ustar00balaybalay# Author: Lisandro Dalcin # Contact: dalcinl@gmail.com """Typing support.""" from __future__ import annotations from typing import ( Callable, Sequence, Literal, ) from numpy.typing import ( NDArray, ) from .PETSc import ( InsertMode, ScatterMode, NormType, Vec, Mat, NullSpace, KSP, SNES, TS, TAO, TAOLineSearch, DM, ) __all__ = [ "Scalar", "ArrayInt", "ArrayReal", "ArrayComplex", "ArrayScalar", "DimsSpec", "AccessModeSpec", "InsertModeSpec", "ScatterModeSpec", "LayoutSizeSpec", "NormTypeSpec", "MatAssemblySpec", "MatSizeSpec", "MatBlockSizeSpec", "CSRIndicesSpec", "CSRSpec", "NNZSpec", "MatNullFunction", "DMCoarsenHookFunction", "DMRestrictHookFunction", "KSPRHSFunction", "KSPOperatorsFunction", "KSPConvergenceTestFunction", "KSPMonitorFunction", "TSRHSFunction", "TSRHSJacobian", "TSRHSJacobianP", "TSIFunction", "TSIJacobian", "TSIJacobianP", "TSI2Function", "TSI2Jacobian", "TSI2JacobianP", "TSMonitorFunction", "TSPreStepFunction", "TSPostStepFunction", "TSEventHandlerFunction", "TSPostEventFunction", "TSPreStepFunction", "TSPostStepFunction", "TAOObjectiveFunction", "TAOGradientFunction", "TAOObjectiveGradientFunction", "TAOHessianFunction", "TAOUpdateFunction", "TAOMonitorFunction", "TAOConvergedFunction", "TAOJacobianFunction", "TAOResidualFunction", "TAOJacobianResidualFunction", "TAOVariableBoundsFunction", "TAOConstraintsFunction", "TAOLSObjectiveFunction", "TAOLSGradientFunction", "TAOLSObjectiveGradientFunction", ] # --- Sys --- Scalar = float | complex """Scalar type. Scalars can be either `float` or `complex` (but not both) depending on how PETSc was configured (``./configure --with-scalar-type=real|complex``). """ ArrayInt = NDArray[int] """Array of `int`.""" ArrayReal = NDArray[float] """Array of `float`.""" ArrayComplex = NDArray[complex] """Array of `complex`.""" ArrayScalar = NDArray[Scalar] """Array of `Scalar` numbers.""" DimsSpec = tuple[int, ...] """Dimensions specification. N-tuples indicates N-dimensional grid sizes. """ AccessModeSpec = Literal['rw', 'r', 'w'] | None """Access mode specification. Possible values are: - ``'rw'`` Read-Write mode. - ``'r'`` Read-only mode. - ``'w'`` Write-only mode. - `None` as ``'rw'``. """ InsertModeSpec = InsertMode | bool | None """Insertion mode specification. Possible values are: - `InsertMode.ADD_VALUES` Add new value to existing one. - `InsertMode.INSERT_VALUES` Replace existing entry with new value. - `None` as `InsertMode.INSERT_VALUES`. - `False` as `InsertMode.INSERT_VALUES`. - `True` as `InsertMode.ADD_VALUES`. See Also -------- InsertMode """ ScatterModeSpec = ScatterMode | bool | str | None """Scatter mode specification. Possible values are: - `ScatterMode.FORWARD` Forward mode. - `ScatterMode.REVERSE` Reverse mode. - `None` as `ScatterMode.FORWARD`. - `False` as `ScatterMode.FORWARD`. - `True` as `ScatterMode.REVERSE`. - ``'forward'`` as `ScatterMode.FORWARD`. - ``'reverse'`` as `ScatterMode.REVERSE`. See Also -------- ScatterMode """ LayoutSizeSpec = int | tuple[int, int] """`int` or 2-`tuple` of `int` describing the layout sizes. A single `int` indicates global size. A `tuple` of `int` indicates ``(local_size, global_size)``. See Also -------- Sys.splitOwnership """ NormTypeSpec = NormType | None """Norm type specification. Possible values include: - `NormType.NORM_1` The 1-norm: Σₙ abs(xₙ) for vectors, maxₙ (Σᵢ abs(xₙᵢ)) for matrices. - `NormType.NORM_2` The 2-norm: √(Σₙ xₙ²) for vectors, largest singular values for matrices. - `NormType.NORM_INFINITY` The ∞-norm: maxₙ abs(xₙ) for vectors, maxᵢ (Σₙ abs(xₙᵢ)) for matrices. - `NormType.NORM_FROBENIUS` The Frobenius norm: same as 2-norm for vectors, √(Σₙᵢ xₙᵢ²) for matrices. - `NormType.NORM_1_AND_2` Compute both `NormType.NORM_1` and `NormType.NORM_2`. - `None` as `NormType.NORM_2` for vectors, `NormType.NORM_FROBENIUS` for matrices. See Also -------- PETSc.NormType, petsc.NormType """ # --- Mat --- MatAssemblySpec = Mat.AssemblyType | bool | None """Matrix assembly specification. Possible values are: - `Mat.AssemblyType.FINAL` - `Mat.AssemblyType.FLUSH` - `None` as `Mat.AssemblyType.FINAL` - `False` as `Mat.AssemblyType.FINAL` - `True` as `Mat.AssemblyType.FLUSH` See Also -------- petsc.MatAssemblyType """ MatSizeSpec = int | tuple[int, int] | tuple[tuple[int, int], tuple[int, int]] """`int` or (nested) `tuple` of `int` describing the matrix sizes. If `int` then rows = columns. A single `tuple` of `int` indicates ``(rows, columns)``. A nested `tuple` of `int` indicates ``((local_rows, rows), (local_columns, columns))``. See Also -------- Sys.splitOwnership """ MatBlockSizeSpec = int | tuple[int, int] """The row and column block sizes. If a single `int` is provided then rows and columns share the same block size. """ CSRIndicesSpec = tuple[Sequence[int], Sequence[int]] """CSR indices format specification. A 2-tuple carrying the ``(row_start, col_indices)`` information. """ CSRSpec = tuple[Sequence[int], Sequence[int], Sequence[Scalar]] """CSR format specification. A 3-tuple carrying the ``(row_start, col_indices, values)`` information. """ NNZSpec = int | Sequence[int] | tuple[Sequence[int], Sequence[int]] """Nonzero pattern specification. A single `int` corresponds to fixed number of non-zeros per row. A `Sequence` of `int` indicates different non-zeros per row. If a 2-`tuple` is used, the elements of the tuple corresponds to the on-process and off-process parts of the matrix. See Also -------- petsc.MatSeqAIJSetPreallocation, petsc.MatMPIAIJSetPreallocation """ # --- MatNullSpace --- MatNullFunction = Callable[[NullSpace, Vec], None] """`PETSc.NullSpace` callback.""" # --- DM --- DMCoarsenHookFunction = Callable[[DM, DM], None] """`PETSc.DM` coarsening hook callback.""" DMRestrictHookFunction = Callable[[DM, Mat, Vec, Mat, DM], None] """`PETSc.DM` restriction hook callback.""" # --- KSP --- KSPRHSFunction = Callable[[KSP, Vec], None] """`PETSc.KSP` right hand side function callback.""" KSPOperatorsFunction = Callable[[KSP, Mat, Mat], None] """`PETSc.KSP` operators function callback.""" KSPConvergenceTestFunction = Callable[[KSP, int, float], KSP.ConvergedReason] """`PETSc.KSP` convergence test callback.""" KSPMonitorFunction = Callable[[KSP, int, float], None] """`PETSc.KSP` monitor callback.""" # --- SNES --- SNESMonitorFunction = Callable[[SNES, int, float], None] """`SNES` monitor callback.""" SNESObjFunction = Callable[[SNES, Vec], None] """`SNES` objective function callback.""" SNESFunction = Callable[[SNES, Vec, Vec], None] """`SNES` residual function callback.""" SNESJacobianFunction = Callable[[SNES, Vec, Mat, Mat], None] """`SNES` Jacobian callback.""" SNESGuessFunction = Callable[[SNES, Vec], None] """`SNES` initial guess callback.""" SNESUpdateFunction = Callable[[SNES, int], None] """`SNES` step update callback.""" SNESLSPreFunction = Callable[[Vec, Vec], None] """`SNES` linesearch pre-check update callback.""" SNESNGSFunction = Callable[[SNES, Vec, Vec], None] """`SNES` nonlinear Gauss-Seidel callback.""" SNESConvergedFunction = Callable[[SNES, int, tuple[float, float, float]], SNES.ConvergedReason] """`SNES` convergence test callback.""" # --- TS --- TSRHSFunction = Callable[[TS, float, Vec, Vec], None] """`TS` right hand side function callback.""" TSRHSJacobian = Callable[[TS, float, Vec, Mat, Mat], None] """`TS` right hand side Jacobian callback.""" TSRHSJacobianP = Callable[[TS, float, Vec, Mat], None] """`TS` right hand side parameter Jacobian callback.""" TSIFunction = Callable[[TS, float, Vec, Vec, Vec], None] """`TS` implicit function callback.""" TSIJacobian = Callable[[TS, float, Vec, Vec, float, Mat, Mat], None] """`TS` implicit Jacobian callback.""" TSIJacobianP = Callable[[TS, float, Vec, Vec, float, Mat], None] """`TS` implicit parameter Jacobian callback.""" TSI2Function = Callable[[TS, float, Vec, Vec, Vec, Vec], None] """`TS` implicit 2nd order function callback.""" TSI2Jacobian = Callable[[TS, float, Vec, Vec, Vec, float, float, Mat, Mat], None] """`TS` implicit 2nd order Jacobian callback.""" TSI2JacobianP = Callable[[TS, float, Vec, Vec, Vec, float, float, Mat], None] """`TS` implicit 2nd order parameter Jacobian callback.""" TSMonitorFunction = Callable[[TS, int, float, Vec], None] """`TS` monitor callback.""" TSPreStepFunction = Callable[[TS], None] """`TS` pre-step callback.""" TSPostStepFunction = Callable[[TS], None] """`TS` post-step callback.""" TSEventHandlerFunction = Callable[[TS, float, Vec, NDArray[Scalar]], None] """`TS` event handler callback.""" TSPostEventFunction = Callable[[TS, NDArray[int], float, Vec, bool], None] """`TS` post-event handler callback.""" # --- TAO --- TAOObjectiveFunction = Callable[[TAO, Vec], float] """`TAO` objective function callback.""" TAOGradientFunction = Callable[[TAO, Vec, Vec], None] """`TAO` objective gradient callback.""" TAOObjectiveGradientFunction = Callable[[TAO, Vec, Vec], float] """`TAO` objective function and gradient callback.""" TAOHessianFunction = Callable[[TAO, Vec, Mat, Mat], None] """`TAO` objective Hessian callback.""" TAOUpdateFunction = Callable[[TAO, int], None] """`TAO` update callback.""" TAOMonitorFunction = Callable[[TAO], None] """`TAO` monitor callback.""" TAOConvergedFunction = Callable[[TAO], None] """`TAO` convergence test callback.""" TAOJacobianFunction = Callable[[TAO, Vec, Mat, Mat], None] """`TAO` Jacobian callback.""" TAOResidualFunction = Callable[[TAO, Vec, Vec], None] """`TAO` residual callback.""" TAOJacobianResidualFunction = Callable[[TAO, Vec, Mat, Mat], None] """`TAO` Jacobian residual callback.""" TAOVariableBoundsFunction = Callable[[TAO, Vec, Vec], None] """`TAO` variable bounds callback.""" TAOConstraintsFunction = Callable[[TAO, Vec, Vec], None] """`TAO` constraints callback.""" TAOLSObjectiveFunction = Callable[[TAOLineSearch, Vec], float] """`TAOLineSearch` objective function callback.""" TAOLSGradientFunction = Callable[[TAOLineSearch, Vec, Vec], None] """`TAOLineSearch` objective gradient callback.""" TAOLSObjectiveGradientFunction = Callable[[TAOLineSearch, Vec, Vec], float] """`TAOLineSearch` objective function and gradient callback.""" ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1709010084.4003754 petsc4py-3.20.5/src/petsc4py.egg-info/0000755000175000017500000000000014567266244016432 5ustar00balaybalay././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709010084.0 petsc4py-3.20.5/src/petsc4py.egg-info/PKG-INFO0000644000175000017500000000477714567266244017546 0ustar00balaybalayMetadata-Version: 2.1 Name: petsc4py Version: 3.20.5 Summary: PETSc for Python Home-page: https://gitlab.com/petsc/petsc Download-URL: https://pypi.io/packages/source/p/petsc4py/petsc4py-3.20.5.tar.gz Author: Lisandro Dalcin Author-email: dalcinl@gmail.com Maintainer: PETSc Team Maintainer-email: petsc-maint@mcs.anl.gov License: BSD-2-Clause Keywords: scientific computing,parallel computing,MPI,PETSc Platform: POSIX Platform: Linux Platform: macOS Platform: FreeBSD Classifier: License :: OSI Approved :: BSD License Classifier: Operating System :: POSIX Classifier: Intended Audience :: Developers Classifier: Intended Audience :: Science/Research Classifier: Programming Language :: C Classifier: Programming Language :: C++ Classifier: Programming Language :: Cython Classifier: Programming Language :: Python Classifier: Programming Language :: Python :: 2 Classifier: Programming Language :: Python :: 3 Classifier: Programming Language :: Python :: Implementation :: CPython Classifier: Topic :: Scientific/Engineering Classifier: Topic :: Software Development :: Libraries :: Python Modules Classifier: Development Status :: 5 - Production/Stable Requires: numpy Description-Content-Type: text/x-rst Provides-Extra: doc License-File: LICENSE.rst PETSc for Python ================ Python bindings for PETSc. Install ------- If you have a working MPI implementation and the ``mpicc`` compiler wrapper is on your search path, it is highly recommended to install ``mpi4py`` first:: $ pip install mpi4py Ensure you have NumPy installed:: $ pip install numpy and finally:: $ pip install petsc petsc4py Citations --------- If PETSc for Python been significant to a project that leads to an academic publication, please acknowledge that fact by citing the project. * L. Dalcin, P. Kler, R. Paz, and A. Cosimo, *Parallel Distributed Computing using Python*, Advances in Water Resources, 34(9):1124-1139, 2011. http://dx.doi.org/10.1016/j.advwatres.2011.04.013 * S. Balay, S. Abhyankar, M. Adams, S. Benson, J. Brown, P. Brune, K. Buschelman, E. Constantinescu, L. Dalcin, A. Dener, V. Eijkhout, J. Faibussowitsch, W. Gropp, V. Hapla, T. Isaac, P. Jolivet, D. Karpeyev, D. Kaushik, M. Knepley, F. Kong, S. Kruger, D. May, L. Curfman McInnes, R. Mills, L. Mitchell, T. Munson, J. Roman, K. Rupp, P. Sanan, J Sarich, B. Smith, S. Zampini, H. Zhang, and H. Zhang, J. Zhang, *PETSc/TAO Users Manual*, ANL-21/39 - Revision 3.20, 2023. http://dx.doi.org/10.2172/2205494, https://petsc.org/release/docs/manual/manual.pdf ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709010084.0 petsc4py-3.20.5/src/petsc4py.egg-info/SOURCES.txt0000644000175000017500000001622614567266244020325 0ustar00balaybalayCHANGES.rst DESCRIPTION.rst LICENSE.rst MANIFEST.in README.rst setup.cfg setup.py conf/__init__.py conf/confpetsc.py conf/cyautodoc.py conf/cythonize.py conf/cythonize.sh conf/epydoc.cfg conf/epydocify.py conf/stubgen.py demo/legacy/makefile demo/legacy/binary-io/makefile demo/legacy/binary-io/matvecio.py demo/legacy/bratu2d/bratu2d.py demo/legacy/bratu2d/bratu2df90.f90 demo/legacy/bratu2d/bratu2dnpy.py demo/legacy/bratu2d/makefile demo/legacy/bratu3d/bratu3d.py demo/legacy/bratu3d/makefile demo/legacy/dmplex/anisotropic_adaptation.py demo/legacy/dmplex/distribute_field.py demo/legacy/dmplex/isotropic_adaptation.py demo/legacy/kspsolve/makefile demo/legacy/kspsolve/petsc-cg.py demo/legacy/kspsolve/petsc-ksp.py demo/legacy/kspsolve/petsc-mat.py demo/legacy/kspsolve/test_mat_cg.py demo/legacy/kspsolve/test_mat_ksp.py demo/legacy/ode/bouncing_ball.py demo/legacy/ode/ce.py demo/legacy/ode/heat.py demo/legacy/ode/orego.py demo/legacy/ode/rober.py demo/legacy/ode/vanderpol.py demo/legacy/perftest/App.f90 demo/legacy/perftest/App.pyf demo/legacy/perftest/driver.c demo/legacy/perftest/driver.py demo/legacy/perftest/makefile demo/legacy/perftest/makefile.f2py demo/legacy/perftest/makefile.petsc demo/legacy/petsc-examples/makefile demo/legacy/petsc-examples/ksp/ex2.py demo/legacy/petsc-examples/ksp/ex23.py demo/legacy/petsc-examples/ksp/makefile demo/legacy/poisson2d/makefile demo/legacy/poisson2d/poisson2d.py demo/legacy/poisson3d/del2lib.f90 demo/legacy/poisson3d/del2mat.h demo/legacy/poisson3d/del2mat.py demo/legacy/poisson3d/makefile demo/legacy/poisson3d/makefile.petsc demo/legacy/poisson3d/poisson3d.c demo/legacy/poisson3d/poisson3d.py demo/legacy/taosolve/chwirut.py demo/legacy/taosolve/rosenbrock.py demo/legacy/wrap-cython/Bratu3D.pyx demo/legacy/wrap-cython/Bratu3Dimpl.c demo/legacy/wrap-cython/Bratu3Dimpl.h demo/legacy/wrap-cython/makefile demo/legacy/wrap-cython/run_demo.py demo/legacy/wrap-cython/setup.py demo/legacy/wrap-f2py/.f2py_f2cmap demo/legacy/wrap-f2py/Bratu2D.F90 demo/legacy/wrap-f2py/Bratu2D.pyf demo/legacy/wrap-f2py/Bratu2Dmodule.h demo/legacy/wrap-f2py/makefile demo/legacy/wrap-f2py/run_demo.py demo/legacy/wrap-f2py/setup.py demo/legacy/wrap-swig/Bratu3D.c demo/legacy/wrap-swig/Bratu3D.h demo/legacy/wrap-swig/Bratu3D.i demo/legacy/wrap-swig/makefile demo/legacy/wrap-swig/run_demo.py demo/legacy/wrap-swig/setup.py demo/poisson2d/poisson2d.py demo/python_types/ksppython_protocol.py demo/python_types/mat.py demo/python_types/matpython_protocol.py demo/python_types/pc.py demo/python_types/pcpython_protocol.py docs/index.rst docs/source/.gitignore docs/source/Makefile docs/source/apidoc.py docs/source/citing.rst docs/source/conf.py docs/source/documentation_standards.rst docs/source/index.rst docs/source/install.rst docs/source/links.txt docs/source/overview.rst docs/source/petsc_options.rst docs/source/petsc_python_types.rst docs/source/reference.rst docs/source/_templates/layout.html docs/source/_templates/autosummary/class.rst docs/source/_templates/autosummary/module.rst src/cython.h src/lib-petsc/compat.h src/lib-petsc/custom.h src/lib-petsc/initpkg.h src/lib-petsc/compat/cuda.h src/lib-petsc/compat/h2opus.h src/lib-petsc/compat/hdf5.h src/lib-petsc/compat/hip.h src/lib-petsc/compat/hpddm.h src/lib-petsc/compat/hypre.h src/lib-petsc/compat/mpi.h src/lib-petsc/compat/mumps.h src/lib-petsc/compat/spai.h src/lib-petsc/compat/tao.h src/lib-petsc/compat/viennacl.h src/petsc4py/PETSc.pxd src/petsc4py/PETSc.py src/petsc4py/PETSc.pyx src/petsc4py/__init__.pxd src/petsc4py/__init__.py src/petsc4py/__init__.pyi src/petsc4py/__main__.py src/petsc4py/__main__.pyi src/petsc4py/py.typed src/petsc4py/typing.py src/petsc4py.egg-info/PKG-INFO src/petsc4py.egg-info/SOURCES.txt src/petsc4py.egg-info/dependency_links.txt src/petsc4py.egg-info/not-zip-safe src/petsc4py.egg-info/requires.txt src/petsc4py.egg-info/top_level.txt src/petsc4py/PETSc/AO.pyx src/petsc4py/PETSc/CAPI.pyx src/petsc4py/PETSc/Comm.pyx src/petsc4py/PETSc/Const.pyx src/petsc4py/PETSc/DM.pyx src/petsc4py/PETSc/DMComposite.pyx src/petsc4py/PETSc/DMDA.pyx src/petsc4py/PETSc/DMLabel.pyx src/petsc4py/PETSc/DMPlex.pyx src/petsc4py/PETSc/DMShell.pyx src/petsc4py/PETSc/DMStag.pyx src/petsc4py/PETSc/DMSwarm.pyx src/petsc4py/PETSc/DMUtils.pyx src/petsc4py/PETSc/DS.pyx src/petsc4py/PETSc/DT.pyx src/petsc4py/PETSc/Device.pyx src/petsc4py/PETSc/Error.pyx src/petsc4py/PETSc/FE.pyx src/petsc4py/PETSc/IS.pyx src/petsc4py/PETSc/KSP.pyx src/petsc4py/PETSc/Log.pyx src/petsc4py/PETSc/Mat.pyx src/petsc4py/PETSc/MatPartitioning.pyx src/petsc4py/PETSc/Object.pyx src/petsc4py/PETSc/Options.pyx src/petsc4py/PETSc/PC.pyx src/petsc4py/PETSc/PETSc.pyx src/petsc4py/PETSc/Partitioner.pyx src/petsc4py/PETSc/Random.pyx src/petsc4py/PETSc/SF.pyx src/petsc4py/PETSc/SNES.pyx src/petsc4py/PETSc/Scatter.pyx src/petsc4py/PETSc/Section.pyx src/petsc4py/PETSc/Space.pyx src/petsc4py/PETSc/Sys.pyx src/petsc4py/PETSc/TAO.pyx src/petsc4py/PETSc/TS.pyx src/petsc4py/PETSc/Vec.pyx src/petsc4py/PETSc/Viewer.pyx src/petsc4py/PETSc/arraynpy.pxi src/petsc4py/PETSc/cyclicgc.pxi src/petsc4py/PETSc/dlpack.pxi src/petsc4py/PETSc/libpetsc4py.pyx src/petsc4py/PETSc/petscao.pxi src/petsc4py/PETSc/petscdef.pxi src/petsc4py/PETSc/petscdevice.pxi src/petsc4py/PETSc/petscdm.pxi src/petsc4py/PETSc/petscdmcomposite.pxi src/petsc4py/PETSc/petscdmda.pxi src/petsc4py/PETSc/petscdmlabel.pxi src/petsc4py/PETSc/petscdmplex.pxi src/petsc4py/PETSc/petscdmshell.pxi src/petsc4py/PETSc/petscdmstag.pxi src/petsc4py/PETSc/petscdmswarm.pxi src/petsc4py/PETSc/petscdmutils.pxi src/petsc4py/PETSc/petscds.pxi src/petsc4py/PETSc/petscdt.pxi src/petsc4py/PETSc/petscfe.pxi src/petsc4py/PETSc/petscis.pxi src/petsc4py/PETSc/petscksp.pxi src/petsc4py/PETSc/petsclayout.pxi src/petsc4py/PETSc/petsclog.pxi src/petsc4py/PETSc/petscmat.pxi src/petsc4py/PETSc/petscmatpartitioning.pxi src/petsc4py/PETSc/petscmem.pxi src/petsc4py/PETSc/petscmpi.pxi src/petsc4py/PETSc/petscobj.pxi src/petsc4py/PETSc/petscopt.pxi src/petsc4py/PETSc/petscpartitioner.pxi src/petsc4py/PETSc/petscpc.pxi src/petsc4py/PETSc/petscpyappctx.pxi src/petsc4py/PETSc/petscrand.pxi src/petsc4py/PETSc/petscsct.pxi src/petsc4py/PETSc/petscsec.pxi src/petsc4py/PETSc/petscsf.pxi src/petsc4py/PETSc/petscsnes.pxi src/petsc4py/PETSc/petscspace.pxi src/petsc4py/PETSc/petscsys.pxi src/petsc4py/PETSc/petsctao.pxi src/petsc4py/PETSc/petscts.pxi src/petsc4py/PETSc/petscvec.pxi src/petsc4py/PETSc/petscvwr.pxi src/petsc4py/PETSc/typing.pxi src/petsc4py/include/petsc4py/numpy.h src/petsc4py/include/petsc4py/petsc4py.h src/petsc4py/include/petsc4py/petsc4py.i src/petsc4py/include/petsc4py/pybuffer.h src/petsc4py/include/petsc4py/pyscalar.h src/petsc4py/lib/__init__.py src/petsc4py/lib/__init__.pyi src/petsc4py/lib/petsc.cfg test/runtests.py test/test_comm.py test/test_dmda.py test/test_dmplex.py test/test_dmshell.py test/test_dmstag.py test/test_gc.py test/test_is.py test/test_ksp.py test/test_ksp_py.py test/test_lgmap.py test/test_log.py test/test_mat_aij.py test/test_mat_dense.py test/test_mat_fact.py test/test_mat_py.py test/test_nsp.py test/test_object.py test/test_optdb.py test/test_pc_py.py test/test_snes.py test/test_snes_py.py test/test_stdout.py test/test_sys.py test/test_tao.py test/test_tao_py.py test/test_ts.py test/test_ts_py.py test/test_vec.py././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709010084.0 petsc4py-3.20.5/src/petsc4py.egg-info/dependency_links.txt0000644000175000017500000000000114567266244022500 0ustar00balaybalay ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709009280.0 petsc4py-3.20.5/src/petsc4py.egg-info/not-zip-safe0000644000175000017500000000000114567264600020652 0ustar00balaybalay ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709010084.0 petsc4py-3.20.5/src/petsc4py.egg-info/requires.txt0000644000175000017500000000017014567266244021030 0ustar00balaybalaynumpy [doc] pydata-sphinx-theme==0.15.1 sphinx>=7.0.0 sphobjinv pylit [doc:python_version < "3.11"] typing_extensions ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709010084.0 petsc4py-3.20.5/src/petsc4py.egg-info/top_level.txt0000644000175000017500000000001114567266244021154 0ustar00balaybalaypetsc4py ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1709010084.4493752 petsc4py-3.20.5/test/0000755000175000017500000000000014567266244013355 5ustar00balaybalay././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/test/runtests.py0000644000175000017500000001701214567251135015610 0ustar00balaybalay# Author: Lisandro Dalcin # Contact: dalcinl@gmail.com import os import sys import optparse import unittest __unittest = True components = [ 'PETSc', ] def getoptionparser(): parser = optparse.OptionParser() parser.add_option("-q", "--quiet", action="store_const", const=0, dest="verbose", default=1, help="do not print status messages to stdout") parser.add_option("-v", "--verbose", action="store_const", const=2, dest="verbose", default=1, help="print status messages to stdout") parser.add_option("-i", "--include", type="string", action="append", dest="include", default=[], help="include tests matching PATTERN", metavar="PATTERN") parser.add_option("-e", "--exclude", type="string", action="append", dest="exclude", default=[], help="exclude tests matching PATTERN", metavar="PATTERN") parser.add_option("-k", "--pattern", type="string", action="append", dest="patterns", default=[], help="only run tests which match the given substring") parser.add_option("-f", "--failfast", action="store_true", dest="failfast", default=False, help="Stop on first failure") parser.add_option("--no-builddir", action="store_false", dest="builddir", default=True, help="disable testing from build directory") parser.add_option("--path", type="string", action="append", dest="path", default=[], help="prepend PATH to sys.path", metavar="PATH") parser.add_option("--arch", type="string", action="store", dest="arch", default=None, help="use PETSC_ARCH", metavar="PETSC_ARCH") parser.add_option("-s","--summary", action="store_true", dest="summary", default=0, help="print PETSc log summary") parser.add_option("--no-memdebug", action="store_false", dest="memdebug", default=True, help="Do not use PETSc memory debugging") return parser def getbuilddir(): try: try: from setuptools.dist import Distribution except ImportError: from distutils.dist import Distribution try: from setuptools.command.build import build except ImportError: from distutils.command.build import build cmd_obj = build(Distribution()) cmd_obj.finalize_options() return cmd_obj.build_platlib except Exception: return None def getprocessorinfo(): try: name = os.uname()[1] except: import platform name = platform.uname()[1] from petsc4py.PETSc import COMM_WORLD rank = COMM_WORLD.getRank() return (rank, name) def getlibraryinfo(name): modname = "%s4py.%s" % (name.lower(), name) module = __import__(modname, fromlist=[name]) (major, minor, micro), devel = module.Sys.getVersion(devel=True) r = not devel if r: release = 'release' else: release = 'development' arch = module.__arch__ return ( "%s %d.%d.%d %s (conf: '%s')" % (name, major, minor, micro, release, arch) ) def getpythoninfo(): x, y, z = sys.version_info[:3] return ("Python %d.%d.%d (%s)" % (x, y, z, sys.executable)) def getpackageinfo(pkg): try: pkg = __import__(pkg) except ImportError: return None name = pkg.__name__ version = pkg.__version__ path = pkg.__path__[0] return ("%s %s (%s)" % (name, version, path)) def setup_python(options): rootdir = os.path.dirname(os.path.dirname(__file__)) builddir = os.path.join(rootdir, getbuilddir()) if options.builddir and os.path.exists(builddir): sys.path.insert(0, builddir) if options.path: path = options.path[:] path.reverse() for p in path: sys.path.insert(0, p) def setup_unittest(options): from unittest import TestSuite try: from unittest.runner import _WritelnDecorator except ImportError: from unittest import _WritelnDecorator # writeln_orig = _WritelnDecorator.writeln def writeln(self, message=''): try: self.stream.flush() except: pass writeln_orig(self, message) try: self.stream.flush() except: pass _WritelnDecorator.writeln = writeln def import_package(options, pkgname): args = [sys.argv[0]] if options.memdebug: args.append('-malloc_debug') args.append('-malloc_dump') if options.summary: args.append('-log_view') package = __import__(pkgname) package.init(args, arch=options.arch) def print_banner(options): r, n = getprocessorinfo() prefix = "[%d@%s]" % (r, n) def writeln(message='', endl='\n'): if message is None: return from petsc4py.PETSc import Sys message = "%s %s" % (prefix, message) Sys.syncPrint(message, endl=endl, flush=True) if options.verbose: writeln(getpythoninfo()) writeln(getpackageinfo('numpy')) for entry in components: writeln(getlibraryinfo(entry)) writeln(getpackageinfo('%s4py' % entry.lower())) def load_tests(options, args): from glob import glob import re testsuitedir = os.path.dirname(__file__) sys.path.insert(0, testsuitedir) pattern = 'test_*.py' wildcard = os.path.join(testsuitedir, pattern) testfiles = glob(wildcard) testfiles.sort() testsuite = unittest.TestSuite() testloader = unittest.TestLoader() if options.patterns: testloader.testNamePatterns = [ ('*%s*' % p) if ('*' not in p) else p for p in options.patterns ] include = exclude = None if options.include: include = re.compile('|'.join(options.include)).search if options.exclude: exclude = re.compile('|'.join(options.exclude)).search for testfile in testfiles: filename = os.path.basename(testfile) testname = os.path.splitext(filename)[0] if ((exclude and exclude(testname)) or (include and not include(testname))): continue module = __import__(testname) for arg in args: try: cases = testloader.loadTestsFromNames((arg,), module) testsuite.addTests(cases) except AttributeError: pass if not args: cases = testloader.loadTestsFromModule(module) testsuite.addTests(cases) return testsuite def run_tests(options, testsuite, runner=None): if runner is None: runner = unittest.TextTestRunner(verbosity=options.verbose) runner.failfast = options.failfast result = runner.run(testsuite) return result.wasSuccessful() def abort(code=1): os.abort() def shutdown(success): pass def main(args=None): pkgname = '%s4py' % components[-1].lower() parser = getoptionparser() (options, args) = parser.parse_args(args) setup_python(options) setup_unittest(options) import_package(options, pkgname) print_banner(options) testsuite = load_tests(options, args) success = run_tests(options, testsuite) if not success and options.failfast: abort() shutdown(success) return not success if __name__ == '__main__': import sys sys.dont_write_bytecode = True sys.exit(main()) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/test/test_comm.py0000644000175000017500000000572614567251135015724 0ustar00balaybalayfrom petsc4py import PETSc import unittest # -------------------------------------------------------------------- class TestComm(unittest.TestCase): def testInit(self): comm_null1 = PETSc.Comm() comm_null2 = PETSc.Comm(PETSc.COMM_NULL) comm_world = PETSc.Comm(PETSc.COMM_WORLD) comm_self = PETSc.Comm(PETSc.COMM_SELF) self.assertEqual(comm_null1, PETSc.COMM_NULL) self.assertEqual(comm_null2, PETSc.COMM_NULL) self.assertEqual(comm_world, PETSc.COMM_WORLD) self.assertEqual(comm_self, PETSc.COMM_SELF) def testDupDestr(self): self.assertRaises(ValueError, PETSc.COMM_NULL.duplicate) comm = PETSc.COMM_SELF.duplicate() comm.destroy() self.assertEqual(comm, PETSc.COMM_NULL) del comm comm = PETSc.COMM_WORLD.duplicate() comm.destroy() self.assertEqual(comm, PETSc.COMM_NULL) del comm def testBarrier(self): self.assertRaises(ValueError, PETSc.COMM_NULL.barrier) PETSc.COMM_SELF.barrier() PETSc.COMM_WORLD.barrier() def testSize(self): self.assertRaises(ValueError, PETSc.COMM_NULL.getSize) self.assertTrue(PETSc.COMM_WORLD.getSize() >= 1) self.assertEqual(PETSc.COMM_SELF.getSize(), 1) def testRank(self): self.assertRaises(ValueError, PETSc.COMM_NULL.getRank) self.assertEqual(PETSc.COMM_SELF.getRank(), 0) self.assertTrue(PETSc.COMM_WORLD.getRank() >= 0) def testProperties(self): self.assertEqual(PETSc.COMM_SELF.getSize(), PETSc.COMM_SELF.size) self.assertEqual(PETSc.COMM_SELF.getRank(), PETSc.COMM_SELF.rank) self.assertEqual(PETSc.COMM_WORLD.getSize(), PETSc.COMM_WORLD.size) self.assertEqual(PETSc.COMM_WORLD.getRank(), PETSc.COMM_WORLD.rank) def testCompatMPI4PY(self): try: from mpi4py import MPI except ImportError: return # mpi4py -> petsc4py cn = PETSc.Comm(MPI.COMM_NULL) cs = PETSc.Comm(MPI.COMM_SELF) cw = PETSc.Comm(MPI.COMM_WORLD) self.assertEqual(cn, PETSc.COMM_NULL) self.assertEqual(cs, PETSc.COMM_SELF) self.assertEqual(cw, PETSc.COMM_WORLD) # petsc4py - > mpi4py cn = PETSc.COMM_NULL.tompi4py() self.assertTrue(isinstance(cn, MPI.Comm)) self.assertFalse(cn) cs = PETSc.COMM_SELF.tompi4py() self.assertTrue(isinstance(cs, MPI.Intracomm)) self.assertEqual(cs.Get_size(), 1) self.assertEqual(cs.Get_rank(), 0) cw = PETSc.COMM_WORLD.tompi4py() self.assertTrue(isinstance(cw, MPI.Intracomm)) self.assertEqual(cw.Get_size(), PETSc.COMM_WORLD.getSize()) self.assertEqual(cw.Get_rank(), PETSc.COMM_WORLD.getRank()) # -------------------------------------------------------------------- if __name__ == '__main__': unittest.main() ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/test/test_dmda.py0000644000175000017500000003627014567251135015674 0ustar00balaybalayfrom petsc4py import PETSc import unittest # -------------------------------------------------------------------- class BaseTestDA(object): COMM = PETSc.COMM_WORLD SIZES = None BOUNDARY = None DOF = 1 STENCIL = PETSc.DMDA.StencilType.STAR SWIDTH = 1 def setUp(self): self.da = PETSc.DMDA().create(dim=len(self.SIZES), dof=self.DOF, sizes=self.SIZES, boundary_type=self.BOUNDARY, stencil_type=self.STENCIL, stencil_width=self.SWIDTH, comm=self.COMM) def tearDown(self): self.da = None PETSc.garbage_cleanup() def testGetInfo(self): dim = self.da.getDim() dof = self.da.getDof() sizes = self.da.getSizes() psizes = self.da.getProcSizes() boundary = self.da.getBoundaryType() stencil_type = self.da.getStencilType() stencil_width = self.da.getStencilWidth() self.assertEqual(dim, len(self.SIZES)) self.assertEqual(dof, self.DOF) self.assertEqual(sizes, tuple(self.SIZES)) self.assertEqual(boundary, self.BOUNDARY or (0,)*dim) self.assertEqual(stencil_type, self.STENCIL) self.assertEqual(stencil_width, self.SWIDTH) def testRangesCorners(self): dim = self.da.getDim() ranges = self.da.getRanges() starts, lsizes = self.da.getCorners() self.assertEqual(dim, len(ranges)) self.assertEqual(dim, len(starts)) self.assertEqual(dim, len(lsizes)) for i in range(dim): s, e = ranges[i] self.assertEqual(s, starts[i]) self.assertEqual(e-s, lsizes[i]) def testGhostRangesCorners(self): dim = self.da.getDim() ranges = self.da.getGhostRanges() starts, lsizes = self.da.getGhostCorners() self.assertEqual(dim, len(ranges)) self.assertEqual(dim, len(starts)) self.assertEqual(dim, len(lsizes)) for i in range(dim): s, e = ranges[i] self.assertEqual(s, starts[i]) self.assertEqual(e-s, lsizes[i]) def testOwnershipRanges(self): dim = self.da.getDim() ownership_ranges = self.da.getOwnershipRanges() procsizes = self.da.getProcSizes() self.assertEqual(len(procsizes), len(ownership_ranges)) for i,m in enumerate(procsizes): self.assertEqual(m, len(ownership_ranges[i])) def testFieldName(self): for i in range(self.da.getDof()): self.da.setFieldName(i, "field%d" % i) for i in range(self.da.getDof()): name = self.da.getFieldName(i) self.assertEqual(name, "field%d" % i) def testCoordinates(self): self.da.setUniformCoordinates(0,1,0,1,0,1) # c = self.da.getCoordinates() self.da.setCoordinates(c) c.destroy() cda = self.da.getCoordinateDM() cda.destroy() # c = self.da.getCoordinates() self.da.setCoordinates(c) c.destroy() gc = self.da.getCoordinatesLocal() gc.destroy() def testCreateVecMat(self): vn = self.da.createNaturalVec() vg = self.da.createGlobalVec() vl = self.da.createLocalVec() mat = self.da.createMat() self.assertTrue(mat.getType() in ('aij', 'seqaij', 'mpiaij')) vn.set(1.0) self.da.naturalToGlobal(vn,vg) self.assertEqual(vg.max()[1], 1.0) self.assertEqual(vg.min()[1], 1.0) self.da.globalToLocal(vg,vl) self.assertEqual(vl.max()[1], 1.0) self.assertTrue (vl.min()[1] in (1.0, 0.0)) vn.set(0.0) self.da.globalToNatural(vg,vn) self.assertEqual(vn.max()[1], 1.0) self.assertEqual(vn.min()[1], 1.0) vl2 = self.da.createLocalVec() self.da.localToLocal(vl,vl2) self.assertEqual(vl2.max()[1], 1.0) self.assertTrue (vl2.min()[1] in (1.0, 0.0)) NONE = PETSc.DM.BoundaryType.NONE s = self.da.stencil_width btype = self.da.boundary_type psize = self.da.proc_sizes for b, p in zip(btype, psize): if b != NONE and p == 1: return vg2 = self.da.createGlobalVec() self.da.localToGlobal(vl2,vg2) def testGetVec(self): vg = self.da.getGlobalVec() vl = self.da.getLocalVec() try: vg.set(1.0) self.assertEqual(vg.max()[1], 1.0) self.assertEqual(vg.min()[1], 1.0) self.da.globalToLocal(vg,vl) self.assertEqual(vl.max()[1], 1.0) self.assertTrue (vl.min()[1] in (1.0, 0.0)) vl.set(2.0) NONE = PETSc.DM.BoundaryType.NONE s = self.da.stencil_width btype = self.da.boundary_type psize = self.da.proc_sizes for b, p in zip(btype, psize): if b != NONE and p == 1: return self.da.localToGlobal(vl,vg) self.assertEqual(vg.max()[1], 2.0) self.assertTrue (vg.min()[1] in (2.0, 0.0)) finally: self.da.restoreGlobalVec(vg) self.da.restoreLocalVec(vl) def testGetOther(self): ao = self.da.getAO() lgmap = self.da.getLGMap() l2g, g2l = self.da.getScatter() def testRefineCoarsen(self): da = self.da rda = da.refine() self.assertEqual(da.getDim(), rda.getDim()) self.assertEqual(da.getDof(), rda.getDof()) if da.dim != 1: self.assertEqual(da.getStencilType(), rda.getStencilType()) self.assertEqual(da.getStencilWidth(), rda.getStencilWidth()) cda = rda.coarsen() self.assertEqual(rda.getDim(), cda.getDim()) self.assertEqual(rda.getDof(), cda.getDof()) for n1, n2 in zip(self.da.getSizes(), cda.getSizes()): self.assertTrue(abs(n1-n2)<=1) def testCoarsenRefine(self): da = self.da cda = self.da.coarsen() self.assertEqual(da.getDim(), cda.getDim()) self.assertEqual(da.getDof(), cda.getDof()) if da.dim != 1: self.assertEqual(da.getStencilType(), cda.getStencilType()) self.assertEqual(da.getStencilWidth(), cda.getStencilWidth()) rda = cda.refine() for n1, n2 in zip(self.da.getSizes(), rda.getSizes()): self.assertTrue(abs(n1-n2)<=1) def testRefineHierarchy(self): levels = self.da.refineHierarchy(2) self.assertTrue(isinstance(levels, list)) self.assertEqual(len(levels), 2) for item in levels: self.assertTrue(isinstance(item, PETSc.DM)) def testCoarsenHierarchy(self): levels = self.da.coarsenHierarchy(2) self.assertTrue(isinstance(levels, list)) self.assertEqual(len(levels), 2) for item in levels: self.assertTrue(isinstance(item, PETSc.DM)) def testCreateInterpolation(self): da = self.da if da.dim == 1: return rda = da.refine() mat, vec = da.createInterpolation(rda) def testCreateInjection(self): da = self.da if da.dim == 1: return rda = da.refine() scatter = da.createInjection(rda) def testzeroRowsColumnsStencil(self): da = self.da A = da.createMatrix() x = da.createGlobalVector() x.set(2.0) A.setDiagonal(x) diag1 = x.duplicate() A.getDiagonal(diag1) if self.SIZES != 2: #only coded test for 2D case return istart,iend, jstart, jend = da.getRanges() self.assertTrue(x.equal(diag1)) zeroidx = [] for i in range(istart,iend): for j in range(jstart,jend): row = PETSc.Mat.Stencil() row.index = (i,j) zeroidx = zeroidx + [row] diag2 = x.duplicate() diag2.set(1.0) A.zeroRowsColumnsStencil(zeroidx, 1.0, x, diag2) ans = x.duplicate() ans.set(2.0) self.assertTrue(ans.equal(diag2)) MIRROR = PETSc.DMDA.BoundaryType.MIRROR GHOSTED = PETSc.DMDA.BoundaryType.GHOSTED PERIODIC = PETSc.DMDA.BoundaryType.PERIODIC TWIST = PETSc.DMDA.BoundaryType.TWIST SCALE = 4 class BaseTestDA_1D(BaseTestDA): SIZES = [100*SCALE] class BaseTestDA_2D(BaseTestDA): SIZES = [9*SCALE,11*SCALE] class BaseTestDA_3D(BaseTestDA): SIZES = [6*SCALE,7*SCALE,8*SCALE] # -------------------------------------------------------------------- class TestDA_1D(BaseTestDA_1D, unittest.TestCase): pass class TestDA_1D_W0(TestDA_1D): SWIDTH = 0 class TestDA_1D_W2(TestDA_1D): SWIDTH = 2 class TestDA_2D(BaseTestDA_2D, unittest.TestCase): pass class TestDA_2D_W0(TestDA_2D): SWIDTH = 0 class TestDA_2D_W0_N2(TestDA_2D): DOF = 2 SWIDTH = 0 class TestDA_2D_W2(TestDA_2D): SWIDTH = 2 class TestDA_2D_W2_N2(TestDA_2D): DOF = 2 SWIDTH = 2 class TestDA_2D_PXY(TestDA_2D): SIZES = [13*SCALE,17*SCALE] DOF = 2 SWIDTH = 5 BOUNDARY = (PERIODIC,)*2 class TestDA_2D_GXY(TestDA_2D): SIZES = [13*SCALE,17*SCALE] DOF = 2 SWIDTH = 5 BOUNDARY = (GHOSTED,)*2 class TestDA_2D_TXY(TestDA_2D): SIZES = [13*SCALE,17*SCALE] DOF = 2 SWIDTH = 5 BOUNDARY = (TWIST,)*2 class TestDA_3D(BaseTestDA_3D, unittest.TestCase): pass class TestDA_3D_W0(TestDA_3D): SWIDTH = 0 class TestDA_3D_W0_N2(TestDA_3D): DOF = 2 SWIDTH = 0 class TestDA_3D_W2(TestDA_3D): SWIDTH = 2 class TestDA_3D_W2_N2(TestDA_3D): DOF = 2 SWIDTH = 2 class TestDA_3D_PXYZ(TestDA_3D): SIZES = [11*SCALE,13*SCALE,17*SCALE] DOF = 2 SWIDTH = 3 BOUNDARY = (PERIODIC,)*3 class TestDA_3D_GXYZ(TestDA_3D): SIZES = [11*SCALE,13*SCALE,17*SCALE] DOF = 2 SWIDTH = 3 BOUNDARY = (GHOSTED,)*3 class TestDA_3D_TXYZ(TestDA_3D): SIZES = [11*SCALE,13*SCALE,17*SCALE] DOF = 2 SWIDTH = 3 BOUNDARY = (TWIST,)*3 # -------------------------------------------------------------------- DIM = (1,2,3,) DOF = (None,1,2,3,4,5,) BOUNDARY_TYPE = ( None, "none", (0,)*3, 0, "ghosted", (GHOSTED,)*3, GHOSTED, "periodic", (PERIODIC,)*3, PERIODIC, "twist", (TWIST,)*3, TWIST, ) STENCIL_TYPE = (None,"star","box") STENCIL_WIDTH = (None,0,1,2,3) DIM = (1,2,3) DOF = (None,2,5) BOUNDARY_TYPE = (None,"none","periodic","ghosted","twist") STENCIL_TYPE = (None,"box") STENCIL_WIDTH = (None,1,2) class TestDACreate(unittest.TestCase): pass counter = 0 for dim in DIM: for dof in DOF: for boundary in BOUNDARY_TYPE: if isinstance(boundary, tuple): boundary = boundary[:dim] for stencil in STENCIL_TYPE: for width in STENCIL_WIDTH: kargs = dict(sizes=[8*SCALE]*dim, dim=dim, dof=dof, boundary_type=boundary, stencil_type=stencil, stencil_width=width) def testCreate(self, kargs=kargs): kargs = dict(kargs) da = PETSc.DMDA().create(**kargs) da.destroy() setattr(TestDACreate, "testCreate%04d"%counter, testCreate) del testCreate, kargs counter += 1 del counter, dim, dof, boundary, stencil, width class TestDADuplicate(unittest.TestCase): pass counter = 0 for dim in DIM: for dof in DOF: for boundary in BOUNDARY_TYPE: if isinstance(boundary, tuple): boundary = boundary[:dim] for stencil in STENCIL_TYPE: for width in STENCIL_WIDTH: kargs = dict(dim=dim, dof=dof, boundary_type=boundary, stencil_type=stencil, stencil_width=width) def testDuplicate(self, kargs=kargs): kargs = dict(kargs) dim = kargs.pop('dim') dof = kargs['dof'] boundary = kargs['boundary_type'] stencil = kargs['stencil_type'] width = kargs['stencil_width'] da = PETSc.DMDA().create([8*SCALE]*dim) newda = da.duplicate(**kargs) self.assertEqual(newda.dim, da.dim) self.assertEqual(newda.sizes, da.sizes) self.assertEqual(newda.proc_sizes, da.proc_sizes) self.assertEqual(newda.ranges, da.ranges) self.assertEqual(newda.corners, da.corners) if (newda.boundary_type == da.boundary_type and newda.stencil_width == da.stencil_width): self.assertEqual(newda.ghost_ranges, da.ghost_ranges) self.assertEqual(newda.ghost_corners, da.ghost_corners) if dof is None: dof = da.dof if boundary is None: boundary = da.boundary_type elif boundary == "none": boundary = (0,) * dim elif boundary == "mirror": boundary = (MIRROR,) * dim elif boundary == "ghosted": boundary = (GHOSTED,) * dim elif boundary == "periodic": boundary = (PERIODIC,) * dim elif boundary == "twist": boundary = (TWIST,) * dim elif isinstance(boundary, int): boundary = (boundary,) * dim if stencil is None: stencil = da.stencil[0] if width is None: width = da.stencil_width self.assertEqual(newda.dof, dof) self.assertEqual(newda.boundary_type, boundary) if dim == 1: self.assertEqual(newda.stencil, (stencil, width)) newda.destroy() da.destroy() setattr(TestDADuplicate, "testDuplicate%04d"%counter, testDuplicate) del testDuplicate, kargs counter += 1 del counter, dim, dof, boundary, stencil, width # -------------------------------------------------------------------- if PETSc.COMM_WORLD.getSize() > 1: del TestDA_1D_W0 del TestDA_2D_W0, TestDA_2D_W0_N2 del TestDA_3D_W0, TestDA_3D_W0_N2 # -------------------------------------------------------------------- if __name__ == '__main__': unittest.main() # -------------------------------------------------------------------- ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/test/test_dmplex.py0000644000175000017500000005077214567251135016263 0ustar00balaybalayimport petsc4py from petsc4py import PETSc import unittest import os import filecmp import numpy as np # -------------------------------------------------------------------- ERR_ARG_OUTOFRANGE = 63 class BaseTestPlex(object): COMM = PETSc.COMM_WORLD DIM = 1 CELLS = [[0, 1], [1, 2]] COORDS = [[0.], [0.5], [1.]] COMP = 1 DOFS = [1, 0] def setUp(self): self.plex = PETSc.DMPlex().createFromCellList(self.DIM, self.CELLS, self.COORDS, comm=self.COMM) def tearDown(self): self.plex.destroy() self.plex = None PETSc.garbage_cleanup() def testTopology(self): rank = self.COMM.rank dim = self.plex.getDimension() pStart, pEnd = self.plex.getChart() cStart, cEnd = self.plex.getHeightStratum(0) vStart, vEnd = self.plex.getDepthStratum(0) numDepths = self.plex.getLabelSize("depth") coords_raw = self.plex.getCoordinates().getArray() coords = np.reshape(coords_raw, (vEnd - vStart, dim)) self.assertEqual(dim, self.DIM) self.assertEqual(numDepths, self.DIM+1) if rank == 0 and self.CELLS is not None: self.assertEqual(cEnd-cStart, len(self.CELLS)) if rank == 0 and self.COORDS is not None: self.assertEqual(vEnd-vStart, len(self.COORDS)) self.assertTrue((coords == self.COORDS).all()) def testClosure(self): pStart, pEnd = self.plex.getChart() for p in range(pStart, pEnd): closure = self.plex.getTransitiveClosure(p)[0] for c in closure: cone = self.plex.getCone(c) self.assertEqual(self.plex.getConeSize(c), len(cone)) for i in cone: self.assertIn(i, closure) star = self.plex.getTransitiveClosure(p, useCone=False)[0] for s in star: support = self.plex.getSupport(s) self.assertEqual(self.plex.getSupportSize(s), len(support)) for i in support: self.assertIn(i, star) def testAdjacency(self): PETSc.DMPlex.setAdjacencyUseAnchors(self.plex, False) flag = PETSc.DMPlex.getAdjacencyUseAnchors(self.plex) self.assertFalse(flag) PETSc.DMPlex.setAdjacencyUseAnchors(self.plex, True) flag = PETSc.DMPlex.getAdjacencyUseAnchors(self.plex) self.assertTrue(flag) PETSc.DMPlex.setBasicAdjacency(self.plex, False, False) flagA, flagB = PETSc.DMPlex.getBasicAdjacency(self.plex) self.assertFalse(flagA) self.assertFalse(flagB) PETSc.DMPlex.setBasicAdjacency(self.plex, True, True) flagA, flagB = PETSc.DMPlex.getBasicAdjacency(self.plex) self.assertTrue(flagA) self.assertTrue(flagB) pStart, pEnd = self.plex.getChart() for p in range(pStart, pEnd): adjacency = self.plex.getAdjacency(p) self.assertTrue(p in adjacency) self.assertTrue(len(adjacency) > 1) def testSectionDofs(self): self.plex.setNumFields(1) section = self.plex.createSection([self.COMP], [self.DOFS]) size = section.getStorageSize() entity_dofs = [self.plex.getStratumSize("depth", d) * self.DOFS[d] for d in range(self.DIM+1)] self.assertEqual(sum(entity_dofs), size) def testSectionClosure(self): section = self.plex.createSection([self.COMP], [self.DOFS]) self.plex.setSection(section) vec = self.plex.createLocalVec() pStart, pEnd = self.plex.getChart() for p in range(pStart, pEnd): for i in range(section.getDof(p)): off = section.getOffset(p) vec.setValue(off+i, p) for p in range(pStart, pEnd): point_closure = self.plex.getTransitiveClosure(p)[0] dof_closure = self.plex.vecGetClosure(section, vec, p) for p in dof_closure: self.assertIn(p, point_closure) def testBoundaryLabel(self): pStart, pEnd = self.plex.getChart() if (pEnd - pStart == 0): return self.assertFalse(self.plex.hasLabel("boundary")) self.plex.markBoundaryFaces("boundary") self.assertTrue(self.plex.hasLabel("boundary")) faces = self.plex.getStratumIS("boundary", 1) for f in faces.getIndices(): points, orient = self.plex.getTransitiveClosure(f, useCone=True) for p in points: self.plex.setLabelValue("boundary", p, 1) for p in range(pStart, pEnd): if self.plex.getLabelValue("boundary", p) != 1: self.plex.setLabelValue("boundary", p, 2) numBoundary = self.plex.getStratumSize("boundary", 1) numInterior = self.plex.getStratumSize("boundary", 2) self.assertNotEqual(numBoundary, pEnd - pStart) self.assertNotEqual(numInterior, pEnd - pStart) self.assertEqual(numBoundary + numInterior, pEnd - pStart) def testMetric(self): if self.DIM == 1: return self.plex.distribute() if self.CELLS is None and not self.plex.isSimplex(): return self.plex.orient() h_min = 1.0e-30 h_max = 1.0e+30 a_max = 1.0e+10 target = 8.0 p = 1.0 beta = 1.3 hausd = 0.01 self.plex.metricSetUniform(False) self.plex.metricSetIsotropic(False) self.plex.metricSetRestrictAnisotropyFirst(False) self.plex.metricSetNoInsertion(False) self.plex.metricSetNoSwapping(False) self.plex.metricSetNoMovement(False) self.plex.metricSetNoSurf(False) self.plex.metricSetVerbosity(-1) self.plex.metricSetNumIterations(3) self.plex.metricSetMinimumMagnitude(h_min) self.plex.metricSetMaximumMagnitude(h_max) self.plex.metricSetMaximumAnisotropy(a_max) self.plex.metricSetTargetComplexity(target) self.plex.metricSetNormalizationOrder(p) self.plex.metricSetGradationFactor(beta) self.plex.metricSetHausdorffNumber(hausd) self.assertFalse(self.plex.metricIsUniform()) self.assertFalse(self.plex.metricIsIsotropic()) self.assertFalse(self.plex.metricRestrictAnisotropyFirst()) self.assertFalse(self.plex.metricNoInsertion()) self.assertFalse(self.plex.metricNoSwapping()) self.assertFalse(self.plex.metricNoMovement()) self.assertFalse(self.plex.metricNoSurf()) assert self.plex.metricGetVerbosity() == -1 assert self.plex.metricGetNumIterations() == 3 assert np.isclose(self.plex.metricGetMinimumMagnitude(), h_min) assert np.isclose(self.plex.metricGetMaximumMagnitude(), h_max) assert np.isclose(self.plex.metricGetMaximumAnisotropy(), a_max) assert np.isclose(self.plex.metricGetTargetComplexity(), target) assert np.isclose(self.plex.metricGetNormalizationOrder(), p) assert np.isclose(self.plex.metricGetGradationFactor(), beta) assert np.isclose(self.plex.metricGetHausdorffNumber(), hausd) metric1 = self.plex.metricCreateUniform(0.5) metric2 = self.plex.metricCreateUniform(1.0) metric = self.plex.metricCreate() det = self.plex.metricDeterminantCreate() self.plex.metricAverage2(metric1, metric2, metric) metric1.array[:] *= 1.5 assert np.allclose(metric.array, metric1.array) self.plex.metricIntersection2(metric1, metric2, metric) assert np.allclose(metric.array, metric2.array) self.plex.metricEnforceSPD(metric, metric1, det[0]) assert np.allclose(metric.array, metric1.array) self.plex.metricNormalize(metric, metric1, det[0], restrictSizes=False, restrictAnisotropy=False) metric2.scale(pow(target, 2.0/self.DIM)) assert np.allclose(metric1.array, metric2.array) def testAdapt(self): if self.DIM == 1: return self.plex.orient() plex = self.plex.refine() plex.distribute() if self.CELLS is None and not plex.isSimplex(): return if sum(self.DOFS) > 1: return metric = plex.metricCreateUniform(9.0) try: newplex = plex.adaptMetric(metric,"") except PETSc.Error as exc: if exc.ierr != ERR_ARG_OUTOFRANGE: raise # -------------------------------------------------------------------- class BaseTestPlex_2D(BaseTestPlex): DIM = 2 CELLS = [[0, 1, 3], [1, 3, 4], [1, 2, 4], [2, 4, 5], [3, 4, 6], [4, 6, 7], [4, 5, 7], [5, 7, 8]] COORDS = [[0.0, 0.0], [0.5, 0.0], [1.0, 0.0], [0.0, 0.5], [0.5, 0.5], [1.0, 0.5], [0.0, 1.0], [0.5, 1.0], [1.0, 1.0]] DOFS = [1, 0, 0] class BaseTestPlex_3D(BaseTestPlex): DIM = 3 CELLS = [[0, 2, 3, 7], [0, 2, 6, 7], [0, 4, 6, 7], [0, 1, 3, 7], [0, 1, 5, 7], [0, 4, 5, 7]] COORDS = [[0., 0., 0.], [1., 0., 0.], [0., 1., 0.], [1., 1., 0.], [0., 0., 1.], [1., 0., 1.], [0., 1., 1.], [1., 1., 1.]] DOFS = [1, 0, 0, 0] # -------------------------------------------------------------------- class TestPlex_1D(BaseTestPlex, unittest.TestCase): pass class TestPlex_2D(BaseTestPlex_2D, unittest.TestCase): def testTransform(self): plex = self.plex cstart, cend = plex.getHeightStratum(0) tr = PETSc.DMPlexTransform().create(comm=PETSc.COMM_WORLD) tr.setType(PETSc.DMPlexTransformType.REFINEALFELD) tr.setDM(plex) tr.setUp() newplex = tr.apply(plex) tr.destroy() newcstart, newcend = newplex.getHeightStratum(0) newplex.destroy() self.assertTrue((newcend-newcstart) == 3*(cend-cstart)) class TestPlex_3D(BaseTestPlex_3D, unittest.TestCase): pass class TestPlex_2D_P3(BaseTestPlex_2D, unittest.TestCase): DOFS = [1, 2, 1] class TestPlex_3D_P3(BaseTestPlex_3D, unittest.TestCase): DOFS = [1, 2, 1, 0] class TestPlex_3D_P4(BaseTestPlex_3D, unittest.TestCase): DOFS = [1, 3, 3, 1] class TestPlex_2D_BoxTensor(BaseTestPlex_2D, unittest.TestCase): CELLS = None COORDS = None def setUp(self): self.plex = PETSc.DMPlex().createBoxMesh([3,3], simplex=False) class TestPlex_3D_BoxTensor(BaseTestPlex_3D, unittest.TestCase): CELLS = None COORDS = None def setUp(self): self.plex = PETSc.DMPlex().createBoxMesh([3,3,3], simplex=False) try: raise PETSc.Error PETSc.DMPlex().createBoxMesh([2,2], simplex=True, comm=PETSc.COMM_SELF).destroy() except PETSc.Error: pass else: class TestPlex_2D_Box(BaseTestPlex_2D, unittest.TestCase): CELLS = None COORDS = None def setUp(self): self.plex = PETSc.DMPlex().createBoxMesh([1,1], simplex=True) class TestPlex_2D_Boundary(BaseTestPlex_2D, unittest.TestCase): CELLS = None COORDS = None def setUp(self): boundary = PETSc.DMPlex().create(self.COMM) boundary.createSquareBoundary([0., 0.], [1., 1.], [2, 2]) boundary.setDimension(self.DIM-1) self.plex = PETSc.DMPlex().generate(boundary) class TestPlex_3D_Box(BaseTestPlex_3D, unittest.TestCase): CELLS = None COORDS = None def setUp(self): self.plex = PETSc.DMPlex().createBoxMesh([1,1,1], simplex=True) class TestPlex_3D_Boundary(BaseTestPlex_3D, unittest.TestCase): CELLS = None COORDS = None def setUp(self): boundary = PETSc.DMPlex().create(self.COMM) boundary.createCubeBoundary([0., 0., 0.], [1., 1., 1.], [1, 1, 1]) boundary.setDimension(self.DIM-1) self.plex = PETSc.DMPlex().generate(boundary) # -------------------------------------------------------------------- PETSC_DIR = petsc4py.get_config()['PETSC_DIR'] def check_dtype(method): def wrapper(self, *args, **kwargs): if PETSc.ScalarType is PETSc.ComplexType: return else: return method(self, *args, **kwargs) return wrapper def check_package(method): def wrapper(self, *args, **kwargs): if not PETSc.Sys.hasExternalPackage("hdf5"): return elif self.PARTITIONERTYPE != "simple" and \ not PETSc.Sys.hasExternalPackage(self.PARTITIONERTYPE): return else: return method(self, *args, **kwargs) return wrapper def check_nsize(method): def wrapper(self, *args, **kwargs): if PETSc.COMM_WORLD.size != self.NSIZE: return else: return method(self, *args, **kwargs) return wrapper class BaseTestPlexHDF5(object): NSIZE = 4 NTIMES = 3 def setUp(self): self.txtvwr = PETSc.Viewer() def tearDown(self): if not PETSc.COMM_WORLD.rank: if os.path.exists(self.outfile()): os.remove(self.outfile()) if os.path.exists(self.tmp_output_file()): os.remove(self.tmp_output_file()) self.txtvwr = None def _name(self): return "%s_outformat-%s_%s" % (self.SUFFIX, self.OUTFORMAT, self.PARTITIONERTYPE) def infile(self): return os.path.join(PETSC_DIR, "share/petsc/datafiles/", "meshes/blockcylinder-50.h5") def outfile(self): return os.path.join("./temp_test_dmplex_%s.h5" % self._name()) def informat(self): return PETSc.Viewer.Format.HDF5_XDMF def outformat(self): d = {"hdf5_petsc": PETSc.Viewer.Format.HDF5_PETSC, "hdf5_xdmf": PETSc.Viewer.Format.HDF5_XDMF} return d[self.OUTFORMAT] def partitionerType(self): d = {"simple": PETSc.Partitioner.Type.SIMPLE, "ptscotch": PETSc.Partitioner.Type.PTSCOTCH, "parmetis": PETSc.Partitioner.Type.PARMETIS} return d[self.PARTITIONERTYPE] def ref_output_file(self): return os.path.join(PETSC_DIR, "src/dm/impls/plex/tutorials/", "output/ex5_%s.out" % self._name()) def tmp_output_file(self): return os.path.join("./temp_test_dmplex_%s.out" % self._name()) def outputText(self, msg, comm): if not comm.rank: with open(self.tmp_output_file(), 'a') as f: f.write(msg) def outputPlex(self, plex): self.txtvwr.createASCII(self.tmp_output_file(), mode='a', comm=plex.comm) plex.view(viewer=self.txtvwr) self.txtvwr.destroy() @check_dtype @check_package @check_nsize def testViewLoadCycle(self): grank = PETSc.COMM_WORLD.rank for i in range(self.NTIMES): if i == 0: infname = self.infile() informt = self.informat() else: infname = self.outfile() informt = self.outformat() if self.HETEROGENEOUS: mycolor = (grank > self.NTIMES - i) else: mycolor = 0 try: import mpi4py except ImportError: self.skipTest('mpi4py') # throws special exception to signal test skip mpicomm = PETSc.COMM_WORLD.tompi4py() comm = PETSc.Comm(comm=mpicomm.Split(color=mycolor, key=grank)) if mycolor == 0: self.outputText("Begin cycle %d\n" % i, comm) plex = PETSc.DMPlex() vwr = PETSc.ViewerHDF5() # Create plex plex.create(comm=comm) plex.setName("DMPlex Object") # Load data from XDMF into dm in parallel vwr.create(infname, mode='r', comm=comm) vwr.pushFormat(format=informt) plex.load(viewer=vwr) plex.setOptionsPrefix("loaded_") plex.distributeSetDefault(False) plex.setFromOptions() vwr.popFormat() vwr.destroy() self.outputPlex(plex) # Test DM is indeed distributed flg = plex.isDistributed() self.outputText("Loaded mesh distributed? %s\n" % str(flg).upper(), comm) # Interpolate plex.interpolate() plex.setOptionsPrefix("interpolated_") plex.setFromOptions() self.outputPlex(plex) # Redistribute part = plex.getPartitioner() part.setType(self.partitionerType()) _ = plex.distribute(overlap=0) plex.setName("DMPlex Object") plex.setOptionsPrefix("redistributed_") plex.setFromOptions() self.outputPlex(plex) # Save redistributed dm to XDMF in parallel vwr.create(self.outfile(), mode='w', comm=comm) vwr.pushFormat(format=self.outformat()) plex.setName("DMPlex Object") plex.view(viewer=vwr) vwr.popFormat() vwr.destroy() # Destroy plex plex.destroy() self.outputText("End cycle %d\n--------\n" % i, comm) PETSc.COMM_WORLD.Barrier() # Check that the output is identical to that of plex/tutorial/ex5.c. self.assertTrue(filecmp.cmp(self.tmp_output_file(), self.ref_output_file(), shallow=False), 'Contents of the files not the same.') PETSc.COMM_WORLD.Barrier() class BaseTestPlexHDF5Homogeneous(BaseTestPlexHDF5): """Test save on N / load on N.""" SUFFIX = 0 HETEROGENEOUS = False class BaseTestPlexHDF5Heterogeneous(BaseTestPlexHDF5): """Test save on N / load on M.""" SUFFIX = 1 HETEROGENEOUS = True class TestPlexHDF5PETSCSimpleHomogeneous(BaseTestPlexHDF5Homogeneous, unittest.TestCase): OUTFORMAT = "hdf5_petsc" PARTITIONERTYPE = "simple" """ Skipping. PTScotch produces different distributions when run in a sequence in a single session. class TestPlexHDF5PETSCPTScotchHomogeneous(BaseTestPlexHDF5Homogeneous, unittest.TestCase): OUTFORMAT = "hdf5_petsc" PARTITIONERTYPE = "ptscotch" """ class TestPlexHDF5PETSCParmetisHomogeneous(BaseTestPlexHDF5Homogeneous, unittest.TestCase): OUTFORMAT = "hdf5_petsc" PARTITIONERTYPE = "parmetis" class TestPlexHDF5XDMFSimpleHomogeneous(BaseTestPlexHDF5Homogeneous, unittest.TestCase): OUTFORMAT = "hdf5_xdmf" PARTITIONERTYPE = "simple" """ Skipping. PTScotch produces different distributions when run in a sequence in a single session. class TestPlexHDF5XDMFPTScotchHomogeneous(BaseTestPlexHDF5Homogeneous, unittest.TestCase): OUTFORMAT = "hdf5_xdmf" PARTITIONERTYPE = "ptscotch" """ class TestPlexHDF5XDMFParmetisHomogeneous(BaseTestPlexHDF5Homogeneous, unittest.TestCase): OUTFORMAT = "hdf5_xdmf" PARTITIONERTYPE = "parmetis" class TestPlexHDF5PETSCSimpleHeterogeneous(BaseTestPlexHDF5Heterogeneous, unittest.TestCase): OUTFORMAT = "hdf5_petsc" PARTITIONERTYPE = "simple" """ Skipping. PTScotch produces different distributions when run in a sequence in a single session. class TestPlexHDF5PETSCPTScotchHeterogeneous(BaseTestPlexHDF5Heterogeneous, unittest.TestCase): OUTFORMAT = "hdf5_petsc" PARTITIONERTYPE = "ptscotch" """ class TestPlexHDF5PETSCParmetisHeterogeneous(BaseTestPlexHDF5Heterogeneous, unittest.TestCase): OUTFORMAT = "hdf5_petsc" PARTITIONERTYPE = "parmetis" class TestPlexHDF5XDMFSimpleHeterogeneous(BaseTestPlexHDF5Heterogeneous, unittest.TestCase): OUTFORMAT = "hdf5_xdmf" PARTITIONERTYPE = "simple" class TestPlexHDF5XDMFPTScotchHeterogeneous(BaseTestPlexHDF5Heterogeneous, unittest.TestCase): OUTFORMAT = "hdf5_xdmf" PARTITIONERTYPE = "ptscotch" class TestPlexHDF5XDMFParmetisHeterogeneous(BaseTestPlexHDF5Heterogeneous, unittest.TestCase): OUTFORMAT = "hdf5_xdmf" PARTITIONERTYPE = "parmetis" # -------------------------------------------------------------------- if __name__ == '__main__': unittest.main() ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/test/test_dmshell.py0000644000175000017500000001722214567251135016413 0ustar00balaybalayfrom petsc4py import PETSc import unittest import numpy as np class TestDMShell(unittest.TestCase): COMM = PETSc.COMM_WORLD def setUp(self): self.dm = PETSc.DMShell().create(comm=self.COMM) def tearDown(self): self.dm.destroy() self.dm = None PETSc.garbage_cleanup() def testSetGlobalVector(self): vec = PETSc.Vec().create(comm=self.COMM) vec.setSizes((10, None)) vec.setUp() self.dm.setGlobalVector(vec) gvec = self.dm.createGlobalVector() self.assertEqual(vec.getSizes(), gvec.getSizes()) self.assertEqual(vec.comm, gvec.comm) def testSetCreateGlobalVector(self): def create_vec(dm): v = PETSc.Vec().create(comm=dm.comm) v.setSizes((10, None)) v.setUp() return v self.dm.setCreateGlobalVector(create_vec) gvec = self.dm.createGlobalVector() self.assertEqual(gvec.comm, self.dm.comm) self.assertEqual(gvec.getLocalSize(), 10) def testSetLocalVector(self): vec = PETSc.Vec().create(comm=PETSc.COMM_SELF) vec.setSizes((1 + 10*self.COMM.rank, None)) vec.setUp() self.dm.setLocalVector(vec) lvec = self.dm.createLocalVector() self.assertEqual(vec.getSizes(), lvec.getSizes()) lsize, gsize = lvec.getSizes() self.assertEqual(lsize, gsize) self.assertEqual(lvec.comm, PETSc.COMM_SELF) def testSetCreateLocalVector(self): def create_vec(dm): v = PETSc.Vec().create(comm=PETSc.COMM_SELF) v.setSizes((1 + 10*dm.comm.rank, None)) v.setUp() return v self.dm.setCreateLocalVector(create_vec) lvec = self.dm.createLocalVector() lsize, gsize = lvec.getSizes() self.assertEqual(lsize, gsize) self.assertEqual(lsize, 1 + 10*self.dm.comm.rank) self.assertEqual(lvec.comm, PETSc.COMM_SELF) def testSetMatrix(self): mat = PETSc.Mat().create(comm=self.COMM) mat.setSizes(((10, None), (2, None))) mat.setUp() mat.assemble() self.dm.setMatrix(mat) nmat = self.dm.createMatrix() self.assertEqual(nmat.getSizes(), mat.getSizes()) def testSetCreateMatrix(self): def create_mat(dm): mat = PETSc.Mat().create(comm=self.COMM) mat.setSizes(((10, None), (2, None))) mat.setUp() return mat self.dm.setCreateMatrix(create_mat) nmat = self.dm.createMatrix() self.assertEqual(nmat.getSizes(), create_mat(self.dm).getSizes()) def testGlobalToLocal(self): def begin(dm, ivec, mode, ovec): if mode == PETSc.InsertMode.INSERT_VALUES: ovec[...] = ivec[...] elif mode == PETSc.InsertMode.ADD_VALUES: ovec[...] += ivec[...] def end(dm, ivec, mode, ovec): pass vec = PETSc.Vec().create(comm=self.COMM) vec.setSizes((10, None)) vec.setUp() vec[...] = self.dm.comm.rank + 1 ovec = PETSc.Vec().create(comm=PETSc.COMM_SELF) ovec.setSizes((10, None)) ovec.setUp() self.dm.setGlobalToLocal(begin, end) self.dm.globalToLocal(vec, ovec, addv=PETSc.InsertMode.INSERT_VALUES) self.assertTrue(np.allclose(vec.getArray(), ovec.getArray())) self.dm.globalToLocal(vec, ovec, addv=PETSc.InsertMode.ADD_VALUES) self.assertTrue(np.allclose(2*vec.getArray(), ovec.getArray())) def testLocalToGlobal(self): def begin(dm, ivec, mode, ovec): if mode == PETSc.InsertMode.INSERT_VALUES: ovec[...] = ivec[...] elif mode == PETSc.InsertMode.ADD_VALUES: ovec[...] += ivec[...] def end(dm, ivec, mode, ovec): pass vec = PETSc.Vec().create(comm=PETSc.COMM_SELF) vec.setSizes((10, None)) vec.setUp() vec[...] = self.dm.comm.rank + 1 ovec = PETSc.Vec().create(comm=self.COMM) ovec.setSizes((10, None)) ovec.setUp() self.dm.setLocalToGlobal(begin, end) self.dm.localToGlobal(vec, ovec, addv=PETSc.InsertMode.INSERT_VALUES) self.assertTrue(np.allclose(vec.getArray(), ovec.getArray())) self.dm.localToGlobal(vec, ovec, addv=PETSc.InsertMode.ADD_VALUES) self.assertTrue(np.allclose(2*vec.getArray(), ovec.getArray())) def testLocalToLocal(self): def begin(dm, ivec, mode, ovec): if mode == PETSc.InsertMode.INSERT_VALUES: ovec[...] = ivec[...] elif mode == PETSc.InsertMode.ADD_VALUES: ovec[...] += ivec[...] def end(dm, ivec, mode, ovec): pass vec = PETSc.Vec().create(comm=PETSc.COMM_SELF) vec.setSizes((10, None)) vec.setUp() vec[...] = self.dm.comm.rank + 1 ovec = vec.duplicate() self.dm.setLocalToLocal(begin, end) self.dm.localToLocal(vec, ovec, addv=PETSc.InsertMode.INSERT_VALUES) self.assertTrue(np.allclose(vec.getArray(), ovec.getArray())) self.dm.localToLocal(vec, ovec, addv=PETSc.InsertMode.ADD_VALUES) self.assertTrue(np.allclose(2*vec.getArray(), ovec.getArray())) def testGlobalToLocalVecScatter(self): vec = PETSc.Vec().create() vec.setSizes((10, None)) vec.setUp() sct, ovec = PETSc.Scatter.toAll(vec) self.dm.setGlobalToLocalVecScatter(sct) self.dm.globalToLocal(vec, ovec, addv=PETSc.InsertMode.INSERT_VALUES) self.assertTrue(np.allclose(vec.getArray(), ovec.getArray())) def testGlobalToLocalVecScatter(self): vec = PETSc.Vec().create() vec.setSizes((10, None)) vec.setUp() sct, ovec = PETSc.Scatter.toAll(vec) self.dm.setGlobalToLocalVecScatter(sct) self.dm.globalToLocal(vec, ovec, addv=PETSc.InsertMode.INSERT_VALUES) def testLocalToGlobalVecScatter(self): vec = PETSc.Vec().create() vec.setSizes((10, None)) vec.setUp() sct, ovec = PETSc.Scatter.toAll(vec) self.dm.setLocalToGlobalVecScatter(sct) self.dm.localToGlobal(vec, ovec, addv=PETSc.InsertMode.INSERT_VALUES) def testLocalToLocalVecScatter(self): vec = PETSc.Vec().create() vec.setSizes((10, None)) vec.setUp() sct, ovec = PETSc.Scatter.toAll(vec) self.dm.setLocalToLocalVecScatter(sct) self.dm.localToLocal(vec, ovec, addv=PETSc.InsertMode.INSERT_VALUES) def testCoarsenRefine(self): cdm = PETSc.DMShell().create(comm=self.COMM) def coarsen(dm, comm): return cdm def refine(dm, comm): return self.dm cdm.setRefine(refine) self.dm.setCoarsen(coarsen) coarsened = self.dm.coarsen() self.assertEqual(coarsened, cdm) refined = coarsened.refine() self.assertEqual(refined, self.dm) def testCreateInterpolation(self): mat = PETSc.Mat().create() mat.setSizes(((10, None), (10, None))) mat.setUp() vec = PETSc.Vec().create() vec.setSizes((10, None)) vec.setUp() def create_interp(dm, dmf): return mat, vec self.dm.setCreateInterpolation(create_interp) m, v = self.dm.createInterpolation(self.dm) self.assertEqual(m, mat) self.assertEqual(v, vec) def testCreateInjection(self): mat = PETSc.Mat().create() mat.setSizes(((10, None), (10, None))) mat.setUp() def create_inject(dm, dmf): return mat self.dm.setCreateInjection(create_inject) m = self.dm.createInjection(self.dm) self.assertEqual(m, mat) if __name__ == '__main__': unittest.main() ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/test/test_dmstag.py0000644000175000017500000003760014567251135016244 0ustar00balaybalayfrom petsc4py import PETSc import unittest # -------------------------------------------------------------------- class BaseTestDMStag(object): COMM = PETSc.COMM_WORLD STENCIL = PETSc.DMStag.StencilType.BOX SWIDTH = 1 PROC_SIZES = None OWNERSHIP_RANGES = None def setUp(self): dim = len(self.SIZES) self.da = PETSc.DMStag().create(dim, dofs=self.DOFS, sizes=self.SIZES, boundary_types=self.BOUNDARY, stencil_type=self.STENCIL, stencil_width=self.SWIDTH, comm=self.COMM, proc_sizes=self.PROC_SIZES, ownership_ranges=self.OWNERSHIP_RANGES, setUp=True) self.directda = PETSc.DMStag().create(dim) self.directda.setStencilType(self.STENCIL) self.directda.setStencilWidth(self.SWIDTH) self.directda.setBoundaryTypes(self.BOUNDARY) self.directda.setDof(self.DOFS) self.directda.setGlobalSizes(self.SIZES) if self.PROC_SIZES is not None: self.directda.setProcSizes(self.PROC_SIZES) if self.OWNERSHIP_RANGES is not None: self.directda.setOwnershipRanges(self.OWNERSHIP_RANGES) self.directda.setUp() def tearDown(self): self.da = None self.directda = None PETSc.garbage_cleanup() def testCoordinates(self): self.da.setCoordinateDMType('stag') self.da.setUniformCoordinates(0,1,0,1,0,1) self.da.setUniformCoordinatesExplicit(0,1,0,1,0,1) cda = self.da.getCoordinateDM() datype = cda.getType() self.assertEqual(datype,'stag') cda.destroy() c = self.da.getCoordinatesLocal() self.da.setCoordinatesLocal(c) gc = self.da.getCoordinatesLocal() self.assertEqual(c.max()[1], gc.max()[1]) self.assertEqual(c.min()[1], gc.min()[1]) c = self.da.getCoordinates() self.da.setCoordinates(c) gc = self.da.getCoordinates() self.assertEqual(c.max()[1], gc.max()[1]) self.assertEqual(c.min()[1], gc.min()[1]) self.directda.setCoordinateDMType('product') self.directda.setUniformCoordinates(0,1,0,1,0,1) self.directda.setUniformCoordinatesProduct(0,1,0,1,0,1) cda = self.directda.getCoordinateDM() datype = cda.getType() self.assertEqual(datype,'product') cda.destroy() def testGetVec(self): vg = self.da.getGlobalVec() vl = self.da.getLocalVec() vg.set(1.0) self.assertEqual(vg.max()[1], 1.0) self.assertEqual(vg.min()[1], 1.0) self.da.globalToLocal(vg,vl) self.assertEqual(vl.max()[1], 1.0) self.assertTrue (vl.min()[1] in (1.0, 0.0)) vl.set(2.0) self.da.localToGlobal(vl,vg) self.assertEqual(vg.max()[1], 2.0) self.assertTrue (vg.min()[1] in (2.0, 0.0)) self.da.restoreGlobalVec(vg) self.da.restoreLocalVec(vl) def testGetOther(self): lgmap = self.da.getLGMap() dlgmap = self.directda.getLGMap() def testDof(self): dim = self.da.getDim() dofs = self.da.getDof() if dim == 1: dof0 = self.da.getLocationDof('left') dof1 = self.da.getLocationDof('element') self.assertEqual(dofs[0],dof0) self.assertEqual(dofs[1],dof1) if dim == 2: dof0 = self.da.getLocationDof('down_left') dof1 = self.da.getLocationDof('left') dof2 = self.da.getLocationDof('element') self.assertEqual(dofs[0],dof0) self.assertEqual(dofs[1],dof1) self.assertEqual(dofs[2],dof2) if dim == 3: dof0 = self.da.getLocationDof('back_down_right') dof1 = self.da.getLocationDof('down_left') dof2 = self.da.getLocationDof('left') dof3 = self.da.getLocationDof('element') self.assertEqual(dofs[0],dof0) self.assertEqual(dofs[1],dof1) self.assertEqual(dofs[2],dof2) self.assertEqual(dofs[3],dof3) def testMigrateVec(self): vec = self.da.createGlobalVec() dmTo = self.da.createCompatibleDMStag(self.NEWDOF) vecTo = dmTo.createGlobalVec() self.da.migrateVec(vec, dmTo, vecTo) def testDMDAInterface(self): return self.da.setCoordinateDMType('stag') self.da.setUniformCoordinates(0,1,0,1,0,1) dim = self.da.getDim() dofs = self.da.getDof() vec = self.da.createGlobalVec() if dim == 1: da,davec = self.da.VecSplitToDMDA(vec,'left',-dofs[0]) da,davec = self.da.VecSplitToDMDA(vec,'element',-dofs[1]) if dim == 2: da,davec = self.da.VecSplitToDMDA(vec,'down_left',-dofs[0]) da,davec = self.da.VecSplitToDMDA(vec,'down_left',-dofs[1]) da,davec = self.da.VecSplitToDMDA(vec,'down_left',-dofs[2]) if dim == 3: da,davec = self.da.VecSplitToDMDA(vec,'back_down_right',-dofs[0]) da,davec = self.da.VecSplitToDMDA(vec,'down_left',-dofs[1]) da,davec = self.da.VecSplitToDMDA(vec,'left',-dofs[2]) da,davec = self.da.VecSplitToDMDA(vec,'element',-dofs[3]) GHOSTED = PETSc.DM.BoundaryType.GHOSTED PERIODIC = PETSc.DM.BoundaryType.PERIODIC NONE = PETSc.DM.BoundaryType.NONE SCALE = 4 class BaseTestDMStag_1D(BaseTestDMStag): SIZES = [100*SCALE,] BOUNDARY = [NONE,] class BaseTestDMStag_2D(BaseTestDMStag): SIZES = [9*SCALE, 11*SCALE] BOUNDARY = [NONE, NONE] class BaseTestDMStag_3D(BaseTestDMStag): SIZES = [6*SCALE, 7*SCALE, 8*SCALE] BOUNDARY = [NONE, NONE, NONE] # -------------------------------------------------------------------- class TestDMStag_1D_W0_N11(BaseTestDMStag_1D, unittest.TestCase): SWIDTH = 0 DOFS = (1,1) NEWDOF = (2,1) class TestDMStag_1D_W0_N21(BaseTestDMStag_1D, unittest.TestCase): SWIDTH = 0 DOFS = (2,1) NEWDOF = (2,2) class TestDMStag_1D_W0_N12(BaseTestDMStag_1D, unittest.TestCase): SWIDTH = 0 DOFS = (1,2) NEWDOF = (2,2) class TestDMStag_1D_W2_N11(BaseTestDMStag_1D, unittest.TestCase): SWIDTH = 2 DOFS = (1,1) NEWDOF = (2,1) class TestDMStag_1D_W2_N21(BaseTestDMStag_1D, unittest.TestCase): SWIDTH = 2 DOFS = (2,1) NEWDOF = (2,2) class TestDMStag_1D_W2_N12(BaseTestDMStag_1D, unittest.TestCase): SWIDTH = 2 DOFS = (1,2) NEWDOF = (2,2) class TestDMStag_2D_W0_N112(BaseTestDMStag_2D, unittest.TestCase): DOFS = (1,1,2) SWIDTH = 0 NEWDOF = (2,2,2) class TestDMStag_2D_W2_N112(BaseTestDMStag_2D, unittest.TestCase): DOFS = (1,1,2) SWIDTH = 2 NEWDOF = (2,2,2) class TestDMStag_2D_PXY(BaseTestDMStag_2D, unittest.TestCase): SIZES = [13*SCALE,17*SCALE] DOFS = (1,1,2) SWIDTH = 5 BOUNDARY = (PERIODIC,)*2 NEWDOF = (2,2,2) class TestDMStag_2D_GXY(BaseTestDMStag_2D, unittest.TestCase): SIZES = [13*SCALE,17*SCALE] DOFS = (1,1,2) SWIDTH = 5 BOUNDARY = (GHOSTED,)*2 NEWDOF = (2,2,2) class TestDMStag_3D_W0_N1123(BaseTestDMStag_3D, unittest.TestCase): DOFS = (1,1,2,3) SWIDTH = 0 NEWDOF = (2,2,3,3) class TestDMStag_3D_W2_N1123(BaseTestDMStag_3D, unittest.TestCase): DOFS = (1,1,2,3) SWIDTH = 2 NEWDOF = (2,2,3,3) class TestDMStag_3D_PXYZ(BaseTestDMStag_3D, unittest.TestCase): SIZES = [11*SCALE,13*SCALE,17*SCALE] DOFS = (1,1,2,3) NEWDOF = (2,2,3,3) SWIDTH = 3 BOUNDARY = (PERIODIC,)*3 class TestDMStag_3D_GXYZ(BaseTestDMStag_3D, unittest.TestCase): SIZES = [11*SCALE,13*SCALE,17*SCALE] DOFS = (1,1,2,3) NEWDOF = (2,2,3,3) SWIDTH = 3 BOUNDARY = (GHOSTED,)*3 # -------------------------------------------------------------------- DIM = (1,2,3) DOF0 = (0,1,2) DOF1 = (0,1,2) DOF2 = (0,1,2) DOF3 = (0,1,2) BOUNDARY_TYPE = ('none', 'ghosted', 'periodic') STENCIL_TYPE = ('none', 'star', 'box') STENCIL_WIDTH = (0,1,2,3) class TestDMStagCreate(unittest.TestCase): pass counter = 0 for dim in DIM: for dof0 in DOF0: for dof1 in DOF1: for dof2 in DOF2: if dim == 1 and dof2 > 0: continue for dof3 in DOF3: if dim == 2 and dof3 > 0: continue if dof0==0 and dof1==0 and dof2==0 and dof3==0: continue dofs = [dof0,dof1,dof2,dof3][:dim+1] for boundary in BOUNDARY_TYPE: if boundary == "periodic": continue # XXX broken for stencil in STENCIL_TYPE: if stencil == 'none' and boundary != 'none': continue for width in STENCIL_WIDTH: if stencil == 'none' and width > 0: continue if stencil in ['star','box'] and width == 0: continue kargs = dict(dim=dim, dofs=dofs, boundary_type=boundary, stencil_type=stencil, stencil_width=width) def testCreate(self,kargs=kargs): kargs = dict(kargs) cda = PETSc.DMStag().create(kargs['dim'], dofs = kargs['dofs'], sizes = [8*SCALE,]*kargs['dim'], boundary_types = [kargs['boundary_type'],]*kargs['dim'], stencil_type = kargs['stencil_type'], stencil_width = kargs['stencil_width'], setUp=True) dda = PETSc.DMStag().create(kargs['dim']) dda.setStencilType(kargs['stencil_type']) dda.setStencilWidth(kargs['stencil_width']) dda.setBoundaryTypes([kargs['boundary_type'],]*kargs['dim']) dda.setDof(kargs['dofs']) dda.setGlobalSizes([8*SCALE,]*kargs['dim']) dda.setUp() cdim = cda.getDim() cdof = cda.getDof() cgsizes = cda.getGlobalSizes() clsizes = cda.getLocalSizes() cboundary = cda.getBoundaryTypes() cstencil_type = cda.getStencilType() cstencil_width = cda.getStencilWidth() centries_per_element = cda.getEntriesPerElement() cstarts, csizes, cnextra = cda.getCorners() cisLastRank = cda.getIsLastRank() cisFirstRank = cda.getIsFirstRank() cownershipranges = cda.getOwnershipRanges() cprocsizes = cda.getProcSizes() ddim = dda.getDim() ddof = dda.getDof() dgsizes = dda.getGlobalSizes() dlsizes = dda.getLocalSizes() dboundary = dda.getBoundaryTypes() dstencil_type = dda.getStencilType() dstencil_width = dda.getStencilWidth() dentries_per_element = dda.getEntriesPerElement() dstarts, dsizes, dnextra = dda.getCorners() disLastRank = dda.getIsLastRank() disFirstRank = dda.getIsFirstRank() downershipranges = dda.getOwnershipRanges() dprocsizes = dda.getProcSizes() self.assertEqual(cdim,kargs['dim']) self.assertEqual(cdof,tuple(kargs['dofs'])) self.assertEqual(cboundary,tuple([kargs['boundary_type'],]*kargs['dim'])) self.assertEqual(cstencil_type,kargs['stencil_type']) self.assertEqual(cstencil_width,kargs['stencil_width']) self.assertEqual(cgsizes,tuple([8*SCALE,]*kargs['dim'])) self.assertEqual(cdim,ddim) self.assertEqual(cdof,ddof) self.assertEqual(cgsizes,dgsizes) self.assertEqual(clsizes,dlsizes) self.assertEqual(cboundary,dboundary) self.assertEqual(cstencil_type,dstencil_type) self.assertEqual(cstencil_width,dstencil_width) self.assertEqual(centries_per_element,dentries_per_element) self.assertEqual(cstarts,dstarts) self.assertEqual(csizes,dsizes) self.assertEqual(cnextra,dnextra) self.assertEqual(cisLastRank,disLastRank) self.assertEqual(cisFirstRank,disFirstRank) self.assertEqual(cprocsizes, dprocsizes) for co,do in zip(cownershipranges, downershipranges): for i,j in zip(co,do): self.assertEqual(i,j) self.assertEqual(cdim+1,len(cdof)) self.assertEqual(cdim,len(cgsizes)) self.assertEqual(cdim,len(clsizes)) self.assertEqual(cdim,len(cboundary)) self.assertEqual(cdim,len(cstarts)) self.assertEqual(cdim,len(csizes)) self.assertEqual(cdim,len(cnextra)) self.assertEqual(cdim,len(cisLastRank)) self.assertEqual(cdim,len(cisLastRank)) if cdim == 1: self.assertEqual(centries_per_element, cdof[0] + cdof[1]) if cdim == 2: self.assertEqual(centries_per_element, cdof[0] + 2*cdof[1] + cdof[2]) if cdim == 3: self.assertEqual(centries_per_element, cdof[0] + 3*cdof[1] + 3*cdof[2] + cdof[3]) for i in range(cdim): self.assertEqual(csizes[i], clsizes[i]) if cisLastRank[i]: self.assertEqual(cnextra[i],1) if (cnextra[i]==1): self.assertTrue(cisLastRank[i]) if (cisFirstRank[i]): self.assertEqual(cstarts[i],0) self.assertEqual(len(cprocsizes), len(cownershipranges)) self.assertEqual(len(cprocsizes), cdim) for i,m in enumerate(cprocsizes): self.assertEqual(m, len(cownershipranges[i])) dda.destroy() cda.destroy() setattr(TestDMStagCreate, "testCreate%05d"%counter, testCreate) del testCreate counter += 1 del counter, dim, dofs, dof0, dof1, dof2, dof3, boundary, stencil, width # -------------------------------------------------------------------- if __name__ == '__main__': unittest.main() # -------------------------------------------------------------------- ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/test/test_gc.py0000644000175000017500000000464714567251135015363 0ustar00balaybalayfrom petsc4py import PETSc import unittest import gc, weakref import warnings # -------------------------------------------------------------------- ## gc.set_debug((gc.DEBUG_STATS | ## gc.DEBUG_LEAK) & ## ~gc.DEBUG_SAVEALL) # -------------------------------------------------------------------- class BaseTestGC(object): def setUp(self): self.obj = self.CLASS().create(comm=PETSc.COMM_SELF) def tearDown(self): wref = self.make_weakref() self.assertTrue(wref() is self.obj) self.obj = None gc.collect() self.assertTrue(wref() is None) PETSc.garbage_cleanup() def make_weakref(self): wref = weakref.ref(self.obj) return wref def testCycleInSelf(self): self.obj.setAttr('myself', self.obj) def testCycleInMethod(self): self.obj.setAttr('mymeth', self.obj.view) def testCycleInInstance(self): class A: pass a = A() a.obj = self.obj self.obj.setAttr('myinst', a) def testCycleInAllWays(self): self.testCycleInSelf() self.testCycleInMethod() self.testCycleInInstance() # -------------------------------------------------------------------- class TestGCVec(BaseTestGC, unittest.TestCase): CLASS = PETSc.Vec class TestGCVecSubType(TestGCVec): CLASS = type('_Vec', (PETSc.Vec,), {}) class TestGCMat(BaseTestGC, unittest.TestCase): CLASS = PETSc.Mat class TestGCMatSubType(TestGCMat): CLASS = type('_Mat', (PETSc.Mat,), {}) class TestGCPC(BaseTestGC, unittest.TestCase): CLASS = PETSc.PC class TestGCPCSubType(TestGCPC): CLASS = type('_PC', (PETSc.PC,), {}) class TestGCKSP(BaseTestGC, unittest.TestCase): CLASS = PETSc.KSP class TestGCKSPSubType(TestGCKSP): CLASS = type('_KSP', (PETSc.KSP,), {}) class TestGCSNES(BaseTestGC, unittest.TestCase): CLASS = PETSc.SNES def testCycleInAppCtx(self): self.obj.setAppCtx(self.obj) class TestGCSNESSubType(TestGCSNES): CLASS = type('_SNES', (PETSc.SNES,), {}) class TestGCTS(BaseTestGC, unittest.TestCase): CLASS = PETSc.TS def testCycleInAppCtx(self): self.obj.setAppCtx(self.obj) class TestGCTSSubType(TestGCTS): CLASS = type('_TS', (PETSc.TS,), {}) def testCycleInAppCtx(self): self.obj.setAppCtx(self.obj) # -------------------------------------------------------------------- if __name__ == '__main__': unittest.main() ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/test/test_is.py0000644000175000017500000001124714567251135015377 0ustar00balaybalayfrom petsc4py import PETSc import unittest import random # -------------------------------------------------------------------- class BaseTestIS(object): TYPE = None def tearDown(self): self.iset = None PETSc.garbage_cleanup() def testGetType(self): istype = self.iset.getType() self.assertEqual(istype, self.TYPE) def testGetSize(self): lsize = self.iset.getLocalSize() gsize = self.iset.getSize() self.assertTrue(lsize <= gsize) def testDuplicate(self): iset = self.iset.duplicate() self.assertTrue(self.iset.equal(iset)) del iset def testCopy(self): iset = self.iset.copy() self.assertTrue(self.iset.equal(iset)) del iset def testEqual(self): self.assertTrue(self.iset.equal(self.iset)) iset = self.iset.duplicate() self.assertTrue(self.iset.equal(iset)) del iset def testSort(self): self.iset.sort() self.assertTrue(self.iset.isSorted()) def testDifference(self): iset = self.iset.difference(self.iset) self.assertEqual(iset.getLocalSize(), 0) del iset def testComplement(self): self.iset.sort() nmin = self.iset.getIndices().min() nmax = self.iset.getIndices().max() iset = self.iset.complement(nmin, nmax+1) iset.complement(nmin, nmax+1) del iset def testSum(self): if self.iset.getComm().getSize() > 1: return self.iset.sort() iset = self.iset.duplicate() iset.sum(self.iset) self.assertTrue(self.iset.equal(iset)) del iset def testExpand(self): iset = self.iset.expand(self.iset) if self.iset.type == iset.type: self.assertTrue(self.iset.equal(iset)) del iset def testRenumber(self): (n1,is1) = self.iset.renumber() (n2,is2) = self.iset.renumber(self.iset) del is1 del is2 def testProperties(self): proplist = ['sizes', 'size', 'local_size', 'indices', 'permutation', 'identity', 'sorted'] for prop in proplist: self.assertTrue(hasattr(self.iset, prop)) def testArray(self): import numpy refs = self.iset.getRefCount() arr1 = numpy.asarray(self.iset) self.assertEqual(self.iset.getRefCount(), refs+1) arr2 = self.iset.array self.assertEqual(self.iset.getRefCount(), refs+2) self.assertTrue((arr1 == arr2).all()) del arr2 self.assertEqual(self.iset.getRefCount(), refs+1) del arr1 self.assertEqual(self.iset.getRefCount(), refs) # -------------------------------------------------------------------- class TestISGeneral(BaseTestIS, unittest.TestCase): TYPE = PETSc.IS.Type.GENERAL def setUp(self): self.idx = list(range(10)) random.shuffle(self.idx) self.iset = PETSc.IS().createGeneral(self.idx) def testGetIndices(self): idx = self.iset.getIndices() self.assertEqual(self.idx, list(idx)) class TestISStride(BaseTestIS, unittest.TestCase): TYPE = PETSc.IS.Type.STRIDE def setUp(self): self.info = (10, 7, 3) size, start, step = self.info self.iset = PETSc.IS().createStride(size, start, step) def testGetIndices(self): size, start, step = self.info indices = [start+i*step for i in range(size)] self.assertEqual(list(self.iset.getIndices()), indices) def testToGeneral(self): self.iset.toGeneral() self.assertEqual(self.iset.getType(), PETSc.IS.Type.GENERAL) class TestISBlock(BaseTestIS, unittest.TestCase): TYPE = PETSc.IS.Type.BLOCK def setUp(self): self.bsize = 3 self.index = list(range(0,10,2)) random.shuffle(self.index) self.iset = PETSc.IS().createBlock(self.bsize, self.index) self.assertEqual(self.iset.getType(), PETSc.IS.Type.BLOCK) def testGetSize(self): lsize = self.iset.getLocalSize() self.assertEqual(lsize/self.bsize, len(self.index)) def testGetBlockSize(self): bs = self.iset.getBlockSize() self.assertEqual(bs, self.bsize) def testGetBlockIndices(self): index = list(self.iset.getBlockIndices()) self.assertEqual(index, self.index) def testGetIndices(self): bs = self.bsize idx = [] for i in self.iset.getBlockIndices(): for j in range(bs): idx.append(i*bs+j) index = list(self.iset.getIndices()) #self.assertEqual(index, idx) # -------------------------------------------------------------------- if __name__ == '__main__': unittest.main() ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/test/test_ksp.py0000644000175000017500000001544014567251135015560 0ustar00balaybalay# -------------------------------------------------------------------- from petsc4py import PETSc import unittest from sys import getrefcount # -------------------------------------------------------------------- class BaseTestKSP(object): KSP_TYPE = None PC_TYPE = None def setUp(self): ksp = PETSc.KSP() ksp.create(PETSc.COMM_SELF) if self.KSP_TYPE: ksp.setType(self.KSP_TYPE) if self.PC_TYPE: pc = ksp.getPC() pc.setType(self.PC_TYPE) self.ksp = ksp def tearDown(self): self.ksp = None PETSc.garbage_cleanup() def testGetSetType(self): self.assertEqual(self.ksp.getType(), self.KSP_TYPE) self.ksp.setType(self.KSP_TYPE) self.assertEqual(self.ksp.getType(), self.KSP_TYPE) def testTols(self): tols = self.ksp.getTolerances() self.ksp.setTolerances(*tols) tnames = ('rtol', 'atol', 'divtol', 'max_it') tolvals = [getattr(self.ksp, t) for t in tnames] self.assertEqual(tuple(tols), tuple(tolvals)) def testProperties(self): ksp = self.ksp # ksp.appctx = (1,2,3) self.assertEqual(ksp.appctx, (1,2,3)) ksp.appctx = None self.assertEqual(ksp.appctx, None) # side = ksp.pc_side ksp.pc_side = side self.assertEqual(ksp.pc_side, side) # nt = ksp.norm_type ksp.norm_type = nt self.assertEqual(ksp.norm_type, nt) # ksp.its = 1 self.assertEqual(ksp.its, 1) ksp.its = 0 self.assertEqual(ksp.its, 0) # ksp.norm = 1 self.assertEqual(ksp.norm, 1) ksp.norm = 0 self.assertEqual(ksp.norm, 0) # rh = ksp.history self.assertTrue(len(rh)==0) # reason = PETSc.KSP.ConvergedReason.CONVERGED_ITS ksp.reason = reason self.assertEqual(ksp.reason, reason) self.assertTrue(ksp.is_converged) self.assertFalse(ksp.is_diverged) self.assertFalse(ksp.is_iterating) reason = PETSc.KSP.ConvergedReason.DIVERGED_MAX_IT ksp.reason = reason self.assertEqual(ksp.reason, reason) self.assertFalse(ksp.is_converged) self.assertTrue(ksp.is_diverged) self.assertFalse(ksp.is_iterating) reason = PETSc.KSP.ConvergedReason.CONVERGED_ITERATING ksp.reason = reason self.assertEqual(ksp.reason, reason) self.assertFalse(ksp.is_converged) self.assertFalse(ksp.is_diverged) self.assertTrue(ksp.is_iterating) def testGetSetPC(self): oldpc = self.ksp.getPC() self.assertEqual(oldpc.getRefCount(), 2) newpc = PETSc.PC() newpc.create(self.ksp.getComm()) self.assertEqual(newpc.getRefCount(), 1) self.ksp.setPC(newpc) self.assertEqual(newpc.getRefCount(), 2) self.assertEqual(oldpc.getRefCount(), 1) oldpc.destroy() self.assertFalse(bool(oldpc)) pc = self.ksp.getPC() self.assertTrue(bool(pc)) self.assertEqual(pc, newpc) self.assertEqual(pc.getRefCount(), 3) newpc.destroy() self.assertFalse(bool(newpc)) self.assertEqual(pc.getRefCount(), 2) def testSolve(self): A = PETSc.Mat().create(PETSc.COMM_SELF) A.setSizes([3,3]) A.setType(PETSc.Mat.Type.SEQAIJ) A.setPreallocationNNZ(1) for i in range(3): A.setValue(i, i, 0.9/(i+1)) A.assemble() A.shift(1) x, b = A.createVecs() b.set(10) x.setRandom() self.ksp.setOperators(A) self.ksp.setConvergenceHistory() self.ksp.solve(b, x) r = b.duplicate() u = x.duplicate() self.ksp.buildSolution(u) self.ksp.buildResidual(u) rh = self.ksp.getConvergenceHistory() self.ksp.setConvergenceHistory(0) rh = self.ksp.getConvergenceHistory() self.assertEqual(len(rh), 0) del A, x, b def testResetAndSolve(self): self.ksp.reset() self.testSolve() self.ksp.reset() self.testSolve() self.ksp.reset() def testSetMonitor(self): reshist = {} def monitor(ksp, its, rnorm): reshist[its] = rnorm refcnt = getrefcount(monitor) self.ksp.setMonitor(monitor) self.assertEqual(getrefcount(monitor), refcnt + 1) ## self.testSolve() reshist = {} self.ksp.monitorCancel() self.assertEqual(getrefcount(monitor), refcnt) self.testSolve() self.assertEqual(len(reshist), 0) ## Monitor = PETSc.KSP.Monitor ## self.ksp.setMonitor(Monitor()) ## self.ksp.setMonitor(Monitor.DEFAULT) ## self.ksp.setMonitor(Monitor.TRUE_RESIDUAL_NORM) ## self.ksp.setMonitor(Monitor.SOLUTION) def testSetConvergenceTest(self): def converged(ksp, its, rnorm): if its > 10: return True return False refcnt = getrefcount(converged) self.ksp.setConvergenceTest(converged) self.assertEqual(getrefcount(converged), refcnt + 1) self.ksp.setConvergenceTest(None) self.assertEqual(getrefcount(converged), refcnt) # -------------------------------------------------------------------- class TestKSPPREONLY(BaseTestKSP, unittest.TestCase): KSP_TYPE = PETSc.KSP.Type.PREONLY PC_TYPE = PETSc.PC.Type.LU class TestKSPRICHARDSON(BaseTestKSP, unittest.TestCase): KSP_TYPE = PETSc.KSP.Type.RICHARDSON class TestKSPCHEBYCHEV(BaseTestKSP, unittest.TestCase): try: KSP_TYPE = PETSc.KSP.Type.CHEBYSHEV except AttributeError: KSP_TYPE = PETSc.KSP.Type.CHEBYCHEV class TestKSPCG(BaseTestKSP, unittest.TestCase): KSP_TYPE = PETSc.KSP.Type.CG class TestKSPCGNE(BaseTestKSP, unittest.TestCase): KSP_TYPE = PETSc.KSP.Type.CGNE class TestKSPSTCG(BaseTestKSP, unittest.TestCase): KSP_TYPE = PETSc.KSP.Type.STCG class TestKSPBCGS(BaseTestKSP, unittest.TestCase): KSP_TYPE = PETSc.KSP.Type.BCGS class TestKSPBCGSL(BaseTestKSP, unittest.TestCase): KSP_TYPE = PETSc.KSP.Type.BCGSL class TestKSPCGS(BaseTestKSP, unittest.TestCase): KSP_TYPE = PETSc.KSP.Type.CGS class TestKSPQCG(BaseTestKSP, unittest.TestCase): KSP_TYPE = PETSc.KSP.Type.QCG PC_TYPE = PETSc.PC.Type.JACOBI class TestKSPBICG(BaseTestKSP, unittest.TestCase): KSP_TYPE = PETSc.KSP.Type.BICG class TestKSPGMRES(BaseTestKSP, unittest.TestCase): KSP_TYPE = PETSc.KSP.Type.GMRES class TestKSPFGMRES(BaseTestKSP, unittest.TestCase): KSP_TYPE = PETSc.KSP.Type.FGMRES # -------------------------------------------------------------------- if PETSc.ScalarType().dtype.char in 'FDG': del TestKSPSTCG # -------------------------------------------------------------------- if __name__ == '__main__': unittest.main() ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/test/test_ksp_py.py0000644000175000017500000000601314567251135016264 0ustar00balaybalay# -------------------------------------------------------------------- from petsc4py import PETSc import unittest from sys import getrefcount # -------------------------------------------------------------------- class MyKSP(object): def __init__(self): pass def create(self, ksp): self.work = [] def destroy(self, ksp): for v in self.work: v.destroy() def setUp(self, ksp): self.work[:] = ksp.getWorkVecs(right=2, left=None) def reset(self, ksp): for v in self.work: v.destroy() del self.work[:] def loop(self, ksp, r): its = ksp.getIterationNumber() rnorm = r.norm() ksp.setResidualNorm(rnorm) ksp.logConvergenceHistory(rnorm) ksp.monitor(its, rnorm) reason = ksp.callConvergenceTest(its, rnorm) if not reason: ksp.setIterationNumber(its+1) else: ksp.setConvergedReason(reason) return reason class MyRichardson(MyKSP): def solve(self, ksp, b, x): A, B = ksp.getOperators() P = ksp.getPC() r, z = self.work # A.mult(x, r) r.aypx(-1, b) P.apply(r, z) x.axpy(1, z) while not self.loop(ksp, z): A.mult(x, r) r.aypx(-1, b) P.apply(r, z) x.axpy(1, z) class MyCG(MyKSP): def setUp(self, ksp): super(MyCG, self).setUp(ksp) d = self.work[0].duplicate() q = d.duplicate() self.work += [d, q] def solve(self, ksp, b, x): A, B = ksp.getOperators() P = ksp.getPC() r, z, d, q = self.work # A.mult(x, r) r.aypx(-1, b) r.copy(d) delta_0 = r.dot(r) delta = delta_0 while not self.loop(ksp, r): A.mult(d, q) alpha = delta / d.dot(q) x.axpy(+alpha, d) r.axpy(-alpha, q) delta_old = delta delta = r.dot(r) beta = delta / delta_old d.aypx(beta, r) # -------------------------------------------------------------------- from test_ksp import BaseTestKSP class BaseTestKSPPYTHON(BaseTestKSP): KSP_TYPE = PETSc.KSP.Type.PYTHON ContextClass = None def setUp(self): super(BaseTestKSPPYTHON, self).setUp() ctx = self.ContextClass() self.ksp.setPythonContext(ctx) def testGetType(self): ctx = self.ksp.getPythonContext() pytype = "{0}.{1}".format(ctx.__module__, type(ctx).__name__) self.assertTrue(self.ksp.getPythonType() == pytype) def tearDown(self): self.ksp.destroy() PETSc.garbage_cleanup() class TestKSPPYTHON_RICH(BaseTestKSPPYTHON, unittest.TestCase): PC_TYPE = PETSc.PC.Type.JACOBI ContextClass = MyRichardson class TestKSPPYTHON_CG(BaseTestKSPPYTHON, unittest.TestCase): PC_TYPE = PETSc.PC.Type.NONE ContextClass = MyCG # -------------------------------------------------------------------- if __name__ == '__main__': unittest.main() ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/test/test_lgmap.py0000644000175000017500000001073714567251135016067 0ustar00balaybalayfrom petsc4py import PETSc import unittest # -------------------------------------------------------------------- class BaseTestLGMap(object): def _mk_idx(self, comm): comm_size = comm.getSize() comm_rank = comm.getRank() lsize = 10 first = lsize * comm_rank last = first + lsize if comm_rank > 0: first -= 1 if comm_rank < (comm_size-1): last += 1 return list(range(first, last)) def tearDown(self): self.lgmap = None PETSc.garbage_cleanup() def testGetSize(self): size = self.lgmap.getSize() self.assertTrue(size >= 0) def testGetIndices(self): size = self.lgmap.getSize() idx = self.lgmap.getIndices() self.assertEqual(len(idx), size) for i, val in enumerate(self.idx): self.assertEqual(idx[i], val) def testGetInfo(self): info = self.lgmap.getInfo() self.assertEqual(type(info), dict) if self.lgmap.getComm().getSize() == 1: self.assertEqual(info, {}) else: self.assertTrue(len(info) > 1) self.assertTrue(len(info) < 4) def testApply(self): idxin = list(range(self.lgmap.getSize())) idxout = self.lgmap.apply(idxin) self.lgmap.apply(idxin, idxout) invmap = self.lgmap.applyInverse(idxout) def testApplyIS(self): is_in = PETSc.IS().createStride(self.lgmap.getSize()) is_out = self.lgmap.apply(is_in) def testProperties(self): for prop in ('size', 'indices', 'info'): self.assertTrue(hasattr(self.lgmap, prop)) # -------------------------------------------------------------------- class TestLGMap(BaseTestLGMap, unittest.TestCase): def setUp(self): self.idx = self._mk_idx(PETSc.COMM_WORLD) self.lgmap = PETSc.LGMap().create(self.idx, comm=PETSc.COMM_WORLD) class TestLGMapIS(BaseTestLGMap, unittest.TestCase): def setUp(self): self.idx = self._mk_idx(PETSc.COMM_WORLD) self.iset = PETSc.IS().createGeneral(self.idx, comm=PETSc.COMM_WORLD) self.lgmap = PETSc.LGMap().create(self.iset) def tearDown(self): self.iset = None self.lgmap = None def testSameComm(self): comm1 = self.lgmap.getComm() comm2 = self.iset.getComm() self.assertEqual(comm1, comm2) # -------------------------------------------------------------------- class TestLGMapBlock(unittest.TestCase): BS = 3 def setUp(self): comm = PETSc.COMM_WORLD comm_size = comm.getSize() comm_rank = comm.getRank() lsize = 10 first = lsize * comm_rank last = first + lsize if comm_rank > 0: first -= 1 if comm_rank < (comm_size-1): last += 1 self.idx = list(range(first, last)) bs = self.BS self.lgmap = PETSc.LGMap().create(self.idx, bs, comm=PETSc.COMM_WORLD) def tearDown(self): self.lgmap = None def testGetSize(self): size = self.lgmap.getSize() self.assertTrue(size >= 0) def testGetBlockSize(self): bs = self.lgmap.getBlockSize() self.assertEqual(bs, self.BS) def testGetBlockIndices(self): size = self.lgmap.getSize() bs = self.lgmap.getBlockSize() idx = self.lgmap.getBlockIndices() self.assertEqual(len(idx), size//bs) for i, val in enumerate(self.idx): self.assertEqual(idx[i], val) def testGetIndices(self): size = self.lgmap.getSize() bs = self.lgmap.getBlockSize() idx = self.lgmap.getIndices() self.assertEqual(len(idx), size) for i, val in enumerate(self.idx): for j in range(bs): self.assertEqual(idx[i*bs+j], val*bs+j) def testGetBlockInfo(self): info = self.lgmap.getBlockInfo() self.assertEqual(type(info), dict) if self.lgmap.getComm().getSize() == 1: self.assertEqual(info, {}) else: self.assertTrue(len(info) > 1) self.assertTrue(len(info) < 4) def testGetInfo(self): info = self.lgmap.getInfo() self.assertEqual(type(info), dict) if self.lgmap.getComm().getSize() == 1: self.assertEqual(info, {}) else: self.assertTrue(len(info) > 1) self.assertTrue(len(info) < 4) # -------------------------------------------------------------------- if __name__ == '__main__': unittest.main() ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/test/test_log.py0000644000175000017500000000733314567251135015546 0ustar00balaybalay# -------------------------------------------------------------------- if __name__ == "__main__": import sys, petsc4py petsc4py.init(sys.argv+['-log_view']) # -------------------------------------------------------------------- from petsc4py import PETSc import unittest # -------------------------------------------------------------------- class TestLog(unittest.TestCase): def setUp(self): #PETSc.Log.begin() # register stages self.stage1 = PETSc.Log.Stage('Stage 1') self.stage2 = PETSc.Log.Stage('Stage 2') # register classes self.klassA = PETSc.Log.Class('Class A') self.klassB = PETSc.Log.Class('Class B') # register events self.event1 = PETSc.Log.Event('Event 1') # no class self.event2 = PETSc.Log.Event('Event 2') # no class self.eventA = PETSc.Log.Event('Event A', self.klassA) self.eventB = PETSc.Log.Event('Event B', self.klassB) def testGetName(self): self.assertEqual(self.klassA.name, 'Class A') self.assertEqual(self.klassB.name, 'Class B') self.assertEqual(self.event1.name, 'Event 1') self.assertEqual(self.event2.name, 'Event 2') self.assertEqual(self.eventA.name, 'Event A') self.assertEqual(self.eventB.name, 'Event B') self.assertEqual(self.stage1.name, 'Stage 1') self.assertEqual(self.stage2.name, 'Stage 2') def testLogBeginEnd(self): # ----- self._run_events() # in main stage self._run_stages() # in user stages # ----- for event in self._get_events(): event.deactivate() event.setActive(False) event.active = False self._run_events() # should not be logged for event in self._get_events(): event.activate() event.setActive(True) event.active = True # ----- for klass in self._get_classes(): klass.deactivate() klass.setActive(False) klass.active = False self._run_events() # A and B should not be logged for klass in self._get_classes(): klass.activate() klass.setActive(True) klass.active = True # ----- for stage in self._get_stages(): active = stage.getActive() self.assertTrue(active) self.assertTrue(stage.active) stage.setActive(False) active = stage.getActive() self.assertFalse(active) self.assertFalse(stage.active) self._run_stages() # should not be logged for stage in self._get_stages(): stage.setActive(True) stage.active = True active = stage.getActive() self.assertTrue(active) self.assertTrue(stage.active) # ----- self._run_events() self._run_stages() def _run_stages(self): for stage in self._get_stages(): self._run_events(stage) def _get_stages(self): return (self.stage1, self.stage2) def _get_classes(self): return (self.klassA, self.klassB) def _get_events(self): return (self.event1, self.event2, self.eventA, self.eventB) def _run_events(self, stage=None): if stage is not None: stage.push() self._events_begin() self._events_end() if stage is not None: stage.pop() def _events_begin(self): for event in self._get_events(): event.begin() def _events_end(self): for event in reversed(self._get_events()): event.end() # -------------------------------------------------------------------- if __name__ == '__main__': unittest.main() ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/test/test_mat_aij.py0000644000175000017500000007117714567251135016400 0ustar00balaybalayfrom petsc4py import PETSc import unittest import numpy as N import numpy as np def mkgraph(comm, m, n): start = m*n * comm.rank end = start + m*n idt = PETSc.IntType rows = [] for I in range(start, end) : rows.append([]) adj = rows[-1] i = I//n; j = I - i*n if i> 0 : J = I-n; adj.append(J) if j> 0 : J = I-1; adj.append(J) adj.append(I) if j< n-1: J = I+1; adj.append(J) if i< m-1: J = I+n; adj.append(J) nods = N.array(range(start, end), dtype=idt) xadj = N.array([0]*(len(rows)+1), dtype=idt) xadj[0] = 0 xadj[1:] = N.cumsum([len(r) for r in rows], dtype=idt) if not rows: adjy = N.array([],dtype=idt) else: adjy = N.concatenate(rows).astype(idt) return nods, xadj, adjy class BaseTestMatAnyAIJ(object): COMM = PETSc.COMM_NULL TYPE = None GRID = 0, 0 BSIZE = None def setUp(self): COMM = self.COMM GM, GN = self.GRID BS = self.BSIZE # try: rbs, cbs = BS rbs = rbs or 1 cbs = cbs or 1 except (TypeError, ValueError): rbs = cbs = BS or 1 sdt = dtype = PETSc.ScalarType self.rows, self.xadj, self.adjy = mkgraph(COMM, GM, GN) self.vals = N.array(range(1, 1 + len(self.adjy)*rbs*cbs), dtype=sdt) self.vals.shape = (-1, rbs, cbs) # m, n = GM, GN rowsz = (m*n*rbs, None) colsz = (m*n*cbs, None) A = self.A = PETSc.Mat().create(comm=COMM) A.setType(self.TYPE) A.setSizes([rowsz, colsz], BS) def tearDown(self): self.A.destroy() self.A = None PETSc.garbage_cleanup() def testSetPreallocNNZ(self): nnz = [5, 2] self.A.setPreallocationNNZ(nnz) self._chk_bs(self.A, self.BSIZE) opt = PETSc.Mat.Option.NEW_NONZERO_ALLOCATION_ERR self.A.setOption(opt, True) ai, aj, av = self._set_values() self.A.assemble() self._chk_aij(self.A, ai, aj) opt = PETSc.Mat.Option.NEW_NONZERO_LOCATION_ERR self.A.setOption(opt, True) ai, aj, av = self._set_values_ijv() self.A.assemble() self._chk_aij(self.A, ai, aj) def testSetPreallocNNZ_2(self): _, ai, _, _ =self._get_aijv() d_nnz = N.diff(ai) nnz = [d_nnz, 3] self.A.setPreallocationNNZ(nnz) self._chk_bs(self.A, self.BSIZE) opt = PETSc.Mat.Option.NEW_NONZERO_ALLOCATION_ERR self.A.setOption(opt, True) ai, aj, av = self._set_values() self.A.assemble() self._chk_aij(self.A, ai, aj) opt = PETSc.Mat.Option.NEW_NONZERO_LOCATION_ERR self.A.setOption(opt, True) ai, aj, av =self._set_values_ijv() self.A.assemble() self._chk_aij(self.A, ai, aj) def testSetPreallocCSR(self): if 'is' in self.A.getType(): return # XXX _, ai, aj, _ = self._get_aijv() csr = [ai, aj] self.A.setPreallocationCSR(csr) self._chk_bs(self.A, self.BSIZE) self._chk_aij(self.A, ai, aj) opt = PETSc.Mat.Option.NEW_NONZERO_LOCATION_ERR self.A.setOption(opt, True) self._set_values() self.A.assemble() self._chk_aij(self.A, ai, aj) self._set_values_ijv() self.A.assemble() self._chk_aij(self.A, ai, aj) def testSetPreallocCSR_2(self): if 'is' in self.A.getType(): return # XXX _, ai, aj, av =self._get_aijv() csr = [ai, aj, av] self.A.setPreallocationCSR(csr) self._chk_bs(self.A, self.BSIZE) self._chk_aij(self.A, ai, aj) opt = PETSc.Mat.Option.NEW_NONZERO_LOCATION_ERR self.A.setOption(opt, True) self._set_values() self.A.assemble() self._chk_aij(self.A, ai, aj) self._set_values_ijv() self.A.assemble() self._chk_aij(self.A, ai, aj) def testSetValues(self): self._preallocate() opt = PETSc.Mat.Option.NEW_NONZERO_ALLOCATION_ERR self.A.setOption(opt, True) ai, aj, av = self._set_values() self.A.assemble() self._chk_aij(self.A, ai, aj) opt = PETSc.Mat.Option.NEW_NONZERO_LOCATION_ERR self.A.setOption(opt, True) ai, aj, av = self._set_values() self.A.assemble() self._chk_aij(self.A, ai, aj) def testSetValuesIJV(self): self._preallocate() opt = PETSc.Mat.Option.NEW_NONZERO_ALLOCATION_ERR self.A.setOption(opt, True) ai, aj, av = self._set_values_ijv() self.A.assemble() self._chk_aij(self.A, ai, aj) opt = PETSc.Mat.Option.NEW_NONZERO_LOCATION_ERR self.A.setOption(opt, True) ai, aj, av = self._set_values_ijv() self.A.assemble() self._chk_aij(self.A, ai, aj) def testGetValuesCSR(self): if 'is' in self.A.getType(): return # XXX self._preallocate() self._set_values_ijv() A = self.A A.assemble() if 'sbaij' in A.getType(): opt = PETSc.Mat.Option.GETROW_UPPERTRIANGULAR self.A.setOption(opt, True) ai, aj, av = A.getValuesCSR() rstart, rend = A.getOwnershipRange() for row in range(rstart, rend): cols, vals = A.getRow(row) i = row - rstart self.assertTrue(N.allclose(aj[ai[i]:ai[i+1]], cols)) self.assertTrue(N.allclose(av[ai[i]:ai[i+1]], vals)) def testConvertToSAME(self): self._preallocate() self._set_values_ijv() A = self.A A.assemble() A.convert('same') def testConvertToDENSE(self): self._preallocate() self._set_values_ijv() A = self.A A.assemble() x, y = A.getVecs() x.setRandom() z = y.duplicate() A.mult(x, y) if A.type.endswith('sbaij'): return B = PETSc.Mat() A.convert('dense', B) # initial B.mult(x, z) self.assertTrue(np.allclose(y.array, z.array)) A.convert('dense', B) # reuse B.mult(x, z) self.assertTrue(np.allclose(y.array, z.array)) A.convert('dense') # inplace A.mult(x, z) self.assertTrue(np.allclose(y.array, z.array)) def testConvertToAIJ(self): self._preallocate() self._set_values_ijv() A = self.A A.assemble() x, y = A.getVecs() x.setRandom() z = y.duplicate() A.mult(x, y) if A.type.endswith('sbaij'): return B = PETSc.Mat() A.convert('aij', B) # initial B.mult(x, z) self.assertTrue(np.allclose(y.array, z.array)) A.convert('aij', B) # reuse B.mult(x, z) self.assertTrue(np.allclose(y.array, z.array)) A.convert('aij') # inplace A.mult(x, z) self.assertTrue(np.allclose(y.array, z.array)) def testGetDiagonalBlock(self): if 'is' in self.A.getType(): return # XXX self._preallocate() self._set_values_ijv() self.A.assemble() B = self.A.getDiagonalBlock() self.assertEqual(self.A.getLocalSize(), B.getSize()) B.destroy() def testInvertBlockDiagonal(self): if 'is' in self.A.getType(): return # XXX try: _ = len(self.BSIZE) return except (TypeError, ValueError): pass self._preallocate() rbs, cbs = self.A.getBlockSizes() if rbs != cbs: return self._set_values_ijv() self.A.assemble() self.A.shift(1000) # Make nonsingular ibdiag = self.A.invertBlockDiagonal() bs = self.A.getBlockSize() m, _ = self.A.getLocalSize() self.assertEqual(ibdiag.shape, (m//bs, bs, bs)) tmp = N.empty((m//bs, bs, bs), dtype=PETSc.ScalarType) rstart, rend = self.A.getOwnershipRange() s, e = rstart//bs, rend//bs for i in range(s, e): rows = cols = N.arange(i*bs,(i+1)*bs, dtype=PETSc.IntType) vals = self.A.getValues(rows,cols) tmp[i-s,:,:] = N.linalg.inv(vals) self.assertTrue(N.allclose(ibdiag, tmp)) def testCreateSubMatrix(self): if 'baij' in self.A.getType(): return # XXX self._preallocate() self._set_values_ijv() self.A.assemble() # rank = self.A.getComm().getRank() rs, re = self.A.getOwnershipRange() cs, ce = self.A.getOwnershipRangeColumn() rows = N.array(range(rs, re), dtype=PETSc.IntType) cols = N.array(range(cs, ce), dtype=PETSc.IntType) rows = PETSc.IS().createGeneral(rows, comm=self.A.getComm()) cols = PETSc.IS().createGeneral(cols, comm=self.A.getComm()) # S = self.A.createSubMatrix(rows, None) S.zeroEntries() self.A.createSubMatrix(rows, None, S) S.destroy() # S = self.A.createSubMatrix(rows, cols) S.zeroEntries() self.A.createSubMatrix(rows, cols, S) S.destroy() def testCreateSubMatrices(self): if 'baij' in self.A.getType(): return # XXX if 'is' in self.A.getType(): return # XXX self._preallocate() self._set_values_ijv() self.A.assemble() # rs, re = self.A.getOwnershipRange() cs, ce = self.A.getOwnershipRangeColumn() rows = N.array(range(rs, re), dtype=PETSc.IntType) cols = N.array(range(cs, ce), dtype=PETSc.IntType) rows = PETSc.IS().createGeneral(rows, comm=self.A.getComm()) cols = PETSc.IS().createGeneral(cols, comm=self.A.getComm()) # (S,) = self.A.createSubMatrices(rows, cols) S.zeroEntries() self.A.createSubMatrices(rows, cols, submats=[S]) S.destroy() # (S1,) = self.A.createSubMatrices([rows], [cols]) (S2,) = self.A.createSubMatrices([rows], [cols]) self.assertTrue(S1.equal(S2)) S2.zeroEntries() self.A.createSubMatrices([rows], [cols], [S2]) self.assertTrue(S1.equal(S2)) S1.destroy() S2.destroy() # if 'seq' not in self.A.getType(): return # XXX S1, S2 = self.A.createSubMatrices([rows, rows], [cols, cols]) self.assertTrue(S1.equal(S2)) S1.zeroEntries() S2.zeroEntries() self.A.createSubMatrices([rows, rows], [cols, cols], [S1, S2]) self.assertTrue(S1.equal(S2)) S1.destroy() S2.destroy() def testGetRedundantMatrix(self): if 'aijcrl' in self.A.getType(): return # duplicate not supported if 'mpisbaij' in self.A.getType(): return # not working if 'is' in self.A.getType(): return # XXX self._preallocate() self._set_values_ijv() self.A.assemble() #Test the most simple case sizecommA = self.A.getComm().getSize() Ared = self.A.getRedundantMatrix(sizecommA) sizecommAred = Ared.getComm().getSize() self.assertEqual(1, sizecommAred) Ared.destroy() def testCreateTranspose(self): self._preallocate() self._set_values_ijv() self.A.assemble() A = self.A AT = PETSc.Mat().createTranspose(A) x, y = A.createVecs() xt, yt = AT.createVecs() # y.setRandom() A.multTranspose(y, x) y.copy(xt) AT.mult(xt, yt) self.assertTrue(yt.equal(x)) # x.setRandom() A.mult(x, y) x.copy(yt) AT.multTranspose(yt, xt) self.assertTrue(xt.equal(y)) def _get_aijv(self): return (self.rows, self.xadj, self.adjy, self.vals,) def _preallocate(self): self.A.setPreallocationNNZ([5, 2]) def _set_values(self): import sys if hasattr(sys, 'gettotalrefcount'): return self._set_values_ijv() # XXX Why the code below leak refs as a beast ??? row, ai, aj, av =self._get_aijv() if not self.BSIZE: setvalues = self.A.setValues else: setvalues = self.A.setValuesBlocked for i, r in enumerate(row): s, e = ai[i], ai[i+1] setvalues(r, aj[s:e], av[s:e]) return ai, aj, av def _set_values_ijv(self): row, ai, aj, av =self._get_aijv() if not self.BSIZE: setvalues = self.A.setValuesIJV else: setvalues = self.A.setValuesBlockedIJV setvalues(ai, aj, av, rowmap=row) setvalues(ai, aj, av, rowmap=None) return ai, aj, av def _chk_bs(self, A, bs): self.assertEqual(A.getBlockSize(), bs or 1) def _chk_bsizes(self, A, bsizes): try: rbs, cbs = bsizes except (TypeError, ValueError): rbs = cbs = bsizes self.assertEqual(A.getBlockSizes(), (rbs, cbs)) def _chk_aij(self, A, i, j): compressed = bool(self.BSIZE) ai, aj = A.getRowIJ(compressed=compressed) if ai is not None and aj is not None: self.assertTrue(N.all(i==ai)) self.assertTrue(N.all(j==aj)) ai, aj = A.getColumnIJ(compressed=compressed) if ai is not None and aj is not None: self.assertTrue(N.all(i==ai)) self.assertTrue(N.all(j==aj)) # -- AIJ --------------------- class BaseTestMatAIJ(BaseTestMatAnyAIJ, unittest.TestCase): COMM = PETSc.COMM_WORLD TYPE = PETSc.Mat.Type.AIJ GRID = 0, 0 BSIZE = None # -- Seq AIJ -- class TestMatSeqAIJ(BaseTestMatAIJ): COMM = PETSc.COMM_SELF TYPE = PETSc.Mat.Type.SEQAIJ class TestMatSeqAIJ_G23(TestMatSeqAIJ): GRID = 2, 3 class TestMatSeqAIJ_G45(TestMatSeqAIJ): GRID = 4, 5 class TestMatSeqAIJ_G89(TestMatSeqAIJ): GRID = 8, 9 # -- MPI AIJ -- class TestMatMPIAIJ(BaseTestMatAIJ): COMM = PETSc.COMM_WORLD TYPE = PETSc.Mat.Type.MPIAIJ class TestMatMPIAIJ_G23(TestMatMPIAIJ): GRID = 2, 3 class TestMatMPIAIJ_G45(TestMatMPIAIJ): GRID = 4, 5 class TestMatMPIAIJ_G89(TestMatMPIAIJ): GRID = 8, 9 # -- Block AIJ --------------- class BaseTestMatBAIJ(BaseTestMatAnyAIJ, unittest.TestCase): COMM = PETSc.COMM_WORLD TYPE = PETSc.Mat.Type.BAIJ GRID = 0, 0 BSIZE = 1 # -- Seq Block AIJ -- class TestMatSeqBAIJ(BaseTestMatBAIJ): COMM = PETSc.COMM_SELF TYPE = PETSc.Mat.Type.SEQBAIJ # bs = 1 class TestMatSeqBAIJ_G23(TestMatSeqBAIJ): GRID = 2, 3 class TestMatSeqBAIJ_G45(TestMatSeqBAIJ): GRID = 4, 5 class TestMatSeqBAIJ_G89(TestMatSeqBAIJ): GRID = 8, 9 # bs = 2 class TestMatSeqBAIJ_G23_B2(TestMatSeqBAIJ_G23): BSIZE = 2 class TestMatSeqBAIJ_G45_B2(TestMatSeqBAIJ_G45): BSIZE = 2 class TestMatSeqBAIJ_G89_B2(TestMatSeqBAIJ_G89): BSIZE = 2 # bs = 3 class TestMatSeqBAIJ_G23_B3(TestMatSeqBAIJ_G23): BSIZE = 3 class TestMatSeqBAIJ_G45_B3(TestMatSeqBAIJ_G45): BSIZE = 3 class TestMatSeqBAIJ_G89_B3(TestMatSeqBAIJ_G89): BSIZE = 3 # bs = 4 class TestMatSeqBAIJ_G23_B4(TestMatSeqBAIJ_G23): BSIZE = 4 class TestMatSeqBAIJ_G45_B4(TestMatSeqBAIJ_G45): BSIZE = 4 class TestMatSeqBAIJ_G89_B4(TestMatSeqBAIJ_G89): BSIZE = 4 # bs = 5 class TestMatSeqBAIJ_G23_B5(TestMatSeqBAIJ_G23): BSIZE = 5 class TestMatSeqBAIJ_G45_B5(TestMatSeqBAIJ_G45): BSIZE = 5 class TestMatSeqBAIJ_G89_B5(TestMatSeqBAIJ_G89): BSIZE = 5 # -- MPI Block AIJ -- class TestMatMPIBAIJ(BaseTestMatBAIJ): COMM = PETSc.COMM_WORLD TYPE = PETSc.Mat.Type.MPIBAIJ # bs = 1 class TestMatMPIBAIJ_G23(TestMatMPIBAIJ): GRID = 2, 3 class TestMatMPIBAIJ_G45(TestMatMPIBAIJ): GRID = 4, 5 class TestMatMPIBAIJ_G89(TestMatMPIBAIJ): GRID = 8, 9 # bs = 2 class TestMatMPIBAIJ_G23_B2(TestMatMPIBAIJ_G23): BSIZE = 2 class TestMatMPIBAIJ_G45_B2(TestMatMPIBAIJ_G45): BSIZE = 2 class TestMatMPIBAIJ_G89_B2(TestMatMPIBAIJ_G89): BSIZE = 2 # bs = 3 class TestMatMPIBAIJ_G23_B3(TestMatMPIBAIJ_G23): BSIZE = 3 class TestMatMPIBAIJ_G45_B3(TestMatMPIBAIJ_G45): BSIZE = 3 class TestMatMPIBAIJ_G89_B3(TestMatMPIBAIJ_G89): BSIZE = 3 # bs = 4 class TestMatMPIBAIJ_G23_B4(TestMatMPIBAIJ_G23): BSIZE = 4 class TestMatMPIBAIJ_G45_B4(TestMatMPIBAIJ_G45): BSIZE = 4 class TestMatMPIBAIJ_G89_B4(TestMatMPIBAIJ_G89): BSIZE = 4 # bs = 5 class TestMatMPIBAIJ_G23_B5(TestMatMPIBAIJ_G23): BSIZE = 5 class TestMatMPIBAIJ_G45_B5(TestMatMPIBAIJ_G45): BSIZE = 5 class TestMatMPIBAIJ_G89_B5(TestMatMPIBAIJ_G89): BSIZE = 5 # -- SymmBlock AIJ --------------- class BaseTestMatSBAIJ(BaseTestMatAnyAIJ, unittest.TestCase): COMM = PETSc.COMM_WORLD TYPE = PETSc.Mat.Type.SBAIJ GRID = 0, 0 BSIZE = 1 def testInvertBlockDiagonal(self): pass def _chk_aij(self, A, i, j): ai, aj = A.getRowIJ(compressed=True) if ai is not None and aj is not None: if 0: # XXX Implement self.assertTrue(N.all(i==ai)) self.assertTrue(N.all(j==aj)) ai, aj = A.getColumnIJ(compressed=True) if ai is not None and aj is not None: if 0: # XXX Implement self.assertTrue(N.all(i==ai)) self.assertTrue(N.all(j==aj)) # -- Seq SymmBlock AIJ -- class TestMatSeqSBAIJ(BaseTestMatSBAIJ): COMM = PETSc.COMM_SELF TYPE = PETSc.Mat.Type.SEQSBAIJ # bs = 1 class TestMatSeqSBAIJ_G23(TestMatSeqSBAIJ): GRID = 2, 3 class TestMatSeqSBAIJ_G45(TestMatSeqSBAIJ): GRID = 4, 5 class TestMatSeqSBAIJ_G89(TestMatSeqSBAIJ): GRID = 8, 9 # bs = 2 class TestMatSeqSBAIJ_G23_B2(TestMatSeqSBAIJ_G23): BSIZE = 2 class TestMatSeqSBAIJ_G45_B2(TestMatSeqSBAIJ_G45): BSIZE = 2 class TestMatSeqSBAIJ_G89_B2(TestMatSeqSBAIJ_G89): BSIZE = 2 # bs = 3 class TestMatSeqSBAIJ_G23_B3(TestMatSeqSBAIJ_G23): BSIZE = 3 class TestMatSeqSBAIJ_G45_B3(TestMatSeqSBAIJ_G45): BSIZE = 3 class TestMatSeqSBAIJ_G89_B3(TestMatSeqSBAIJ_G89): BSIZE = 3 # bs = 4 class TestMatSeqSBAIJ_G23_B4(TestMatSeqSBAIJ_G23): BSIZE = 4 class TestMatSeqSBAIJ_G45_B4(TestMatSeqSBAIJ_G45): BSIZE = 4 class TestMatSeqSBAIJ_G89_B4(TestMatSeqSBAIJ_G89): BSIZE = 4 # bs = 5 class TestMatSeqSBAIJ_G23_B5(TestMatSeqSBAIJ_G23): BSIZE = 5 class TestMatSeqSBAIJ_G45_B5(TestMatSeqSBAIJ_G45): BSIZE = 5 class TestMatSeqSBAIJ_G89_B5(TestMatSeqSBAIJ_G89): BSIZE = 5 # -- MPI SymmBlock AIJ -- class TestMatMPISBAIJ(BaseTestMatSBAIJ): COMM = PETSc.COMM_WORLD TYPE = PETSc.Mat.Type.MPISBAIJ # bs = 1 class TestMatMPISBAIJ_G23(TestMatMPISBAIJ): GRID = 2, 3 class TestMatMPISBAIJ_G45(TestMatMPISBAIJ): GRID = 4, 5 class TestMatMPISBAIJ_G89(TestMatMPISBAIJ): GRID = 8, 9 # bs = 2 class TestMatMPISBAIJ_G23_B2(TestMatMPISBAIJ_G23): BSIZE = 2 class TestMatMPISBAIJ_G45_B2(TestMatMPISBAIJ_G45): BSIZE = 2 class TestMatMPISBAIJ_G89_B2(TestMatMPISBAIJ_G89): BSIZE = 2 # bs = 3 class TestMatMPISBAIJ_G23_B3(TestMatMPISBAIJ_G23): BSIZE = 3 class TestMatMPISBAIJ_G45_B3(TestMatMPISBAIJ_G45): BSIZE = 3 class TestMatMPISBAIJ_G89_B3(TestMatMPISBAIJ_G89): BSIZE = 3 # bs = 4 class TestMatMPISBAIJ_G23_B4(TestMatMPISBAIJ_G23): BSIZE = 4 class TestMatMPISBAIJ_G45_B4(TestMatMPISBAIJ_G45): BSIZE = 4 class TestMatMPISBAIJ_G89_B4(TestMatMPISBAIJ_G89): BSIZE = 4 # bs = 5 class TestMatMPISBAIJ_G23_B5(TestMatMPISBAIJ_G23): BSIZE = 5 class TestMatMPISBAIJ_G45_B5(TestMatMPISBAIJ_G45): BSIZE = 5 class TestMatMPISBAIJ_G89_B5(TestMatMPISBAIJ_G89): BSIZE = 5 # -- AIJ + Block --------------- class BaseTestMatAIJ_B(BaseTestMatAnyAIJ, unittest.TestCase): COMM = PETSc.COMM_WORLD TYPE = PETSc.Mat.Type.AIJ GRID = 0, 0 BSIZE = 1 def testSetPreallocNNZ(self):pass def testSetPreallocNNZ_2(self):pass def testSetPreallocCSR(self):pass def testSetPreallocCSR_2(self):pass def testSetValues(self): self._preallocate() opt = PETSc.Mat.Option.NEW_NONZERO_ALLOCATION_ERR self.A.setOption(opt, True) ai, aj, av = self._set_values() self.A.assemble() self._chk_aij(self.A, ai, aj) opt = PETSc.Mat.Option.NEW_NONZERO_LOCATION_ERR self.A.setOption(opt, True) ai, aj, av = self._set_values() self.A.assemble() self._chk_aij(self.A, ai, aj) def testSetValuesIJV(self): self._preallocate() opt = PETSc.Mat.Option.NEW_NONZERO_ALLOCATION_ERR self.A.setOption(opt, True) ai, aj, av = self._set_values_ijv() self.A.assemble() self._chk_aij(self.A, ai, aj) opt = PETSc.Mat.Option.NEW_NONZERO_LOCATION_ERR self.A.setOption(opt, True) ai, aj, av = self._set_values_ijv() self.A.assemble() self._chk_aij(self.A, ai, aj) def _preallocate(self): self.A.setPreallocationNNZ([5*self.BSIZE, 3*self.BSIZE]) self._chk_bs(self.A, self.BSIZE) def _chk_aij(self, A, i, j): bs = self.BSIZE or 1 ai, aj = A.getRowIJ() if ai is not None and aj is not None: ## XXX map and check !! #self.assertTrue(N.all(i==ai)) #self.assertTrue(N.all(j==aj)) pass ai, aj = A.getColumnIJ(compressed=bool(self.BSIZE)) if ai is not None and aj is not None: ## XXX map and check !! #self.assertTrue(N.all(i==ai)) #self.assertTrue(N.all(j==aj)) pass # -- Seq AIJ + Block -- class TestMatSeqAIJ_B(BaseTestMatAIJ_B): COMM = PETSc.COMM_SELF TYPE = PETSc.Mat.Type.SEQAIJ # bs = 1 class TestMatSeqAIJ_B_G23(TestMatSeqAIJ_B): GRID = 2, 3 class TestMatSeqAIJ_B_G45(TestMatSeqAIJ_B): GRID = 4, 5 class TestMatSeqAIJ_B_G89(TestMatSeqAIJ_B): GRID = 8, 9 # bs = 2 class TestMatSeqAIJ_B_G23_B2(TestMatSeqAIJ_B_G23): BSIZE = 2 class TestMatSeqAIJ_B_G45_B2(TestMatSeqAIJ_B_G45): BSIZE = 2 class TestMatSeqAIJ_B_G89_B2(TestMatSeqAIJ_B_G89): BSIZE = 2 # bs = 3 class TestMatSeqAIJ_B_G23_B3(TestMatSeqAIJ_B_G23): BSIZE = 3 class TestMatSeqAIJ_B_G45_B3(TestMatSeqAIJ_B_G45): BSIZE = 3 class TestMatSeqAIJ_B_G89_B3(TestMatSeqAIJ_B_G89): BSIZE = 3 # bs = 4 class TestMatSeqAIJ_B_G23_B4(TestMatSeqAIJ_B_G23): BSIZE = 4 class TestMatSeqAIJ_B_G45_B4(TestMatSeqAIJ_B_G45): BSIZE = 4 class TestMatSeqAIJ_B_G89_B4(TestMatSeqAIJ_B_G89): BSIZE = 4 # bs = 5 class TestMatSeqAIJ_B_G23_B5(TestMatSeqAIJ_B_G23): BSIZE = 5 class TestMatSeqAIJ_B_G45_B5(TestMatSeqAIJ_B_G45): BSIZE = 5 class TestMatSeqAIJ_B_G89_B5(TestMatSeqAIJ_B_G89): BSIZE = 5 # -- MPI AIJ + Block -- class TestMatMPIAIJ_B(BaseTestMatAIJ_B): COMM = PETSc.COMM_WORLD TYPE = PETSc.Mat.Type.MPIAIJ # bs = 1 class TestMatMPIAIJ_B_G23(TestMatMPIAIJ_B): GRID = 2, 3 class TestMatMPIAIJ_B_G45(TestMatMPIAIJ_B): GRID = 4, 5 class TestMatMPIAIJ_B_G89(TestMatMPIAIJ_B): GRID = 8, 9 # bs = 2 class TestMatMPIAIJ_B_G23_B2(TestMatMPIAIJ_B_G23): BSIZE = 2 class TestMatMPIAIJ_B_G45_B2(TestMatMPIAIJ_B_G45): BSIZE = 2 class TestMatMPIAIJ_B_G89_B2(TestMatMPIAIJ_B_G89): BSIZE = 2 # bs = 3 class TestMatMPIAIJ_B_G23_B3(TestMatMPIAIJ_B_G23): BSIZE = 3 class TestMatMPIAIJ_B_G45_B3(TestMatMPIAIJ_B_G45): BSIZE = 3 class TestMatMPIAIJ_B_G89_B3(TestMatMPIAIJ_B_G89): BSIZE = 3 # bs = 4 class TestMatMPIAIJ_B_G23_B4(TestMatMPIAIJ_B_G23): BSIZE = 4 class TestMatMPIAIJ_B_G45_B4(TestMatMPIAIJ_B_G45): BSIZE = 4 class TestMatMPIAIJ_B_G89_B4(TestMatMPIAIJ_B_G89): BSIZE = 4 # bs = 5 class TestMatMPIAIJ_B_G23_B5(TestMatMPIAIJ_B_G23): BSIZE = 5 class TestMatMPIAIJ_B_G45_B5(TestMatMPIAIJ_B_G45): BSIZE = 5 class TestMatMPIAIJ_B_G89_B5(TestMatMPIAIJ_B_G89): BSIZE = 5 # -- Non-square blocks -- class BaseTestMatAIJ_B(BaseTestMatAnyAIJ, unittest.TestCase): COMM = PETSc.COMM_WORLD TYPE = PETSc.Mat.Type.AIJ GRID = 0, 0 BSIZE = 4, 2 def _preallocate(self): try: rbs, cbs = self.BSIZE except (TypeError, ValueError): rbs = cbs = self.BSIZE self.A.setPreallocationNNZ([5*rbs, 3*cbs]) self._chk_bsizes(self.A, self.BSIZE) def testSetPreallocNNZ(self):pass def testSetPreallocNNZ_2(self):pass def testSetPreallocCSR(self):pass def testSetPreallocCSR_2(self):pass def testSetValues(self): self._preallocate() opt = PETSc.Mat.Option.NEW_NONZERO_ALLOCATION_ERR self.A.setOption(opt, True) ai, aj, av = self._set_values() self.A.assemble() self._chk_aij(self.A, ai, aj) opt = PETSc.Mat.Option.NEW_NONZERO_LOCATION_ERR self.A.setOption(opt, True) ai, aj, av = self._set_values() self.A.assemble() self._chk_aij(self.A, ai, aj) def testSetValuesIJV(self): self._preallocate() opt = PETSc.Mat.Option.NEW_NONZERO_ALLOCATION_ERR self.A.setOption(opt, True) ai, aj, av = self._set_values_ijv() self.A.assemble() self._chk_aij(self.A, ai, aj) opt = PETSc.Mat.Option.NEW_NONZERO_LOCATION_ERR self.A.setOption(opt, True) ai, aj, av = self._set_values_ijv() self.A.assemble() self._chk_aij(self.A, ai, aj) def _chk_aij(self, A, i, j): bs = self.BSIZE or 1 ai, aj = A.getRowIJ() if ai is not None and aj is not None: ## XXX map and check !! #self.assertTrue(N.all(i==ai)) #self.assertTrue(N.all(j==aj)) pass ai, aj = A.getColumnIJ() if ai is not None and aj is not None: ## XXX map and check !! #self.assertTrue(N.all(i==ai)) #self.assertTrue(N.all(j==aj)) pass # -- AIJCRL --------------------- class BaseTestMatAIJCRL(BaseTestMatAIJ, unittest.TestCase): TYPE = PETSc.Mat.Type.AIJCRL # -- Seq AIJCRL -- class TestMatSeqAIJCRL(BaseTestMatAIJCRL): COMM = PETSc.COMM_SELF TYPE = PETSc.Mat.Type.SEQAIJCRL class TestMatSeqAIJCRL_G23(TestMatSeqAIJCRL): GRID = 2, 3 class TestMatSeqAIJCRL_G45(TestMatSeqAIJCRL): GRID = 4, 5 class TestMatSeqAIJCRL_G89(TestMatSeqAIJCRL): GRID = 8, 9 # -- MPI AIJCRL -- class TestMatMPIAIJCRL(BaseTestMatAIJCRL): COMM = PETSc.COMM_WORLD TYPE = PETSc.Mat.Type.MPIAIJCRL class TestMatMPIAIJCRL_G23(TestMatMPIAIJCRL): GRID = 2, 3 class TestMatMPIAIJCRL_G45(TestMatMPIAIJCRL): GRID = 4, 5 class TestMatMPIAIJCRL_G89(TestMatMPIAIJCRL): GRID = 8, 9 # -- AIJCRL + Block ------------- class BaseTestMatAIJCRL_B(BaseTestMatAIJ_B, unittest.TestCase): TYPE = PETSc.Mat.Type.AIJCRL # -- Seq AIJCRL + Block -- class TestMatSeqAIJCRL_B(BaseTestMatAIJCRL_B): COMM = PETSc.COMM_SELF TYPE = PETSc.Mat.Type.SEQAIJCRL # bs = 1 class TestMatSeqAIJCRL_B_G23(TestMatSeqAIJCRL_B): GRID = 2, 3 class TestMatSeqAIJCRL_B_G45(TestMatSeqAIJCRL_B): GRID = 4, 5 class TestMatSeqAIJCRL_B_G89(TestMatSeqAIJCRL_B): GRID = 8, 9 # bs = 2 class TestMatSeqAIJCRL_B_G23_B2(TestMatSeqAIJCRL_B_G23): BSIZE = 2 class TestMatSeqAIJCRL_B_G45_B2(TestMatSeqAIJCRL_B_G45): BSIZE = 2 class TestMatSeqAIJCRL_B_G89_B2(TestMatSeqAIJCRL_B_G89): BSIZE = 2 # bs = 3 class TestMatSeqAIJCRL_B_G23_B3(TestMatSeqAIJCRL_B_G23): BSIZE = 3 class TestMatSeqAIJCRL_B_G45_B3(TestMatSeqAIJCRL_B_G45): BSIZE = 3 class TestMatSeqAIJCRL_B_G89_B3(TestMatSeqAIJCRL_B_G89): BSIZE = 3 # bs = 4 class TestMatSeqAIJCRL_B_G23_B4(TestMatSeqAIJCRL_B_G23): BSIZE = 4 class TestMatSeqAIJCRL_B_G45_B4(TestMatSeqAIJCRL_B_G45): BSIZE = 4 class TestMatSeqAIJCRL_B_G89_B4(TestMatSeqAIJCRL_B_G89): BSIZE = 4 # bs = 5 class TestMatSeqAIJCRL_B_G23_B5(TestMatSeqAIJCRL_B_G23): BSIZE = 5 class TestMatSeqAIJCRL_B_G45_B5(TestMatSeqAIJCRL_B_G45): BSIZE = 5 class TestMatSeqAIJCRL_B_G89_B5(TestMatSeqAIJCRL_B_G89): BSIZE = 5 # -- MPI AIJCRL + Block -- class TestMatMPIAIJCRL_B(BaseTestMatAIJCRL_B): COMM = PETSc.COMM_WORLD TYPE = PETSc.Mat.Type.MPIAIJCRL # bs = 1 class TestMatMPIAIJCRL_B_G23(TestMatMPIAIJCRL_B): GRID = 2, 3 class TestMatMPIAIJCRL_B_G45(TestMatMPIAIJCRL_B): GRID = 4, 5 class TestMatMPIAIJCRL_B_G89(TestMatMPIAIJCRL_B): GRID = 8, 9 # bs = 2 class TestMatMPIAIJCRL_B_G23_B2(TestMatMPIAIJCRL_B_G23): BSIZE = 2 class TestMatMPIAIJCRL_B_G45_B2(TestMatMPIAIJCRL_B_G45): BSIZE = 2 class TestMatMPIAIJCRL_B_G89_B2(TestMatMPIAIJCRL_B_G89): BSIZE = 2 # bs = 3 class TestMatMPIAIJCRL_B_G23_B3(TestMatMPIAIJCRL_B_G23): BSIZE = 3 class TestMatMPIAIJCRL_B_G45_B3(TestMatMPIAIJCRL_B_G45): BSIZE = 3 class TestMatMPIAIJCRL_B_G89_B3(TestMatMPIAIJCRL_B_G89): BSIZE = 3 # bs = 4 class TestMatMPIAIJCRL_B_G23_B4(TestMatMPIAIJCRL_B_G23): BSIZE = 4 class TestMatMPIAIJCRL_B_G45_B4(TestMatMPIAIJCRL_B_G45): BSIZE = 4 class TestMatMPIAIJCRL_B_G89_B4(TestMatMPIAIJCRL_B_G89): BSIZE = 4 # bs = 5 class TestMatMPIAIJCRL_B_G23_B5(TestMatMPIAIJCRL_B_G23): BSIZE = 5 class TestMatMPIAIJCRL_B_G45_B5(TestMatMPIAIJCRL_B_G45): BSIZE = 5 class TestMatMPIAIJCRL_B_G89_B5(TestMatMPIAIJCRL_B_G89): BSIZE = 5 # -- MATIS -- class TestMatIS(BaseTestMatAIJ): COMM = PETSc.COMM_WORLD TYPE = PETSc.Mat.Type.IS class TestMatIS_G23(TestMatIS): GRID = 2, 3 class TestMatIS_G45(TestMatIS): GRID = 4, 5 class TestMatIS_G89(TestMatIS): GRID = 8, 9 # ----- if __name__ == '__main__': unittest.main() ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/test/test_mat_dense.py0000644000175000017500000001530214567251135016717 0ustar00balaybalayfrom petsc4py import PETSc import unittest import numpy as np def mkdata(comm, m, N, bs): start = m * comm.rank end = start + m idt = PETSc.IntType sdt = PETSc.ScalarType rows = np.array(range(start, end), dtype=idt) cols = np.array(range(0, N), dtype=idt) vals = np.array(range(0, m*N*bs*bs), dtype=sdt) vals.shape = (-1, bs, bs) return rows, cols, vals class BaseTestMatAnyDense(object): COMM = PETSc.COMM_NULL GRID = 0, 0 BSIZE = None TYPE = PETSc.Mat.Type.DENSE def setUp(self): COMM = self.COMM GM, GN = self.GRID BS = self.BSIZE #or 1 # self.A = PETSc.Mat().create(comm=COMM) bs = BS or 1; m, N = GM, GN; rowsz = (m*bs, None) colsz = (None, N*bs) self.A.setSizes([rowsz, colsz], BS) self.A.setType(self.TYPE) def tearDown(self): self.A.destroy() self.A = None PETSc.garbage_cleanup() def testSetValues(self): self._preallocate() r, c, v = self._set_values() self.A.assemble() self._chk_array(self.A, r, c, v) r, c, v = self._set_values() self.A.assemble() self._chk_array(self.A, r, c, v) def testGetDiagonalBlock(self): M, N = self.A.getSize() # only for square matrices if M != N: return self._preallocate() self._set_values() self.A.assemble() B = self.A.getDiagonalBlock() self.assertEqual(self.A.getLocalSize(), B.getSize()) B.destroy() def testCreateTranspose(self): self._preallocate() self._set_values() self.A.assemble() A = self.A AT = PETSc.Mat().createTranspose(A) x, y = A.createVecs() xt, yt = AT.createVecs() # y.setRandom() A.multTranspose(y, x) y.copy(xt) AT.mult(xt, yt) self.assertTrue(yt.equal(x)) # x.setRandom() A.mult(x, y) x.copy(yt) AT.multTranspose(yt, xt) self.assertTrue(xt.equal(y)) def _preallocate(self): self.A.setPreallocationDense(None) def _set_values(self): COMM = self.COMM GM, GN = self.GRID BS = self.BSIZE or 1 rows, cols, vals = mkdata(COMM, GM, GN, BS) if not self.BSIZE: setvalues = self.A.setValues else: setvalues = self.A.setValuesBlocked setvalues(rows, cols, vals) return rows, cols, vals def _chk_bs(self, A, bs): self.assertEqual(A.getBlockSize(), bs or 1) def _chk_array(self, A, r, c, v): return # XXX vals = self.A.getValues(r, c) vals.shape = v.shape self.assertTrue(np.allclose(vals, v)) # -- Dense --------------------- class BaseTestMatDense(BaseTestMatAnyDense, unittest.TestCase): COMM = PETSc.COMM_WORLD GRID = 0, 0 BSIZE = None # -- Seq Dense -- class TestMatSeqDense(BaseTestMatDense): COMM = PETSc.COMM_SELF TYPE = PETSc.Mat.Type.SEQDENSE class TestMatSeqDense_G23(TestMatSeqDense): GRID = 2, 3 class TestMatSeqDense_G45(TestMatSeqDense): GRID = 4, 5 class TestMatSeqDense_G77(TestMatSeqDense): GRID = 7, 7 class TestMatSeqDense_G89(TestMatSeqDense): GRID = 8, 9 # -- MPI Dense -- class TestMatMPIDense(BaseTestMatDense): COMM = PETSc.COMM_WORLD TYPE = PETSc.Mat.Type.MPIDENSE class TestMatMPIDense_G23(TestMatMPIDense): GRID = 2, 3 class TestMatMPIDense_G45(TestMatMPIDense): GRID = 4, 5 class TestMatMPIDense_G77(TestMatMPIDense): GRID = 7, 7 class TestMatMPIDense_G89(TestMatMPIDense): GRID = 8, 9 # -- Dense + Block --------------- class BaseTestMatDense_B(BaseTestMatAnyDense, unittest.TestCase): COMM = PETSc.COMM_WORLD GRID = 0, 0 BSIZE = 1 def _preallocate(self): #self.A.setBlockSize(self.BSIZE) self.A.setPreallocationDense(None) #self.A.setBlockSize(self.BSIZE) self._chk_bs(self.A, self.BSIZE) # -- Seq Dense + Block -- class TestMatSeqDense_B(BaseTestMatDense_B): COMM = PETSc.COMM_SELF TYPE = PETSc.Mat.Type.SEQDENSE # bs = 1 class TestMatSeqDense_B_G23(TestMatSeqDense_B): GRID = 2, 3 class TestMatSeqDense_B_G45(TestMatSeqDense_B): GRID = 4, 5 class TestMatSeqDense_B_G89(TestMatSeqDense_B): GRID = 8, 9 # bs = 2 class TestMatSeqDense_B_G23_B2(TestMatSeqDense_B_G23): BSIZE = 2 class TestMatSeqDense_B_G45_B2(TestMatSeqDense_B_G45): BSIZE = 2 class TestMatSeqDense_B_G89_B2(TestMatSeqDense_B_G89): BSIZE = 2 # bs = 3 class TestMatSeqDense_B_G23_B3(TestMatSeqDense_B_G23): BSIZE = 3 class TestMatSeqDense_B_G45_B3(TestMatSeqDense_B_G45): BSIZE = 3 class TestMatSeqDense_B_G89_B3(TestMatSeqDense_B_G89): BSIZE = 3 # bs = 4 class TestMatSeqDense_B_G23_B4(TestMatSeqDense_B_G23): BSIZE = 4 class TestMatSeqDense_B_G45_B4(TestMatSeqDense_B_G45): BSIZE = 4 class TestMatSeqDense_B_G89_B4(TestMatSeqDense_B_G89): BSIZE = 4 # bs = 5 class TestMatSeqDense_B_G23_B5(TestMatSeqDense_B_G23): BSIZE = 5 class TestMatSeqDense_B_G45_B5(TestMatSeqDense_B_G45): BSIZE = 5 class TestMatSeqDense_B_G89_B5(TestMatSeqDense_B_G89): BSIZE = 5 # -- MPI Dense + Block -- class TestMatMPIDense_B(BaseTestMatDense_B): COMM = PETSc.COMM_WORLD TYPE = PETSc.Mat.Type.MPIDENSE # bs = 1 class TestMatMPIDense_B_G23(TestMatMPIDense_B): GRID = 2, 3 class TestMatMPIDense_B_G45(TestMatMPIDense_B): GRID = 4, 5 class TestMatMPIDense_B_G77(TestMatMPIDense_B): GRID = 7, 7 class TestMatMPIDense_B_G89(TestMatMPIDense_B): GRID = 8, 9 # bs = 2 class TestMatMPIDense_B_G23_B2(TestMatMPIDense_B_G23): BSIZE = 2 class TestMatMPIDense_B_G45_B2(TestMatMPIDense_B_G45): BSIZE = 2 class TestMatMPIDense_B_G77_B2(TestMatMPIDense_B_G77): BSIZE = 2 class TestMatMPIDense_B_G89_B2(TestMatMPIDense_B_G89): BSIZE = 2 # bs = 3 class TestMatMPIDense_B_G23_B3(TestMatMPIDense_B_G23): BSIZE = 3 class TestMatMPIDense_B_G45_B3(TestMatMPIDense_B_G45): BSIZE = 3 class TestMatMPIDense_B_G77_B3(TestMatMPIDense_B_G77): BSIZE = 3 class TestMatMPIDense_B_G89_B3(TestMatMPIDense_B_G89): BSIZE = 3 # bs = 4 class TestMatMPIDense_B_G23_B4(TestMatMPIDense_B_G23): BSIZE = 4 class TestMatMPIDense_B_G45_B4(TestMatMPIDense_B_G45): BSIZE = 4 class TestMatMPIDense_B_G77_B4(TestMatMPIDense_B_G77): BSIZE = 4 class TestMatMPIDense_B_G89_B4(TestMatMPIDense_B_G89): BSIZE = 4 # bs = 5 class TestMatMPIDense_B_G23_B5(TestMatMPIDense_B_G23): BSIZE = 5 class TestMatMPIDense_B_G45_B5(TestMatMPIDense_B_G45): BSIZE = 5 class TestMatMPIDense_B_G77_B5(TestMatMPIDense_B_G77): BSIZE = 5 class TestMatMPIDense_B_G89_B5(TestMatMPIDense_B_G89): BSIZE = 5 # ----- if __name__ == '__main__': unittest.main() ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/test/test_mat_fact.py0000644000175000017500000001161714567251135016543 0ustar00balaybalayfrom petsc4py import PETSc import unittest import numpy as N def mkmat(n, mtype, opts): A = PETSc.Mat().create(PETSc.COMM_SELF) A.setSizes([n,n]) A.setType(mtype) A.setUp() for o in opts: A.setOption(o, True) return A def mksys_diag(n, mtype, opts): A = mkmat(n, mtype, opts) x, b = A.createVecs() for i in range(n): A[i,i] = i+1 x[i] = 1.0/(i+1) b[i] = 1 A.assemble() x.assemble() b.assemble() return A, x, b def mksys_poi2(n, mtype, opts): A = mkmat(n, mtype, opts) x, b = A.createVecs() for i in range(n): if i == 0: cols = [i, i+1] vals = [2, -1] elif i == n-1: cols = [i-1, i] vals = [-1, 2] else: cols = [i-1, i, i+1] vals = [-1, 2, -1] A[i,cols] = vals x[i] = i+1 b[i] = 0 A.assemble() x.assemble() b.assemble() A.mult(x,b) return A, x, b class BaseTestMatFactor(object): MKSYS = None MTYPE = None MOPTS = () def setUp(self): A, x, b = self.MKSYS(10, self.MTYPE, self.MOPTS) self.A = A self.x = x self.b = b def tearDown(self): self.A.setUnfactored() self.A.destroy(); self.A = None self.x.destroy(); self.x = None self.b.destroy(); self.b = None PETSc.garbage_cleanup() class BaseTestMatFactorLU(BaseTestMatFactor): def testFactorLU(self): r, c = self.A.getOrdering("nd") self.A.reorderForNonzeroDiagonal(r, c) self.A.factorLU(r,c,{'zeropivot':1e-5}) x = self.x.duplicate() self.A.solve(self.b, x) x.axpy(-1, self.x) self.assertTrue(x.norm() < 1e-3) class BaseTestMatFactorILU(BaseTestMatFactor): def testFactorILU(self): r, c = self.A.getOrdering("natural") self.A.factorILU(r,c,{'levels':0}) x = self.x.duplicate() self.A.solve(self.b, x) x.axpy(-1, self.x) self.assertTrue(x.norm() < 1e-3) ## class BaseTestMatFactorILUDT(BaseTestMatFactor): ## ## def testFactorILUDT(self): ## r, c = self.A.getOrdering("natural") ## self.A = self.A.factorILUDT(r,c) ## x = self.x.duplicate() ## self.A.solve(self.b, x) ## x.axpy(-1, self.x) ## self.assertTrue(x.norm() < 1e-3) ## class BaseTestMatFactorChol(BaseTestMatFactor): def testFactorChol(self): r, c = self.A.getOrdering("natural") self.A.factorCholesky(r) x = self.x.duplicate() self.A.solve(self.b, x) x.axpy(-1, self.x) self.assertTrue(x.norm() < 1e-3) class BaseTestMatFactorICC(BaseTestMatFactor): def testFactorICC(self): r, c = self.A.getOrdering("natural") self.A.factorICC(r) x = self.x.duplicate() self.A.solve(self.b, x) x.axpy(-1, self.x) self.assertTrue(x.norm() < 1e-3) # -------------------------------------------------------------------- class TestMatFactorA1(BaseTestMatFactorLU, BaseTestMatFactorChol, unittest.TestCase): MKSYS = staticmethod(mksys_diag) MTYPE = PETSc.Mat.Type.SEQDENSE class TestMatFactorA2(BaseTestMatFactorLU, BaseTestMatFactorChol, unittest.TestCase): MKSYS = staticmethod(mksys_poi2) MTYPE = PETSc.Mat.Type.SEQDENSE # --- class TestMatFactorB1(BaseTestMatFactorLU, BaseTestMatFactorILU, ## BaseTestMatFactorILUDT, unittest.TestCase): MKSYS = staticmethod(mksys_diag) MTYPE = PETSc.Mat.Type.SEQAIJ class TestMatFactorB2(BaseTestMatFactorLU, BaseTestMatFactorILU, ## BaseTestMatFactorILUDT, unittest.TestCase): MKSYS = staticmethod(mksys_poi2) MTYPE = PETSc.Mat.Type.SEQAIJ # --- class TestMatFactorC1(BaseTestMatFactorLU, BaseTestMatFactorILU, unittest.TestCase): MKSYS = staticmethod(mksys_diag) MTYPE = PETSc.Mat.Type.SEQBAIJ class TestMatFactorC2(BaseTestMatFactorLU, BaseTestMatFactorILU, unittest.TestCase): MKSYS = staticmethod(mksys_poi2) MTYPE = PETSc.Mat.Type.SEQBAIJ # --- class TestMatFactorD1(BaseTestMatFactorChol, BaseTestMatFactorICC, unittest.TestCase): MKSYS = staticmethod(mksys_diag) MTYPE = PETSc.Mat.Type.SEQSBAIJ MOPTS = [PETSc.Mat.Option.IGNORE_LOWER_TRIANGULAR] class TestMatFactorD2(BaseTestMatFactorChol, BaseTestMatFactorICC, unittest.TestCase): MKSYS = staticmethod(mksys_poi2) MTYPE = PETSc.Mat.Type.SEQSBAIJ MOPTS = [PETSc.Mat.Option.IGNORE_LOWER_TRIANGULAR] # -------------------------------------------------------------------- if __name__ == '__main__': unittest.main() ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/test/test_mat_py.py0000644000175000017500000005134314567251135016256 0ustar00balaybalayfrom petsc4py import PETSc import unittest, numpy from sys import getrefcount # -------------------------------------------------------------------- class Matrix(object): def __init__(self): pass def create(self, mat): pass def destroy(self, mat): pass class ScaledIdentity(Matrix): s = 2.0 def scale(self, mat, s): self.s *= s def shift(self, mat, s): self.s += s def mult(self, mat, x, y): x.copy(y) y.scale(self.s) def duplicate(self, mat, op): dmat = PETSc.Mat() dctx = ScaledIdentity() dmat.createPython(mat.getSizes(), dctx, comm=mat.getComm()) if op == PETSc.Mat.DuplicateOption.COPY_VALUES: dctx.s = self.s dmat.setUp() return dmat def getDiagonal(self, mat, vd): vd.set(self.s) def productSetFromOptions(self, mat, producttype, A, B, C): return True def productSymbolic(self, mat, product, producttype, A, B, C): if producttype == 'AB': if mat is A: # product = identity * B product.setType(B.getType()) product.setSizes(B.getSizes()) product.setUp() product.assemble() B.copy(product) elif mat is B: # product = A * identity product.setType(A.getType()) product.setSizes(A.getSizes()) product.setUp() product.assemble() A.copy(product) else: raise RuntimeError('wrong configuration') elif producttype == 'AtB': if mat is A: # product = identity^T * B product.setType(B.getType()) product.setSizes(B.getSizes()) product.setUp() product.assemble() B.copy(product) elif mat is B: # product = A^T * identity tmp = PETSc.Mat() A.transpose(tmp) product.setType(tmp.getType()) product.setSizes(tmp.getSizes()) product.setUp() product.assemble() tmp.copy(product) else: raise RuntimeError('wrong configuration') elif producttype == 'ABt': if mat is A: # product = identity * B^T tmp = PETSc.Mat() B.transpose(tmp) product.setType(tmp.getType()) product.setSizes(tmp.getSizes()) product.setUp() product.assemble() tmp.copy(product) elif mat is B: # product = A * identity^T product.setType(A.getType()) product.setSizes(A.getSizes()) product.setUp() product.assemble() A.copy(product) else: raise RuntimeError('wrong configuration') elif producttype == 'PtAP': if mat is A: # product = P^T * identity * P self.tmp = PETSc.Mat() B.transposeMatMult(B, self.tmp) product.setType(self.tmp.getType()) product.setSizes(self.tmp.getSizes()) product.setUp() product.assemble() self.tmp.copy(product) elif mat is B: # product = identity^T * A * identity product.setType(A.getType()) product.setSizes(A.getSizes()) product.setUp() product.assemble() A.copy(product) else: raise RuntimeError('wrong configuration') elif producttype == 'RARt': if mat is A: # product = R * identity * R^t self.tmp = PETSc.Mat() B.matTransposeMult(B, self.tmp) product.setType(self.tmp.getType()) product.setSizes(self.tmp.getSizes()) product.setUp() product.assemble() self.tmp.copy(product) elif mat is B: # product = identity * A * identity^T product.setType(A.getType()) product.setSizes(A.getSizes()) product.setUp() product.assemble() A.copy(product) else: raise RuntimeError('wrong configuration') elif producttype == 'ABC': if mat is A: # product = identity * B * C self.tmp = PETSc.Mat() B.matMult(C, self.tmp) product.setType(self.tmp.getType()) product.setSizes(self.tmp.getSizes()) product.setUp() product.assemble() self.tmp.copy(product) elif mat is B: # product = A * identity * C self.tmp = PETSc.Mat() A.matMult(C, self.tmp) product.setType(self.tmp.getType()) product.setSizes(self.tmp.getSizes()) product.setUp() product.assemble() self.tmp.copy(product) elif mat is C: # product = A * B * identity self.tmp = PETSc.Mat() A.matMult(B, self.tmp) product.setType(self.tmp.getType()) product.setSizes(self.tmp.getSizes()) product.setUp() product.assemble() self.tmp.copy(product) else: raise RuntimeError('wrong configuration') else: raise RuntimeError('Product {} not implemented'.format(producttype)) product.zeroEntries() def productNumeric(self, mat, product, producttype, A, B, C): if producttype == 'AB': if mat is A: # product = identity * B B.copy(product, structure=True) elif mat is B: # product = A * identity A.copy(product, structure=True) else: raise RuntimeError('wrong configuration') product.scale(self.s) elif producttype == 'AtB': if mat is A: # product = identity^T * B B.copy(product, structure=True) elif mat is B: # product = A^T * identity A.setTransposePrecursor(product) A.transpose(product) else: raise RuntimeError('wrong configuration') product.scale(self.s) elif producttype == 'ABt': if mat is A: # product = identity * B^T B.setTransposePrecursor(product) B.transpose(product) elif mat is B: # product = A * identity^T A.copy(product, structure=True) else: raise RuntimeError('wrong configuration') product.scale(self.s) elif producttype == 'PtAP': if mat is A: # product = P^T * identity * P B.transposeMatMult(B, self.tmp) self.tmp.copy(product, structure=True) product.scale(self.s) elif mat is B: # product = identity^T * A * identity A.copy(product, structure=True) product.scale(self.s**2) else: raise RuntimeError('wrong configuration') elif producttype == 'RARt': if mat is A: # product = R * identity * R^t B.matTransposeMult(B, self.tmp) self.tmp.copy(product, structure=True) product.scale(self.s) elif mat is B: # product = identity * A * identity^T A.copy(product, structure=True) product.scale(self.s**2) else: raise RuntimeError('wrong configuration') elif producttype == 'ABC': if mat is A: # product = identity * B * C B.matMult(C, self.tmp) self.tmp.copy(product, structure=True) elif mat is B: # product = A * identity * C A.matMult(C, self.tmp) self.tmp.copy(product, structure=True) elif mat is C: # product = A * B * identity A.matMult(B, self.tmp) self.tmp.copy(product, structure=True) else: raise RuntimeError('wrong configuration') product.scale(self.s) else: raise RuntimeError('Product {} not implemented'.format(producttype)) class Diagonal(Matrix): def create(self, mat): super(Diagonal,self).create(mat) mat.setUp() self.D = mat.createVecLeft() def destroy(self, mat): self.D.destroy() super(Diagonal,self).destroy(mat) def scale(self, mat, a): self.D.scale(a) def shift(self, mat, a): self.D.shift(a) def zeroEntries(self, mat): self.D.zeroEntries() def mult(self, mat, x, y): y.pointwiseMult(x, self.D) def duplicate(self, mat, op): dmat = PETSc.Mat() dctx = Diagonal() dmat.createPython(mat.getSizes(), dctx, comm=mat.getComm()) dctx.D = self.D.duplicate() if op == PETSc.Mat.DuplicateOption.COPY_VALUES: self.D.copy(dctx.D) dmat.setUp() return dmat def getDiagonal(self, mat, vd): self.D.copy(vd) def setDiagonal(self, mat, vd, im): if isinstance (im, bool): addv = im if addv: self.D.axpy(1, vd) else: vd.copy(self.D) elif im == PETSc.InsertMode.INSERT_VALUES: vd.copy(self.D) elif im == PETSc.InsertMode.ADD_VALUES: self.D.axpy(1, vd) else: raise ValueError('wrong InsertMode %d'% im) def diagonalScale(self, mat, vl, vr): if vl: self.D.pointwiseMult(self.D, vl) if vr: self.D.pointwiseMult(self.D, vr) # -------------------------------------------------------------------- class TestMatrix(unittest.TestCase): COMM = PETSc.COMM_WORLD PYMOD = __name__ PYCLS = 'Matrix' def _getCtx(self): return self.A.getPythonContext() def setUp(self): N = self.N = 13 self.A = PETSc.Mat() if 0: # command line way self.A.create(self.COMM) self.A.setSizes([N,N]) self.A.setType('python') OptDB = PETSc.Options(self.A) OptDB['mat_python_type'] = '%s.%s' % (self.PYMOD,self.PYCLS) self.A.setFromOptions() self.A.setUp() del OptDB['mat_python_type'] self.assertTrue(self._getCtx() is not None) else: # python way context = globals()[self.PYCLS]() self.A.createPython([N,N], context, comm=self.COMM) self.A.setUp() self.assertTrue(self._getCtx() is context) self.assertEqual(getrefcount(context), 3) del context self.assertEqual(getrefcount(self._getCtx()), 2) def tearDown(self): ctx = self.A.getPythonContext() self.assertEqual(getrefcount(ctx), 3) self.A.destroy() # XXX self.A = None PETSc.garbage_cleanup() self.assertEqual(getrefcount(ctx), 2) #import gc,pprint; pprint.pprint(gc.get_referrers(ctx)) def testBasic(self): ctx = self.A.getPythonContext() self.assertTrue(self._getCtx() is ctx) self.assertEqual(getrefcount(ctx), 3) def testZeroEntries(self): f = lambda : self.A.zeroEntries() self.assertRaises(Exception, f) def testMult(self): x, y = self.A.createVecs() f = lambda : self.A.mult(x, y) self.assertRaises(Exception, f) def testMultTranspose(self): x, y = self.A.createVecs() f = lambda : self.A.multTranspose(x, y) self.assertRaises(Exception, f) def testGetDiagonal(self): d = self.A.createVecLeft() f = lambda : self.A.getDiagonal(d) self.assertRaises(Exception, f) def testSetDiagonal(self): d = self.A.createVecLeft() f = lambda : self.A.setDiagonal(d) self.assertRaises(Exception, f) def testDiagonalScale(self): x, y = self.A.createVecs() f = lambda : self.A.diagonalScale(x, y) self.assertRaises(Exception, f) def testDuplicate(self): f1 = lambda : self.A.duplicate(x, True) f2 = lambda : self.A.duplicate(x, False) self.assertRaises(Exception, f1) self.assertRaises(Exception, f2) def testSetVecType(self): self.A.setVecType('mpi') self.assertTrue('mpi' == self.A.getVecType()) def testH2Opus(self): if not PETSc.Sys.hasExternalPackage("h2opus"): return if self.A.getComm().Get_size() > 1: return h = PETSc.Mat() # need matrix vector and its transpose for norm estimation AA = self.A.getPythonContext() if not hasattr(AA,'mult'): return AA.multTranspose = AA.mult # without coordinates h.createH2OpusFromMat(self.A,leafsize=2) h.assemble() h.destroy() # with coordinates coords = numpy.linspace((1,2,3),(10,20,30),self.A.getSize()[0],dtype=PETSc.RealType) h.createH2OpusFromMat(self.A,coords,leafsize=2) h.assemble() # test API h.H2OpusOrthogonalize() h.H2OpusCompress(1.e-1) # Low-rank update U = PETSc.Mat() U.createDense([h.getSizes()[0],3],comm=h.getComm()) U.setUp() U.setRandom() he = PETSc.Mat() h.convert('dense',he) he.axpy(1.0, U.matTransposeMult(U)) h.H2OpusLowRankUpdate(U) self.assertTrue(he.equal(h)) h.destroy() del AA.multTranspose def testGetType(self): ctx = self.A.getPythonContext() pytype = "{0}.{1}".format(ctx.__module__, type(ctx).__name__) self.assertTrue(self.A.getPythonType() == pytype) class TestScaledIdentity(TestMatrix): PYCLS = 'ScaledIdentity' def testMult(self): s = self._getCtx().s x, y = self.A.createVecs() x.setRandom() self.A.mult(x,y) self.assertTrue(y.equal(s*x)) def testMultTransposeSymmKnown(self): s = self._getCtx().s x, y = self.A.createVecs() x.setRandom() self.A.setOption(PETSc.Mat.Option.SYMMETRIC, True) self.A.multTranspose(x,y) self.assertTrue(y.equal(s*x)) self.A.setOption(PETSc.Mat.Option.SYMMETRIC, False) f = lambda : self.A.multTranspose(x, y) self.assertRaises(Exception, f) def testMultTransposeNewMeth(self): s = self._getCtx().s x, y = self.A.createVecs() x.setRandom() AA = self.A.getPythonContext() AA.multTranspose = AA.mult self.A.multTranspose(x,y) del AA.multTranspose self.assertTrue(y.equal(s*x)) def testGetDiagonal(self): s = self._getCtx().s d = self.A.createVecLeft() o = d.duplicate() o.set(s) self.A.getDiagonal(d) self.assertTrue(o.equal(d)) def testDuplicate(self): B = self.A.duplicate(False) self.assertTrue(B.getPythonContext().s == 2) B = self.A.duplicate(True) self.assertTrue(B.getPythonContext().s == self.A.getPythonContext().s) def testMatMat(self): s = self._getCtx().s R = PETSc.Random().create(self.COMM) R.setFromOptions() A = PETSc.Mat().create(self.COMM) A.setSizes(self.A.getSizes()) A.setType(PETSc.Mat.Type.AIJ) A.setPreallocationNNZ(None) A.setRandom(R) B = PETSc.Mat().create(self.COMM) B.setSizes(self.A.getSizes()) B.setType(PETSc.Mat.Type.AIJ) B.setPreallocationNNZ(None) B.setRandom(R) I = PETSc.Mat().create(self.COMM) I.setSizes(self.A.getSizes()) I.setType(PETSc.Mat.Type.AIJ) I.setUp() I.assemble() I.shift(s) self.assertTrue(self.A.matMult(A).equal(I.matMult(A))) self.assertTrue(A.matMult(self.A).equal(A.matMult(I))) if self.A.getComm().Get_size() == 1: self.assertTrue(self.A.matTransposeMult(A).equal(I.matTransposeMult(A))) self.assertTrue(A.matTransposeMult(self.A).equal(A.matTransposeMult(I))) self.assertTrue(self.A.transposeMatMult(A).equal(I.transposeMatMult(A))) self.assertTrue(A.transposeMatMult(self.A).equal(A.transposeMatMult(I))) self.assertAlmostEqual((self.A.ptap(A) - I.ptap(A)).norm(), 0.0, places=5) self.assertAlmostEqual((A.ptap(self.A) - A.ptap(I)).norm(), 0.0, places=5) if self.A.getComm().Get_size() == 1: self.assertAlmostEqual((self.A.rart(A) - I.rart(A)).norm(), 0.0, places=5) self.assertAlmostEqual((A.rart(self.A) - A.rart(I)).norm(), 0.0, places=5) self.assertAlmostEqual((self.A.matMatMult(A,B)-I.matMatMult(A,B)).norm(), 0.0, places=5) self.assertAlmostEqual((A.matMatMult(self.A,B)-A.matMatMult(I,B)).norm(), 0.0, places=5) self.assertAlmostEqual((A.matMatMult(B,self.A)-A.matMatMult(B,I)).norm(), 0.0, places=5) def testShift(self): sold = self._getCtx().s self.A.shift(-0.5) s = self._getCtx().s self.assertTrue(s == sold - 0.5) def testScale(self): sold = self._getCtx().s self.A.scale(-0.5) s = self._getCtx().s self.assertTrue(s == sold * -0.5) def testDiagonalMat(self): s = self._getCtx().s B = PETSc.Mat().createConstantDiagonal(self.A.getSizes(), s, comm=self.A.getComm()) self.assertTrue(self.A.equal(B)) class TestDiagonal(TestMatrix): PYCLS = 'Diagonal' def setUp(self): super(TestDiagonal, self).setUp() D = self.A.createVecLeft() s, e = D.getOwnershipRange() for i in range(s, e): D[i] = i+1 D.assemble() self.A.setDiagonal(D) def testZeroEntries(self): self.A.zeroEntries() D = self._getCtx().D self.assertEqual(D.norm(), 0) def testMult(self): x, y = self.A.createVecs() x.set(1) self.A.mult(x,y) self.assertTrue(y.equal(self._getCtx().D)) def testMultTransposeSymmKnown(self): x, y = self.A.createVecs() x.set(1) self.A.setOption(PETSc.Mat.Option.SYMMETRIC, True) self.A.multTranspose(x,y) self.assertTrue(y.equal(self._getCtx().D)) self.A.setOption(PETSc.Mat.Option.SYMMETRIC, False) f = lambda : self.A.multTranspose(x, y) self.assertRaises(Exception, f) def testMultTransposeNewMeth(self): x, y = self.A.createVecs() x.set(1) AA = self.A.getPythonContext() AA.multTranspose = AA.mult self.A.multTranspose(x,y) del AA.multTranspose self.assertTrue(y.equal(self._getCtx().D)) def testDuplicate(self): B = self.A.duplicate(False) B = self.A.duplicate(True) self.assertTrue(B.getPythonContext().D.equal(self.A.getPythonContext().D)) def testGetDiagonal(self): d = self.A.createVecLeft() self.A.getDiagonal(d) self.assertTrue(d.equal(self._getCtx().D)) def testSetDiagonal(self): d = self.A.createVecLeft() d.setRandom() self.A.setDiagonal(d) self.assertTrue(d.equal(self._getCtx().D)) def testDiagonalScale(self): x, y = self.A.createVecs() x.set(2) y.set(3) old = self._getCtx().D.copy() self.A.diagonalScale(x, y) D = self._getCtx().D self.assertTrue(D.equal(old*6)) def testCreateTranspose(self): A = self.A A.setOption(PETSc.Mat.Option.SYMMETRIC, True) AT = PETSc.Mat().createTranspose(A) x, y = A.createVecs() xt, yt = AT.createVecs() # y.setRandom() A.multTranspose(y, x) y.copy(xt) AT.mult(xt, yt) self.assertTrue(yt.equal(x)) # x.setRandom() A.mult(x, y) x.copy(yt) AT.multTranspose(yt, xt) self.assertTrue(xt.equal(y)) del A def testConvert(self): self.assertTrue(self.A.convert(PETSc.Mat.Type.AIJ,PETSc.Mat()).equal(self.A)) self.assertTrue(self.A.convert(PETSc.Mat.Type.BAIJ,PETSc.Mat()).equal(self.A)) self.assertTrue(self.A.convert(PETSc.Mat.Type.SBAIJ,PETSc.Mat()).equal(self.A)) self.assertTrue(self.A.convert(PETSc.Mat.Type.DENSE,PETSc.Mat()).equal(self.A)) def testShift(self): old = self._getCtx().D.copy() self.A.shift(-0.5) D = self._getCtx().D self.assertTrue(D.equal(old-0.5)) def testScale(self): old = self._getCtx().D.copy() self.A.scale(-0.5) D = self._getCtx().D self.assertTrue(D.equal(-0.5*old)) def testDiagonalMat(self): D = self._getCtx().D.copy() B = PETSc.Mat().createDiagonal(D) self.assertTrue(self.A.equal(B)) # -------------------------------------------------------------------- if __name__ == '__main__': unittest.main() ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/test/test_nsp.py0000644000175000017500000000471314567251135015564 0ustar00balaybalayimport unittest from petsc4py import PETSc import numpy as N from sys import getrefcount # -------------------------------------------------------------------- def allclose(seq1, seq2): for v1, v2 in zip(seq1, seq2): if abs(v1-v2) > 1e-5: return False return True class TestNullSpace(unittest.TestCase): def setUp(self): u1 = PETSc.Vec().createSeq(3) u2 = PETSc.Vec().createSeq(3) u1[0], u1[1], u1[2] = [1, 2, 0]; u1.normalize() u2[0], u2[1], u2[2] = [2, -1, 0]; u2.normalize() basis = [u1, u2] nullsp = PETSc.NullSpace().create(False, basis, comm=PETSc.COMM_SELF) self.basis = basis self.nullsp = nullsp def tearDown(self): self.basis = None self.nullsp = None PETSc.garbage_cleanup() def _remove(self): v = PETSc.Vec().createSeq(3); v[0], v[1], v[2] = [7, 8, 9] w = v.copy() self.nullsp.remove(w) return (v, w) def testRemove(self): v, w = self._remove() tols = (0, 1e-5) self.assertTrue(allclose(v.array, [7, 8, 9])) self.assertTrue(allclose(w.array, [0, 0, 9])) del v, w def testRemoveInplace(self): v, w = self._remove() self.nullsp.remove(v) self.assertTrue(v.equal(w)) del v, w def testRemoveWithFunction(self): def myremove(nsp, vec): vec.setArray([1,2,3]) self.nullsp.setFunction(myremove) v, w = self._remove() self.assertTrue(allclose(v.array, [7, 8, 9])) self.assertTrue(allclose(w.array, [1, 2, 3])) self.nullsp.remove(v) self.assertTrue(allclose(v.array, [1, 2, 3])) self.nullsp.setFunction(None) self.testRemove() def testGetSetFunction(self): def rem(nsp, vec): vec.set(0) self.nullsp.setFunction(rem) self.assertEqual(getrefcount(rem)-1, 2) dct = self.nullsp.getDict() self.assertTrue(dct is not None) self.assertEqual(getrefcount(dct)-1, 2) fun, a, kw = dct['__function__'] self.assertTrue(fun is rem) self.nullsp.setFunction(None) fun = dct.get('__function__') self.assertEqual(getrefcount(rem)-1, 1) self.assertTrue(fun is None) # -------------------------------------------------------------------- if __name__ == '__main__': unittest.main() # -------------------------------------------------------------------- ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/test/test_object.py0000644000175000017500000002134014567251135016225 0ustar00balaybalayimport unittest from petsc4py import PETSc # -------------------------------------------------------------------- class BaseTestObject(object): CLASS, FACTORY = None, None TARGS, KARGS = (), {} BUILD = None def setUp(self): self.obj = self.CLASS() getattr(self.obj,self.FACTORY)(*self.TARGS, **self.KARGS) if not self.obj: self.obj.create() def tearDown(self): self.obj = None PETSc.garbage_cleanup() def testTypeRegistry(self): type_reg = PETSc.__type_registry__ classid = self.obj.getClassId() typeobj = self.CLASS if isinstance(self.obj, PETSc.DMDA): typeobj = PETSc.DM self.assertTrue(type_reg[classid] is typeobj ) def testLogClass(self): name = self.CLASS.__name__ if name == 'DMDA': name = 'DM' logcls = PETSc.Log.Class(name) classid = self.obj.getClassId() self.assertEqual(logcls.id, classid) def testClass(self): self.assertTrue(isinstance(self.obj, self.CLASS)) self.assertTrue(type(self.obj) is self.CLASS) def testNonZero(self): self.assertTrue(bool(self.obj)) def testDestroy(self): self.assertTrue(bool(self.obj)) self.obj.destroy() self.assertFalse(bool(self.obj)) ## self.assertRaises(PETSc.Error, self.obj.destroy) ## self.assertTrue(self.obj.this is this) def testOptions(self): self.assertFalse(self.obj.getOptionsPrefix()) prefix1 = 'my_' self.obj.setOptionsPrefix(prefix1) self.assertEqual(self.obj.getOptionsPrefix(), prefix1) prefix2 = 'opt_' self.obj.setOptionsPrefix(prefix2) self.assertEqual(self.obj.getOptionsPrefix(), prefix2) ## self.obj.appendOptionsPrefix(prefix1) ## self.assertEqual(self.obj.getOptionsPrefix(), ## prefix2 + prefix1) ## self.obj.prependOptionsPrefix(prefix1) ## self.assertEqual(self.obj.getOptionsPrefix(), ## prefix1 + prefix2 + prefix1) self.obj.setFromOptions() def testName(self): oldname = self.obj.getName() newname = '%s-%s' %(oldname, oldname) self.obj.setName(newname) self.assertEqual(self.obj.getName(), newname) self.obj.setName(oldname) self.assertEqual(self.obj.getName(), oldname) def testComm(self): comm = self.obj.getComm() self.assertTrue(isinstance(comm, PETSc.Comm)) self.assertTrue(comm in [PETSc.COMM_SELF, PETSc.COMM_WORLD]) def testRefCount(self): self.assertEqual(self.obj.getRefCount(), 1) self.obj.incRef() self.assertEqual(self.obj.getRefCount(), 2) self.obj.incRef() self.assertEqual(self.obj.getRefCount(), 3) self.obj.decRef() self.assertEqual(self.obj.getRefCount(), 2) self.obj.decRef() self.assertEqual(self.obj.getRefCount(), 1) self.obj.decRef() self.assertFalse(bool(self.obj)) def testHandle(self): self.assertTrue(self.obj.handle) self.assertTrue(self.obj.fortran) h, f = self.obj.handle, self.obj.fortran if (h>0 and f>0) or (h<0 and f<0): self.assertEqual(h, f) self.obj.destroy() self.assertFalse(self.obj.handle) self.assertFalse(self.obj.fortran) def testComposeQuery(self): import copy try: myobj = copy.deepcopy(self.obj) except NotImplementedError: return self.assertEqual(myobj.getRefCount(), 1) self.obj.compose('myobj', myobj) self.assertTrue(type(self.obj.query('myobj')) is self.CLASS) self.assertEqual(self.obj.query('myobj'), myobj) self.assertEqual(myobj.getRefCount(), 2) self.obj.compose('myobj', None) self.assertEqual(myobj.getRefCount(), 1) self.assertEqual(self.obj.query('myobj'), None) myobj.destroy() def testProperties(self): self.assertEqual(self.obj.getClassId(), self.obj.classid) self.assertEqual(self.obj.getClassName(), self.obj.klass) self.assertEqual(self.obj.getType(), self.obj.type) self.assertEqual(self.obj.getName(), self.obj.name) self.assertEqual(self.obj.getComm(), self.obj.comm) self.assertEqual(self.obj.getRefCount(), self.obj.refcount) def testShallowCopy(self): import copy rc = self.obj.getRefCount() obj = copy.copy(self.obj) self.assertTrue(obj is not self.obj) self.assertTrue(obj == self.obj) self.assertTrue(type(obj) is type(self.obj)) self.assertEqual(obj.getRefCount(), rc+1) del obj self.assertEqual(self.obj.getRefCount(), rc) def testDeepCopy(self): import copy rc = self.obj.getRefCount() try: obj = copy.deepcopy(self.obj) except NotImplementedError: return self.assertTrue(obj is not self.obj) self.assertTrue(obj != self.obj) self.assertTrue(type(obj) is type(self.obj)) self.assertEqual(self.obj.getRefCount(), rc) self.assertEqual(obj.getRefCount(), 1) del obj def testStateInspection(self): state = self.obj.stateGet() self.obj.stateIncrease() self.assertTrue(state < self.obj.stateGet()) self.obj.stateSet(0) self.assertTrue(self.obj.stateGet() == 0) self.obj.stateSet(state) self.assertTrue(self.obj.stateGet() == state) # -------------------------------------------------------------------- class TestObjectRandom(BaseTestObject, unittest.TestCase): CLASS = PETSc.Random FACTORY = 'create' class TestObjectViewer(BaseTestObject, unittest.TestCase): CLASS = PETSc.Viewer FACTORY = 'create' class TestObjectIS(BaseTestObject, unittest.TestCase): CLASS = PETSc.IS FACTORY = 'createGeneral' TARGS = ([],) class TestObjectLGMap(BaseTestObject, unittest.TestCase): CLASS = PETSc.LGMap FACTORY = 'create' TARGS = ([],) class TestObjectAO(BaseTestObject, unittest.TestCase): CLASS = PETSc.AO FACTORY = 'createMapping' TARGS = ([], []) class TestObjectDMDA(BaseTestObject, unittest.TestCase): CLASS = PETSc.DMDA FACTORY = 'create' TARGS = ([3,3,3],) class TestObjectDS(BaseTestObject, unittest.TestCase): CLASS = PETSc.DS FACTORY = 'create' class TestObjectVec(BaseTestObject, unittest.TestCase): CLASS = PETSc.Vec FACTORY = 'createSeq' TARGS = (0,) def setUp(self): BaseTestObject.setUp(self) self.obj.assemble() class TestObjectMat(BaseTestObject, unittest.TestCase): CLASS = PETSc.Mat FACTORY = 'createAIJ' TARGS = (0,) KARGS = {'nnz':0, 'comm': PETSc.COMM_SELF} def setUp(self): BaseTestObject.setUp(self) self.obj.assemble() class TestObjectMatPartitioning(BaseTestObject, unittest.TestCase): CLASS = PETSc.MatPartitioning FACTORY = 'create' class TestObjectNullSpace(BaseTestObject, unittest.TestCase): CLASS = PETSc.NullSpace FACTORY = 'create' TARGS = (True, []) class TestObjectKSP(BaseTestObject, unittest.TestCase): CLASS = PETSc.KSP FACTORY = 'create' class TestObjectPC(BaseTestObject, unittest.TestCase): CLASS = PETSc.PC FACTORY = 'create' class TestObjectSNES(BaseTestObject, unittest.TestCase): CLASS = PETSc.SNES FACTORY = 'create' class TestObjectTS(BaseTestObject, unittest.TestCase): CLASS = PETSc.TS FACTORY = 'create' def setUp(self): super(TestObjectTS, self).setUp() self.obj.setProblemType(PETSc.TS.ProblemType.NONLINEAR) self.obj.setType(PETSc.TS.Type.BEULER) class TestObjectTAO(BaseTestObject, unittest.TestCase): CLASS = PETSc.TAO FACTORY = 'create' class TestObjectAOBasic(BaseTestObject, unittest.TestCase): CLASS = PETSc.AO FACTORY = 'createBasic' TARGS = ([], []) class TestObjectAOMapping(BaseTestObject, unittest.TestCase): CLASS = PETSc.AO FACTORY = 'createMapping' TARGS = ([], []) # class TestObjectFE(BaseTestObject, unittest.TestCase): # CLASS = PETSc.FE # FACTORY = 'create' # # class TestObjectQuad(BaseTestObject, unittest.TestCase): # CLASS = PETSc.Quad # FACTORY = 'create' class TestObjectDMLabel(BaseTestObject, unittest.TestCase): CLASS = PETSc.DMLabel FACTORY = 'create' TARGS = ("test",) class TestObjectSpace(BaseTestObject, unittest.TestCase): CLASS = PETSc.Space FACTORY = 'create' class TestObjectDualSpace(BaseTestObject, unittest.TestCase): CLASS = PETSc.DualSpace FACTORY = 'create' # -------------------------------------------------------------------- import numpy if numpy.iscomplexobj(PETSc.ScalarType()): del TestObjectTAO if __name__ == '__main__': unittest.main() ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/test/test_optdb.py0000644000175000017500000000535014567251135016072 0ustar00balaybalayimport unittest from petsc4py import PETSc from sys import getrefcount # -------------------------------------------------------------------- class TestOptions(unittest.TestCase): PREFIX = 'myopts-' OPTLIST = [('bool', True), ('int', -7), ('real', 5), ('scalar', 3), ('string', 'petsc4py'), ] def _putopts(self, opts=None, OPTLIST=None): if opts is None: opts = self.opts if OPTLIST is None: OPTLIST = self.OPTLIST for k,v in OPTLIST: opts[k] = v def _delopts(self, opts=None, OPTLIST=None): if opts is None: opts = self.opts if OPTLIST is None: OPTLIST = self.OPTLIST for k,v in OPTLIST: del opts[k] def setUp(self): self.opts = PETSc.Options(self.PREFIX) def tearDown(self): self.opts = None PETSc.garbage_cleanup() def testHasOpts(self): self._putopts() for k, v in self.OPTLIST: self.assertTrue(self.opts.hasName(k)) self.assertTrue(k in self.opts) missing = k+'-missing' self.assertFalse(self.opts.hasName(missing)) self.assertFalse(missing in self.opts) self._delopts() def testGetOpts(self): self._putopts() for k, v in self.OPTLIST: getopt = getattr(self.opts, 'get'+k.title()) self.assertEqual(getopt(k), v) self._delopts() def testGetAll(self): self._putopts() allopts = self.opts.getAll() self.assertTrue(type(allopts) is dict) optlist = [(k, str(v).lower()) for (k,v) in self.OPTLIST] for k,v in allopts.items(): self.assertTrue((k, v) in optlist) self._delopts() def testGetAllQuoted(self): dct = {'o0' : '"0 1 2"', 'o1' : '"a b c"', 'o2' : '"x y z"',} for k in dct: self.opts[k] = dct[k] allopts = self.opts.getAll() for k in dct: self.assertEqual(allopts[k], dct[k][1:-1]) del self.opts[k] def testMonitor(self): optlist = [] mon = lambda n,v: optlist.append((n,v)) self.opts.setMonitor(mon) self.assertEqual(getrefcount(mon)-1, 2) self._putopts() target = [(self.PREFIX+k, str(v).lower()) for k, v in self.OPTLIST] self.assertEqual(optlist, target) self.opts.cancelMonitor() self.assertEqual(getrefcount(mon)-1, 1) self._delopts() # -------------------------------------------------------------------- del TestOptions.testMonitor # XXX if __name__ == '__main__': unittest.main() ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/test/test_pc_py.py0000644000175000017500000002361514567251135016100 0ustar00balaybalay# -------------------------------------------------------------------- from petsc4py import PETSc import unittest from sys import getrefcount # -------------------------------------------------------------------- class BaseMyPC(object): def setup(self, pc): pass def reset(self, pc): pass def apply(self, pc, x, y): raise NotImplementedError def applyT(self, pc, x, y): self.apply(pc, x, y) def applyS(self, pc, x, y): self.apply(pc, x, y) def applySL(self, pc, x, y): self.applyS(pc, x, y) def applySR(self, pc, x, y): self.applyS(pc, x, y) def applyRich(self, pc, x, y, w, tols): self.apply(pc, x, y) def applyM(self, pc, x, y): raise NotImplementedError class MyPCNone(BaseMyPC): def apply(self, pc, x, y): x.copy(y) def applyM(self, pc, x, y): x.copy(y) class MyPCJacobi(BaseMyPC): def setup(self, pc): A, P = pc.getOperators() self.diag = P.getDiagonal() self.diag.reciprocal() def reset(self, pc): self.diag.destroy() del self.diag def apply(self, pc, x, y): y.pointwiseMult(self.diag, x) def applyS(self, pc, x, y): self.diag.copy(y) y.sqrtabs() y.pointwiseMult(y, x) def applyM(self, pc, x, y): x.copy(y) y.diagonalScale(L=self.diag) class PC_PYTHON_CLASS(object): def __init__(self): self.impl = None self.log = {} def _log(self, method, *args): self.log.setdefault(method, 0) self.log[method] += 1 def create(self, pc): self._log('create', pc) def destroy(self, pc): self._log('destroy') self.impl = None def reset(self, pc): self._log('reset', pc) def view(self, pc, vw): self._log('view', pc, vw) assert isinstance(pc, PETSc.PC) assert isinstance(vw, PETSc.Viewer) pass def setFromOptions(self, pc): self._log('setFromOptions', pc) assert isinstance(pc, PETSc.PC) OptDB = PETSc.Options(pc) impl = OptDB.getString('impl','MyPCNone') klass = globals()[impl] self.impl = klass() def setUp(self, pc): self._log('setUp', pc) assert isinstance(pc, PETSc.PC) self.impl.setup(pc) def preSolve(self, pc, ksp, b, x): self._log('preSolve', pc, ksp, b, x) def postSolve(self, pc, ksp, b, x): self._log('postSolve', pc, ksp, b, x) def apply(self, pc, x, y): self._log('apply', pc, x, y) assert isinstance(pc, PETSc.PC) assert isinstance(x, PETSc.Vec) assert isinstance(y, PETSc.Vec) self.impl.apply(pc, x, y) def applySymmetricLeft(self, pc, x, y): self._log('applySymmetricLeft', pc, x, y) assert isinstance(pc, PETSc.PC) assert isinstance(x, PETSc.Vec) assert isinstance(y, PETSc.Vec) self.impl.applySL(pc, x, y) def applySymmetricRight(self, pc, x, y): self._log('applySymmetricRight', pc, x, y) assert isinstance(pc, PETSc.PC) assert isinstance(x, PETSc.Vec) assert isinstance(y, PETSc.Vec) self.impl.applySR(pc, x, y) def applyTranspose(self, pc, x, y): self._log('applyTranspose', pc, x, y) assert isinstance(pc, PETSc.PC) assert isinstance(x, PETSc.Vec) assert isinstance(y, PETSc.Vec) self.impl.applyT(pc, x, y) def matApply(self, pc, x, y): self._log('matApply', pc, x, y) assert isinstance(pc, PETSc.PC) assert isinstance(x, PETSc.Mat) assert isinstance(y, PETSc.Mat) self.impl.applyM(pc, x, y) def applyRichardson(self, pc, x, y, w, tols): self._log('applyRichardson', pc, x, y, w, tols) assert isinstance(pc, PETSc.PC) assert isinstance(x, PETSc.Vec) assert isinstance(y, PETSc.Vec) assert isinstance(w, PETSc.Vec) assert isinstance(tols, tuple) assert len(tols) == 4 self.impl.applyRich(pc, x, y, w, tols) class TestPCPYTHON(unittest.TestCase): PC_TYPE = PETSc.PC.Type.PYTHON PC_PREFIX = 'test-' def setUp(self): pc = self.pc = PETSc.PC() pc.create(PETSc.COMM_SELF) pc.setType(self.PC_TYPE) module = __name__ factory = 'PC_PYTHON_CLASS' self.pc.prefix = self.PC_PREFIX OptDB = PETSc.Options(self.pc) assert OptDB.prefix == self.pc.prefix OptDB['pc_python_type'] = '%s.%s' % (module, factory) self.pc.setFromOptions() del OptDB['pc_python_type'] assert self._getCtx().log['create'] == 1 assert self._getCtx().log['setFromOptions'] == 1 ctx = self._getCtx() self.assertEqual(getrefcount(ctx), 3) def testGetType(self): ctx = self.pc.getPythonContext() pytype = "{0}.{1}".format(ctx.__module__, type(ctx).__name__) self.assertTrue(self.pc.getPythonType() == pytype) def tearDown(self): ctx = self._getCtx() self.pc.destroy() # XXX self.pc = None PETSc.garbage_cleanup() assert ctx.log['destroy'] == 1 self.assertEqual(getrefcount(ctx), 2) def _prepare(self): A = PETSc.Mat().createAIJ([3,3], comm=PETSc.COMM_SELF) A.setUp() A.assemble() A.shift(10) x, y = A.createVecs() x.setRandom() self.pc.setOperators(A, A) X = PETSc.Mat().createDense([3,5], comm=PETSc.COMM_SELF).setUp() X.assemble() Y = PETSc.Mat().createDense([3,5], comm=PETSc.COMM_SELF).setUp() Y.assemble() assert (A,A) == self.pc.getOperators() return A, x, y, X, Y def _getCtx(self): return self.pc.getPythonContext() def _applyMeth(self, meth): A, x, y, X, Y = self._prepare() if meth == 'matApply': getattr(self.pc, meth)(X,Y) x.copy(y) else: getattr(self.pc, meth)(x,y) X.copy(Y) if 'reset' not in self._getCtx().log: assert self._getCtx().log['setUp'] == 1 assert self._getCtx().log[meth] == 1 else: nreset = self._getCtx().log['reset'] nsetup = self._getCtx().log['setUp'] nmeth = self._getCtx().log[meth] assert (nreset == nsetup) assert (nreset == nmeth) if isinstance(self._getCtx().impl, MyPCNone): self.assertTrue(y.equal(x)) self.assertTrue(Y.equal(X)) def testApply(self): self._applyMeth('apply') def testApplySymmetricLeft(self): self._applyMeth('applySymmetricLeft') def testApplySymmetricRight(self): self._applyMeth('applySymmetricRight') def testApplyTranspose(self): self._applyMeth('applyTranspose') def testApplyMat(self): self._applyMeth('matApply') ## def testApplyRichardson(self): ## x, y = self._prepare() ## w = x.duplicate() ## tols = 0,0,0,0 ## self.pc.applyRichardson(x,y,w,tols) ## assert self._getCtx().log['setUp'] == 1 ## assert self._getCtx().log['applyRichardson'] == 1 ## def testView(self): ## vw = PETSc.ViewerString(100, self.pc.comm) ## self.pc.view(vw) ## s = vw.getString() ## assert 'python' in s ## module = __name__ ## factory = 'self._getCtx()' ## assert '.'.join([module, factory]) in s def testResetAndApply(self): self.pc.reset() self.testApply() self.pc.reset() self.testApply() self.pc.reset() def testKSPSolve(self): A, x, y, _, _ = self._prepare() ksp = PETSc.KSP().create(self.pc.comm) ksp.setType(PETSc.KSP.Type.PREONLY) assert self.pc.getRefCount() == 1 ksp.setPC(self.pc) assert self.pc.getRefCount() == 2 # normal ksp solve, twice ksp.solve(x,y) assert self._getCtx().log['setUp' ] == 1 assert self._getCtx().log['apply' ] == 1 assert self._getCtx().log['preSolve' ] == 1 assert self._getCtx().log['postSolve'] == 1 ksp.solve(x,y) assert self._getCtx().log['setUp' ] == 1 assert self._getCtx().log['apply' ] == 2 assert self._getCtx().log['preSolve' ] == 2 assert self._getCtx().log['postSolve'] == 2 # transpose ksp solve, twice ksp.solveTranspose(x,y) assert self._getCtx().log['setUp' ] == 1 assert self._getCtx().log['applyTranspose'] == 1 ksp.solveTranspose(x,y) assert self._getCtx().log['setUp' ] == 1 assert self._getCtx().log['applyTranspose'] == 2 del ksp # ksp.destroy() PETSc.garbage_cleanup() self.assertEqual(self.pc.getRefCount(), 1) def testGetSetContext(self): ctx = self.pc.getPythonContext() self.pc.setPythonContext(ctx) self.assertEqual(getrefcount(ctx), 3) del ctx class TestPCPYTHON2(TestPCPYTHON): def setUp(self): OptDB = PETSc.Options(self.PC_PREFIX) OptDB['impl'] = 'MyPCJacobi' super(TestPCPYTHON2, self).setUp() clsname = type(self._getCtx().impl).__name__ assert clsname == OptDB['impl'] del OptDB['impl'] class TestPCPYTHON3(TestPCPYTHON): def setUp(self): pc = self.pc = PETSc.PC() ctx = PC_PYTHON_CLASS() pc.createPython(ctx, comm=PETSc.COMM_SELF) self.pc.prefix = self.PC_PREFIX self.pc.setFromOptions() assert self._getCtx().log['create'] == 1 assert self._getCtx().log['setFromOptions'] == 1 class TestPCPYTHON4(TestPCPYTHON3): def setUp(self): OptDB = PETSc.Options(self.PC_PREFIX) OptDB['impl'] = 'MyPCJacobi' super(TestPCPYTHON4, self).setUp() clsname = type(self._getCtx().impl).__name__ assert clsname == OptDB['impl'] del OptDB['impl'] # -------------------------------------------------------------------- if __name__ == '__main__': unittest.main() ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/test/test_snes.py0000644000175000017500000003137114567251135015734 0ustar00balaybalay# -------------------------------------------------------------------- from petsc4py import PETSc import unittest from sys import getrefcount import numpy # -------------------------------------------------------------------- class Function: def __call__(self, snes, x, f): f[0] = (x[0]*x[0] + x[0]*x[1] - 3.0).item() f[1] = (x[0]*x[1] + x[1]*x[1] - 6.0).item() f.assemble() class Jacobian: def __call__(self, snes, x, J, P): P[0,0] = (2.0*x[0] + x[1]).item() P[0,1] = (x[0]).item() P[1,0] = (x[1]).item() P[1,1] = (x[0] + 2.0*x[1]).item() P.assemble() if J != P: J.assemble() # -------------------------------------------------------------------- class BaseTestSNES(object): SNES_TYPE = None def setUp(self): snes = PETSc.SNES() snes.create(PETSc.COMM_SELF) if self.SNES_TYPE: snes.setType(self.SNES_TYPE) self.snes = snes def tearDown(self): self.snes = None PETSc.garbage_cleanup() def testGetSetType(self): self.assertEqual(self.snes.getType(), self.SNES_TYPE) self.snes.setType(self.SNES_TYPE) self.assertEqual(self.snes.getType(), self.SNES_TYPE) def testTols(self): tols = self.snes.getTolerances() self.snes.setTolerances(*tols) tnames = ('rtol', 'atol','stol', 'max_it') tolvals = [getattr(self.snes, t) for t in tnames] self.assertEqual(tuple(tols), tuple(tolvals)) def testProperties(self): snes = self.snes # snes.appctx = (1,2,3) self.assertEqual(snes.appctx, (1,2,3)) snes.appctx = None self.assertEqual(snes.appctx, None) # snes.its = 1 self.assertEqual(snes.its, 1) snes.its = 0 self.assertEqual(snes.its, 0) # snes.norm = 1 self.assertEqual(snes.norm, 1) snes.norm = 0 self.assertEqual(snes.norm, 0) # rh, ih = snes.history self.assertTrue(len(rh)==0) self.assertTrue(len(ih)==0) # reason = PETSc.SNES.ConvergedReason.CONVERGED_ITS snes.reason = reason self.assertEqual(snes.reason, reason) self.assertTrue(snes.is_converged) self.assertFalse(snes.is_diverged) self.assertFalse(snes.is_iterating) reason = PETSc.SNES.ConvergedReason.DIVERGED_MAX_IT snes.reason = reason self.assertEqual(snes.reason, reason) self.assertFalse(snes.is_converged) self.assertTrue(snes.is_diverged) self.assertFalse(snes.is_iterating) reason = PETSc.SNES.ConvergedReason.CONVERGED_ITERATING snes.reason = reason self.assertEqual(snes.reason, reason) self.assertFalse(snes.is_converged) self.assertFalse(snes.is_diverged) self.assertTrue(snes.is_iterating) # self.assertFalse(snes.use_ew) self.assertFalse(snes.use_mf) self.assertFalse(snes.use_fd) def testGetSetFunc(self): r, func = self.snes.getFunction() self.assertFalse(r) self.assertTrue(func is None) r = PETSc.Vec().createSeq(2) func = Function() refcnt = getrefcount(func) self.snes.setFunction(func, r) self.snes.setFunction(func, r) self.assertEqual(getrefcount(func), refcnt + 1) r2, func2 = self.snes.getFunction() self.assertEqual(r, r2) self.assertEqual(func, func2[0]) self.assertEqual(getrefcount(func), refcnt + 1) r3, func3 = self.snes.getFunction() self.assertEqual(r, r3) self.assertEqual(func, func3[0]) self.assertEqual(getrefcount(func), refcnt + 1) def testCompFunc(self): r = PETSc.Vec().createSeq(2) func = Function() self.snes.setFunction(func, r) x, y = r.duplicate(), r.duplicate() x[0], x[1] = [1, 2] self.snes.computeFunction(x, y) self.assertAlmostEqual(abs(y[0]), 0.0, places=5) self.assertAlmostEqual(abs(y[1]), 0.0, places=5) def testGetSetJac(self): A, P, jac = self.snes.getJacobian() self.assertFalse(A) self.assertFalse(P) self.assertTrue(jac is None) J = PETSc.Mat().create(PETSc.COMM_SELF) J.setSizes([2,2]) J.setType(PETSc.Mat.Type.SEQAIJ) J.setUp() jac = Jacobian() refcnt = getrefcount(jac) self.snes.setJacobian(jac, J) self.snes.setJacobian(jac, J) self.assertEqual(getrefcount(jac), refcnt + 1) J2, P2, jac2 = self.snes.getJacobian() self.assertEqual(J, J2) self.assertEqual(J2, P2) self.assertEqual(jac, jac2[0]) self.assertEqual(getrefcount(jac), refcnt + 1) J3, P3, jac3 = self.snes.getJacobian() self.assertEqual(J, J3) self.assertEqual(J3, P3) self.assertEqual(jac, jac3[0]) self.assertEqual(getrefcount(jac), refcnt + 1) def testCompJac(self): J = PETSc.Mat().create(PETSc.COMM_SELF) J.setSizes([2,2]) J.setType(PETSc.Mat.Type.SEQAIJ) J.setUp() jac = Jacobian() self.snes.setJacobian(jac, J) x = PETSc.Vec().createSeq(2) x[0], x[1] = [1, 2] self.snes.getKSP().getPC() self.snes.computeJacobian(x, J) def testGetSetUpd(self): self.assertTrue(self.snes.getUpdate() is None) upd = lambda snes, it: None refcnt = getrefcount(upd) self.snes.setUpdate(upd) self.assertEqual(getrefcount(upd), refcnt + 1) self.snes.setUpdate(upd) self.assertEqual(getrefcount(upd), refcnt + 1) self.snes.setUpdate(None) self.assertTrue(self.snes.getUpdate() is None) self.assertEqual(getrefcount(upd), refcnt) self.snes.setUpdate(upd) self.assertEqual(getrefcount(upd), refcnt + 1) upd2 = lambda snes, it: None refcnt2 = getrefcount(upd2) self.snes.setUpdate(upd2) self.assertEqual(getrefcount(upd), refcnt) self.assertEqual(getrefcount(upd2), refcnt2 + 1) tmp = self.snes.getUpdate()[0] self.assertTrue(tmp is upd2) self.assertEqual(getrefcount(upd2), refcnt2 + 2) del tmp self.snes.setUpdate(None) self.assertTrue(self.snes.getUpdate() is None) self.assertEqual(getrefcount(upd2), refcnt2) def testGetKSP(self): ksp = self.snes.getKSP() self.assertEqual(ksp.getRefCount(), 2) def testSolve(self): J = PETSc.Mat().create(PETSc.COMM_SELF) J.setSizes([2,2]) J.setType(PETSc.Mat.Type.SEQAIJ) J.setUp() r = PETSc.Vec().createSeq(2) x = PETSc.Vec().createSeq(2) b = PETSc.Vec().createSeq(2) self.snes.setFunction(Function(), r) self.snes.setJacobian(Jacobian(), J) x.setArray([2,3]) b.set(0) self.snes.setConvergenceHistory() self.snes.setFromOptions() self.snes.solve(b, x) rh, ih = self.snes.getConvergenceHistory() self.snes.setConvergenceHistory(0, reset=True) rh, ih = self.snes.getConvergenceHistory() self.assertEqual(len(rh), 0) self.assertEqual(len(ih), 0) self.assertAlmostEqual(abs(x[0]), 1.0, places=5) self.assertAlmostEqual(abs(x[1]), 2.0, places=5) # XXX this test should not be here ! reason = self.snes.callConvergenceTest(1, 0, 0, 0) self.assertTrue(reason > 0) # test interface x = self.snes.getSolution() x.setArray([2,3]) self.snes.solve() self.assertAlmostEqual(abs(x[0]), 1.0, places=5) self.assertAlmostEqual(abs(x[1]), 2.0, places=5) def testResetAndSolve(self): self.snes.reset() self.testSolve() self.snes.reset() self.testSolve() self.snes.reset() def testSetMonitor(self): reshist = {} def monitor(snes, its, fgnorm): reshist[its] = fgnorm refcnt = getrefcount(monitor) self.snes.setMonitor(monitor) self.assertEqual(getrefcount(monitor), refcnt + 1) self.testSolve() self.assertTrue(len(reshist) > 0) reshist = {} self.snes.monitorCancel() self.assertEqual(getrefcount(monitor), refcnt) self.testSolve() self.assertTrue(len(reshist) == 0) self.snes.setMonitor(monitor) self.snes.monitor(1, 7) self.assertTrue(reshist[1] == 7) ## Monitor = PETSc.SNES.Monitor ## self.snes.setMonitor(Monitor()) ## self.snes.setMonitor(Monitor.DEFAULT) ## self.snes.setMonitor(Monitor.SOLUTION) ## self.snes.setMonitor(Monitor.RESIDUAL) ## self.snes.setMonitor(Monitor.SOLUTION_UPDATE) def testSetGetStepFails(self): its = self.snes.getIterationNumber() self.assertEqual(its, 0) fails = self.snes.getNonlinearStepFailures() self.assertEqual(fails, 0) fails = self.snes.getMaxNonlinearStepFailures() self.assertEqual(fails, 1) self.snes.setMaxNonlinearStepFailures(5) fails = self.snes.getMaxNonlinearStepFailures() self.assertEqual(fails, 5) self.snes.setMaxNonlinearStepFailures(1) fails = self.snes.getMaxNonlinearStepFailures() self.assertEqual(fails, 1) def testSetGetLinFails(self): its = self.snes.getLinearSolveIterations() self.assertEqual(its, 0) fails = self.snes.getLinearSolveFailures() self.assertEqual(fails, 0) fails = self.snes.getMaxLinearSolveFailures() self.assertEqual(fails, 1) self.snes.setMaxLinearSolveFailures(5) fails = self.snes.getMaxLinearSolveFailures() self.assertEqual(fails, 5) self.snes.setMaxLinearSolveFailures(1) fails = self.snes.getMaxLinearSolveFailures() self.assertEqual(fails, 1) def testEW(self): self.snes.setUseEW(False) self.assertFalse(self.snes.getUseEW()) self.snes.setUseEW(True) self.assertTrue(self.snes.getUseEW()) params = self.snes.getParamsEW() params['version'] = 1 self.snes.setParamsEW(**params) params = self.snes.getParamsEW() self.assertEqual(params['version'], 1) params['version'] = PETSc.DEFAULT self.snes.setParamsEW(**params) params = self.snes.getParamsEW() self.assertEqual(params['version'], 1) def testMF(self): #self.snes.setOptionsPrefix('MF-') #opts = PETSc.Options(self.snes) #opts['mat_mffd_type'] = 'ds' #opts['snes_monitor'] = 'stdout' #opts['ksp_monitor'] = 'stdout' #opts['snes_view'] = 'stdout' J = PETSc.Mat().create(PETSc.COMM_SELF) J.setSizes([2,2]) J.setType(PETSc.Mat.Type.SEQAIJ) J.setUp() r = PETSc.Vec().createSeq(2) x = PETSc.Vec().createSeq(2) b = PETSc.Vec().createSeq(2) fun = Function() jac = Jacobian() self.snes.setFunction(fun, r) self.snes.setJacobian(jac, J) self.assertFalse(self.snes.getUseMF()) self.snes.setUseMF(False) self.assertFalse(self.snes.getUseMF()) self.snes.setUseMF(True) self.assertTrue(self.snes.getUseMF()) self.snes.setFromOptions() if self.snes.getType() != PETSc.SNES.Type.NEWTONTR: x.setArray([2,3]) b.set(0) self.snes.solve(b, x) self.assertAlmostEqual(abs(x[0]), 1.0, places=5) self.assertAlmostEqual(abs(x[1]), 2.0, places=5) def testFDColor(self): J = PETSc.Mat().create(PETSc.COMM_SELF) J.setSizes([2,2]) J.setType(PETSc.Mat.Type.SEQAIJ) J.setUp() r = PETSc.Vec().createSeq(2) x = PETSc.Vec().createSeq(2) b = PETSc.Vec().createSeq(2) fun = Function() jac = Jacobian() self.snes.setFunction(fun, r) self.snes.setJacobian(jac, J) self.assertFalse(self.snes.getUseFD()) jac(self.snes, x, J, J) self.snes.setUseFD(False) self.assertFalse(self.snes.getUseFD()) self.snes.setUseFD(True) self.assertTrue(self.snes.getUseFD()) self.snes.setFromOptions() x.setArray([2,3]) b.set(0) self.snes.solve(b, x) self.assertAlmostEqual(abs(x[0]), 1.0, places=4) self.assertAlmostEqual(abs(x[1]), 2.0, places=4) def testNPC(self): self.snes.appctx = (1,2,3) npc = self.snes.getNPC() self.assertEqual(npc.appctx, (1,2,3)) # -------------------------------------------------------------------- class TestSNESLS(BaseTestSNES, unittest.TestCase): SNES_TYPE = PETSc.SNES.Type.NEWTONLS class TestSNESTR(BaseTestSNES, unittest.TestCase): SNES_TYPE = PETSc.SNES.Type.NEWTONTR # -------------------------------------------------------------------- if __name__ == '__main__': unittest.main() ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/test/test_snes_py.py0000644000175000017500000000602714567251135016444 0ustar00balaybalay# -------------------------------------------------------------------- from petsc4py import PETSc import unittest from sys import getrefcount # -------------------------------------------------------------------- class MySNES(object): def __init__(self): self.trace = False self.call_log = {} def _log(self, method, *args): self.call_log.setdefault(method, 0) self.call_log[method] += 1 if not self.trace: return clsname = self.__class__.__name__ pargs = [] for a in args: pargs.append(a) if isinstance(a, PETSc.Object): pargs[-1] = type(a).__name__ pargs = tuple(pargs) print ('%-20s' % ('%s.%s%s'% (clsname, method, pargs))) def create(self,*args): self._log('create', *args) def destroy(self,*args): self._log('destroy', *args) if not self.trace: return for k, v in self.call_log.items(): print ('%-20s %2d' % (k, v)) def view(self, snes, viewer): self._log('view', snes, viewer) def setFromOptions(self, snes): OptDB = PETSc.Options(snes) self.trace = OptDB.getBool('trace',self.trace) self._log('setFromOptions',snes) def setUp(self, snes): self._log('setUp', snes) def reset(self, snes): self._log('reset', snes) #def preSolve(self, snes): # self._log('preSolve', snes) # #def postSolve(self, snes): # self._log('postSolve', snes) def preStep(self, snes): self._log('preStep', snes) def postStep(self, snes): self._log('postStep', snes) #def computeFunction(self, snes, x, F): # self._log('computeFunction', snes, x, F) # snes.computeFunction(x, F) # #def computeJacobian(self, snes, x, A, B): # self._log('computeJacobian', snes, x, A, B) # flag = snes.computeJacobian(x, A, B) # return flag # #def linearSolve(self, snes, b, x): # self._log('linearSolve', snes, b, x) # snes.ksp.solve(b,x) # ## return False # not succeed # if snes.ksp.getConvergedReason() < 0: # return False # not succeed # return True # succeed # #def lineSearch(self, snes, x, y, F): # self._log('lineSearch', snes, x, y, F) # x.axpy(-1,y) # snes.computeFunction(x, F) # ## return False # not succeed # return True # succeed from test_snes import BaseTestSNES class TestSNESPython(BaseTestSNES, unittest.TestCase): SNES_TYPE = PETSc.SNES.Type.PYTHON def setUp(self): super(TestSNESPython, self).setUp() self.snes.setPythonContext(MySNES()) def testGetType(self): ctx = self.snes.getPythonContext() pytype = "{0}.{1}".format(ctx.__module__, type(ctx).__name__) self.assertTrue(self.snes.getPythonType() == pytype) # -------------------------------------------------------------------- if __name__ == '__main__': unittest.main() # -------------------------------------------------------------------- ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/test/test_stdout.py0000644000175000017500000000301414567251135016277 0ustar00balaybalayimport unittest # -------------------------------------------------------------------- class TestStdout(unittest.TestCase): def testStdoutRedirect(self): from io import StringIO import sys prevstdout = sys.stdout prevstderr = sys.stderr sys.stdout = StringIO() sys.stderr = StringIO() import numpy as np from petsc4py import PETSc if not (__name__ == '__main__'): PETSc._push_python_vfprintf() a = np.array([0.,0.,0.],dtype=PETSc.ScalarType) a_vec = PETSc.Vec().createWithArray(a,comm=PETSc.COMM_SELF) a_vec.view() v = PETSc.Viewer.STDERR(PETSc.COMM_SELF) v.printfASCII("Error message") newstdout = sys.stdout newstderr = sys.stderr sys.stdout = prevstdout sys.stderr = prevstderr output = newstdout.getvalue() error = newstderr.getvalue() if not (__name__ == '__main__'): PETSc._pop_python_vfprintf() stdoutshouldbe = \ """Vec Object: 1 MPI process type: seq 0. 0. 0. """ stderrshouldbe = "Error message" if PETSc._stdout_is_stderr(): stdoutshouldbe = stdoutshouldbe + stderrshouldbe stderrshouldbe = "" self.assertEqual(output,stdoutshouldbe) self.assertEqual(error,stderrshouldbe) # -------------------------------------------------------------------- if __name__ == '__main__': unittest.main() # -------------------------------------------------------------------- ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/test/test_sys.py0000644000175000017500000000321714567251135015600 0ustar00balaybalayimport unittest from petsc4py import PETSc # -------------------------------------------------------------------- class TestVersion(unittest.TestCase): def testGetVersion(self): version = PETSc.Sys.getVersion() self.assertTrue(version > (0, 0, 0)) v, date = PETSc.Sys.getVersion(date=True) self.assertTrue(version == v) self.assertTrue(isinstance(date, str)) v, author = PETSc.Sys.getVersion(author=True) self.assertTrue(version == v) self.assertTrue(isinstance(author, (list,tuple))) def testGetVersionInfo(self): version = PETSc.Sys.getVersion() info = PETSc.Sys.getVersionInfo() self.assertEqual(version, (info['major'], info['minor'], info['subminor'],)) self.assertTrue(isinstance(info['release'], bool)) v, date = PETSc.Sys.getVersion(date=True) self.assertEqual(date, info['date']) def testGetSetDefaultComm(self): c = PETSc.Sys.getDefaultComm() self.assertEqual(c, PETSc.COMM_WORLD) PETSc.Sys.setDefaultComm(PETSc.COMM_SELF) c = PETSc.Sys.getDefaultComm() self.assertEqual(c, PETSc.COMM_SELF) PETSc.Sys.setDefaultComm(PETSc.COMM_WORLD) c = PETSc.Sys.getDefaultComm() self.assertEqual(c, PETSc.COMM_WORLD) f = lambda : PETSc.Sys.setDefaultComm(PETSc.COMM_NULL) self.assertRaises(ValueError, f) # -------------------------------------------------------------------- if __name__ == '__main__': unittest.main() # -------------------------------------------------------------------- ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/test/test_tao.py0000644000175000017500000001002214567251135015535 0ustar00balaybalay# -------------------------------------------------------------------- from petsc4py import PETSc import unittest # -------------------------------------------------------------------- class Objective: def __call__(self, tao, x): return (x[0] - 2.0)**2 + (x[1] - 2.0)**2 - 2.0*(x[0] + x[1]) class Gradient: def __call__(self, tao, x, g): g[0] = 2.0*(x[0] - 2.0) - 2.0 g[1] = 2.0*(x[1] - 2.0) - 2.0 g.assemble() class EqConstraints: def __call__(self, tao, x, c): c[0] = x[0]**2 + x[1] - 2.0 c.assemble() class EqJacobian: def __call__(self, tao, x, J, P): P[0,0] = 2.0*x[0] P[0,1] = 1.0 P.assemble() if J != P: J.assemble() class BaseTestTAO(object): COMM = None def setUp(self): self.tao = PETSc.TAO().create(comm=self.COMM) def tearDown(self): self.tao = None PETSc.garbage_cleanup() def testSetRoutinesToNone(self): tao = self.tao objective, gradient, objgrad = None, None, None constraint, varbounds = None, None hessian, jacobian = None, None tao.setObjective(objective) tao.setGradient(gradient,None) tao.setVariableBounds(varbounds) tao.setObjectiveGradient(objgrad,None) tao.setConstraints(constraint) tao.setHessian(hessian) tao.setJacobian(jacobian) def testGetVecsAndMats(self): tao = self.tao x = tao.getSolution() (g, _) = tao.getGradient() l, u = tao.getVariableBounds() r = None#tao.getConstraintVec() H, HP = None,None#tao.getHessianMat() J, JP = None,None#tao.getJacobianMat() for o in [x, g, r, l, u ,H, HP, J, JP,]: self.assertFalse(o) def testGetKSP(self): ksp = self.tao.getKSP() self.assertFalse(ksp) def testEqualityConstraints(self): if self.tao.getComm().Get_size() > 1: return tao = self.tao x = PETSc.Vec().create(tao.getComm()) x.setType('standard') x.setSizes(2) c = PETSc.Vec().create(tao.getComm()) c.setSizes(1) c.setType(x.getType()) J = PETSc.Mat().create(tao.getComm()) J.setSizes([1, 2]) J.setType(PETSc.Mat.Type.DENSE) J.setUp() tao.setObjective(Objective()) tao.setGradient(Gradient(),None) tao.setEqualityConstraints(EqConstraints(),c) tao.setJacobianEquality(EqJacobian(),J,J) tao.setSolution(x) tao.setType(PETSc.TAO.Type.ALMM) tao.setTolerances(gatol=1.e-4) tao.setFromOptions() tao.solve() self.assertAlmostEqual(abs(x[0]**2 + x[1] - 2.0), 0.0, places=4) def testBNCG(self): if self.tao.getComm().Get_size() > 1: return tao = self.tao x = PETSc.Vec().create(tao.getComm()) x.setType('standard') x.setSizes(2) xl = PETSc.Vec().create(tao.getComm()) xl.setType('standard') xl.setSizes(2) xl.set(0.0) xu = PETSc.Vec().create(tao.getComm()) xu.setType('standard') xu.setSizes(2) xu.set(2.0) tao.setVariableBounds((xl,xu)) tao.setObjective(Objective()) tao.setGradient(Gradient(),None) tao.setSolution(x) tao.setType(PETSc.TAO.Type.BNCG) tao.setTolerances(gatol=1.e-4) ls = tao.getLineSearch() ls.setType(PETSc.TAOLineSearch.Type.UNIT) tao.setFromOptions() tao.solve() self.assertAlmostEqual(x[0], 2.0, places=4) self.assertAlmostEqual(x[1], 2.0, places=4) # -------------------------------------------------------------------- class TestTAOSelf(BaseTestTAO, unittest.TestCase): COMM = PETSc.COMM_SELF class TestTAOWorld(BaseTestTAO, unittest.TestCase): COMM = PETSc.COMM_WORLD # -------------------------------------------------------------------- import numpy if numpy.iscomplexobj(PETSc.ScalarType()): del BaseTestTAO del TestTAOSelf del TestTAOWorld if __name__ == '__main__': unittest.main() ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/test/test_tao_py.py0000644000175000017500000000737714567251135016270 0ustar00balaybalayimport unittest from petsc4py import PETSc from sys import getrefcount # -------------------------------------------------------------------- class Objective: def __call__(self, tao, x): return (x[0] - 1.0)**2 + (x[1] - 2.0)**2 class Gradient: def __call__(self, tao, x, g): g[0] = 2.0*(x[0] - 1.0) g[1] = 2.0*(x[1] - 2.0) g.assemble() class MyTao: def __init__(self): self.log = {} def _log(self, method): self.log.setdefault(method, 0) self.log[method] += 1 def create(self, tao): self._log('create') self.testvec = PETSc.Vec() def destroy(self, tao): self._log('destroy') self.testvec.destroy() def setFromOptions(self, tao): self._log('setFromOptions') def setUp(self, tao): self._log('setUp') self.testvec = tao.getSolution().duplicate() def solve(self, tao): self._log('solve') def step(self, tao, x, g, s): self._log('step') tao.computeGradient(x,g) g.copy(s) s.scale(-1.0) def preStep(self, tao): self._log('preStep') def postStep(self, tao): self._log('postStep') def monitor(self, tao): self._log('monitor') class TestTaoPython(unittest.TestCase): def setUp(self): self.tao = PETSc.TAO() self.tao.createPython(MyTao(), comm=PETSc.COMM_SELF) ctx = self.tao.getPythonContext() self.assertEqual(getrefcount(ctx), 3) self.assertEqual(ctx.log['create'], 1) self.nsolve = 0 def tearDown(self): ctx = self.tao.getPythonContext() self.assertEqual(getrefcount(ctx), 3) self.assertTrue('destroy' not in ctx.log) self.tao.destroy() self.tao = None PETSc.garbage_cleanup() self.assertEqual(ctx.log['destroy'], 1) self.assertEqual(getrefcount(ctx), 2) def testGetType(self): ctx = self.tao.getPythonContext() pytype = "{0}.{1}".format(ctx.__module__, type(ctx).__name__) self.assertTrue(self.tao.getPythonType() == pytype) def testSolve(self): tao = self.tao ctx = tao.getPythonContext() x = PETSc.Vec().create(tao.getComm()) x.setType('standard') x.setSizes(2) y1 = x.duplicate() y2 = x.duplicate() tao.setObjective(Objective()) tao.setGradient(Gradient(),None) tao.setMonitor(ctx.monitor) tao.setFromOptions() tao.setMaximumIterations(3) tao.setSolution(x) # Call the solve method of MyTAO x.set(0.5) tao.solve() n = tao.getIterationNumber() self.assertTrue(n == 0) # Call the default solve method and use step of MyTAO ctx.solve = None x.set(0.5) tao.solve() n = tao.getIterationNumber() self.assertTrue(n == 3) x.copy(y1) # Call the default solve method with the default step method ctx.step = None x.set(0.5) tao.solve() n = tao.getIterationNumber() self.assertTrue(n == 3) x.copy(y2) self.assertTrue(y1.equal(y2)) self.assertTrue(ctx.log['monitor'] == 2*(n+1)) self.assertTrue(ctx.log['preStep'] == 2*n) self.assertTrue(ctx.log['postStep'] == 2*n) self.assertTrue(ctx.log['solve'] == 1) self.assertTrue(ctx.log['setUp'] == 1) self.assertTrue(ctx.log['setFromOptions'] == 1) self.assertTrue(ctx.log['step'] == n) tao.cancelMonitor() # -------------------------------------------------------------------- import numpy if numpy.iscomplexobj(PETSc.ScalarType()): del TestTaoPython if __name__ == '__main__': unittest.main() # -------------------------------------------------------------------- ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/test/test_ts.py0000644000175000017500000001670314567251135015414 0ustar00balaybalayimport unittest from petsc4py import PETSc from sys import getrefcount # -------------------------------------------------------------------- class MyODE: """ du/dt + u**2 = 0; u0,u1,u2 = 1,2,3 """ def __init__(self): self.rhsfunction_calls = 0 self.rhsjacobian_calls = 0 self.ifunction_calls = 0 self.ijacobian_calls = 0 self.presolve_calls = 0 self.update_calls = 0 self.postsolve_calls = 0 self.monitor_calls = 0 def rhsfunction(self,ts,t,u,F): # print ('MyODE.rhsfunction()') self.rhsfunction_calls += 1 f = -(u * u) f.copy(F) def rhsjacobian(self,ts,t,u,J,P): # print ('MyODE.rhsjacobian()') self.rhsjacobian_calls += 1 P.zeroEntries() diag = -2 * u P.setDiagonal(diag) P.assemble() if J != P: J.assemble() return True # same_nz def ifunction(self,ts,t,u,du,F): # print ('MyODE.ifunction()') self.ifunction_calls += 1 f = du + u * u f.copy(F) def ijacobian(self,ts,t,u,du,a,J,P): # print ('MyODE.ijacobian()') self.ijacobian_calls += 1 P.zeroEntries() diag = a + 2 * u P.setDiagonal(diag) P.assemble() if J != P: J.assemble() return True # same_nz def monitor(self, ts, s, t, u): self.monitor_calls += 1 dt = ts.time_step ut = ts.vec_sol.norm() #prn = PETSc.Sys.Print #prn('TS: step %2d, T:%f, dT:%f, u:%f' % (s,t,dt,ut)) class BaseTestTSNonlinear(object): TYPE = None def setUp(self): self.ts = PETSc.TS().create(PETSc.COMM_SELF) eft = PETSc.TS.ExactFinalTime.STEPOVER self.ts.setExactFinalTime(eft) ptype = PETSc.TS.ProblemType.NONLINEAR self.ts.setProblemType(ptype) self.ts.setType(self.TYPE) if PETSc.ScalarType().dtype.char in 'fF': snes = self.ts.getSNES() snes.setTolerances(rtol=1e-6) def tearDown(self): self.ts = None PETSc.garbage_cleanup() class BaseTestTSNonlinearRHS(BaseTestTSNonlinear): def testSolveRHS(self): ts = self.ts dct = self.ts.getDict() self.assertTrue(dct is not None) self.assertTrue(type(dct) is dict) ode = MyODE() J = PETSc.Mat().create(ts.comm) J.setSizes(3); J.setFromOptions() J.setUp() u, f = J.createVecs() ts.setAppCtx(ode) ts.setRHSFunction(ode.rhsfunction, f) ts.setRHSJacobian(ode.rhsjacobian, J, J) ts.setMonitor(ode.monitor) ts.snes.ksp.pc.setType('none') T0, dT, nT = 0.00, 0.1, 10 T = T0 + nT*dT ts.setTime(T0) ts.setTimeStep(dT) ts.setMaxTime(T) ts.setMaxSteps(nT) ts.setFromOptions() u[0], u[1], u[2] = 1, 2, 3 ts.solve(u) self.assertTrue(ode.rhsfunction_calls > 0) self.assertTrue(ode.rhsjacobian_calls > 0) dct = self.ts.getDict() self.assertTrue('__appctx__' in dct) self.assertTrue('__rhsfunction__' in dct) self.assertTrue('__rhsjacobian__' in dct) self.assertTrue('__monitor__' in dct) n = ode.monitor_calls ts.monitor(ts.step_number, ts.time) self.assertEqual(ode.monitor_calls, n+1) n = ode.monitor_calls ts.monitorCancel() ts.monitor(ts.step_number, ts.time) self.assertEqual(ode.monitor_calls, n) def testFDColorRHS(self): ts = self.ts ode = MyODE() J = PETSc.Mat().create(ts.comm) J.setSizes(5); J.setType('aij') J.setPreallocationNNZ(nnz=1) u, f = J.createVecs() ts.setAppCtx(ode) ts.setRHSFunction(ode.rhsfunction, f) ts.setRHSJacobian(ode.rhsjacobian, J, J) ts.setMonitor(ode.monitor) T0, dT, nT = 0.00, 0.1, 10 T = T0 + nT*dT ts.setTime(T0) ts.setTimeStep(dT) ts.setMaxTime(T) ts.setMaxSteps(nT) ts.setFromOptions() u[0], u[1], u[2] = 1, 2, 3 ts.setSolution(u) ode.rhsjacobian(ts,0,u,J,J) ts.setUp() ts.snes.setUseFD(True) ts.solve(u) def testResetAndSolveRHS(self): self.ts.reset() self.ts.setStepNumber(0) self.testSolveRHS() self.ts.reset() self.ts.setStepNumber(0) self.testSolveRHS() self.ts.reset() class BaseTestTSNonlinearI(BaseTestTSNonlinear): def testSolveI(self): ts = self.ts dct = self.ts.getDict() self.assertTrue(dct is not None) self.assertTrue(type(dct) is dict) ode = MyODE() J = PETSc.Mat().create(ts.comm) J.setSizes(3); J.setFromOptions() J.setUp() u, f = J.createVecs() ts.setAppCtx(ode) ts.setIFunction(ode.ifunction, f) ts.setIJacobian(ode.ijacobian, J, J) ts.setMonitor(ode.monitor) ts.snes.ksp.pc.setType('none') T0, dT, nT = 0.00, 0.1, 10 T = T0 + nT*dT ts.setTime(T0) ts.setTimeStep(dT) ts.setMaxTime(T) ts.setMaxSteps(nT) ts.setFromOptions() u[0], u[1], u[2] = 1, 2, 3 ts.solve(u) self.assertTrue(ode.ifunction_calls > 0) self.assertTrue(ode.ijacobian_calls > 0) dct = self.ts.getDict() self.assertTrue('__appctx__' in dct) self.assertTrue('__ifunction__' in dct) self.assertTrue('__ijacobian__' in dct) self.assertTrue('__monitor__' in dct) n = ode.monitor_calls ts.monitor(ts.step_number, ts.time) self.assertEqual(ode.monitor_calls, n+1) n = ode.monitor_calls ts.monitorCancel() ts.monitor(ts.step_number, ts.time) self.assertEqual(ode.monitor_calls, n) def testFDColorI(self): ts = self.ts ode = MyODE() J = PETSc.Mat().create(ts.comm) J.setSizes(5); J.setType('aij') J.setPreallocationNNZ(nnz=1) J.setFromOptions() u, f = J.createVecs() ts.setAppCtx(ode) ts.setIFunction(ode.ifunction, f) ts.setIJacobian(ode.ijacobian, J, J) ts.setMonitor(ode.monitor) T0, dT, nT = 0.00, 0.1, 10 T = T0 + nT*dT ts.setTime(T0) ts.setTimeStep(dT) ts.setMaxTime(T) ts.setMaxSteps(nT) ts.setFromOptions() u[0], u[1], u[2] = 1, 2, 3 ts.setSolution(u) ode.ijacobian(ts,0,u,0*u,1,J,J) ts.setUp() ts.snes.setUseFD(True) ts.solve(u) def testResetAndSolveI(self): self.ts.reset() self.ts.setStepNumber(0) self.testSolveI() self.ts.reset() self.ts.setStepNumber(0) self.testSolveI() self.ts.reset() class TestTSBeuler(BaseTestTSNonlinearRHS,BaseTestTSNonlinearI, unittest.TestCase): TYPE = PETSc.TS.Type.BEULER class TestTSCN(BaseTestTSNonlinearRHS,BaseTestTSNonlinearI, unittest.TestCase): TYPE = PETSc.TS.Type.CN class TestTSTheta(BaseTestTSNonlinearRHS, BaseTestTSNonlinearI, unittest.TestCase): TYPE = PETSc.TS.Type.THETA class TestTSAlpha(BaseTestTSNonlinearRHS, BaseTestTSNonlinearI, unittest.TestCase): TYPE = PETSc.TS.Type.ALPHA # -------------------------------------------------------------------- if __name__ == '__main__': unittest.main() # -------------------------------------------------------------------- ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/test/test_ts_py.py0000644000175000017500000001212214567251135016113 0ustar00balaybalayimport unittest from petsc4py import PETSc from sys import getrefcount # -------------------------------------------------------------------- class MyODE: """ du/dt + u**2 = 0; u0 = 1 """ def __init__(self): self.function_calls = 0 self.jacobian_calls = 0 def function(self,ts,t,u,du,F): #print 'MyODE.function()' self.function_calls += 1 f = du + u * u f.copy(F) def jacobian(self,ts,t,u,du,a,J,P): #print 'MyODE.jacobian()' self.jacobian_calls += 1 P.zeroEntries() diag = a + 2 * u P.setDiagonal(diag) P.assemble() if J != P: J.assemble() return False # same_nz class MyTS(object): def __init__(self): self.log = {} def _log(self, method, *args): self.log.setdefault(method, 0) self.log[method] += 1 def create(self, ts, *args): self._log('create', *args) self.vec_update = PETSc.Vec() def destroy(self, ts, *args): self._log('destroy', *args) self.vec_update.destroy() def setFromOptions(self, ts, *args): self._log('setFromOptions', *args) def setUp(self, ts, *args): self._log('setUp', ts, *args) self.vec_update = ts.getSolution().duplicate() def reset(self, ts, *args): self._log('reset', ts, *args) def solveStep(self, ts, t, u, *args): self._log('solveStep', ts, t, u, *args) ts.snes.solve(None, u) def adaptStep(self, ts, t, u, *args): self._log('adaptStep', ts, t, u, *args) return (ts.getTimeStep(), True) class TestTSPython(unittest.TestCase): def setUp(self): self.ts = PETSc.TS() self.ts.createPython(MyTS(), comm=PETSc.COMM_SELF) eft = PETSc.TS.ExactFinalTime.STEPOVER self.ts.setExactFinalTime(eft) ctx = self.ts.getPythonContext() self.assertEqual(getrefcount(ctx), 3) self.assertEqual(ctx.log['create'], 1) self.nsolve = 0 def tearDown(self): ctx = self.ts.getPythonContext() self.assertEqual(getrefcount(ctx), 3) self.assertTrue('destroy' not in ctx.log) self.ts.destroy() # XXX self.ts = None PETSc.garbage_cleanup() self.assertEqual(ctx.log['destroy'], 1) self.assertEqual(getrefcount(ctx), 2) def testGetType(self): ctx = self.ts.getPythonContext() pytype = "{0}.{1}".format(ctx.__module__, type(ctx).__name__) self.assertTrue(self.ts.getPythonType() == pytype) def testSolve(self): ts = self.ts ts.setProblemType(ts.ProblemType.NONLINEAR) ode = MyODE() J = PETSc.Mat().create(ts.comm) J.setSizes(3); J.setFromOptions() J.setUp() u, f = J.createVecs() ts.setAppCtx(ode) ts.setIFunction(ode.function, f) ts.setIJacobian(ode.jacobian, J, J) ts.snes.ksp.pc.setType('none') T0, dT, nT = 0.0, 0.1, 10 T = T0 + nT*dT ts.setTime(T0) ts.setTimeStep(dT) ts.setMaxTime(T) ts.setMaxSteps(nT) ts.setFromOptions() u[0], u[1], u[2] = 1, 2, 3 ts.solve(u) self.nsolve +=1 self.assertTrue(ode.function_calls > 0) self.assertTrue(ode.jacobian_calls > 0) ctx = self.ts.getPythonContext() ncalls = self.nsolve * ts.step_number self.assertTrue(ctx.log['solveStep'] == ncalls) self.assertTrue(ctx.log['adaptStep'] == ncalls) del ctx dct = self.ts.getDict() self.assertTrue('__appctx__' in dct) self.assertTrue('__ifunction__' in dct) self.assertTrue('__ijacobian__' in dct) def testFDColor(self): # ts = self.ts ts.setProblemType(ts.ProblemType.NONLINEAR) ode = MyODE() J = PETSc.Mat().create(ts.comm) J.setSizes(5); J.setType('aij'); J.setPreallocationNNZ(1) J.setFromOptions() u, f = J.createVecs() ts.setAppCtx(ode) ts.setIFunction(ode.function, f) ts.setIJacobian(ode.jacobian, J, J) T0, dT, nT = 0.00, 0.1, 10 T = T0 + nT*dT ts.setTime(T0) ts.setTimeStep(dT) ts.setMaxTime(T) ts.setMaxSteps(nT) ts.setFromOptions() u[:] = 1, 2, 3, 4, 5 ts.setSolution(u) ode.jacobian(ts,0.0,u,u,1.0,J,J) ts.snes.setUseFD(True) ts.solve(u) self.nsolve +=1 def testResetAndSolve(self): self.ts.reset() self.ts.setStepNumber(0) self.testSolve() self.ts.reset() self.ts.setStepNumber(0) self.testFDColor() self.ts.reset() self.ts.setStepNumber(0) self.testSolve() self.ts.reset() def testSetAdaptLimits(self): self.ts.setStepLimits(1.0, 2.0) hmin, hmax = self.ts.getStepLimits() self.assertEqual(1.0, hmin) self.assertEqual(2.0, hmax) # -------------------------------------------------------------------- if __name__ == '__main__': unittest.main() # -------------------------------------------------------------------- ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1709003357.0 petsc4py-3.20.5/test/test_vec.py0000644000175000017500000002566614567251135015553 0ustar00balaybalayfrom petsc4py import PETSc import unittest # -------------------------------------------------------------------- class BaseTestVec(object): COMM = None TYPE = None def setUp(self): v = PETSc.Vec() v.create(self.COMM) v.setSizes(100) v.setType(self.TYPE) self.vec = v def tearDown(self): self.vec.destroy() self.vec = None PETSc.garbage_cleanup() def testDuplicate(self): self.vec.set(1) vec = self.vec.duplicate() self.assertFalse(self.vec.equal(vec)) self.assertEqual(self.vec.sizes, vec.sizes) del vec def testCopy(self): self.vec.set(1) vec = self.vec.duplicate() self.vec.copy(vec) self.assertTrue(self.vec.equal(vec)) del vec def testDot(self): self.vec.set(1) d = self.vec.dot(self.vec) self.assertAlmostEqual(abs(d), self.vec.getSize()) self.vec.dotBegin(self.vec) d = self.vec.dotEnd(self.vec) self.assertAlmostEqual(abs(d), self.vec.getSize()) def testNorm(self): from math import sqrt self.vec.set(1) n1 = self.vec.norm(PETSc.NormType.NORM_1) n2 = self.vec.norm(PETSc.NormType.NORM_2) ni = self.vec.norm(PETSc.NormType.NORM_INFINITY) self.assertAlmostEqual(n1, self.vec.getSize()) self.assertAlmostEqual(n2, sqrt(self.vec.getSize())) self.assertAlmostEqual(n2, self.vec.norm()) self.assertAlmostEqual(ni, 1.0) self.vec.normBegin(PETSc.NormType.NORM_1) nn1 = self.vec.normEnd(PETSc.NormType.NORM_1) self.assertAlmostEqual(nn1, n1) self.vec.normBegin() nn2 = self.vec.normEnd() self.assertAlmostEqual(nn2, n2) self.vec.normBegin(PETSc.NormType.NORM_INFINITY) nni = self.vec.normEnd(PETSc.NormType.NORM_INFINITY) self.assertAlmostEqual(nni, ni) def testNormalize(self): from math import sqrt self.vec.set(1) n2 = self.vec.normalize() self.assertAlmostEqual(n2, sqrt(self.vec.getSize())) self.assertAlmostEqual(1, self.vec.norm()) def testSumMinMax(self): self.vec.set(1) self.assertEqual(self.vec.sum(), self.vec.getSize()) self.vec.set(-7) self.assertEqual(self.vec.min()[1], -7) self.vec.set(10) self.assertEqual(self.vec.max()[1], 10) def testSwap(self): v1 = self.vec v2 = v1.duplicate() v1.set(1) v2.set(2) v1.swap(v2) idx, _ = self.vec.getOwnershipRange() self.assertEqual(v1[idx], 2) self.assertEqual(v2[idx], 1) def testBsize(self): self.vec.setBlockSize(1) self.assertEqual(self.vec.getBlockSize(), 1) self.vec.setBlockSize(1) def testGetSetVals(self): start, end = self.vec.getOwnershipRange() self.vec[start] = -7 self.vec[end-1] = -7 self.vec.assemble() self.assertEqual(self.vec[start], -7) self.assertEqual(self.vec[end-1], -7) for i in range(start, end): self.vec[i] = i self.vec.assemble() values = [self.vec[i] for i in range(start, end)] self.assertEqual(values, list(range(start, end))) sz = self.vec.getSize() self.assertEqual(self.vec.sum(), (sz-1)/2.0*sz) def testGetSetValsBlocked(self): return lsize, gsize = self.vec.getSizes() start, end = self.vec.getOwnershipRange() bsizes = list(range(1, lsize+1)) nblocks = list(range(1, lsize+1)) compat = [(bs, nb) for bs in bsizes if not (gsize%bs or lsize % bs) for nb in nblocks if bs*nb <= lsize] for bsize, nblock in compat: self.vec.setBlockSize(bsize) bindex = [start//bsize+i for i in range(nblock)] bvalue = [float(i) for i in range(nblock*bsize)] self.vec.setValuesBlocked(bindex, bvalue) self.vec.assemble() index = [start+i for i in range(nblock*bsize)] value = self.vec.getValues(index) self.assertEqual(bvalue, list(value)) def testGetSetArray(self): self.vec.set(1) arr0 = self.vec.getArray().copy() self.assertEqual(arr0.sum(), self.vec.getLocalSize()) arr0 = self.vec.getArray().copy() self.vec.setRandom() arr1 = self.vec.getArray().copy() self.vec.setArray(arr1) arr1 = self.vec.getArray().copy() arr2 = self.vec.getArray().copy() self.assertTrue((arr1 == arr2).all()) import numpy refs = self.vec.getRefCount() arr3 = numpy.asarray(self.vec) self.assertEqual(self.vec.getRefCount(), refs+1) self.assertTrue((arr1 == arr3).all()) arr3[:] = 0 self.assertAlmostEqual(abs(self.vec.sum()), 0) self.assertEqual(self.vec.max()[1], 0) self.assertEqual(self.vec.min()[1], 0) self.vec.set(1) self.assertAlmostEqual(abs(arr3.sum()), self.vec.getLocalSize()) self.assertEqual(arr3.min(), 1) self.assertEqual(arr3.max(), 1) del arr3 self.assertEqual(self.vec.getRefCount(), refs) def testPlaceArray(self): self.vec.set(1) array = self.vec.getArray().copy() self.vec.placeArray(array) array[:] = 2 self.assertAlmostEqual(abs(self.vec.sum()), 2*self.vec.getSize()) self.vec.resetArray() self.assertAlmostEqual(abs(self.vec.sum()), self.vec.getSize()) def testLocalVector(self): rank = self.vec.getComm().Get_rank() self.vec.getArray()[:] = rank + 1 ln = self.vec.getLocalSize() lvec = self.vec.createLocalVector() self.vec.getLocalVector(lvec) self.assertEqual(abs(lvec.sum()), (rank+1)*ln) self.vec.restoreLocalVector(lvec) self.vec.getLocalVector(lvec,readonly=True) self.assertEqual(abs(lvec.sum()), (rank+1)*ln) self.vec.restoreLocalVector(lvec,readonly=True) lvec.destroy() def testSetOption(self): opt1 = PETSc.Vec.Option.IGNORE_OFF_PROC_ENTRIES opt2 = PETSc.Vec.Option.IGNORE_NEGATIVE_INDICES for opt in [opt1, opt2]*2: for flag in [True,False]*2: self.vec.setOption(opt,flag) def testGetSetItem(self): v = self.vec w = v.duplicate() # v[...] = 7 self.assertEqual(v.max()[1], 7) self.assertEqual(v.min()[1], 7) # v.setRandom() w[...] = v self.assertTrue(w.equal(v)) # v.setRandom() w[...] = v.getArray() self.assertTrue(w.equal(v)) # s, e = v.getOwnershipRange() v.setRandom() w[s:e] = v.getArray().copy() w.assemble() self.assertTrue(w.equal(v)) w1, v1 = w[s], v[s] w2, v2 = w[e-1], v[e-1] self.assertEqual(w1, v1) self.assertEqual(w2, v2) def testMAXPY(self): y = self.vec y.set(1) x = [y.copy() for _ in range(3)] a = [1]*len(x) y.maxpy(a, x) z = y.duplicate() z.set(len(x)+1) assert (y.equal(z)) def testBinOp(self): x = self.vec x.set(1) n = x.getSize() y = 2 + 2*x + 1 - x*3 - 1 self.assertEqual(y.min()[1], 1) self.assertEqual(y.max()[1], 1) z = (4*x)/(2*y) self.assertEqual(z.min()[1], 2) self.assertEqual(z.max()[1], 2) z = z/2 self.assertEqual(z.min()[1], 1) self.assertEqual(z.max()[1], 1) s = (+x) @ (-y) self.assertEqual(s, -n) # M, N = n, 2*n A = PETSc.Mat().createDense((M, N), comm=self.COMM) A.setUp() rs, re = A.getOwnershipRange() cs, ce = A.getOwnershipRangeColumn() a, b = 3, 5 for i in range(rs, re): for j in range(N): A[i, j] = a*i + b*j A.assemble() y = x @ A self.assertEqual(y.getSize(), N) for i in range(cs, ce): self.assertEqual(y[i], a*M*(M-1)/2 + b*i*M) y.set(1) z = A @ y self.assertEqual(z.getSize(), M) for i in range(rs, re): self.assertEqual(z[i], b*N*(N-1)/2 + a*i*N) # -------------------------------------------------------------------- class TestVecSeq(BaseTestVec, unittest.TestCase): COMM = PETSc.COMM_SELF TYPE = PETSc.Vec.Type.SEQ class TestVecMPI(BaseTestVec, unittest.TestCase): COMM = PETSc.COMM_WORLD TYPE = PETSc.Vec.Type.MPI class TestVecShared(BaseTestVec, unittest.TestCase): if PETSc.COMM_WORLD.getSize() == 1: TYPE = PETSc.Vec.Type.SHARED else: TYPE = PETSc.Vec.Type.MPI COMM = PETSc.COMM_WORLD #class TestVecSieve(BaseTestVec, unittest.TestCase): # CLASS = PETSc.VecSieve # TARGS = ([],) #class TestVecGhost(BaseTestVec, unittest.TestCase): # CLASS = PETSc.VecGhost # TARGS = ([],) # -------------------------------------------------------------------- class TestVecWithArray(unittest.TestCase): def testCreateSeq(self): import numpy a = numpy.zeros(5, dtype=PETSc.ScalarType) v1 = PETSc.Vec().createWithArray(a, comm=PETSc.COMM_SELF) v2 = PETSc.Vec().createWithArray(a, size=5, comm=PETSc.COMM_SELF) v3 = PETSc.Vec().createWithArray(a, size=3, comm=PETSc.COMM_SELF) self.assertTrue(v1.size == 5) self.assertTrue(v2.size == 5) self.assertTrue(v3.size == 3) a1 = v1.getDict()['__array__']; self.assertTrue(a is a1) a2 = v2.getDict()['__array__']; self.assertTrue(a is a2) a3 = v3.getDict()['__array__']; self.assertTrue(a is a2) def testCreateMPI(self): import numpy a = numpy.zeros(5, dtype=PETSc.ScalarType) v1 = PETSc.Vec().createWithArray(a, comm=PETSc.COMM_WORLD) v2 = PETSc.Vec().createWithArray(a, size=(5,None), comm=PETSc.COMM_WORLD) v3 = PETSc.Vec().createWithArray(a, size=(3,None), comm=PETSc.COMM_WORLD) self.assertTrue(v1.local_size == 5) self.assertTrue(v2.local_size == 5) self.assertTrue(v3.local_size == 3) a1 = v1.getDict()['__array__']; self.assertTrue(a is a1) a2 = v2.getDict()['__array__']; self.assertTrue(a is a2) a3 = v3.getDict()['__array__']; self.assertTrue(a is a2) def testSetMPIGhost(self): import numpy v = PETSc.Vec().create() v.setType(PETSc.Vec.Type.MPI) v.setSizes((5,None)) ghosts = [i % v.size for i in range(v.owner_range[1],v.owner_range[1]+3)] v.setMPIGhost(ghosts) v.setArray(numpy.array(range(*v.owner_range),dtype=PETSc.ScalarType)) v.ghostUpdate() with v.localForm() as loc: self.assertTrue((loc[0:v.local_size] == range(*v.owner_range)).all()) self.assertTrue((loc[v.local_size:] == ghosts).all()) # -------------------------------------------------------------------- if __name__ == '__main__': unittest.main() # --------------------------------------------------------------------