Skip to content

Commit

Permalink
New DiffMatOnDomain implementation of DiffMatrices
Browse files Browse the repository at this point in the history
It linearly stretches and shift underlying DiffMatrices on an
arbitrary domain.
  • Loading branch information
amorison committed Feb 25, 2023
1 parent 115ed6d commit 90f89a1
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 2 deletions.
26 changes: 25 additions & 1 deletion dmsuite/poly_diff.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@

from abc import ABC, abstractmethod
from dataclasses import dataclass
from functools import cached_property
from functools import cached_property, lru_cache

import numpy as np
from numpy.typing import NDArray
Expand Down Expand Up @@ -335,3 +335,27 @@ def _dmat(self) -> GeneralPoly:

def at_order(self, order: int) -> NDArray:
return self.scale**order * self._dmat.at_order(order)


@dataclass(frozen=True)
class DiffMatOnDomain(DiffMatrices):
"""Differentiation matrices stretched and shifted to a different domain.
The stretching and shifting is done linearly between xmin and xmax.
"""

xmin: float
xmax: float
dmat: DiffMatrices

@cached_property
def stretching(self) -> NDArray:
return (self.dmat.nodes[-1] - self.dmat.nodes[0]) / (self.xmax - self.xmin)

@cached_property
def nodes(self) -> NDArray:
return (self.dmat.nodes - self.dmat.nodes[0]) / self.stretching + self.xmin

@lru_cache
def at_order(self, order: int) -> NDArray:
return self.stretching**order * self.dmat.at_order(order)
18 changes: 17 additions & 1 deletion tests/test_chebdif.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import numpy as np

from dmsuite.poly_diff import Chebyshev
from dmsuite.poly_diff import Chebyshev, DiffMatOnDomain


def test_chebdif4() -> None:
Expand All @@ -12,3 +12,19 @@ def test_chebdif4() -> None:
computed[order - 1] = cheb.at_order(order)
assert np.allclose(cheb.nodes, expected[0])
assert np.allclose(computed, expected[1])


def test_cheb_scaled() -> None:
dmat = DiffMatOnDomain(xmin=1.0, xmax=5.0, dmat=Chebyshev(degree=64))
nodes = dmat.nodes
assert np.allclose(nodes[0], dmat.xmin)
assert np.allclose(nodes[-1], dmat.xmax)
func = nodes**2
dfunc = 2 * nodes
d2func = 2.0
d1_cheb = dmat.at_order(1) @ func
d2_cheb = dmat.at_order(2) @ func
d3_cheb = dmat.at_order(3) @ func
assert np.allclose(d1_cheb, dfunc)
assert np.allclose(d2_cheb, d2func)
assert np.allclose(d3_cheb, 0.0, atol=1e-6)

0 comments on commit 90f89a1

Please sign in to comment.