def test_generate(self): mu = Points() snap = Snapshots(output_name="Pressure", dformat="point") space = PODInterpolation() mu.append([-.5, -.5]) mu.append([.5, -.5]) mu.append([.5, .5]) mu.append([-.5, .5]) snap.append("tests/test_datasets/matlab_00.vtk") snap.append("tests/test_datasets/matlab_01.vtk") snap.append("tests/test_datasets/matlab_02.vtk") snap.append("tests/test_datasets/matlab_03.vtk") space.generate(mu, snap) assert space.pod_basis.shape == (2500, 4)
def test_interpolator(self): mu = Points() snap = Snapshots(output_name="Pressure", dformat="point") space = PODInterpolation() mu.append([-.5, -.5]) mu.append([.5, -.5]) mu.append([.5, .5]) mu.append([-.5, .5]) snap.append("tests/test_datasets/matlab_00.vtk") snap.append("tests/test_datasets/matlab_01.vtk") snap.append("tests/test_datasets/matlab_02.vtk") snap.append("tests/test_datasets/matlab_03.vtk") space.generate(mu, snap) assert isinstance(space.interpolator, LinearInterpolator)
def test_loo_error(self): mu = Points() snap = Snapshots(output_name="Pressure", dformat="point") space = PODInterpolation() mu.append([-.5, -.5]) mu.append([.5, -.5]) mu.append([.5, .5]) mu.append([-.5, .5]) snap.append("tests/test_datasets/matlab_00.vtk") snap.append("tests/test_datasets/matlab_01.vtk") snap.append("tests/test_datasets/matlab_02.vtk") snap.append("tests/test_datasets/matlab_03.vtk") error = space.loo_error(mu, snap) assert error.shape == (4, )
def test_loo_error2(self): mu = Points() snap = Snapshots(output_name="Pressure", dformat="point") space = PODInterpolation() mu.append([-.5, -.5]) mu.append([.5, -.5]) mu.append([.5, .5]) mu.append([-.5, .5]) snap.append("tests/test_datasets/matlab_00.vtk") snap.append("tests/test_datasets/matlab_01.vtk") snap.append("tests/test_datasets/matlab_02.vtk") snap.append("tests/test_datasets/matlab_03.vtk") error = space.loo_error(mu, snap) np.testing.assert_almost_equal(max(error), 0.149130165577, decimal=4)
def test_loo_error(self): mu = Points() snap = Snapshots(output_name="Pressure", dformat="point") space = Pod() mu.append([-.5, -.5]) mu.append([.5, -.5]) mu.append([.5, .5]) mu.append([-.5, .5]) snap.append("tests/test_datasets/matlab_00.vtk") snap.append("tests/test_datasets/matlab_01.vtk") snap.append("tests/test_datasets/matlab_02.vtk") snap.append("tests/test_datasets/matlab_03.vtk") error = space.loo_error(mu, snap) assert error.shape == (4, )
def test_generate(self): mu = Points() snap = Snapshots(output_name="Pressure", dformat="point") space = Pod() mu.append([-.5, -.5]) mu.append([.5, -.5]) mu.append([.5, .5]) mu.append([-.5, .5]) snap.append("tests/test_datasets/matlab_00.vtk") snap.append("tests/test_datasets/matlab_01.vtk") snap.append("tests/test_datasets/matlab_02.vtk") snap.append("tests/test_datasets/matlab_03.vtk") space.generate(mu, snap) assert space.state['pod_basis'].shape == (2500, 4)
def test_loo_error2(self): mu = Points() snap = Snapshots(output_name="Pressure", dformat="point") space = Pod() mu.append([-.5, -.5]) mu.append([.5, -.5]) mu.append([.5, .5]) mu.append([-.5, .5]) snap.append("tests/test_datasets/matlab_00.vtk") snap.append("tests/test_datasets/matlab_01.vtk") snap.append("tests/test_datasets/matlab_02.vtk") snap.append("tests/test_datasets/matlab_03.vtk") error = space.loo_error(mu, snap) np.testing.assert_almost_equal(max(error), 0.149130165577, decimal=4)
def test_interpolator(self): mu = Points() snap = Snapshots(output_name="Pressure", dformat="point") space = PODInterpolation() mu.append([-.5, -.5]) mu.append([.5, -.5]) mu.append([.5, .5]) mu.append([-.5, .5]) snap.append("tests/test_datasets/matlab_00.vtk") snap.append("tests/test_datasets/matlab_01.vtk") snap.append("tests/test_datasets/matlab_02.vtk") snap.append("tests/test_datasets/matlab_03.vtk") space.generate(mu, snap) assert isinstance(space.interpolator, LinearNDInterpolator)
def test_call(self): mu = Points() snap = Snapshots(output_name="Pressure", dformat="point") space = ResponseSurface() mu.append([-.5, -.5]) mu.append([.5, -.5]) mu.append([.5, .5]) mu.append([-.5, .5]) snap.append("tests/test_datasets/matlab_00.vtk") snap.append("tests/test_datasets/matlab_01.vtk") snap.append("tests/test_datasets/matlab_02.vtk") snap.append("tests/test_datasets/matlab_03.vtk") space.generate(mu, snap) solution = space([0, 0]) assert solution.shape == (1, 2500)
def test_dimension_2(self): pts = Points() pts.append([0, 1, 2]) pts.append([3, 4, 5]) pts.append([4, 4, 5]) pts.append([6, 4, 5]) pts.append([6, 7, 5]) assert isinstance(pts.triangulation, scipy.spatial.qhull.Delaunay)
def test_save(self): mu = Points() snap = Snapshots(output_name="Pressure", dformat="point") space = PODInterpolation() mu.append([-.5, -.5]) mu.append([.5, -.5]) mu.append([.5, .5]) mu.append([-.5, .5]) snap.append("tests/test_datasets/matlab_00.vtk") snap.append("tests/test_datasets/matlab_01.vtk") snap.append("tests/test_datasets/matlab_02.vtk") snap.append("tests/test_datasets/matlab_03.vtk") space.generate(mu, snap) space.save("tests/test_datasets/podspace") assert os.path.isfile("tests/test_datasets/podspace")
def test_call(self): mu = Points() snap = Snapshots(output_name="Pressure", dformat="point") space = Interpolation() mu.append([-.5, -.5]) mu.append([.5, -.5]) mu.append([.5, .5]) mu.append([-.5, .5]) snap.append("tests/test_datasets/matlab_00.vtk") snap.append("tests/test_datasets/matlab_01.vtk") snap.append("tests/test_datasets/matlab_02.vtk") snap.append("tests/test_datasets/matlab_03.vtk") space.generate(mu, snap) solution = space([0, 0]) assert solution.shape == (1, 2500)
def test_save(self): mu = Points() snap = Snapshots(output_name="Pressure", dformat="point") space = Pod() mu.append([-.5, -.5]) mu.append([.5, -.5]) mu.append([.5, .5]) mu.append([-.5, .5]) snap.append("tests/test_datasets/matlab_00.vtk") snap.append("tests/test_datasets/matlab_01.vtk") snap.append("tests/test_datasets/matlab_02.vtk") snap.append("tests/test_datasets/matlab_03.vtk") space.generate(mu, snap) space.save("tests/test_datasets/podspace") assert os.path.isfile("tests/test_datasets/podspace")
def test_load(self): mu = Points() snap = Snapshots(output_name="Pressure", dformat="point") space = PODInterpolation() mu.append([-.5, -.5]) mu.append([.5, -.5]) mu.append([.5, .5]) mu.append([-.5, .5]) snap.append("tests/test_datasets/matlab_00.vtk") snap.append("tests/test_datasets/matlab_01.vtk") snap.append("tests/test_datasets/matlab_02.vtk") snap.append("tests/test_datasets/matlab_03.vtk") space.generate(mu, snap) space.save("tests/test_datasets/podspace") another_space = ParametricSpace.load("tests/test_datasets/podspace") assert another_space.pod_basis.shape == (2500, 4) os.remove("tests/test_datasets/podspace")
class Offline(object): """ Offline phase. :param str output_name: the name of the output of interest. :param ParametricSpace space_type: the method used for the reduced space generation. Default is :class:`.PODInterpolation`. :param str weight_name: the name of the output to consider as weight. :param str dformat: the data format to extract from the snapshot files: if the parameter is "cell", the snapshot values refer to the cell data, if the parameter is "point", the snapshot values refer to the point data. These are the only options available. :cvar Points mu: the object that contains the parameter values :cvar Snapshots snapshots: the object that contains the snapshots extracted from the chosen files. :cvar ParametricSpace space: the method used for the reduced space generation. """ def __init__(self, output_name, space_type=PODInterpolation, weight_name=None, dformat='cell'): self.mu = Points() self.snapshots = Snapshots(output_name, weight_name, dformat) self.space = space_type() def init_database(self, values, files): """ Initialize the database with the passed parameter values and snapshot files: the *i*-th parameter has to be the parametric point of the solution stored in the *i*-th file. :param array_like values: the list of parameter values. :param array_like files: the list of the solution files. """ for mu in values: self.mu.append(mu) for fl in files: self.snapshots.append(fl) def init_database_from_file(self, filename): """ Initialize the database by reading the parameter values and the snapshot files from a given filename; this file has to be format as following: first *N* columns indicate the parameter values, the *N+1* column indicates the corresponding snapshot file. Example of a generic file:: par1 par2 ... solution_file1 par1 par2 ... solution_file2 par1 par2 ... solution_file3 :param str filename: name of file where parameter values and snapshot files are stored. """ if not os.path.isfile(filename): raise IOError("File {0!s} not found".format( os.path.abspath(filename))) matrix = np.genfromtxt(filename, dtype=None) num_cols = len(matrix.dtype) if num_cols < 2: raise ValueError("Not valid number of columns in database file") snapshots_files = matrix[matrix.dtype.names[num_cols - 1]].astype(str) mu_values = np.array([ matrix[name].astype(float) for name in matrix.dtype.names[0:num_cols - 1] ]) self.init_database(mu_values.T, snapshots_files) def add_snapshot(self, new_mu, new_file): """ This methos adds the new solution to the database and the new parameter values to the parameter points; this can be done only after the new solution has be computed and placed in the proper directory. :param array_like new_mu: the parameter value to add to database. :param str new_file: the name of snapshot file to add to database. """ self.mu.append(new_mu) self.snapshots.append(new_file) def generate_rb_space(self): """ Generate the reduced basis space by combining the snapshots. It uses the chosen method for the generation. """ self.space.generate(self.mu, self.snapshots) def save_rb_space(self, filename): """ Save the reduced basis space to `filename`. :param str filename: the file where the space will be stored. """ self.space.save(filename) def loo_error(self, func=np.linalg.norm): """ Estimate the approximation error using *leave-one-out* strategy. The main idea is to create several reduced spaces by combining all the snapshots except one. The error vector is computed as the difference between the removed snapshot and the projection onto the properly reduced space. The procedure repeats for each snapshot in the database. The `func` is applied on each vector of error to obtained a float number. :param function func: the function used to assign at each vector of error a float number. It has to take as input a 'numpy.ndarray` and returns a float. Default value is the L2 norm. :return: the vector that contains the errors estimated for all parametric points. :rtype: numpy.ndarray """ return self.space.loo_error(self.mu, self.snapshots, func) def optimal_mu(self, error=None, k=1): """ Return the parametric points where new high-fidelity solutions have to be computed in ordere to globaly reduce the estimated error. These points are the barycentric center of the region (simplex) with higher error. :param numpy.ndarray error: the estimated error evaluated for each snapshot; if error array is not passed, it is computed using :func:`loo_error` with the default function. Default value is None. :param int k: the number of optimal points to return. Default value is 1. :return: the optimal points :rtype: list(numpy.ndarray) """ if error is None: error = self.loo_error() tria = self.mu.triangulation error_on_simplex = np.array([ np.sum(error[smpx]) * simplex_volume(self.mu.values.T[smpx]) for smpx in tria.simplices ]) barycentric_point = [] for index in np.argpartition(error_on_simplex, -k)[-k:]: worst_tria_pts = self.mu.values.T[tria.simplices[index]] worst_tria_err = error[tria.simplices[index]] barycentric_point.append( np.average(worst_tria_pts, axis=0, weights=worst_tria_err)) return barycentric_point
def test_size(self): pts = Points() pts.append([0, 1, 2]) pts.append([3, 4, 5]) assert pts.size == 2
def test_dimension_1(self): pts = Points() pts.append([0, 1, 2]) pts.append([3, 4, 5]) assert pts.dimension == 3
class Offline(object): """ Offline phase. :param str output_name: the name of the output of interest. :param ParametricSpace space_type: the method used for the reduced space generation. Default is :class:`.PODInterpolation`. :param str weight_name: the name of the output to consider as weight. :param str dformat: the data format to extract from the snapshot files: if the parameter is "cell", the snapshot values refer to the cell data, if the parameter is "point", the snapshot values refer to the point data. These are the only options available. :cvar Points mu: the object that contains the parameter values :cvar Snapshots snapshots: the object that contains the snapshots extracted from the chosen files. :cvar ParametricSpace space: the method used for the reduced space generation. """ def __init__(self, output_name, space_type=PODInterpolation, weight_name=None, dformat='cell'): self.mu = Points() self.snapshots = Snapshots(output_name, weight_name, dformat) self.space = space_type() def init_database(self, values, files): """ Initialize the database with the passed parameter values and snapshot files: the *i*-th parameter has to be the parametric point of the solution stored in the *i*-th file. :param array_like values: the list of parameter values. :param array_like files: the list of the solution files. """ for mu in values: self.mu.append(mu) for fl in files: self.snapshots.append(fl) def init_database_from_file(self, filename): """ Initialize the database by reading the parameter values and the snapshot files from a given filename; this file has to be format as following: first *N* columns indicate the parameter values, the *N+1* column indicates the corresponding snapshot file. Example of a generic file:: par1 par2 ... solution_file1 par1 par2 ... solution_file2 par1 par2 ... solution_file3 :param str filename: name of file where parameter values and snapshot files are stored. """ if not os.path.isfile(filename): raise IOError("File {0!s} not found".format( os.path.abspath(filename))) matrix = np.genfromtxt(filename, dtype=None) num_cols = len(matrix.dtype) if num_cols < 2: raise ValueError("Not valid number of columns in database file") snapshots_files = matrix[matrix.dtype.names[num_cols - 1]].astype(str) mu_values = np.array([ matrix[name].astype(float) for name in matrix.dtype.names[0:num_cols - 1] ]) self.init_database(mu_values.T, snapshots_files) def add_snapshot(self, new_mu, new_file): """ This methos adds the new solution to the database and the new parameter values to the parameter points; this can be done only after the new solution has be computed and placed in the proper directory. :param array_like new_mu: the parameter value to add to database. :param str new_file: the name of snapshot file to add to database. """ self.mu.append(new_mu) self.snapshots.append(new_file) def generate_rb_space(self): """ Generate the reduced basis space by combining the snapshots. It uses the chosen method for the generation. """ self.space.generate(self.mu, self.snapshots) def save_rb_space(self, filename): """ Save the reduced basis space to `filename`. :param str filename: the file where the space will be stored. """ self.space.save(filename) def loo_error(self, func=np.linalg.norm): """ Estimate the approximation error using *leave-one-out* strategy. The main idea is to create several reduced spaces by combining all the snapshots except one. The error vector is computed as the difference between the removed snapshot and the projection onto the properly reduced space. The procedure repeats for each snapshot in the database. The `func` is applied on each vector of error to obtained a float number. :param function func: the function used to assign at each vector of error a float number. It has to take as input a 'numpy.ndarray` and returns a float. Default value is the L2 norm. :return: the vector that contains the errors estimated for all parametric points. :rtype: numpy.ndarray """ return self.space.loo_error(self.mu, self.snapshots, func) def optimal_mu(self, error=None, k=1): """ Return the parametric points where new high-fidelity solutions have to be computed in order to globally reduce the estimated error. These points are the barycentric center of the region (simplex) with higher error. :param numpy.ndarray error: the estimated error evaluated for each snapshot; if error array is not passed, it is computed using :func:`loo_error` with the default function. Default value is None. :param int k: the number of optimal points to return. Default value is 1. :return: the optimal points :rtype: list(numpy.ndarray) """ if error is None: error = self.loo_error() tria = self.mu.triangulation error_on_simplex = np.array([ np.sum(error[smpx]) * simplex_volume(self.mu.values.T[smpx]) for smpx in tria.simplices ]) barycentric_point = [] for index in np.argpartition(error_on_simplex, -k)[-k:]: worst_tria_pts = self.mu.values.T[tria.simplices[index]] worst_tria_err = error[tria.simplices[index]] barycentric_point.append( np.average(worst_tria_pts, axis=0, weights=worst_tria_err)) return barycentric_point
def test_append2(self): pts = Points() pts.append([0, 1, 2]) pts.append([3, 4, 5]) expected_values = np.array([[0, 1, 2], [3, 4, 5]]).T np.testing.assert_array_almost_equal(pts.values, expected_values)