Beispiel #1
0
class TestAdjoint(reg_test_classes.RegTest):
    """
    Tests that sensitives calculated from solving an adjoint are correct.
    and jacobian vector products are accurate.

    based on old regression tests 12, and 14
    """

    N_PROCS = 2

    options = None
    ap = None
    ref_file = None

    def setUp(self):
        if not hasattr(self, "name"):
            # return immediately when the setup method is being called on the based class and NOT the
            # classes created using parametrized
            # this will happen when training, but will hopefully be fixed down the line
            return

        super().setUp()

        options = copy.copy(adflowDefOpts)
        options["outputdirectory"] = os.path.join(baseDir, options["outputdirectory"])
        options.update(self.options)

        self.ffdFile = os.path.join(baseDir, "../../input_files/mdo_tutorial_ffd.fmt")

        mesh_options = copy.copy(IDWarpDefOpts)
        mesh_options.update({"gridFile": options["gridfile"]})

        self.ap = copy.deepcopy(self.aero_prob)

        # Setup aeroproblem
        self.ap.evalFuncs = self.evalFuncs

        # add the default dvs to the problem
        for dv in defaultAeroDVs:
            self.ap.addDV(dv)

        self.CFDSolver = ADFLOW(options=options, debug=True)

        self.CFDSolver.setMesh(USMesh(options=mesh_options))
        self.CFDSolver.setDVGeo(setDVGeo(self.ffdFile, cmplx=False))

        # propagates the values from the restart file throughout the code
        self.CFDSolver.getResidual(self.ap)

    def test_residuals(self):
        utils.assert_residuals_allclose(self.handler, self.CFDSolver, self.ap, tol=1e-10)

    def test_adjoint(self):
        utils.assert_adjoint_sens_allclose(self.handler, self.CFDSolver, self.ap, tol=1e-10)
        self.assert_adjoint_failure()
Beispiel #2
0
class TestJacVecFwd(reg_test_classes.RegTest):
    """
    Tests that given a flow state the FWD jacobian vector products are agree the privous values recorded in the ref file.
    """

    N_PROCS = 2

    def setUp(self):
        if not hasattr(self, "name"):
            # return immediately when the setup method is being called on the based class and NOT the
            # classes created using parametrized
            # this will happen when testing, but will hopefully be fixed down the line
            return

        super().setUp()

        options = copy.copy(adflowDefOpts)
        options["outputdirectory"] = os.path.join(baseDir,
                                                  options["outputdirectory"])
        options.update(self.options)

        # Create the solver
        self.CFDSolver = ADFLOW(options=copy.deepcopy(options), debug=True)

        self.ap = copy.deepcopy(self.aero_prob)
        # add the default dvs to the problem
        for dv in defaultAeroDVs:
            self.ap.addDV(dv)

        # propagates the values from the restart file throughout the code
        self.CFDSolver.getResidual(self.ap)

    # ------------------- Derivative routine checks ----------------------------
    def test_wDot(self):
        utils.assert_fwd_mode_wdot_allclose(self.handler,
                                            self.CFDSolver,
                                            self.ap,
                                            seed=314,
                                            tol=5e-9)

    def test_xVDot(self):
        utils.assert_fwd_mode_xVDot_allclose(self.handler,
                                             self.CFDSolver,
                                             self.ap,
                                             seed=314,
                                             tol=1e-10)

    def test_xDvDot(self):
        utils.assert_fwd_mode_xDvDot_allclose(self.handler,
                                              self.CFDSolver,
                                              self.ap,
                                              seed=1.0,
                                              tol=1e-10)
Beispiel #3
0
 def test_import(self):
     CFDSolver = ADFLOW(options=self.options, debug=False)
     res = CFDSolver.getResidual(ap_tutorial_wing)
     res_norm = np.linalg.norm(res)
     np.testing.assert_allclose(res_norm,
                                0.0,
                                atol=1e-11,
                                err_msg="residual")
Beispiel #4
0
 def test_import_block_splitting(self):
     self.options["partitionLikeNProc"] = 50
     CFDSolver = ADFLOW(options=self.options, debug=False)
     res = CFDSolver.getResidual(ap_tutorial_wing)
     res_norm = np.linalg.norm(res)
     np.testing.assert_allclose(res_norm,
                                0.0,
                                atol=1e-11,
                                err_msg="residual")
Beispiel #5
0
class TestSolveOverset(reg_test_classes.RegTest):
    """
    Tests that ADflow can converge the wing from the mdo tutorial using the euler
    equation to the required accuracy as meassure by the norm of the residuals,
    and states, and the accuracy of the functions

    based on the old regression test 17 and 18
    """

    N_PROCS = 2

    options = {
        "gridfile":
        os.path.join(baseDir, "../../input_files/conic_conv_nozzle.cgns"),
        "outputdirectory":
        os.path.join(baseDir, "../output_files"),
        # Physics Parameters
        "equationType":
        "Euler",
        "smoother":
        "DADI",
        "nsubiter":
        3,
        "CFL":
        4.0,
        "CFLCoarse":
        1.25,
        "MGCycle":
        "sg",
        "MGStartLevel":
        -1,
        "nCyclesCoarse":
        250,
        "nCycles":
        1000,
        "monitorvariables": ["cpu", "resrho", "cl", "cd"],
        "volumevariables": ["blank"],
        "surfacevariables": ["mach", "cp", "vx", "vy", "vz", "blank"],
        "useNKSolver":
        True,
        "nkswitchtol":
        0.01,
        "nkadpc":
        True,
        "nkjacobianlag":
        5,
        "nkouterpreconits":
        3,
        "nkinnerpreconits":
        2,
        # Convergence Parameters
        "L2Convergence":
        1e-10,
        "L2ConvergenceCoarse":
        1e-4,
        "adjointl2convergence":
        1e-6,
        "forcesAsTractions":
        True,
        "debugzipper":
        True,
        "nearwalldist":
        0.001,
        # 'nkls':'none',
        "solutionprecision":
        "double",
        "adjointsubspacesize":
        200,
        "outerpreconits":
        3,
        "zipperSurfaceFamily":
        "output_fam",
        "flowtype":
        "internal",
        "blocksplitting":
        True,
    }
    ap = copy.copy(ap_conic_conv_nozzle)
    ref_file = "solve_conic_overset.json"

    def setUp(self):
        super().setUp()

        options = copy.copy(adflowDefOpts)
        options.update(self.options)

        # Setup aeroproblem

        self.ap.setBCVar("Pressure", 79326.7, "downstream")
        self.ap.addDV("Pressure", family="downstream")

        self.ap.setBCVar("PressureStagnation", 100000.0, "upstream")
        self.ap.addDV("PressureStagnation", family="upstream")

        self.ap.setBCVar("TemperatureStagnation", 500.0, "upstream")
        self.ap.addDV("TemperatureStagnation", family="upstream")

        # Create the solver
        self.CFDSolver = ADFLOW(options=options, debug=False)

        self.CFDSolver.addFamilyGroup("upstream", ["inlet"])
        self.CFDSolver.addFamilyGroup("downstream", ["outlet"])
        self.CFDSolver.addFamilyGroup("all_flow", ["inlet", "outlet"])
        self.CFDSolver.addFamilyGroup("output_fam", ["all_flow", "allWalls"])

        self.CFDSolver.addFunction("mdot", "upstream", name="mdot_up")
        self.CFDSolver.addFunction("mdot", "downstream", name="mdot_down")

        self.CFDSolver.addFunction("mavgptot",
                                   "downstream",
                                   name="mavgptot_down")
        self.CFDSolver.addFunction("mavgptot", "upstream", name="mavgptot_up")

        self.CFDSolver.addFunction("aavgptot",
                                   "downstream",
                                   name="aavgptot_down")
        self.CFDSolver.addFunction("aavgptot", "upstream", name="aavgptot_up")

        self.CFDSolver.addFunction("mavgttot",
                                   "downstream",
                                   name="mavgttot_down")
        self.CFDSolver.addFunction("mavgttot", "upstream", name="mavgttot_up")

        self.CFDSolver.addFunction("mavgps", "downstream", name="mavgps_down")
        self.CFDSolver.addFunction("mavgps", "upstream", name="mavgps_up")

        self.CFDSolver.addFunction("aavgps", "downstream", name="aavgps_down")
        self.CFDSolver.addFunction("aavgps", "upstream", name="aavgps_up")

    def test_solve(self):

        # do the solve
        self.CFDSolver(self.ap)

        # check its accuracy
        utils.assert_functions_allclose(self.handler,
                                        self.CFDSolver,
                                        self.ap,
                                        tol=1e-9)
        utils.assert_states_allclose(self.handler, self.CFDSolver, tol=1e-10)
        # Check the residual
        res = self.CFDSolver.getResidual(self.ap)
        totalR0 = self.CFDSolver.getFreeStreamResidual(self.ap)
        res /= totalR0

        reducedSum = self.CFDSolver.comm.reduce(np.sum(res**2))
        if self.CFDSolver.comm.rank == 0:
            self.assertLessEqual(np.sqrt(reducedSum),
                                 self.options["L2Convergence"])
Beispiel #6
0
class TestFunctionals(reg_test_classes.RegTest):
    """
    Tests that given a flow state the residuals, function, forces/tractions,
    and jacobian vector products are accurate.

    """

    N_PROCS = 2

    def setUp(self):
        if not hasattr(self, "name"):
            # return immediately when the setup method is being called on the based class and NOT the
            # classes created using parametrized
            # this will happen when testing, but will hopefully be fixed down the line
            return

        super().setUp()

        options = copy.copy(adflowDefOpts)
        options["outputdirectory"] = os.path.join(baseDir,
                                                  options["outputdirectory"])
        options.update(self.options)

        # Create the solver
        self.CFDSolver = ADFLOW(options=copy.deepcopy(options), debug=True)

        self.ap = copy.deepcopy(self.aero_prob)
        # add the default dvs to the problem
        for dv in defaultAeroDVs:
            self.ap.addDV(dv)

        # propagates the values from the restart file throughout the code
        self.CFDSolver.getResidual(self.ap)

    def test_restart_read(self):
        utils.assert_problem_size_equal(self.handler,
                                        self.CFDSolver,
                                        tol=1e-10)
        utils.assert_states_allclose(self.handler, self.CFDSolver, tol=1e-10)

    def test_residuals(self):
        utils.assert_residuals_allclose(self.handler,
                                        self.CFDSolver,
                                        self.ap,
                                        tol=1e-10)

    def test_functions(self):
        utils.assert_functions_allclose(self.handler,
                                        self.CFDSolver,
                                        self.ap,
                                        tol=1e-9)

    def test_forces_and_tractions(self):
        utils.assert_forces_allclose(self.handler, self.CFDSolver, tol=1e-10)
        utils.assert_tractions_allclose(self.handler,
                                        self.CFDSolver,
                                        tol=1e-10)

        # Reset the option
        self.CFDSolver.setOption("forcesAsTractions", True)

        # Make sure we can write the force file.
        forces_file = os.path.join(self.CFDSolver.getOption("outputdirectory"),
                                   "forces.txt")
        self.CFDSolver.writeForceFile(forces_file)

    # ------------------- Derivative routine checks ----------------------------
    def test_jac_vec_prod_fwd(self):
        utils.assert_fwd_mode_allclose(self.handler,
                                       self.CFDSolver,
                                       self.ap,
                                       tol=5e-9)

    def test_jac_vec_prod_bwd(self):
        utils.assert_bwd_mode_allclose(self.handler,
                                       self.CFDSolver,
                                       self.ap,
                                       tol=1e-10)

    def test_dot_products(self):
        utils.assert_dot_products_allclose(self.handler,
                                           self.CFDSolver,
                                           tol=1e-10)
Beispiel #7
0
class TestJacVecBWDFast(reg_test_classes.RegTest):
    """
    Tests that given a flow state the state jacobian vector products are accurate.
    """

    N_PROCS = 2

    def setUp(self):
        if not hasattr(self, "name"):
            # return immediately when the setup method is being called on the based class and NOT the
            # classes created using parametrized
            # this will happen when testing, but will hopefully be fixed down the line
            return

        super().setUp()

        options = copy.copy(adflowDefOpts)
        options["outputdirectory"] = os.path.join(baseDir,
                                                  options["outputdirectory"])
        options.update(self.options)

        # Create the solver
        self.CFDSolver = ADFLOW(options=copy.deepcopy(options), debug=True)

        self.ap = copy.deepcopy(self.aero_prob)
        # add the default dvs to the problem
        for dv in defaultAeroDVs:
            self.ap.addDV(dv)

        # propagates the values from the restart file throughout the code
        self.CFDSolver.getResidual(self.ap)

    # ------------------- Derivative routine checks ----------------------------
    def test_BWD(self):
        #

        dwBar = self.CFDSolver.getStatePerturbation(314)

        wBar = self.CFDSolver.computeJacobianVectorProductBwd(
            resBar=dwBar,
            wDeriv=True,
        )

        wBarfast = self.CFDSolver.computeJacobianVectorProductBwdFast(
            resBar=dwBar)

        np.testing.assert_allclose(wBar,
                                   wBarfast,
                                   atol=1e-16,
                                   err_msg="w wrt res")

    def test_repeated_calls(self):

        dwBar = self.CFDSolver.getStatePerturbation(314)

        wBarfast1 = self.CFDSolver.computeJacobianVectorProductBwdFast(
            resBar=dwBar)
        wBarfast2 = self.CFDSolver.computeJacobianVectorProductBwdFast(
            resBar=dwBar)

        np.testing.assert_allclose(wBarfast1,
                                   wBarfast2,
                                   atol=1e-16,
                                   err_msg="w wrt res double call")
Beispiel #8
0
class TestJacVecFwdFD(reg_test_classes.RegTest):
    """
    Tests that given a flow state the FWD jacobian vector products are agree with FD.
    """

    N_PROCS = 2

    def setUp(self):
        if not hasattr(self, "name"):
            # return immediately when the setup method is being called on the based class and NOT the
            # classes created using parametrized
            # this will happen when testing, but will hopefully be fixed down the line
            return

        super().setUp()

        options = copy.copy(adflowDefOpts)
        options["outputdirectory"] = os.path.join(baseDir,
                                                  options["outputdirectory"])
        options.update(self.options)

        # Create the solver
        self.CFDSolver = ADFLOW(options=copy.deepcopy(options), debug=True)

        self.ap = copy.deepcopy(self.aero_prob)
        # add the default dvs to the problem
        for dv in defaultAeroDVs:
            self.ap.addDV(dv)

        # propagates the values from the restart file throughout the code
        self.CFDSolver.getResidual(self.ap)

    # ------------------- Derivative routine checks ----------------------------
    def test_wDot(self):
        # perturb each input and check that the outputs match the FD to with in reason
        wDot = self.CFDSolver.getStatePerturbation(321)

        resDot, funcsDot, fDot = self.CFDSolver.computeJacobianVectorProductFwd(
            wDot=wDot, residualDeriv=True, funcDeriv=True, fDeriv=True)
        resDot_FD, funcsDot_FD, fDot_FD = self.CFDSolver.computeJacobianVectorProductFwd(
            wDot=wDot,
            residualDeriv=True,
            funcDeriv=True,
            fDeriv=True,
            mode="FD",
            h=1e-8)

        np.testing.assert_allclose(resDot_FD,
                                   resDot,
                                   rtol=8e-4,
                                   err_msg="residual")

        for func in funcsDot:
            np.testing.assert_allclose(funcsDot_FD[func],
                                       funcsDot[func],
                                       rtol=1e-5,
                                       err_msg=func)

        np.testing.assert_allclose(fDot_FD, fDot, rtol=5e-4, err_msg="forces")

    def test_xVDot(self):
        # perturb each input and check that the outputs match the FD to with in reason
        xVDot = self.CFDSolver.getSpatialPerturbation(314)

        resDot, funcsDot, fDot = self.CFDSolver.computeJacobianVectorProductFwd(
            xVDot=xVDot, residualDeriv=True, funcDeriv=True, fDeriv=True)

        resDot_FD, funcsDot_FD, fDot_FD = self.CFDSolver.computeJacobianVectorProductFwd(
            xVDot=xVDot,
            residualDeriv=True,
            funcDeriv=True,
            fDeriv=True,
            mode="FD",
            h=1e-8)

        idx_max = np.argmax((resDot_FD - resDot) / resDot)
        print(resDot[idx_max], resDot_FD[idx_max])

        np.testing.assert_allclose(resDot_FD,
                                   resDot,
                                   atol=5e-4,
                                   err_msg="residual")

        for func in funcsDot:
            np.testing.assert_allclose(funcsDot_FD[func],
                                       funcsDot[func],
                                       rtol=5e-6,
                                       err_msg=func)

        np.testing.assert_allclose(fDot_FD, fDot, rtol=5e-4, err_msg="forces")

    def test_xDvDot(self):
        # perturb each input and check that the outputs match the FD to with in reason
        step_size = {
            "alpha": 1e-4,
            "beta": 1e-5,
            "mach": 1e-5,
            "P": 1e-1,
            "T": 1e-4,
            "xRef": 1e-5,
            "yRef": 1e-5,
            "zRef": 1e-5,
        }

        for aeroDV in self.ap.DVs.values():
            key = aeroDV.key
            xDvDot = {key: 1.0}

            resDot, funcsDot, fDot = self.CFDSolver.computeJacobianVectorProductFwd(
                xDvDot=xDvDot, residualDeriv=True, funcDeriv=True, fDeriv=True)

            resDot_FD, funcsDot_FD, fDot_FD = self.CFDSolver.computeJacobianVectorProductFwd(
                xDvDot=xDvDot,
                residualDeriv=True,
                funcDeriv=True,
                fDeriv=True,
                mode="FD",
                h=step_size[key])

            # the tolerances here are loose becuase different ouputs have different optimal steps
            np.testing.assert_allclose(resDot_FD,
                                       resDot,
                                       atol=5e-5,
                                       err_msg=f"residual wrt {key}")

            for func in funcsDot:
                if np.abs(funcsDot[func]) <= 1e-16:
                    np.testing.assert_allclose(funcsDot_FD[func],
                                               funcsDot[func],
                                               atol=5e-5,
                                               err_msg=f"{func} wrt {key}")
                else:
                    np.testing.assert_allclose(funcsDot_FD[func],
                                               funcsDot[func],
                                               rtol=1e-3,
                                               err_msg=f"{func} wrt {key}")

            np.testing.assert_allclose(fDot_FD,
                                       fDot,
                                       atol=5e-7,
                                       err_msg=f"forces wrt {key}")