Module PyMPDATA.boundary_conditions.extrapolated
boundary condition extrapolating values from the edge to the halo for scalars and returning edge-of-the-domain value for vectors (with all negative scalar values set to zero)
Expand source code
""" boundary condition extrapolating values from the edge to the halo for scalars
and returning edge-of-the-domain value for vectors (with all negative scalar values
set to zero) """
# pylint: disable=too-many-arguments
from functools import lru_cache
import numba
import numpy as np
from PyMPDATA.impl.enumerations import (
ARG_FOCUS,
INNER,
META_AND_DATA_DATA,
META_AND_DATA_META,
SIGN_LEFT,
)
from PyMPDATA.impl.traversals_common import (
make_fill_halos_loop,
make_fill_halos_loop_vector,
)
class Extrapolated:
"""class which instances are to be passed in boundary_conditions tuple to the
`PyMPDATA.scalar_field.ScalarField` and
`PyMPDATA.vector_field.VectorField` __init__ methods"""
def __init__(self, dim=INNER, eps=1e-10):
self.eps = eps
self.dim = dim
def make_scalar(self, indexers, halo, dtype, jit_flags, dimension_index):
"""returns (lru-cached) Numba-compiled scalar halo-filling callable"""
return _make_scalar_extrapolated(
self.dim,
self.eps,
indexers.ats[dimension_index],
indexers.set,
halo,
dtype,
jit_flags,
)
@staticmethod
def make_vector(indexers, _, __, jit_flags, dimension_index):
"""returns (lru-cached) Numba-compiled vector halo-filling callable"""
return _make_vector_extrapolated(
indexers.atv[dimension_index], indexers.set, jit_flags, dimension_index
)
@lru_cache()
# pylint: disable=too-many-arguments
def _make_scalar_extrapolated(dim, eps, ats, set_value, halo, dtype, jit_flags):
@numba.njit(**jit_flags)
def impl(psi, span, sign):
if sign == SIGN_LEFT:
edg = halo - psi[ARG_FOCUS][dim]
nom = ats(*psi, edg + 1) - ats(*psi, edg)
den = ats(*psi, edg + 2) - ats(*psi, edg + 1)
cnst = nom / den if abs(den) > eps else 0
return max(ats(*psi, 1) - (ats(*psi, 2) - ats(*psi, 1)) * cnst, 0)
edg = span + halo - 1 - psi[ARG_FOCUS][dim]
den = ats(*psi, edg - 1) - ats(*psi, edg - 2)
nom = ats(*psi, edg) - ats(*psi, edg - 1)
cnst = nom / den if abs(den) > eps else 0
return max(ats(*psi, -1) + (ats(*psi, -1) - ats(*psi, -2)) * cnst, 0)
if dtype == complex:
@numba.njit(**jit_flags)
def fill_halos_scalar(psi, span, sign):
return complex(
impl(
(psi[META_AND_DATA_META], psi[META_AND_DATA_DATA].real), span, sign
),
impl(
(psi[META_AND_DATA_META], psi[META_AND_DATA_DATA].imag), span, sign
),
)
else:
@numba.njit(**jit_flags)
def fill_halos_scalar(psi, span, sign):
return impl(psi, span, sign)
return make_fill_halos_loop(jit_flags, set_value, fill_halos_scalar)
@lru_cache()
def _make_vector_extrapolated(atv, set_value, jit_flags, dimension_index):
@numba.njit(**jit_flags)
def fill_halos_parallel(focus_psi, _, sign):
return atv(*focus_psi, sign + 0.5)
@numba.njit(**jit_flags)
def fill_halos_normal(_, __, ___, ____):
return np.nan
return make_fill_halos_loop_vector(
jit_flags, set_value, fill_halos_parallel, fill_halos_normal, dimension_index
)
Classes
class Extrapolated (dim=-1, eps=1e-10)
-
class which instances are to be passed in boundary_conditions tuple to the
ScalarField
andVectorField
init methodsExpand source code
class Extrapolated: """class which instances are to be passed in boundary_conditions tuple to the `PyMPDATA.scalar_field.ScalarField` and `PyMPDATA.vector_field.VectorField` __init__ methods""" def __init__(self, dim=INNER, eps=1e-10): self.eps = eps self.dim = dim def make_scalar(self, indexers, halo, dtype, jit_flags, dimension_index): """returns (lru-cached) Numba-compiled scalar halo-filling callable""" return _make_scalar_extrapolated( self.dim, self.eps, indexers.ats[dimension_index], indexers.set, halo, dtype, jit_flags, ) @staticmethod def make_vector(indexers, _, __, jit_flags, dimension_index): """returns (lru-cached) Numba-compiled vector halo-filling callable""" return _make_vector_extrapolated( indexers.atv[dimension_index], indexers.set, jit_flags, dimension_index )
Static methods
def make_vector(indexers, _, __, jit_flags, dimension_index)
-
returns (lru-cached) Numba-compiled vector halo-filling callable
Expand source code
@staticmethod def make_vector(indexers, _, __, jit_flags, dimension_index): """returns (lru-cached) Numba-compiled vector halo-filling callable""" return _make_vector_extrapolated( indexers.atv[dimension_index], indexers.set, jit_flags, dimension_index )
Methods
def make_scalar(self, indexers, halo, dtype, jit_flags, dimension_index)
-
returns (lru-cached) Numba-compiled scalar halo-filling callable
Expand source code
def make_scalar(self, indexers, halo, dtype, jit_flags, dimension_index): """returns (lru-cached) Numba-compiled scalar halo-filling callable""" return _make_scalar_extrapolated( self.dim, self.eps, indexers.ats[dimension_index], indexers.set, halo, dtype, jit_flags, )