• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

OpenMDAO / dymos / 14334339264

08 Apr 2025 01:07PM UTC coverage: 92.981% (-0.1%) from 93.097%
14334339264

push

github

web-flow
Picard control continuity (#1167)

* Starting to add control continuity conditions to PicardShooting

* Added a continuity constraint component to enforce control continuity in PicardShooting.

* undo a reversion from last PR.

* missed a @use_tempdirs

45 of 48 new or added lines in 2 files covered. (93.75%)

61 existing lines in 6 files now uncovered.

33487 of 36015 relevant lines covered (92.98%)

5.65 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

98.57
/dymos/examples/hull_problem/test/test_hull_problem.py
1
from __future__ import print_function, division, absolute_import
7✔
2
import unittest
7✔
3

4
import numpy as np
7✔
5

6
from openmdao.api import Problem, Group, pyOptSparseDriver
7✔
7
from openmdao.utils.assert_utils import assert_near_equal
7✔
8
from openmdao.utils.testing_utils import use_tempdirs, require_pyoptsparse
7✔
9

10
import dymos as dm
7✔
11
from dymos import Trajectory, GaussLobatto, Phase, Radau, ExplicitShooting, PicardShooting
7✔
12
from dymos.examples.hull_problem.hull_ode import HullProblemODE
7✔
13

14
c = 5
7✔
15

16

17
@use_tempdirs
7✔
18
class TestHull(unittest.TestCase):
7✔
19

20
    @staticmethod
7✔
21
    @require_pyoptsparse(optimizer='IPOPT')
7✔
22
    def make_problem(transcription, control_cnty=True,
7✔
23
                     control_rate_cnty=True, control_rate2_cnty=False):
24
        p = Problem(model=Group())
4✔
25
        p.driver = pyOptSparseDriver()
4✔
26
        p.driver.declare_coloring()
4✔
27
        p.driver.options['optimizer'] = 'IPOPT'
4✔
28
        p.driver.opt_settings['hessian_approximation'] = 'limited-memory'
4✔
29
        p.driver.opt_settings['print_level'] = 0
4✔
30
        p.driver.opt_settings['tol'] = 1.0E-6
4✔
31
        p.driver.opt_settings['linear_solver'] = 'mumps'
4✔
32
        p.driver.declare_coloring()
4✔
33

34
        traj = p.model.add_subsystem('traj', Trajectory())
4✔
35
        phase0 = traj.add_phase('phase', Phase(ode_class=HullProblemODE,
4✔
36
                                               transcription=transcription))
37
        phase0.set_time_options(fix_initial=True, fix_duration=True)
4✔
38
        phase0.add_state('x', fix_initial=True, fix_final=False, rate_source='u')
4✔
39
        phase0.add_state('xL', fix_initial=True, fix_final=False, rate_source='L')
4✔
40
        phase0.add_control('u', opt=True, targets=['u'],
4✔
41
                           continuity=control_cnty,
42
                           rate_continuity=control_rate_cnty,
43
                           rate2_continuity=control_rate2_cnty)
44

45
        phase0.add_objective(f'J = {c}*x**2/2 + xL')
4✔
46

47
        p.setup(check=True)
4✔
48

49
        phase0.set_state_val('x', [1.5, 1])
4✔
50
        phase0.set_state_val('xL', [0, 1])
4✔
51
        phase0.set_time_val(initial=0.0, duration=10.0)
4✔
52
        phase0.set_control_val('u', [-7, -0.14])
4✔
53
        return p
4✔
54

55
    @staticmethod
7✔
56
    def solution(x0, td):
7✔
57

58
        xf = x0 - c * x0 * td / (1 + c * td)
4✔
59
        uf = -c * x0 / (1 + c * td)
4✔
60

61
        return xf, uf
4✔
62

63
    def test_hull_gauss_lobatto(self):
7✔
64
        p = self.make_problem(transcription=GaussLobatto(num_segments=30, order=3))
7✔
65
        dm.run_problem(p, simulate=True)
4✔
66

67
        xf, uf = self.solution(1.5, 10)
4✔
68

69
        assert_near_equal(p.get_val('traj.phase.timeseries.x')[-1],
4✔
70
                          xf,
71
                          tolerance=1e-4)
72

73
        assert_near_equal(p.get_val('traj.phase.timeseries.u')[-1],
4✔
74
                          uf,
75
                          tolerance=1e-4)
76

77
    def test_hull_radau(self):
7✔
78
        p = self.make_problem(transcription=Radau(num_segments=30, order=3))
7✔
79
        dm.run_problem(p, simulate=True)
4✔
80

81
        xf, uf = self.solution(1.5, 10)
4✔
82

83
        assert_near_equal(p.get_val('traj.phase.timeseries.x')[-1],
4✔
84
                          xf,
85
                          tolerance=1e-4)
86

87
        assert_near_equal(p.get_val('traj.phase.timeseries.u')[-1],
4✔
88
                          uf,
89
                          tolerance=1e-4)
90

91
    def test_hull_shooting(self):
7✔
92
        p = self.make_problem(transcription=ExplicitShooting(num_segments=30, order=3))
7✔
93
        dm.run_problem(p, simulate=True)
4✔
94

95
        xf, uf = self.solution(1.5, 10)
4✔
96

97
        assert_near_equal(p.get_val('traj.phase.timeseries.x')[-1],
4✔
98
                          xf,
99
                          tolerance=1e-4)
100

101
        assert_near_equal(p.get_val('traj.phase.timeseries.u')[-1],
4✔
102
                          uf,
103
                          tolerance=1e-4)
104

105
    def test_hull_picard(self):
7✔
106
        p = self.make_problem(transcription=PicardShooting(num_segments=3, nodes_per_seg=11),
7✔
107
                              control_cnty=True,
108
                              control_rate_cnty=True,
109
                              control_rate2_cnty=False)
110
        dm.run_problem(p, run_driver=True, simulate=True)
4✔
111

112
        xf, uf = self.solution(1.5, 10)
4✔
113

114
        assert_near_equal(p.get_val('traj.phase.timeseries.x')[-1],
4✔
115
                          xf,
116
                          tolerance=1e-4)
117

118
        assert_near_equal(p.get_val('traj.phase.timeseries.u')[-1],
4✔
119
                          uf,
120
                          tolerance=1e-4)
121

122
        assert_near_equal(p.get_val('traj.phase.continuity_comp.defect_controls:u'), np.zeros((2, 1)), tolerance=1.0E-4)
4✔
123
        assert_near_equal(p.get_val('traj.phase.continuity_comp.defect_control_rates:u_rate'), np.zeros((2, 1)), tolerance=1.0E-4)
4✔
124

125

126
if __name__ == '__main__':
7✔
NEW
127
    unittest.main()
×
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc