Ejemplo n.º 1
0
    def test_hadamard_accuracy(self):
        systemsize = 4
        eigen_decayrate = 2.0

        # Create Hadmard Quadratic object
        QoI = examples.HadamardQuadratic(systemsize, eigen_decayrate)

        mu = np.zeros(systemsize)
        std_dev = np.eye(systemsize)
        jdist = cp.MvNormal(mu, std_dev)

        active_subspace = ActiveSubspace(QoI, n_dominant_dimensions=4,
                                             n_monte_carlo_samples=10000,
                                             use_svd=True, read_rv_samples=False,
                                             write_rv_samples=False)
        active_subspace.getDominantDirections(QoI, jdist)

        mu_j_analytical = QoI.eval_analytical_QoI_mean(mu, cp.Cov(jdist))
        var_j_analytical = QoI.eval_analytical_QoI_variance(mu, cp.Cov(jdist))

        # Create reduced collocation object
        QoI_dict = {'Hadamard' : {'QoI_func' : QoI.eval_QoI,
                                  'output_dimensions' : 1,
                                  },
                    }
        sc_obj_active = StochasticCollocation2(jdist, 4, 'MvNormal', QoI_dict,
                                        include_derivs=False,
                                        reduced_collocation=True,
                                        dominant_dir=active_subspace.dominant_dir)
        sc_obj_active.evaluateQoIs(jdist)

        mu_j_active = sc_obj_active.mean(of=['Hadamard'])
        var_j_active = sc_obj_active.variance(of=['Hadamard'])
Ejemplo n.º 2
0
    def test_on_exponential(self):
        systemsize = 2
        QoI = examples.Exp_07xp03y(systemsize)

        jdist = cp.J(cp.Uniform(-1,1),
                     cp.Uniform(-1,1))

        active_subspace = ActiveSubspace(QoI, n_dominant_dimensions=1, n_monte_carlo_samples=10000)
        active_subspace.getDominantDirections(QoI, jdist)

        expected_W1 = QoI.a / np.linalg.norm(QoI.a)
        np.testing.assert_almost_equal(active_subspace.dominant_dir[:,0], expected_W1)
Ejemplo n.º 3
0
    def test_SVD_equivalence(self):
        systemsize = 4
        eigen_decayrate = 2.0

        # Create Hadmard Quadratic object
        QoI = examples.HadamardQuadratic(systemsize, eigen_decayrate)

        # Create the joint distribution
        jdist = cp.J(cp.Uniform(-1,1),
                     cp.Uniform(-1,1),
                     cp.Uniform(-1,1),
                     cp.Uniform(-1,1))

        active_subspace_eigen = ActiveSubspace(QoI, n_dominant_dimensions=1,
                                               n_monte_carlo_samples=10000,
                                               use_svd=False, read_rv_samples=False,
                                               write_rv_samples=True)
        active_subspace_eigen.getDominantDirections(QoI, jdist)

        active_subspace_svd = ActiveSubspace(QoI, n_dominant_dimensions=1,
                                             n_monte_carlo_samples=10000,
                                             use_svd=True, read_rv_samples=True,
                                             write_rv_samples=False)
        active_subspace_svd.getDominantDirections(QoI, jdist)

        # Check the iso_eigenvals
        np.testing.assert_almost_equal(active_subspace_eigen.iso_eigenvals, active_subspace_svd.iso_eigenvals)
        # check the iso_eigenvecs
        self.assertTrue(active_subspace_eigen.iso_eigenvecs.shape, active_subspace_svd.iso_eigenvecs.shape)
        for i in range(active_subspace_eigen.iso_eigenvecs.shape[1]):
            arr1 = active_subspace_eigen.iso_eigenvecs[:,i]
            arr2 = active_subspace_svd.iso_eigenvecs[:,i]
            if np.allclose(arr1, arr2) == False:
                np.testing.assert_almost_equal(arr1, -arr2)
Ejemplo n.º 4
0
    def test_on_Hadamard_Quadratic(self):
        systemsize = 4
        eigen_decayrate = 2.0

        # Create Hadmard Quadratic object
        QoI = examples.HadamardQuadratic(systemsize, eigen_decayrate)

        # Create the joint distribution
        jdist = cp.J(cp.Uniform(-1,1),
                     cp.Uniform(-1,1),
                     cp.Uniform(-1,1),
                     cp.Uniform(-1,1))

        # Create the active subspace object
        active_subspace = ActiveSubspace(QoI, n_dominant_dimensions=2, n_monte_carlo_samples=100000)
        active_subspace.getDominantDirections(QoI, jdist)

        # Expected C
        Hessian = QoI.eval_QoIHessian(np.zeros(systemsize), np.zeros(systemsize))
        C = np.matmul(Hessian, Hessian) / 3
        err = C - active_subspace.C_tilde
        self.assertTrue((abs(err) < 1.e-2).all())
Ejemplo n.º 5
0
    1.e-4,
    'correlation function':
    'squar_exp',
}
surrogate_QoI = InterceptorSurrogateQoI(systemsize, surrogate_input_dict)

# Get the dominant directions
dominant_space = DimensionReduction(n_arnoldi_sample=systemsize + 1,
                                    exact_Hessian=False,
                                    sample_radius=1.e-1)
dominant_space.getDominantDirections(surrogate_QoI, jdist, max_eigenmodes=10)

# Get the Active Subspace
active_subspace = ActiveSubspace(surrogate_QoI,
                                 n_dominant_dimensions=20,
                                 n_monte_carlo_samples=1000,
                                 read_rv_samples=False,
                                 use_svd=True,
                                 use_iso_transformation=True)
active_subspace.getDominantDirections(surrogate_QoI, jdist)

# Now get the two angles
n_bases = 2
eigenvecs_dom = dominant_space.iso_eigenvecs[:, 0:n_bases]
eigenvecs_active = active_subspace.iso_eigenvecs[:, 0:n_bases]
angles_radians = utils.compute_subspace_angles(eigenvecs_dom, eigenvecs_active)
angles_degrees = np.degrees(angles_radians)
print(angles_degrees)
"""
# Finally plot
xvals = range(1, n_bases+1)
fname = "dominant_vs_active_angles.pdf"
    def __init__(self,
                 rv_dict,
                 design_point,
                 rdo_factor=2.0,
                 krylov_pert=1.e-1,
                 active_subspace=False,
                 max_eigenmodes=2,
                 n_as_samples=1000):

        self.rdo_factor = rdo_factor

        # Total number of nodes to use in the spanwise (num_y) and
        # chordwise (num_x) directions. Vary these to change the level of fidelity.
        num_y = 21
        num_x = 3
        mesh_dict = {
            'num_y': num_y,
            'num_x': num_x,
            'wing_type': 'rect',
            'symmetry': True,
            'span_cos_spacing': 0.5,
            'span': 3.11,
            'root_chord': 0.3,
        }

        self.uq_systemsize = len(rv_dict)

        dv_dict = {
            'n_twist_cp': 3,
            'n_thickness_cp': 3,
            'n_CM': 3,
            'n_thickness_intersects': 10,
            'n_constraints': 1 + 10 + 1 + 3 + 3,
            'ndv': 3 + 3 + 2,
            'mesh_dict': mesh_dict,
            'rv_dict': rv_dict
        }

        mu, std_dev = self.get_input_rv_statistics(rv_dict)
        self.jdist = cp.MvNormal(mu, std_dev)
        self.QoI = examples.oas_scaneagle2.OASScanEagleWrapper2(
            self.uq_systemsize, dv_dict)
        self.QoI.p['oas_scaneagle.wing.thickness_cp'] = design_point[
            'thickness_cp']
        self.QoI.p['oas_scaneagle.wing.twist_cp'] = design_point['twist_cp']
        self.QoI.p['oas_scaneagle.wing.sweep'] = design_point['sweep']
        self.QoI.p['oas_scaneagle.alpha'] = design_point['alpha']
        self.QoI.p.final_setup()

        # Figure out which dimension reduction technique to use
        start_time = time.time()
        if active_subspace == False:
            self.dominant_space = DimensionReduction(
                n_arnoldi_sample=self.uq_systemsize + 1,
                exact_Hessian=False,
                sample_radius=krylov_pert)
            self.dominant_space.getDominantDirections(
                self.QoI, self.jdist, max_eigenmodes=max_eigenmodes)
        else:
            self.dominant_space = ActiveSubspace(
                self.QoI,
                n_dominant_dimensions=max_eigenmodes,
                n_monte_carlo_samples=n_as_samples,
                read_rv_samples=False,
                use_svd=True,
                use_iso_transformation=True)
            self.dominant_space.getDominantDirections(self.QoI, self.jdist)
            # Reset the design point
            self.QoI.p['oas_scaneagle.wing.thickness_cp'] = design_point[
                'thickness_cp']
            self.QoI.p['oas_scaneagle.wing.twist_cp'] = design_point[
                'twist_cp']
            self.QoI.p['oas_scaneagle.wing.sweep'] = design_point['sweep']
            self.QoI.p['oas_scaneagle.alpha'] = design_point['alpha']
            self.QoI.p.final_setup()
            # Reset the random variables
            self.QoI.update_rv(mu)
        time_elapsed = time.time() - start_time
        print('time_elapsed =', time_elapsed)

        dfuelburn_dict = {
            'dv': {
                'dQoI_func': self.QoI.eval_ObjGradient_dv,
                'output_dimensions': dv_dict['ndv'],
            }
        }
        dcon_dict = {
            'dv': {
                'dQoI_func': self.QoI.eval_ConGradient_dv,
                'output_dimensions': dv_dict['ndv']
            }
        }
        dcon_failure_dict = {
            'dv': {
                'dQoI_func': self.QoI.eval_ConFailureGradient_dv,
                'output_dimensions': dv_dict['ndv'],
            }
        }
        self.QoI_dict = {
            'fuelburn': {
                'QoI_func': self.QoI.eval_QoI,
                'output_dimensions': 1,
                'deriv_dict': dfuelburn_dict
            },
            'constraints': {
                'QoI_func': self.QoI.eval_AllConstraintQoI,
                'output_dimensions': dv_dict['n_constraints'],
                'deriv_dict': dcon_dict
            },
            'con_failure': {
                'QoI_func': self.QoI.eval_confailureQoI,
                'output_dimensions': 1,
                'deriv_dict': dcon_failure_dict
            }
        }
class UQScanEagleOpt(object):
    """
    This class is the conduit for linking pyStatReduce and OpenAeroStruct with
    pyOptSparse.

    **Arguments**
    * `rv_dict` : The random variable dictionary which specifies the random variable,
                  its mean and standard deviation.
    * `design_point` : dictionary of the design variable values.
    * `rdo_factor` : robust design optimization factor, its a multiplier that gets
                     multiplied to the wuantity of interest. Currently a single
                     value is used across all QoIs.
    * `krylov_pert` : finite difference perturbation for the modified Arnoldi method.
    * `active_subspace` : Boolean for either using active subspace or Arnoldi
                          dimension reduction method.
    * `max_eigenmodes` : Maximum number of dominant directons expected from the user.
                         This is the maximum number dominant directions that will be used
                         in the subsequent stochastic collocation object.
    * `n_as_samples` : Number of monte carlo samples used by the active subspace
                       method. This is argument is only utilized if we are using
                       the active subspace method.
    """
    def __init__(self,
                 rv_dict,
                 design_point,
                 rdo_factor=2.0,
                 krylov_pert=1.e-1,
                 active_subspace=False,
                 max_eigenmodes=2,
                 n_as_samples=1000):

        self.rdo_factor = rdo_factor

        # Total number of nodes to use in the spanwise (num_y) and
        # chordwise (num_x) directions. Vary these to change the level of fidelity.
        num_y = 21
        num_x = 3
        mesh_dict = {
            'num_y': num_y,
            'num_x': num_x,
            'wing_type': 'rect',
            'symmetry': True,
            'span_cos_spacing': 0.5,
            'span': 3.11,
            'root_chord': 0.3,
        }

        self.uq_systemsize = len(rv_dict)

        dv_dict = {
            'n_twist_cp': 3,
            'n_thickness_cp': 3,
            'n_CM': 3,
            'n_thickness_intersects': 10,
            'n_constraints': 1 + 10 + 1 + 3 + 3,
            'ndv': 3 + 3 + 2,
            'mesh_dict': mesh_dict,
            'rv_dict': rv_dict
        }

        mu, std_dev = self.get_input_rv_statistics(rv_dict)
        self.jdist = cp.MvNormal(mu, std_dev)
        self.QoI = examples.oas_scaneagle2.OASScanEagleWrapper2(
            self.uq_systemsize, dv_dict)
        self.QoI.p['oas_scaneagle.wing.thickness_cp'] = design_point[
            'thickness_cp']
        self.QoI.p['oas_scaneagle.wing.twist_cp'] = design_point['twist_cp']
        self.QoI.p['oas_scaneagle.wing.sweep'] = design_point['sweep']
        self.QoI.p['oas_scaneagle.alpha'] = design_point['alpha']
        self.QoI.p.final_setup()

        # Figure out which dimension reduction technique to use
        start_time = time.time()
        if active_subspace == False:
            self.dominant_space = DimensionReduction(
                n_arnoldi_sample=self.uq_systemsize + 1,
                exact_Hessian=False,
                sample_radius=krylov_pert)
            self.dominant_space.getDominantDirections(
                self.QoI, self.jdist, max_eigenmodes=max_eigenmodes)
        else:
            self.dominant_space = ActiveSubspace(
                self.QoI,
                n_dominant_dimensions=max_eigenmodes,
                n_monte_carlo_samples=n_as_samples,
                read_rv_samples=False,
                use_svd=True,
                use_iso_transformation=True)
            self.dominant_space.getDominantDirections(self.QoI, self.jdist)
            # Reset the design point
            self.QoI.p['oas_scaneagle.wing.thickness_cp'] = design_point[
                'thickness_cp']
            self.QoI.p['oas_scaneagle.wing.twist_cp'] = design_point[
                'twist_cp']
            self.QoI.p['oas_scaneagle.wing.sweep'] = design_point['sweep']
            self.QoI.p['oas_scaneagle.alpha'] = design_point['alpha']
            self.QoI.p.final_setup()
            # Reset the random variables
            self.QoI.update_rv(mu)
        time_elapsed = time.time() - start_time
        print('time_elapsed =', time_elapsed)

        dfuelburn_dict = {
            'dv': {
                'dQoI_func': self.QoI.eval_ObjGradient_dv,
                'output_dimensions': dv_dict['ndv'],
            }
        }
        dcon_dict = {
            'dv': {
                'dQoI_func': self.QoI.eval_ConGradient_dv,
                'output_dimensions': dv_dict['ndv']
            }
        }
        dcon_failure_dict = {
            'dv': {
                'dQoI_func': self.QoI.eval_ConFailureGradient_dv,
                'output_dimensions': dv_dict['ndv'],
            }
        }
        self.QoI_dict = {
            'fuelburn': {
                'QoI_func': self.QoI.eval_QoI,
                'output_dimensions': 1,
                'deriv_dict': dfuelburn_dict
            },
            'constraints': {
                'QoI_func': self.QoI.eval_AllConstraintQoI,
                'output_dimensions': dv_dict['n_constraints'],
                'deriv_dict': dcon_dict
            },
            'con_failure': {
                'QoI_func': self.QoI.eval_confailureQoI,
                'output_dimensions': 1,
                'deriv_dict': dcon_failure_dict
            }
        }

    def get_input_rv_statistics(self, rv_dict):
        mu, std_dev = utils.get_scaneagle_input_rv_statistics(rv_dict)
        return mu, std_dev
    start_time = time.time()
    sample_radius = 1.e-1
    dominant_space = DimensionReduction(n_arnoldi_sample=int(sys.argv[1]),
                                        exact_Hessian=False,
                                        sample_radius=sample_radius)
    dominant_space.getDominantDirections(dymos_obj, jdist, max_eigenmodes=11)
    # end_time = time.time()
    time_elapsed = time.time() - start_time
    print('eigenvals = ', repr(dominant_space.iso_eigenvals))
    # print('eigenvecs = \n', repr(dominant_space.iso_eigenvecs))
    print('time elapsed = ', time_elapsed)

    # Save to file:
    if sample_radius == 1.e-1:
        fname = fname = os.environ['HOME'] + '/UserApps/pyStatReduce/pystatreduce/optimize/dymos_interceptor/eigenmodes/eigenmodes_' + sys.argv[1] + '_samples'
    elif sample_radius == 1.e-2:
        fname = os.environ['HOME'] + '/UserApps/pyStatReduce/pystatreduce/optimize/dymos_interceptor/eigenmodes/eigenmodes_' + sys.argv[1] + '_samples_1e_2'
    else:
        raise NotImplementedError
    # np.savez(fname, eigenvals=dominant_space.iso_eigenvals, eigenvecs=dominant_space.iso_eigenvecs)
elif use_active_subspace == True:
    dominant_space = ActiveSubspace(dymos_obj,
                                    n_dominant_dimensions=20,
                                    n_monte_carlo_samples=1000,
                                    read_rv_samples=False,
                                    use_svd=True,
                                    use_iso_transformation=True)
    dominant_space.getDominantDirections(dymos_obj, jdist)
    fname = os.environ['HOME'] + '/UserApps/pyStatReduce/pystatreduce/optimize/dymos_interceptor/eigenmodes/eigenmodes_1000_samples_active_subspace'
    np.savez(fname, eigenvals=dominant_space.iso_eigenvals, eigenvecs=dominant_space.iso_eigenvecs)