feectools 0.1.9__tar.gz → 0.1.10__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {feectools-0.1.9/feectools.egg-info → feectools-0.1.10}/PKG-INFO +1 -1
- {feectools-0.1.9 → feectools-0.1.10}/feectools/linalg/basic.py +1 -1
- {feectools-0.1.9 → feectools-0.1.10}/feectools/linalg/solvers.py +222 -2
- {feectools-0.1.9 → feectools-0.1.10/feectools.egg-info}/PKG-INFO +1 -1
- {feectools-0.1.9 → feectools-0.1.10}/pyproject.toml +1 -1
- {feectools-0.1.9 → feectools-0.1.10}/AUTHORS +0 -0
- {feectools-0.1.9 → feectools-0.1.10}/LICENSE +0 -0
- {feectools-0.1.9 → feectools-0.1.10}/README.md +0 -0
- {feectools-0.1.9 → feectools-0.1.10}/feectools/__init__.py +0 -0
- {feectools-0.1.9 → feectools-0.1.10}/feectools/accelerate/__init__.py +0 -0
- {feectools-0.1.9 → feectools-0.1.10}/feectools/accelerate/accelerate.py +0 -0
- {feectools-0.1.9 → feectools-0.1.10}/feectools/accelerate/compile_psydac.mk +0 -0
- {feectools-0.1.9 → feectools-0.1.10}/feectools/api/__init__.py +0 -0
- {feectools-0.1.9 → feectools-0.1.10}/feectools/api/essential_bc.py +0 -0
- {feectools-0.1.9 → feectools-0.1.10}/feectools/api/fem_bilinear_form.py +0 -0
- {feectools-0.1.9 → feectools-0.1.10}/feectools/api/fem_common.py +0 -0
- {feectools-0.1.9 → feectools-0.1.10}/feectools/api/fem_sum_form.py +0 -0
- {feectools-0.1.9 → feectools-0.1.10}/feectools/api/settings.py +0 -0
- {feectools-0.1.9 → feectools-0.1.10}/feectools/core/__init__.py +0 -0
- {feectools-0.1.9 → feectools-0.1.10}/feectools/core/bsplines.py +0 -0
- {feectools-0.1.9 → feectools-0.1.10}/feectools/core/bsplines_kernels.py +0 -0
- {feectools-0.1.9 → feectools-0.1.10}/feectools/core/field_evaluation_kernels.py +0 -0
- {feectools-0.1.9 → feectools-0.1.10}/feectools/core/tests/__init__.py +0 -0
- {feectools-0.1.9 → feectools-0.1.10}/feectools/core/tests/test_bsplines.py +0 -0
- {feectools-0.1.9 → feectools-0.1.10}/feectools/core/tests/test_bsplines_kernel.py +0 -0
- {feectools-0.1.9 → feectools-0.1.10}/feectools/core/tests/test_bsplines_pyccel.py +0 -0
- {feectools-0.1.9 → feectools-0.1.10}/feectools/ddm/__init__.py +0 -0
- {feectools-0.1.9 → feectools-0.1.10}/feectools/ddm/basic.py +0 -0
- {feectools-0.1.9 → feectools-0.1.10}/feectools/ddm/blocking_data_exchanger.py +0 -0
- {feectools-0.1.9 → feectools-0.1.10}/feectools/ddm/cart.py +0 -0
- {feectools-0.1.9 → feectools-0.1.10}/feectools/ddm/interface_data_exchanger.py +0 -0
- {feectools-0.1.9 → feectools-0.1.10}/feectools/ddm/mpi.py +0 -0
- {feectools-0.1.9 → feectools-0.1.10}/feectools/ddm/nonblocking_data_exchanger.py +0 -0
- {feectools-0.1.9 → feectools-0.1.10}/feectools/ddm/partition.py +0 -0
- {feectools-0.1.9 → feectools-0.1.10}/feectools/ddm/petsc.py +0 -0
- {feectools-0.1.9 → feectools-0.1.10}/feectools/ddm/tests/__init__.py +0 -0
- {feectools-0.1.9 → feectools-0.1.10}/feectools/ddm/tests/test_cart_1d.py +0 -0
- {feectools-0.1.9 → feectools-0.1.10}/feectools/ddm/tests/test_cart_2d.py +0 -0
- {feectools-0.1.9 → feectools-0.1.10}/feectools/ddm/tests/test_cart_3d.py +0 -0
- {feectools-0.1.9 → feectools-0.1.10}/feectools/ddm/tests/test_multicart_2d.py +0 -0
- {feectools-0.1.9 → feectools-0.1.10}/feectools/ddm/tests/test_partition.py +0 -0
- {feectools-0.1.9 → feectools-0.1.10}/feectools/ddm/utilities.py +0 -0
- {feectools-0.1.9 → feectools-0.1.10}/feectools/feec/__init__.py +0 -0
- {feectools-0.1.9 → feectools-0.1.10}/feectools/feec/derivatives.py +0 -0
- {feectools-0.1.9 → feectools-0.1.10}/feectools/feec/dof_kernels.py +0 -0
- {feectools-0.1.9 → feectools-0.1.10}/feectools/feec/global_geometric_projectors.py +0 -0
- {feectools-0.1.9 → feectools-0.1.10}/feectools/feec/hodge.py +0 -0
- {feectools-0.1.9 → feectools-0.1.10}/feectools/fem/__init__.py +0 -0
- {feectools-0.1.9 → feectools-0.1.10}/feectools/fem/basic.py +0 -0
- {feectools-0.1.9 → feectools-0.1.10}/feectools/fem/grid.py +0 -0
- {feectools-0.1.9 → feectools-0.1.10}/feectools/fem/lst_preconditioner.py +0 -0
- {feectools-0.1.9 → feectools-0.1.10}/feectools/fem/partitioning.py +0 -0
- {feectools-0.1.9 → feectools-0.1.10}/feectools/fem/projectors.py +0 -0
- {feectools-0.1.9 → feectools-0.1.10}/feectools/fem/splines.py +0 -0
- {feectools-0.1.9 → feectools-0.1.10}/feectools/fem/tensor.py +0 -0
- {feectools-0.1.9 → feectools-0.1.10}/feectools/fem/tests/__init__.py +0 -0
- {feectools-0.1.9 → feectools-0.1.10}/feectools/fem/tests/analytical_profiles_1d.py +0 -0
- {feectools-0.1.9 → feectools-0.1.10}/feectools/fem/tests/analytical_profiles_base.py +0 -0
- {feectools-0.1.9 → feectools-0.1.10}/feectools/fem/tests/splines_error_bounds.py +0 -0
- {feectools-0.1.9 → feectools-0.1.10}/feectools/fem/tests/test_dirichlet_projectors.py +0 -0
- {feectools-0.1.9 → feectools-0.1.10}/feectools/fem/tests/test_spline_histopolation.py +0 -0
- {feectools-0.1.9 → feectools-0.1.10}/feectools/fem/tests/test_spline_interpolation.py +0 -0
- {feectools-0.1.9 → feectools-0.1.10}/feectools/fem/tests/test_splines.py +0 -0
- {feectools-0.1.9 → feectools-0.1.10}/feectools/fem/tests/test_splines_par.py +0 -0
- {feectools-0.1.9 → feectools-0.1.10}/feectools/fem/tests/test_tensor.py +0 -0
- {feectools-0.1.9 → feectools-0.1.10}/feectools/fem/tests/test_vector_spaces.py +0 -0
- {feectools-0.1.9 → feectools-0.1.10}/feectools/fem/tests/utilities.py +0 -0
- {feectools-0.1.9 → feectools-0.1.10}/feectools/fem/vector.py +0 -0
- {feectools-0.1.9 → feectools-0.1.10}/feectools/linalg/__init__.py +0 -0
- {feectools-0.1.9 → feectools-0.1.10}/feectools/linalg/block.py +0 -0
- {feectools-0.1.9 → feectools-0.1.10}/feectools/linalg/direct_solvers.py +0 -0
- {feectools-0.1.9 → feectools-0.1.10}/feectools/linalg/fft.py +0 -0
- {feectools-0.1.9 → feectools-0.1.10}/feectools/linalg/kernels/__init__.py +0 -0
- {feectools-0.1.9 → feectools-0.1.10}/feectools/linalg/kernels/axpy_kernels.py +0 -0
- {feectools-0.1.9 → feectools-0.1.10}/feectools/linalg/kernels/inner_kernels.py +0 -0
- {feectools-0.1.9 → feectools-0.1.10}/feectools/linalg/kernels/matvec_kernels.py +0 -0
- {feectools-0.1.9 → feectools-0.1.10}/feectools/linalg/kernels/stencil2IJV_kernels.py +0 -0
- {feectools-0.1.9 → feectools-0.1.10}/feectools/linalg/kernels/stencil2coo_kernels.py +0 -0
- {feectools-0.1.9 → feectools-0.1.10}/feectools/linalg/kernels/transpose_kernels.py +0 -0
- {feectools-0.1.9 → feectools-0.1.10}/feectools/linalg/kron.py +0 -0
- {feectools-0.1.9 → feectools-0.1.10}/feectools/linalg/memory.py +0 -0
- {feectools-0.1.9 → feectools-0.1.10}/feectools/linalg/sparse.py +0 -0
- {feectools-0.1.9 → feectools-0.1.10}/feectools/linalg/stencil.py +0 -0
- {feectools-0.1.9 → feectools-0.1.10}/feectools/linalg/stencil_dot_kernels.py +0 -0
- {feectools-0.1.9 → feectools-0.1.10}/feectools/linalg/stencil_transpose_kernels.py +0 -0
- {feectools-0.1.9 → feectools-0.1.10}/feectools/linalg/tests/__init__.py +0 -0
- {feectools-0.1.9 → feectools-0.1.10}/feectools/linalg/tests/test_block.py +0 -0
- {feectools-0.1.9 → feectools-0.1.10}/feectools/linalg/tests/test_fft.py +0 -0
- {feectools-0.1.9 → feectools-0.1.10}/feectools/linalg/tests/test_kron_stencil_matrix.py +0 -0
- {feectools-0.1.9 → feectools-0.1.10}/feectools/linalg/tests/test_linalg.py +0 -0
- {feectools-0.1.9 → feectools-0.1.10}/feectools/linalg/tests/test_matrix_free.py +0 -0
- {feectools-0.1.9 → feectools-0.1.10}/feectools/linalg/tests/test_solvers.py +0 -0
- {feectools-0.1.9 → feectools-0.1.10}/feectools/linalg/tests/test_stencil_interface_matrix.py +0 -0
- {feectools-0.1.9 → feectools-0.1.10}/feectools/linalg/tests/test_stencil_vector.py +0 -0
- {feectools-0.1.9 → feectools-0.1.10}/feectools/linalg/tests/test_stencil_vector_space.py +0 -0
- {feectools-0.1.9 → feectools-0.1.10}/feectools/linalg/tests/utilities.py +0 -0
- {feectools-0.1.9 → feectools-0.1.10}/feectools/linalg/topetsc.py +0 -0
- {feectools-0.1.9 → feectools-0.1.10}/feectools/linalg/utilities.py +0 -0
- {feectools-0.1.9 → feectools-0.1.10}/feectools/utilities/__init__.py +0 -0
- {feectools-0.1.9 → feectools-0.1.10}/feectools/utilities/quadratures.py +0 -0
- {feectools-0.1.9 → feectools-0.1.10}/feectools/utilities/utils.py +0 -0
- {feectools-0.1.9 → feectools-0.1.10}/feectools/version.py +0 -0
- {feectools-0.1.9 → feectools-0.1.10}/feectools.egg-info/SOURCES.txt +0 -0
- {feectools-0.1.9 → feectools-0.1.10}/feectools.egg-info/dependency_links.txt +0 -0
- {feectools-0.1.9 → feectools-0.1.10}/feectools.egg-info/entry_points.txt +0 -0
- {feectools-0.1.9 → feectools-0.1.10}/feectools.egg-info/requires.txt +0 -0
- {feectools-0.1.9 → feectools-0.1.10}/feectools.egg-info/top_level.txt +0 -0
- {feectools-0.1.9 → feectools-0.1.10}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: feectools
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.10
|
|
4
4
|
Summary: Slimmed-down fork of Psydac (https://github.com/pyccel/psydac) with less functionality and fewer dependencies.
|
|
5
5
|
Author-email: Psydac development team <psydac@googlegroups.com>
|
|
6
6
|
Maintainer-email: Stefan Possanner <stefan.possanner@ipp.mpg.de>, Max Lindqvist <max.lindqvist@ipp.mpg.de>, Yaman Güçlü <yaman.guclu@gmail.com>, Martin Campos Pinto <martin.campos-pinto@ipp.mpg.de>, Ahmed Ratnani <ratnaniahmed@gmail.com>
|
|
@@ -756,7 +756,7 @@ class ScaledLinearOperator(LinearOperator):
|
|
|
756
756
|
self._scalar = c
|
|
757
757
|
|
|
758
758
|
def toarray(self):
|
|
759
|
-
return self._scalar * self._operator.toarray
|
|
759
|
+
return self._scalar * self._operator.toarray
|
|
760
760
|
|
|
761
761
|
def tosparse(self):
|
|
762
762
|
return self._scalar * self._operator.tosparse().tocsr()
|
|
@@ -4,12 +4,14 @@ This module provides iterative solvers and preconditioners.
|
|
|
4
4
|
|
|
5
5
|
"""
|
|
6
6
|
import cunumpy as xp
|
|
7
|
-
from math import sqrt
|
|
7
|
+
from math import sqrt, inf
|
|
8
8
|
|
|
9
9
|
from feectools.utilities.utils import is_real
|
|
10
10
|
from feectools.linalg.utilities import _sym_ortho
|
|
11
11
|
from feectools.linalg.basic import (Vector, LinearOperator,
|
|
12
12
|
InverseLinearOperator, IdentityOperator, ScaledLinearOperator)
|
|
13
|
+
from feectools.linalg.block import BlockVector, BlockVectorSpace
|
|
14
|
+
|
|
13
15
|
|
|
14
16
|
__all__ = (
|
|
15
17
|
'inverse',
|
|
@@ -20,7 +22,7 @@ __all__ = (
|
|
|
20
22
|
'PBiConjugateGradientStabilized',
|
|
21
23
|
'MinimumResidual',
|
|
22
24
|
'LSMR',
|
|
23
|
-
'GMRES'
|
|
25
|
+
'GMRES',
|
|
24
26
|
)
|
|
25
27
|
|
|
26
28
|
#===============================================================================
|
|
@@ -64,6 +66,8 @@ def inverse(A, solver, **kwargs):
|
|
|
64
66
|
'minres' : MinimumResidual,
|
|
65
67
|
'lsmr' : LSMR,
|
|
66
68
|
'gmres' : GMRES,
|
|
69
|
+
'uzawa' : UzawaSolver,
|
|
70
|
+
'schur' : SchurComplementSolver
|
|
67
71
|
}
|
|
68
72
|
|
|
69
73
|
# Check solver input
|
|
@@ -1912,3 +1916,219 @@ class GMRES(InverseLinearOperator):
|
|
|
1912
1916
|
def dot(self, b, out=None):
|
|
1913
1917
|
return self.solve(b, out=out)
|
|
1914
1918
|
|
|
1919
|
+
|
|
1920
|
+
class UzawaSolver(InverseLinearOperator):
|
|
1921
|
+
def __init__(self, A, *, A11, A22, B1, B2,
|
|
1922
|
+
x0=None, tol=1e-6, maxiter=1000, verbose=False, recycle=False,
|
|
1923
|
+
inner_tol=1e-7, inner_maxiter=1000):
|
|
1924
|
+
|
|
1925
|
+
|
|
1926
|
+
self._options = {
|
|
1927
|
+
"x0": x0, "tol": tol, "maxiter": maxiter,
|
|
1928
|
+
"verbose": verbose, "recycle": recycle,
|
|
1929
|
+
}
|
|
1930
|
+
super().__init__(A, **self._options)
|
|
1931
|
+
|
|
1932
|
+
self._inner_tol = inner_tol if inner_tol is not None else tol
|
|
1933
|
+
self._inner_maxiter = inner_maxiter
|
|
1934
|
+
|
|
1935
|
+
self._A11 = A11
|
|
1936
|
+
self._A22 = A22
|
|
1937
|
+
self._B1 = B1
|
|
1938
|
+
self._B2 = B2
|
|
1939
|
+
|
|
1940
|
+
self._A11inv = self._inner_solve(A11, tol=self._inner_tol, maxiter=self._inner_maxiter)
|
|
1941
|
+
self._A22inv = self._inner_solve(A22, tol=self._inner_tol, maxiter=self._inner_maxiter)
|
|
1942
|
+
|
|
1943
|
+
self._info = None
|
|
1944
|
+
|
|
1945
|
+
@staticmethod
|
|
1946
|
+
def _inner_solve(A, tol=1e-10, maxiter=200):
|
|
1947
|
+
"""Iterative GMRES inverse — works for non-symmetric positive definite operators."""
|
|
1948
|
+
from feectools.linalg.solvers import inverse
|
|
1949
|
+
return inverse(A, "gmres", tol=tol, maxiter=maxiter, recycle=True)
|
|
1950
|
+
|
|
1951
|
+
def update_A11(self, A11):
|
|
1952
|
+
"""Recompute A11 inverse when dt changes."""
|
|
1953
|
+
self._A11 = A11
|
|
1954
|
+
self._A11inv = self._inner_solve(A11, tol=self._inner_tol, maxiter=self._inner_maxiter)
|
|
1955
|
+
|
|
1956
|
+
def solve(self, b, out=None):
|
|
1957
|
+
|
|
1958
|
+
A11 = self._A11
|
|
1959
|
+
A22 = self._A22
|
|
1960
|
+
B1 = self._B1
|
|
1961
|
+
B2 = self._B2
|
|
1962
|
+
A11inv = self._A11inv
|
|
1963
|
+
A22inv = self._A22inv
|
|
1964
|
+
|
|
1965
|
+
tol = self._options["tol"]
|
|
1966
|
+
maxiter = self._options["maxiter"]
|
|
1967
|
+
verbose = self._options["verbose"]
|
|
1968
|
+
recycle = self._options["recycle"]
|
|
1969
|
+
|
|
1970
|
+
F = b[0]
|
|
1971
|
+
g = b[1]
|
|
1972
|
+
f_u = F[0]
|
|
1973
|
+
f_ue = F[1]
|
|
1974
|
+
|
|
1975
|
+
# initial guess
|
|
1976
|
+
x0 = self._options["x0"]
|
|
1977
|
+
if x0 is not None:
|
|
1978
|
+
u = x0[0][0].copy()
|
|
1979
|
+
ue = x0[0][1].copy()
|
|
1980
|
+
p = x0[1].copy()
|
|
1981
|
+
else:
|
|
1982
|
+
u = A11.domain.zeros()
|
|
1983
|
+
ue = A22.domain.zeros()
|
|
1984
|
+
p = B1.codomain.zeros()
|
|
1985
|
+
|
|
1986
|
+
|
|
1987
|
+
if verbose:
|
|
1988
|
+
print("Uzawa solver:")
|
|
1989
|
+
print("+---------+---------------------+")
|
|
1990
|
+
print("+ Iter. # | L2-norm of residual |")
|
|
1991
|
+
print("+---------+---------------------+")
|
|
1992
|
+
template = "| {:7d} | {:19.2e} |"
|
|
1993
|
+
|
|
1994
|
+
for iteration in range(1, maxiter + 1):
|
|
1995
|
+
|
|
1996
|
+
# solve A11 * u = f_u - B1^T * p
|
|
1997
|
+
rhs_u = f_u - B1.T.dot(p)
|
|
1998
|
+
u = A11inv.dot(rhs_u)
|
|
1999
|
+
|
|
2000
|
+
# solve A22 * ue = f_ue - B2^T * p
|
|
2001
|
+
rhs_ue = f_ue - B2.T.dot(p)
|
|
2002
|
+
ue = A22inv.dot(rhs_ue)
|
|
2003
|
+
|
|
2004
|
+
# constraint residual: R = B1*u + B2*ue - g
|
|
2005
|
+
R = B1.dot(u) + B2.dot(ue) - g
|
|
2006
|
+
residual_norm = sqrt(R.inner(R).real)
|
|
2007
|
+
|
|
2008
|
+
if verbose:
|
|
2009
|
+
print(template.format(iteration, residual_norm))
|
|
2010
|
+
|
|
2011
|
+
if residual_norm < tol:
|
|
2012
|
+
break
|
|
2013
|
+
|
|
2014
|
+
# pressure update: steepest descent step size
|
|
2015
|
+
S_R = B1.dot(A11inv.dot(B1.T.dot(R))) + B2.dot(A22inv.dot(B2.T.dot(R)))
|
|
2016
|
+
alpha = R.inner(R).real / R.inner(S_R).real
|
|
2017
|
+
p += alpha * R
|
|
2018
|
+
|
|
2019
|
+
if verbose:
|
|
2020
|
+
print("+---------+---------------------+")
|
|
2021
|
+
|
|
2022
|
+
self._info = {
|
|
2023
|
+
'niter' : iteration,
|
|
2024
|
+
'success' : residual_norm < tol,
|
|
2025
|
+
'res_norm': residual_norm,
|
|
2026
|
+
}
|
|
2027
|
+
|
|
2028
|
+
if recycle:
|
|
2029
|
+
block_u = BlockVector(self.domain.spaces[0], blocks=[u, ue])
|
|
2030
|
+
self._options["x0"] = BlockVector(self.domain, blocks=[block_u, p])
|
|
2031
|
+
|
|
2032
|
+
if out is not None:
|
|
2033
|
+
out[0][0] = u
|
|
2034
|
+
out[0][1] = ue
|
|
2035
|
+
out[1] = p
|
|
2036
|
+
return out
|
|
2037
|
+
|
|
2038
|
+
block_u = BlockVector(BlockVectorSpace(A11.domain, A22.domain), blocks=[u, ue])
|
|
2039
|
+
return BlockVector(self.domain, blocks=[block_u, p])
|
|
2040
|
+
|
|
2041
|
+
def dot(self, b, out=None):
|
|
2042
|
+
return self.solve(b, out=out)
|
|
2043
|
+
|
|
2044
|
+
|
|
2045
|
+
class SchurComplementSolver(InverseLinearOperator):
|
|
2046
|
+
def __init__(self, A, *, A11, A22, B1, B2,
|
|
2047
|
+
x0=None, tol=1e-6, maxiter=1000, verbose=False, recycle=False,
|
|
2048
|
+
inner_tol=1e-7, inner_maxiter=1000):
|
|
2049
|
+
|
|
2050
|
+
self._options = {
|
|
2051
|
+
"x0": x0, "tol": tol, "maxiter": maxiter,
|
|
2052
|
+
"verbose": verbose, "recycle": recycle,
|
|
2053
|
+
}
|
|
2054
|
+
super().__init__(A, **self._options)
|
|
2055
|
+
|
|
2056
|
+
self._inner_tol = inner_tol if inner_tol is not None else tol
|
|
2057
|
+
self._inner_maxiter = inner_maxiter
|
|
2058
|
+
|
|
2059
|
+
self._A11 = A11
|
|
2060
|
+
self._A22 = A22
|
|
2061
|
+
self._B1 = B1
|
|
2062
|
+
self._B2 = B2
|
|
2063
|
+
|
|
2064
|
+
self._A11inv = self._make_inner_solver(A11, self._inner_tol, self._inner_maxiter)
|
|
2065
|
+
self._A22inv = self._make_inner_solver(A22, self._inner_tol, self._inner_maxiter)
|
|
2066
|
+
|
|
2067
|
+
self._Sinv = self._build_schur_solver()
|
|
2068
|
+
|
|
2069
|
+
self._info = None
|
|
2070
|
+
|
|
2071
|
+
def _make_inner_solver(self, A, tol, maxiter):
|
|
2072
|
+
from feectools.linalg.solvers import inverse
|
|
2073
|
+
return inverse(A, "gmres", tol=tol, maxiter=maxiter, recycle=True)
|
|
2074
|
+
|
|
2075
|
+
def _build_schur_operator(self):
|
|
2076
|
+
return (self._B1 @ self._A11inv @ self._B1.T
|
|
2077
|
+
+ self._B2 @ self._A22inv @ self._B2.T)
|
|
2078
|
+
|
|
2079
|
+
def _build_schur_solver(self):
|
|
2080
|
+
from feectools.linalg.solvers import inverse
|
|
2081
|
+
S = self._build_schur_operator()
|
|
2082
|
+
return inverse(S, "gmres",
|
|
2083
|
+
tol=self._options["tol"],
|
|
2084
|
+
maxiter=self._options["maxiter"],
|
|
2085
|
+
verbose=self._options["verbose"],
|
|
2086
|
+
recycle=self._options["recycle"])
|
|
2087
|
+
|
|
2088
|
+
def update_A11(self, A11):
|
|
2089
|
+
"""Recompute A11 inverse and update Schur operator when dt changes."""
|
|
2090
|
+
self._A11 = A11
|
|
2091
|
+
self._A11inv = self._make_inner_solver(A11, self._inner_tol, self._inner_maxiter)
|
|
2092
|
+
# update operator in-place so Sinv keeps its recycled state
|
|
2093
|
+
self._Sinv.linop = self._build_schur_operator()
|
|
2094
|
+
|
|
2095
|
+
def solve(self, b, out=None):
|
|
2096
|
+
|
|
2097
|
+
A11inv = self._A11inv
|
|
2098
|
+
A22inv = self._A22inv
|
|
2099
|
+
B1 = self._B1
|
|
2100
|
+
B2 = self._B2
|
|
2101
|
+
Sinv = self._Sinv
|
|
2102
|
+
|
|
2103
|
+
F = b[0]
|
|
2104
|
+
g = b[1]
|
|
2105
|
+
f_u = F[0]
|
|
2106
|
+
f_ue = F[1]
|
|
2107
|
+
|
|
2108
|
+
# Schur complement RHS: B1*u_f + B2*ue_f - g
|
|
2109
|
+
rhs_p = B1.dot(A11inv.dot(f_u)) + B2.dot(A22inv.dot(f_ue)) - g
|
|
2110
|
+
|
|
2111
|
+
# solve S * p = rhs_p
|
|
2112
|
+
p = Sinv.dot(rhs_p)
|
|
2113
|
+
|
|
2114
|
+
# recover velocities
|
|
2115
|
+
u = A11inv.dot(f_u - B1.T.dot(p))
|
|
2116
|
+
ue = A22inv.dot(f_ue - B2.T.dot(p))
|
|
2117
|
+
|
|
2118
|
+
self._info = Sinv.get_info()
|
|
2119
|
+
|
|
2120
|
+
if self._options["recycle"]:
|
|
2121
|
+
block_u = BlockVector(self.domain.spaces[0], blocks=[u, ue])
|
|
2122
|
+
self._options["x0"] = BlockVector(self.domain, blocks=[block_u, p])
|
|
2123
|
+
|
|
2124
|
+
if out is not None:
|
|
2125
|
+
out[0][0] = u
|
|
2126
|
+
out[0][1] = ue
|
|
2127
|
+
out[1] = p
|
|
2128
|
+
return out
|
|
2129
|
+
|
|
2130
|
+
block_u = BlockVector(self.domain.spaces[0], blocks=[u, ue])
|
|
2131
|
+
return BlockVector(self.domain, blocks=[block_u, p])
|
|
2132
|
+
|
|
2133
|
+
def dot(self, b, out=None):
|
|
2134
|
+
return self.solve(b, out=out)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: feectools
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.10
|
|
4
4
|
Summary: Slimmed-down fork of Psydac (https://github.com/pyccel/psydac) with less functionality and fewer dependencies.
|
|
5
5
|
Author-email: Psydac development team <psydac@googlegroups.com>
|
|
6
6
|
Maintainer-email: Stefan Possanner <stefan.possanner@ipp.mpg.de>, Max Lindqvist <max.lindqvist@ipp.mpg.de>, Yaman Güçlü <yaman.guclu@gmail.com>, Martin Campos Pinto <martin.campos-pinto@ipp.mpg.de>, Ahmed Ratnani <ratnaniahmed@gmail.com>
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "feectools"
|
|
7
|
-
version = "0.1.
|
|
7
|
+
version = "0.1.10"
|
|
8
8
|
description = "Slimmed-down fork of Psydac (https://github.com/pyccel/psydac) with less functionality and fewer dependencies."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">= 3.10"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{feectools-0.1.9 → feectools-0.1.10}/feectools/linalg/tests/test_stencil_interface_matrix.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|