xref: /petsc/src/binding/petsc4py/test/test_tao.py (revision 49b2cd1696dbe4d1f2d7cdc30bc4757c93f0411c)
15808f684SSatish Balay# --------------------------------------------------------------------
25808f684SSatish Balay
3*49b2cd16SPaul T. Kühnerfrom math import sqrt
45808f684SSatish Balayfrom petsc4py import PETSc
55808f684SSatish Balayimport unittest
66f336411SStefano Zampiniimport numpy
76f336411SStefano Zampini
85808f684SSatish Balay
95808f684SSatish Balay# --------------------------------------------------------------------
105971bccaSStefano Zampiniclass Objective:
115971bccaSStefano Zampini    def __call__(self, tao, x):
125971bccaSStefano Zampini        return (x[0] - 2.0) ** 2 + (x[1] - 2.0) ** 2 - 2.0 * (x[0] + x[1])
135971bccaSStefano Zampini
146f336411SStefano Zampini
155971bccaSStefano Zampiniclass Gradient:
165971bccaSStefano Zampini    def __call__(self, tao, x, g):
175971bccaSStefano Zampini        g[0] = 2.0 * (x[0] - 2.0) - 2.0
185971bccaSStefano Zampini        g[1] = 2.0 * (x[1] - 2.0) - 2.0
195971bccaSStefano Zampini        g.assemble()
205971bccaSStefano Zampini
216f336411SStefano Zampini
225971bccaSStefano Zampiniclass EqConstraints:
235971bccaSStefano Zampini    def __call__(self, tao, x, c):
245971bccaSStefano Zampini        c[0] = x[0] ** 2 + x[1] - 2.0
255971bccaSStefano Zampini        c.assemble()
265971bccaSStefano Zampini
276f336411SStefano Zampini
285971bccaSStefano Zampiniclass EqJacobian:
295971bccaSStefano Zampini    def __call__(self, tao, x, J, P):
305971bccaSStefano Zampini        P[0, 0] = 2.0 * x[0]
315971bccaSStefano Zampini        P[0, 1] = 1.0
325971bccaSStefano Zampini        P.assemble()
336f336411SStefano Zampini        if J != P:
346f336411SStefano Zampini            J.assemble()
355808f684SSatish Balay
365808f684SSatish Balay
372944e117SPaul T. Kühnerclass InEqConstraints:
382944e117SPaul T. Kühner    def __call__(self, tao, x, c):
392944e117SPaul T. Kühner        c[0] = x[1] - x[0] ** 2
402944e117SPaul T. Kühner        c.assemble()
412944e117SPaul T. Kühner
422944e117SPaul T. Kühner
432944e117SPaul T. Kühnerclass InEqJacobian:
442944e117SPaul T. Kühner    def __call__(self, tao, x, J, P):
452944e117SPaul T. Kühner        P[0, 0] = -2.0 * x[0]
462944e117SPaul T. Kühner        P[0, 1] = 1.0
472944e117SPaul T. Kühner        P.assemble()
482944e117SPaul T. Kühner        if J != P:
492944e117SPaul T. Kühner            J.assemble()
502944e117SPaul T. Kühner
512944e117SPaul T. Kühner
526f336411SStefano Zampiniclass BaseTestTAO:
535808f684SSatish Balay    COMM = None
545808f684SSatish Balay
555808f684SSatish Balay    def setUp(self):
565808f684SSatish Balay        self.tao = PETSc.TAO().create(comm=self.COMM)
575808f684SSatish Balay
585808f684SSatish Balay    def tearDown(self):
595808f684SSatish Balay        self.tao = None
6062e5d2d2SJDBetteridge        PETSc.garbage_cleanup()
615808f684SSatish Balay
625808f684SSatish Balay    def testSetRoutinesToNone(self):
635808f684SSatish Balay        tao = self.tao
645808f684SSatish Balay        objective, gradient, objgrad = None, None, None
655808f684SSatish Balay        constraint, varbounds = None, None
665808f684SSatish Balay        hessian, jacobian = None, None
675808f684SSatish Balay        tao.setObjective(objective)
68a82e8c82SStefano Zampini        tao.setGradient(gradient, None)
695808f684SSatish Balay        tao.setVariableBounds(varbounds)
70a82e8c82SStefano Zampini        tao.setObjectiveGradient(objgrad, None)
715808f684SSatish Balay        tao.setConstraints(constraint)
725808f684SSatish Balay        tao.setHessian(hessian)
735808f684SSatish Balay        tao.setJacobian(jacobian)
745808f684SSatish Balay
755808f684SSatish Balay    def testGetVecsAndMats(self):
765808f684SSatish Balay        tao = self.tao
775808f684SSatish Balay        x = tao.getSolution()
78a82e8c82SStefano Zampini        (g, _) = tao.getGradient()
796f336411SStefano Zampini        low, up = tao.getVariableBounds()
805808f684SSatish Balay        r = None  # tao.getConstraintVec()
815808f684SSatish Balay        H, HP = None, None  # tao.getHessianMat()
825808f684SSatish Balay        J, JP = None, None  # tao.getJacobianMat()
836f336411SStefano Zampini        for o in [
846f336411SStefano Zampini            x,
856f336411SStefano Zampini            g,
866f336411SStefano Zampini            r,
876f336411SStefano Zampini            low,
886f336411SStefano Zampini            up,
896f336411SStefano Zampini            H,
906f336411SStefano Zampini            HP,
916f336411SStefano Zampini            J,
926f336411SStefano Zampini            JP,
936f336411SStefano Zampini        ]:
945808f684SSatish Balay            self.assertFalse(o)
955808f684SSatish Balay
965808f684SSatish Balay    def testGetKSP(self):
975808f684SSatish Balay        ksp = self.tao.getKSP()
985808f684SSatish Balay        self.assertFalse(ksp)
995808f684SSatish Balay
1005971bccaSStefano Zampini    def testEqualityConstraints(self):
1015971bccaSStefano Zampini        if self.tao.getComm().Get_size() > 1:
1025971bccaSStefano Zampini            return
1035971bccaSStefano Zampini        tao = self.tao
1045971bccaSStefano Zampini
1055971bccaSStefano Zampini        x = PETSc.Vec().create(tao.getComm())
1065971bccaSStefano Zampini        x.setType('standard')
1075971bccaSStefano Zampini        x.setSizes(2)
1085971bccaSStefano Zampini        c = PETSc.Vec().create(tao.getComm())
1095971bccaSStefano Zampini        c.setSizes(1)
1105971bccaSStefano Zampini        c.setType(x.getType())
1115971bccaSStefano Zampini        J = PETSc.Mat().create(tao.getComm())
1125971bccaSStefano Zampini        J.setSizes([1, 2])
1135971bccaSStefano Zampini        J.setType(PETSc.Mat.Type.DENSE)
1145971bccaSStefano Zampini        J.setUp()
1155971bccaSStefano Zampini
1165971bccaSStefano Zampini        tao.setObjective(Objective())
117a82e8c82SStefano Zampini        tao.setGradient(Gradient(), None)
1185971bccaSStefano Zampini        tao.setEqualityConstraints(EqConstraints(), c)
1195971bccaSStefano Zampini        tao.setJacobianEquality(EqJacobian(), J, J)
120a82e8c82SStefano Zampini        tao.setSolution(x)
1215971bccaSStefano Zampini        tao.setType(PETSc.TAO.Type.ALMM)
122*49b2cd16SPaul T. Kühner        tao.setALMMType(PETSc.TAO.ALMMType.PHR)
1236f336411SStefano Zampini        tao.setTolerances(gatol=1.0e-4)
1245971bccaSStefano Zampini        tao.setFromOptions()
1255971bccaSStefano Zampini        tao.solve()
126*49b2cd16SPaul T. Kühner        self.assertTrue(tao.getALMMType() == PETSc.TAO.ALMMType.PHR)
1275971bccaSStefano Zampini        self.assertAlmostEqual(abs(x[0] ** 2 + x[1] - 2.0), 0.0, places=4)
128*49b2cd16SPaul T. Kühner        self.assertAlmostEqual(x[0], 0.7351392590499015014254200465, places=4)
129*49b2cd16SPaul T. Kühner        self.assertAlmostEqual(x[1], 1.4595702698035618134357683666, places=4)
1305971bccaSStefano Zampini
1312944e117SPaul T. Kühner    def testInequlityConstraints(self):
1322944e117SPaul T. Kühner        if self.tao.getComm().Get_size() > 1:
1332944e117SPaul T. Kühner            return
1342944e117SPaul T. Kühner        tao = self.tao
1352944e117SPaul T. Kühner
1362944e117SPaul T. Kühner        x = PETSc.Vec().create(tao.getComm())
1372944e117SPaul T. Kühner        x.setType('standard')
1382944e117SPaul T. Kühner        x.setSizes(2)
1392944e117SPaul T. Kühner        c = PETSc.Vec().create(tao.getComm())
1402944e117SPaul T. Kühner        c.setSizes(1)
1412944e117SPaul T. Kühner        c.setType(x.getType())
1422944e117SPaul T. Kühner        J = PETSc.Mat().create(tao.getComm())
1432944e117SPaul T. Kühner        J.setSizes([1, 2])
1442944e117SPaul T. Kühner        J.setType(PETSc.Mat.Type.DENSE)
1452944e117SPaul T. Kühner        J.setUp()
1462944e117SPaul T. Kühner
1472944e117SPaul T. Kühner        tao.setObjective(Objective())
1482944e117SPaul T. Kühner        tao.setGradient(Gradient(), None)
1492944e117SPaul T. Kühner        tao.setInequalityConstraints(InEqConstraints(), c)
1502944e117SPaul T. Kühner        tao.setJacobianInequality(InEqJacobian(), J, J)
1512944e117SPaul T. Kühner        tao.setSolution(x)
1522944e117SPaul T. Kühner        tao.setType(PETSc.TAO.Type.ALMM)
153*49b2cd16SPaul T. Kühner        tao.setALMMType(PETSc.TAO.ALMMType.CLASSIC)
1542944e117SPaul T. Kühner        tao.setTolerances(gatol=1.0e-4)
1552944e117SPaul T. Kühner        tao.setFromOptions()
1562944e117SPaul T. Kühner        tao.solve()
157*49b2cd16SPaul T. Kühner
158*49b2cd16SPaul T. Kühner        self.assertTrue(tao.getALMMType() == PETSc.TAO.ALMMType.CLASSIC)
1592944e117SPaul T. Kühner        self.assertTrue(x[1] - x[0] ** 2 >= -1.0e-4)
160*49b2cd16SPaul T. Kühner        self.assertAlmostEqual(x[0], 0.5 + sqrt(7) / 2, places=4)
161*49b2cd16SPaul T. Kühner        self.assertAlmostEqual(x[1], 2 + sqrt(7) / 2, places=4)
1622944e117SPaul T. Kühner
163d6e07cdcSHong Zhang    def testBNCG(self):
164d6e07cdcSHong Zhang        if self.tao.getComm().Get_size() > 1:
165d6e07cdcSHong Zhang            return
166d6e07cdcSHong Zhang        tao = self.tao
167d6e07cdcSHong Zhang
168d6e07cdcSHong Zhang        x = PETSc.Vec().create(tao.getComm())
169d6e07cdcSHong Zhang        x.setType('standard')
170d6e07cdcSHong Zhang        x.setSizes(2)
171d6e07cdcSHong Zhang        xl = PETSc.Vec().create(tao.getComm())
172d6e07cdcSHong Zhang        xl.setType('standard')
173d6e07cdcSHong Zhang        xl.setSizes(2)
174d6e07cdcSHong Zhang        xl.set(0.0)
175d6e07cdcSHong Zhang        xu = PETSc.Vec().create(tao.getComm())
176d6e07cdcSHong Zhang        xu.setType('standard')
177d6e07cdcSHong Zhang        xu.setSizes(2)
178d6e07cdcSHong Zhang        xu.set(2.0)
179d6e07cdcSHong Zhang        tao.setVariableBounds((xl, xu))
180d6e07cdcSHong Zhang        tao.setObjective(Objective())
181d6e07cdcSHong Zhang        tao.setGradient(Gradient(), None)
182d6e07cdcSHong Zhang        tao.setSolution(x)
183d6e07cdcSHong Zhang        tao.setType(PETSc.TAO.Type.BNCG)
1846f336411SStefano Zampini        tao.setTolerances(gatol=1.0e-4)
185d6e07cdcSHong Zhang        ls = tao.getLineSearch()
186d6e07cdcSHong Zhang        ls.setType(PETSc.TAOLineSearch.Type.UNIT)
187d6e07cdcSHong Zhang        tao.setFromOptions()
188d6e07cdcSHong Zhang        tao.solve()
189d6e07cdcSHong Zhang        self.assertAlmostEqual(x[0], 2.0, places=4)
190d6e07cdcSHong Zhang        self.assertAlmostEqual(x[1], 2.0, places=4)
191d6e07cdcSHong Zhang
1926f336411SStefano Zampini
1935808f684SSatish Balay# --------------------------------------------------------------------
1945808f684SSatish Balay
1956f336411SStefano Zampini
1965808f684SSatish Balayclass TestTAOSelf(BaseTestTAO, unittest.TestCase):
1975808f684SSatish Balay    COMM = PETSc.COMM_SELF
1985808f684SSatish Balay
1996f336411SStefano Zampini
2005808f684SSatish Balayclass TestTAOWorld(BaseTestTAO, unittest.TestCase):
2015808f684SSatish Balay    COMM = PETSc.COMM_WORLD
2025808f684SSatish Balay
2036f336411SStefano Zampini
2045808f684SSatish Balay# --------------------------------------------------------------------
2055808f684SSatish Balay
2066f336411SStefano Zampini
2075808f684SSatish Balayif numpy.iscomplexobj(PETSc.ScalarType()):
2085808f684SSatish Balay    del BaseTestTAO
2095808f684SSatish Balay    del TestTAOSelf
2105808f684SSatish Balay    del TestTAOWorld
2115808f684SSatish Balay
2125808f684SSatish Balayif __name__ == '__main__':
2135808f684SSatish Balay    unittest.main()
214