Commit d1bf1be7 authored by Patrick Buchfink's avatar Patrick Buchfink Committed by Stephan Rave
Browse files

QuadraticHamiltonianModel guaranteed with blocked phase space

parent 4aef2182
...@@ -8,7 +8,7 @@ from pymor.algorithms.timestepping import ImplicitMidpointTimeStepper ...@@ -8,7 +8,7 @@ from pymor.algorithms.timestepping import ImplicitMidpointTimeStepper
from pymor.algorithms.to_matrix import to_matrix from pymor.algorithms.to_matrix import to_matrix
from pymor.models.basic import InstationaryModel from pymor.models.basic import InstationaryModel
from pymor.operators.block import BlockOperator from pymor.operators.block import BlockOperator
from pymor.operators.constructions import ConcatenationOperator, VectorOperator from pymor.operators.constructions import ConcatenationOperator, NumpyConversionOperator, VectorOperator
from pymor.operators.interface import Operator from pymor.operators.interface import Operator
from pymor.operators.numpy import NumpyMatrixOperator, NumpyVectorSpace from pymor.operators.numpy import NumpyMatrixOperator, NumpyVectorSpace
from pymor.operators.symplectic import CanonicalSymplecticFormOperator from pymor.operators.symplectic import CanonicalSymplecticFormOperator
...@@ -72,28 +72,44 @@ class QuadraticHamiltonianModel(InstationaryModel): ...@@ -72,28 +72,44 @@ class QuadraticHamiltonianModel(InstationaryModel):
assert isinstance(H_op, Operator) and H_op.linear and H_op.range == H_op.source \ assert isinstance(H_op, Operator) and H_op.linear and H_op.range == H_op.source \
and H_op.range.dim % 2 == 0 and H_op.range.dim % 2 == 0
if isinstance(H_op.range, NumpyVectorSpace):
# make H_op compatible with blocked phase_space
assert H_op.range.dim % 2 == 0, 'H_op.range has to be even dimensional'
half_dim = H_op.range.dim // 2
phase_space = BlockVectorSpace([NumpyVectorSpace(half_dim)] * 2)
H_op = ConcatenationOperator([
NumpyConversionOperator(phase_space, direction='from_numpy'),
H_op,
NumpyConversionOperator(phase_space, direction='to_numpy'),
])
if h is None: if h is None:
h = H_op.range.zeros() h = H_op.range.zeros()
if isinstance(h, VectorArray): if isinstance(h, VectorArray):
assert h in H_op.range
h = VectorOperator(h, name='h') h = VectorOperator(h, name='h')
# generate correct canonical J if isinstance(h.range, NumpyVectorSpace):
if isinstance(H_op, BlockOperator): # make h compatible with blocked phase_space
self.J = CanonicalSymplecticFormOperator(H_op.source) assert h.range.dim % 2 == 0, 'h.range has to be even dimensional'
elif isinstance(H_op.range, NumpyVectorSpace): half_dim = h.range.dim // 2
assert H_op.range.dim % 2 == 0, 'H_op.range has to be even dimensional' phase_space = H_op.range
half_dim = H_op.range.dim // 2 h = ConcatenationOperator([
phase_space = BlockVectorSpace([NumpyVectorSpace(half_dim)] * 2) NumpyConversionOperator(phase_space, direction='from_numpy'),
J = CanonicalSymplecticFormOperator(phase_space) h,
self.J = NumpyMatrixOperator(to_matrix(J).toarray()) ])
else: assert h.range is H_op.range
raise NotImplementedError('Canonical Poisson matrix not implemented for this case.')
if isinstance(initial_data.space, NumpyVectorSpace):
# make initial_data compatible with blocked phase_space
initial_data = H_op.source.from_numpy(initial_data.to_numpy())
# J based on blocked phase_space
self.J = CanonicalSymplecticFormOperator(H_op.source)
# the contract expand structure is mainly relevant for reduced quadratic Hamiltonian systems # the contract expand structure is mainly relevant for reduced quadratic Hamiltonian systems
# minus is required since operator in an InstationaryModel is on the LHS # minus is required since operator in an InstationaryModel is on the LHS
operator = -contract(expand(ConcatenationOperator([self.J, H_op]))) operator = -ConcatenationOperator([self.J, H_op])
rhs = ConcatenationOperator([self.J, h]) rhs = ConcatenationOperator([self.J, h])
super().__init__(T, initial_data, operator, rhs, super().__init__(T, initial_data, operator, rhs,
time_stepper=time_stepper, time_stepper=time_stepper,
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment