Page Menu
Home
c4science
Search
Configure Global Search
Log In
Files
F93405274
oscillator_problem_engine.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
Thu, Nov 28, 12:39
Size
5 KB
Mime Type
text/x-python
Expires
Sat, Nov 30, 12:39 (1 d, 21 h)
Engine
blob
Format
Raw Data
Handle
22629334
Attached To
R6746 RationalROMPy
oscillator_problem_engine.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/>.
#
import
numpy
as
np
import
scipy.sparse
as
scsp
from
numbers
import
Number
from
rrompy.hfengines.base.linear_affine_engine
import
LinearAffineEngine
from
rrompy.hfengines.base.scipy_engine_base
import
(
ScipyEngineBase
,
ScipyEngineBaseTensorized
)
from
rrompy.utilities.base.types
import
List
,
Np1D
,
Np2D
from
rrompy.utilities.base
import
verbosityManager
as
vbMng
from
rrompy.utilities.exception_manager
import
RROMPyAssert
,
RROMPyException
from
rrompy.parameter
import
checkParameter
__all__
=
[
'OscillatorProblemEngine'
,
'AugmentedOscillatorProblemEngine'
]
class
OscillatorProblemEngine
(
LinearAffineEngine
,
ScipyEngineBaseTensorized
):
"""
Solver for damped mass oscillator problems.
Each i represents the factor in front of mu_i, except for i=0, which is a
constant. For each i:
(mass_i)_j = mass of j-th mass
(damping_i)_jk = damping between j-th and k-th mass
(stiffness_i)_jk = stiffness between j-th and k-th mass
Others:
input_ij = stiffness between i-th input and j-th mass
output_ij = contribution of j-th mass's position to i-th output
"""
def
__init__
(
self
,
mass
:
List
[
Np1D
],
damping
:
List
[
Np2D
],
stiffness
:
List
[
Np2D
],
input
:
Np2D
,
output
:
Np2D
,
verbosity
:
int
=
10
,
timestamp
:
bool
=
True
):
super
()
.
__init__
(
verbosity
=
verbosity
,
timestamp
=
timestamp
)
self
.
_affinePoly
=
True
N
,
self
.
npar
=
len
(
mass
[
0
]),
len
(
mass
)
RROMPyAssert
(
len
(
damping
),
self
.
npar
,
"Number of parameters"
)
RROMPyAssert
(
len
(
stiffness
),
self
.
npar
,
"Number of parameters"
)
input
=
np
.
array
(
input
)
if
input
.
ndim
<
2
:
input
=
input
.
reshape
(
-
1
,
1
)
self
.
nports
=
input
.
shape
[
1
]
self
.
nAs
,
self
.
As
,
self
.
thAs
=
3
*
self
.
npar
,
[],
[]
self
.
nbs
,
self
.
bs
=
1
,
[
input
.
flatten
()]
self
.
_C
=
output
for
j
in
range
(
self
.
npar
):
deg
=
[
0
]
*
(
self
.
npar
-
1
)
if
j
!=
0
:
deg
[
j
-
1
]
=
1
K
=
-
stiffness
[
j
]
Dj
=
-
1.j
*
damping
[
j
]
if
isinstance
(
Dj
,
(
np
.
ndarray
,)):
Mm
=
np
.
diag
(
-
mass
[
j
])
else
:
Mm
=
scsp
.
diags
([
-
mass
[
j
]],
[
0
],
format
=
Dj
.
format
)
for
n
in
range
(
N
):
K
[
n
,
n
]
=
-
np
.
sum
(
K
[
n
])
if
j
==
0
:
K
[
n
,
n
]
+=
np
.
sum
(
input
[
n
])
Dj
[
n
,
n
]
=
-
np
.
sum
(
Dj
[
n
])
self
.
As
+=
[
K
,
Dj
,
Mm
]
self
.
thAs
+=
[
self
.
getMonomialSingleWeight
([
0
]
+
deg
),
self
.
getMonomialSingleWeight
([
1
]
+
deg
),
self
.
getMonomialSingleWeight
([
2
]
+
deg
)]
if
isinstance
(
self
.
As
[
0
],
(
np
.
ndarray
,)):
self
.
setSolver
(
"SOLVE"
)
else
:
self
.
setSolver
(
"SPSOLVE"
,
{
"use_umfpack"
:
False
})
class
AugmentedOscillatorProblemEngine
(
OscillatorProblemEngine
):
"""
Solver for damped mass oscillator problems.
Each i represents the factor in front of mu_i, except for i=0, which is a
constant. For each i:
(mass_i)_j = mass of j-th mass
(damping_i)_jk = damping between j-th and k-th mass
(stiffness_i)_jk = stiffness between j-th and k-th mass
Others:
input_ij = stiffness between i-th input and j-th mass
output_ij = contribution of j-th mass's position to i-th output
"""
def
__init__
(
self
,
*
args
,
**
kwargs
):
super
()
.
__init__
(
*
args
,
**
kwargs
)
N
,
self
.
_nAs
=
self
.
As
[
0
]
.
shape
[
1
],
2
*
self
.
npar
self
.
bs
=
[
np
.
pad
(
self
.
bs
[
0
]
.
reshape
(
-
1
,
self
.
nports
),
[(
N
,
0
),
(
0
,
0
)],
'constant'
)
.
flatten
()]
if
(
not
isinstance
(
self
.
_C
,
(
Number
,))
and
self
.
_C
.
shape
[
1
]
!=
2
*
N
):
RROMPyAssert
(
self
.
_C
.
shape
[
1
],
N
,
"Shape of output"
)
self
.
_C
=
np
.
pad
(
self
.
_C
,
[(
0
,
0
),
(
0
,
N
)],
'constant'
)
As
,
thAs
=
[],
[]
for
j
in
range
(
self
.
npar
):
K
,
Dj
,
Mm
=
self
.
As
[
3
*
j
],
self
.
As
[
3
*
j
+
1
],
self
.
As
[
3
*
j
+
2
]
if
isinstance
(
Dj
,
(
np
.
ndarray
,)):
I
,
Z
=
1.j
*
np
.
eye
(
N
),
np
.
zeros
((
N
,
N
))
Deff
=
np
.
block
([[
Z
,
-
I
],
[
K
,
Dj
]])
Meff
=
np
.
block
([[
I
,
Z
],
[
Z
,
Mm
]])
else
:
I
=
1.j
*
scsp
.
eye
(
N
)
Deff
=
scsp
.
bmat
([[
None
,
-
I
],
[
K
,
Dj
]],
format
=
Mm
.
format
)
Meff
=
scsp
.
block_diag
([
I
,
Mm
],
format
=
Mm
.
format
)
As
+=
[
Deff
,
Meff
]
thAs
+=
[
self
.
thAs
[
3
*
j
],
self
.
thAs
[
3
*
j
+
1
]]
self
.
As
,
self
.
thAs
=
As
,
thAs
if
isinstance
(
self
.
As
[
0
],
(
np
.
ndarray
,)):
self
.
setSolver
(
"SOLVE"
)
else
:
self
.
setSolver
(
"SPSOLVE"
,
{
"use_umfpack"
:
False
})
Event Timeline
Log In to Comment