forked from OpenMDAO/OpenMDAO
-
Notifications
You must be signed in to change notification settings - Fork 1
/
linear_block_gs.py
63 lines (51 loc) · 2.51 KB
/
linear_block_gs.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
"""Define the LinearBlockGS class."""
from openmdao.solvers.solver import BlockLinearSolver
class LinearBlockGS(BlockLinearSolver):
"""
Linear block Gauss-Seidel solver.
"""
SOLVER = 'LN: LNBGS'
def _single_iteration(self):
"""
Perform the operations in the iteration loop.
"""
system = self._system()
mode = self._mode
vec_names = self._vec_names
if mode == 'fwd':
for isub, (subsys, local) in enumerate(system._all_subsystem_iter()):
if self._rel_systems is not None and subsys.pathname not in self._rel_systems:
continue
for vec_name in vec_names:
# must always do the transfer on all procs even if subsys not local
system._transfer(vec_name, mode, isub)
if not local:
continue
scope_out, scope_in = system._get_scope(subsys)
subsys._apply_linear(None, vec_names, self._rel_systems, mode, scope_out, scope_in)
for vec_name in vec_names:
if vec_name in subsys._rel_vec_names:
b_vec = system._vectors['residual'][vec_name]
b_vec *= -1.0
b_vec._data += self._rhs_vecs[vec_name]
subsys._solve_linear(vec_names, mode, self._rel_systems)
else: # rev
subsystems = system._subsystems_allprocs
for isub in range(len(system._subsystems_allprocs) - 1, -1, -1):
subsys = subsystems[isub]
local = subsys.name in system._loc_subsys_map
if self._rel_systems is not None and subsys.pathname not in self._rel_systems:
continue
for vec_name in vec_names:
if local and vec_name in subsys._rel_vec_names:
b_vec = system._vectors['output'][vec_name]
b_vec.set_const(0.0)
system._transfer(vec_name, mode, isub)
if local and vec_name in subsys._rel_vec_names:
b_vec *= -1.0
b_vec._data += self._rhs_vecs[vec_name]
if local:
subsys._solve_linear(vec_names, mode, self._rel_systems)
scope_out, scope_in = system._get_scope(subsys)
subsys._apply_linear(None, vec_names, self._rel_systems, mode,
scope_out, scope_in)