Page Menu
Home
c4science
Search
Configure Global Search
Log In
Files
F61103337
generic_approximant.py
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Subscribers
None
File Metadata
Details
File Info
Storage
Attached
Created
Sat, May 4, 13:43
Size
19 KB
Mime Type
text/x-python
Expires
Mon, May 6, 13:43 (2 d)
Engine
blob
Format
Raw Data
Handle
17465595
Attached To
R6746 RationalROMPy
generic_approximant.py
View Options
# Copyright (C) 2018 by the RROMPy authors
#
# This file is part of RROMPy.
#
# RROMPy is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# RROMPy is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with RROMPy. If not, see <http://www.gnu.org/licenses/>.
#
from
abc
import
abstractmethod
import
numpy
as
np
from
copy
import
copy
from
rrompy.sampling.base.sampling_engine_base
import
SamplingEngineBase
from
rrompy.utilities.base.types
import
Np1D
,
DictAny
,
HFEng
,
sampleEng
,
strLst
from
rrompy.utilities.base
import
purgeDict
,
verbosityDepth
__all__
=
[
'GenericApproximant'
]
class
GenericApproximant
:
"""
ABSTRACT
ROM approximant computation for parametric problems.
Args:
HFEngine: HF problem solver.
mu0(optional): Default parameter. Defaults to 0.
approxParameters(optional): Dictionary containing values for main
parameters of approximant. Recognized keys are:
- 'POD': whether to compute POD of snapshots; defaults to True.
Defaults to empty dict.
verbosity(optional): Verbosity level. Defaults to 10.
Attributes:
HFEngine: HF problem solver.
mu0: Default parameter.
w: Weight for norm computation.
approxParameters: Dictionary containing values for main parameters of
approximant. Recognized keys are in parameterList.
parameterList: Recognized keys of approximant parameters:
- 'POD': whether to compute POD of snapshots.
verbosity: Verbosity level.
POD: Whether to compute POD of snapshots.
samplingEngine: Sampling engine.
uHF: High fidelity solution with wavenumber lastSolvedHF as numpy
complex vector.
lastSolvedHF: Wavenumber corresponding to last computed high fidelity
solution.
uApp: Last evaluated approximant as numpy complex vector.
lastApproxParameters: List of parameters corresponding to last
computed approximant.
"""
def
__init__
(
self
,
HFEngine
:
HFEng
,
mu0
:
complex
=
0
,
approxParameters
:
DictAny
=
{},
homogeneized
:
bool
=
False
,
verbosity
:
int
=
10
):
self
.
_preInit
()
self
.
verbosity
=
verbosity
if
self
.
verbosity
>=
10
:
verbosityDepth
(
"INIT"
,
(
"Initializing approximant engine of "
"type {}."
)
.
format
(
self
.
name
()))
self
.
HFEngine
=
HFEngine
self
.
_HFEngine0
=
copy
(
HFEngine
)
self
.
_addParametersToList
([
"POD"
])
self
.
mu0
=
mu0
self
.
homogeneized
=
homogeneized
self
.
approxParameters
=
approxParameters
self
.
_postInit
()
def
_preInit
(
self
):
if
not
hasattr
(
self
,
"depth"
):
self
.
depth
=
0
else
:
self
.
depth
+=
1
def
_addParametersToList
(
self
,
what
:
strLst
):
if
not
hasattr
(
self
,
"parameterList"
):
self
.
parameterList
=
[]
self
.
parameterList
+=
what
def
_postInit
(
self
):
if
self
.
depth
==
0
:
if
self
.
verbosity
>=
10
:
verbosityDepth
(
"DEL"
,
"Done initializing.
\n
"
)
del
self
.
depth
else
:
self
.
depth
-=
1
def
name
(
self
)
->
str
:
return
self
.
__class__
.
__name__
def
__str__
(
self
)
->
str
:
return
self
.
name
()
def
__repr__
(
self
)
->
str
:
return
self
.
__str__
()
+
" at "
+
hex
(
id
(
self
))
def
setupSampling
(
self
,
SamplingEngine
:
sampleEng
=
SamplingEngineBase
):
"""Setup sampling engine."""
self
.
samplingEngine
=
SamplingEngine
(
self
.
HFEngine
,
verbosity
=
self
.
verbosity
)
@property
def
approxParameters
(
self
):
"""Value of approximant parameters."""
return
self
.
_approxParameters
@approxParameters.setter
def
approxParameters
(
self
,
approxParams
):
if
not
hasattr
(
self
,
"approxParameters"
):
self
.
_approxParameters
=
{}
approxParameters
=
purgeDict
(
approxParams
,
self
.
parameterList
,
dictname
=
self
.
name
()
+
".approxParameters"
,
baselevel
=
1
)
keyList
=
list
(
approxParameters
.
keys
())
if
"POD"
in
keyList
:
self
.
POD
=
approxParameters
[
"POD"
]
elif
hasattr
(
self
,
"POD"
):
self
.
POD
=
self
.
POD
else
:
self
.
POD
=
True
@property
def
POD
(
self
):
"""Value of POD."""
return
self
.
_POD
@POD.setter
def
POD
(
self
,
POD
):
if
hasattr
(
self
,
"POD"
):
PODold
=
self
.
POD
else
:
PODold
=
-
1
self
.
_POD
=
POD
self
.
_approxParameters
[
"POD"
]
=
self
.
POD
if
PODold
!=
self
.
POD
:
self
.
setupSampling
()
self
.
resetSamples
()
@property
def
homogeneized
(
self
):
"""Value of homogeneized."""
return
self
.
_homogeneized
@homogeneized.setter
def
homogeneized
(
self
,
homogeneized
):
if
not
hasattr
(
self
,
"_homogeneized"
):
self
.
_homogeneized
=
None
if
homogeneized
!=
self
.
homogeneized
:
self
.
_homogeneized
=
homogeneized
self
.
resetSamples
()
def
solveHF
(
self
,
mu
:
complex
=
None
):
"""
Find high fidelity solution with original parameters and arbitrary
parameter.
Args:
mu: Target parameter.
"""
if
mu
is
None
:
mu
=
self
.
mu0
if
(
not
hasattr
(
self
,
"lastSolvedHF"
)
or
not
np
.
isclose
(
self
.
lastSolvedHF
,
mu
)):
self
.
uHF
=
self
.
samplingEngine
.
solveLS
(
mu
,
homogeneized
=
self
.
homogeneized
)
self
.
lastSolvedHF
=
mu
def
resetSamples
(
self
):
"""Reset samples."""
if
hasattr
(
self
,
"samplingEngine"
):
self
.
samplingEngine
.
resetHistory
()
else
:
self
.
setupSampling
()
def
plotSamples
(
self
,
name
:
str
=
"u"
,
save
:
str
=
None
,
what
:
strLst
=
'all'
,
saveFormat
:
str
=
"eps"
,
saveDPI
:
int
=
100
,
**
figspecs
):
"""
Do some nice plots of the samples.
Args:
name(optional): Name to be shown as title of the plots. Defaults to
'u'.
what(optional): Which plots to do. If list, can contain 'ABS',
'PHASE', 'REAL', 'IMAG'. If str, same plus wildcard 'ALL'.
Defaults to 'ALL'.
save(optional): Where to save plot(s). Defaults to None, i.e. no
saving.
saveFormat(optional): Format for saved plot(s). Defaults to "eps".
saveDPI(optional): DPI for saved plot(s). Defaults to 100.
figspecs(optional key args): Optional arguments for matplotlib
figure creation.
"""
self
.
samplingEngine
.
plotSamples
(
name
=
name
,
save
=
save
,
what
=
what
,
saveFormat
=
saveFormat
,
saveDPI
=
saveDPI
,
**
figspecs
)
@abstractmethod
def
setupApprox
(
self
):
"""
Setup approximant. (ABSTRACT)
Any specialization should include something like
self.computeDerivatives()
if not self.checkComputedApprox():
...
self.lastApproxParameters = copy(self.approxParameters)
"""
pass
def
checkComputedApprox
(
self
)
->
bool
:
"""
Check if setup of new approximant is not needed.
Returns:
True if new setup is not needed. False otherwise.
"""
return
(
hasattr
(
self
,
"lastApproxParameters"
)
and
self
.
approxParameters
==
self
.
lastApproxParameters
)
@abstractmethod
def
evalApproxReduced
(
self
,
mu
:
complex
):
"""
Evaluate reduced representation of approximant at arbitrary parameter.
(ABSTRACT)
Any specialization should include something like
self.setupApprox()
self.uAppReduced = ...
Args:
mu: Target parameter.
"""
pass
@abstractmethod
def
evalApprox
(
self
,
mu
:
complex
):
"""
Evaluate approximant at arbitrary parameter. (ABSTRACT)
Any specialization should include something like
self.evalApproxReduced(mu)
self.uApp = ...
Args:
mu: Target parameter.
"""
pass
def
getHF
(
self
,
mu
:
complex
,
homogeneized
:
bool
=
False
)
->
Np1D
:
"""
Get HF solution at arbitrary parameter.
Args:
mu: Target parameter.
homogeneized(optional): Whether to remove Dirichlet BC. Defaults to
False.
Returns:
HFsolution.
"""
self
.
solveHF
(
mu
)
if
self
.
homogeneized
and
not
homogeneized
:
return
self
.
uHF
+
self
.
HFEngine
.
liftDirichletData
(
mu
)
if
not
self
.
homogeneized
and
homogeneized
:
return
self
.
uHF
-
self
.
HFEngine
.
liftDirichletData
(
mu
)
return
self
.
uHF
def
getRHS
(
self
,
mu
:
complex
,
homogeneized
:
bool
=
False
)
->
Np1D
:
"""
Get linear system RHS at arbitrary parameter.
Args:
mu: Target parameter.
homogeneized(optional): Whether to remove Dirichlet BC. Defaults to
False.
Returns:
Linear system RHS.
"""
return
self
.
HFEngine
.
residual
(
None
,
mu
,
homogeneized
=
homogeneized
)
def
getAppReduced
(
self
,
mu
:
complex
)
->
Np1D
:
"""
Get approximant at arbitrary parameter.
Args:
mu: Target parameter.
Returns:
Reduced approximant.
"""
self
.
evalApproxReduced
(
mu
)
return
self
.
uAppReduced
def
getApp
(
self
,
mu
:
complex
,
homogeneized
:
bool
=
False
)
->
Np1D
:
"""
Get approximant at arbitrary parameter.
Args:
mu: Target parameter.
homogeneized(optional): Whether to remove Dirichlet BC. Defaults to
False.
Returns:
Approximant.
"""
self
.
evalApprox
(
mu
)
if
self
.
homogeneized
and
not
homogeneized
:
return
self
.
uApp
+
self
.
HFEngine
.
liftDirichletData
(
mu
)
if
not
self
.
homogeneized
and
homogeneized
:
return
self
.
uApp
-
self
.
HFEngine
.
liftDirichletData
(
mu
)
return
self
.
uApp
def
getRes
(
self
,
mu
:
complex
,
homogeneized
:
bool
=
False
)
->
Np1D
:
"""
Get residual at arbitrary parameter.
Args:
mu: Target parameter.
homogeneized(optional): Whether to remove Dirichlet BC. Defaults to
False.
Returns:
Approximant residual.
"""
return
self
.
HFEngine
.
residual
(
self
.
getApp
(
mu
,
homogeneized
),
mu
,
homogeneized
=
homogeneized
)
def
getErr
(
self
,
mu
:
complex
,
homogeneized
:
bool
=
False
)
->
Np1D
:
"""
Get error at arbitrary parameter.
Args:
mu: Target parameter.
homogeneized(optional): Whether to remove Dirichlet BC. Defaults to
False.
Returns:
Approximant error.
"""
return
self
.
getApp
(
mu
,
homogeneized
)
-
self
.
getHF
(
mu
,
homogeneized
)
@abstractmethod
def
getPoles
(
self
)
->
Np1D
:
"""
Obtain approximant poles.
Returns:
Numpy complex vector of poles.
"""
pass
def
normHF
(
self
,
mu
:
complex
,
homogeneized
:
bool
=
False
)
->
float
:
"""
Compute norm of HF solution at arbitrary parameter.
Args:
mu: Target parameter.
homogeneized(optional): Whether to remove Dirichlet BC. Defaults to
False.
Returns:
Target norm of HFsolution.
"""
return
self
.
HFEngine
.
norm
(
self
.
getHF
(
mu
,
homogeneized
))
def
normRHS
(
self
,
mu
:
complex
,
homogeneized
:
bool
=
False
)
->
Np1D
:
"""
Compute norm of linear system RHS at arbitrary parameter.
Args:
mu: Target parameter.
homogeneized(optional): Whether to remove Dirichlet BC. Defaults to
False.
Returns:
Norm of linear system RHS.
"""
return
self
.
HFEngine
.
norm
(
self
.
getRHS
(
mu
,
homogeneized
))
def
normApp
(
self
,
mu
:
complex
,
homogeneized
:
bool
=
False
)
->
float
:
"""
Compute norm of approximant at arbitrary parameter.
Args:
mu: Target parameter.
homogeneized(optional): Whether to remove Dirichlet BC. Defaults to
False.
Returns:
Target norm of approximant.
"""
return
self
.
HFEngine
.
norm
(
self
.
getApp
(
mu
,
homogeneized
))
def
normRes
(
self
,
mu
:
complex
,
homogeneized
:
bool
=
False
)
->
float
:
"""
Compute norm of approximant residual at arbitrary parameter.
Args:
mu: Target parameter.
homogeneized(optional): Whether to remove Dirichlet BC. Defaults to
False.
Returns:
Target norm of (A(mu)app(mu) - f(mu)).
"""
return
self
.
HFEngine
.
norm
(
self
.
getRes
(
mu
,
homogeneized
))
def
normErr
(
self
,
mu
:
complex
,
homogeneized
:
bool
=
False
)
->
float
:
"""
Compute norm of approximant error at arbitrary parameter.
Args:
mu: Target parameter.
homogeneized(optional): Whether to remove Dirichlet BC. Defaults to
False.
Returns:
Target norm of (approximant - HFsolution).
"""
return
self
.
HFEngine
.
norm
(
self
.
getErr
(
mu
,
homogeneized
))
def
plotHF
(
self
,
mu
:
complex
,
name
:
str
=
"uHF"
,
save
:
str
=
None
,
what
:
strLst
=
'all'
,
saveFormat
:
str
=
"eps"
,
saveDPI
:
int
=
100
,
homogeneized
:
bool
=
False
,
**
figspecs
):
"""
Do some nice plots of the HF solution at arbitrary parameter.
Args:
mu: Target parameter.
name(optional): Name to be shown as title of the plots. Defaults to
'u'.
what(optional): Which plots to do. If list, can contain 'ABS',
'PHASE', 'REAL', 'IMAG'. If str, same plus wildcard 'ALL'.
Defaults to 'ALL'.
save(optional): Where to save plot(s). Defaults to None, i.e. no
saving.
saveFormat(optional): Format for saved plot(s). Defaults to "eps".
saveDPI(optional): DPI for saved plot(s). Defaults to 100.
homogeneized(optional): Whether to remove Dirichlet BC. Defaults to
False.
figspecs(optional key args): Optional arguments for matplotlib
figure creation.
"""
uHF
=
self
.
getHF
(
mu
,
homogeneized
)
self
.
HFEngine
.
plot
(
uHF
,
name
=
name
,
save
=
save
,
what
=
what
,
saveFormat
=
saveFormat
,
saveDPI
=
saveDPI
,
**
figspecs
)
def
plotApp
(
self
,
mu
:
complex
,
name
:
str
=
"uApp"
,
save
:
str
=
None
,
what
:
strLst
=
'all'
,
saveFormat
:
str
=
"eps"
,
saveDPI
:
int
=
100
,
homogeneized
:
bool
=
False
,
**
figspecs
):
"""
Do some nice plots of approximant at arbitrary parameter.
Args:
mu: Target parameter.
name(optional): Name to be shown as title of the plots. Defaults to
'u'.
what(optional): Which plots to do. If list, can contain 'ABS',
'PHASE', 'REAL', 'IMAG'. If str, same plus wildcard 'ALL'.
Defaults to 'ALL'.
save(optional): Where to save plot(s). Defaults to None, i.e. no
saving.
saveFormat(optional): Format for saved plot(s). Defaults to "eps".
saveDPI(optional): DPI for saved plot(s). Defaults to 100.
homogeneized(optional): Whether to remove Dirichlet BC. Defaults to
False.
figspecs(optional key args): Optional arguments for matplotlib
figure creation.
"""
uApp
=
self
.
getApp
(
mu
,
homogeneized
)
self
.
HFEngine
.
plot
(
uApp
,
name
=
name
,
save
=
save
,
what
=
what
,
saveFormat
=
saveFormat
,
saveDPI
=
saveDPI
,
**
figspecs
)
def
plotRes
(
self
,
mu
:
complex
,
name
:
str
=
"res"
,
save
:
str
=
None
,
what
:
strLst
=
'all'
,
saveFormat
:
str
=
"eps"
,
saveDPI
:
int
=
100
,
homogeneized
:
bool
=
False
,
**
figspecs
):
"""
Do some nice plots of approximation residual at arbitrary parameter.
Args:
mu: Target parameter.
name(optional): Name to be shown as title of the plots. Defaults to
'u'.
what(optional): Which plots to do. If list, can contain 'ABS',
'PHASE', 'REAL', 'IMAG'. If str, same plus wildcard 'ALL'.
Defaults to 'ALL'.
save(optional): Where to save plot(s). Defaults to None, i.e. no
saving.
saveFormat(optional): Format for saved plot(s). Defaults to "eps".
saveDPI(optional): DPI for saved plot(s). Defaults to 100.
homogeneized(optional): Whether to remove Dirichlet BC. Defaults to
False.
figspecs(optional key args): Optional arguments for matplotlib
figure creation.
"""
uRes
=
self
.
getRes
(
mu
,
homogeneized
)
self
.
HFEngine
.
plot
(
uRes
,
name
=
name
,
save
=
save
,
what
=
what
,
saveFormat
=
saveFormat
,
saveDPI
=
saveDPI
,
**
figspecs
)
def
plotErr
(
self
,
mu
:
complex
,
name
:
str
=
"err"
,
save
:
str
=
None
,
what
:
strLst
=
'all'
,
saveFormat
:
str
=
"eps"
,
saveDPI
:
int
=
100
,
homogeneized
:
bool
=
False
,
**
figspecs
):
"""
Do some nice plots of approximation error at arbitrary parameter.
Args:
mu: Target parameter.
name(optional): Name to be shown as title of the plots. Defaults to
'u'.
what(optional): Which plots to do. If list, can contain 'ABS',
'PHASE', 'REAL', 'IMAG'. If str, same plus wildcard 'ALL'.
Defaults to 'ALL'.
save(optional): Where to save plot(s). Defaults to None, i.e. no
saving.
saveFormat(optional): Format for saved plot(s). Defaults to "eps".
saveDPI(optional): DPI for saved plot(s). Defaults to 100.
homogeneized(optional): Whether to remove Dirichlet BC. Defaults to
False.
figspecs(optional key args): Optional arguments for matplotlib
figure creation.
"""
uErr
=
self
.
getErr
(
mu
,
homogeneized
)
self
.
HFEngine
.
plot
(
uErr
,
name
=
name
,
save
=
save
,
what
=
what
,
saveFormat
=
saveFormat
,
saveDPI
=
saveDPI
,
**
figspecs
)
Event Timeline
Log In to Comment