diff --git a/ANN_Data_Generator.py b/ANN_Data_Generator.py index 992f4abf15be8cb52dcac549ace723a8b1cf0b17..2d57bafde67ee7d5186f4503241978fc7a357778 100644 --- a/ANN_Data_Generator.py +++ b/ANN_Data_Generator.py @@ -31,7 +31,8 @@ class TrainingDataGenerator: """ def __init__(self, initial_conditions, left_bound=-1, right_bound=1, - balance=0.5, stencil_length=3, directory='test_data'): + balance=0.5, stencil_length=3, directory='test_data', + add_reconstructions=True): """Initializes TrainingDataGenerator. Parameters @@ -49,11 +50,15 @@ class TrainingDataGenerator: directory : str, optional Path to directory in which training data is saved. Default: 'test_data'. + add_reconstructions: bool, optional + Flag whether reconstructions of the middle cell are included. + Default: True. """ self._balance = balance self._left_bound = left_bound self._right_bound = right_bound + self._add_reconstructions = add_reconstructions # Set stencil length if stencil_length % 2 == 0: @@ -174,7 +179,10 @@ class TrainingDataGenerator: print('Samples to complete:', num_samples) tic = time.perf_counter() - input_data = np.zeros((num_samples, self._stencil_length+2)) + num_datapoints = self._stencil_length + if self._add_reconstructions: + num_datapoints += 2 + input_data = np.zeros((num_samples, num_datapoints)) num_init_cond = len(initial_conditions) count = 0 for i in range(num_samples): @@ -202,7 +210,8 @@ class TrainingDataGenerator: right_bound=right_bound, quadrature='Gauss', quadrature_config={'num_eval_points': polynomial_degree+1}) input_data[i] = dg_scheme.build_training_data( - adjustment, self._stencil_length, initial_condition) + adjustment, self._stencil_length, self._add_reconstructions, + initial_condition) count += 1 if count % 1000 == 0: diff --git a/DG_Approximation.py b/DG_Approximation.py index 014f90d507c8d1449b5009dcaba01d9c35d9040b..334892294e2879698ab0af082184514eab1289d4 100644 --- a/DG_Approximation.py +++ b/DG_Approximation.py @@ -8,6 +8,9 @@ TODO: Adapt TCD from Soraya (Dropbox->...->TEST_troubled-cell-detector->Troubled_Cell_Detector) TODO: Add verbose output TODO: Improve file naming (e.g. use '.' instead of '__') +TODO: Give option to leave out reconstructions for ANN data -> Done +TODO: Force input_size for each ANN model to be stencil length +TODO: Combine ANN workflows Critical, but not urgent: TODO: Use cfl_number for updating, not just time @@ -384,6 +387,8 @@ class DGScheme: Extent of adjustment of each evaluation point in x-direction. stencil_length : int Size of training data array. + add_reconstructions: bool + Flag whether reconstructions of the middle cell are included. initial_condition : InitialCondition object, optional Initial condition used for calculation. Default: None (i.e. instance variable). @@ -399,5 +404,6 @@ class DGScheme: initial_condition = self._init_cond projection = self._do_initial_projection(initial_condition, adjustment) - return self._detector.calculate_cell_average_and_reconstructions( - projection[:, 1:-1], stencil_length) + return self._detector.calculate_cell_average(projection[:, 1:-1], + stencil_length, + add_reconstructions) diff --git a/Troubled_Cell_Detector.py b/Troubled_Cell_Detector.py index 18f6cb73ec46098553c5b029cc21a20caca352f5..1537699384f8e330e35c799dd8a5edf613195071 100644 --- a/Troubled_Cell_Detector.py +++ b/Troubled_Cell_Detector.py @@ -132,13 +132,13 @@ class TroubledCellDetector: """ pass - def calculate_cell_average_and_reconstructions(self, projection, - stencil_length): - """Calculates cell averages and reconstructions for a given projection. + def calculate_cell_average(self, projection, stencil_length, + add_reconstructions=True): + """Calculates cell averages for a given projection. Calculate the cell averages of all cells in a projection. - Reconstructions are only calculated for the middle cell and added - left and right to it, respectively. + If desired, reconstructions are calculated for the middle cell + and added left and right to it, respectively. Parameters ---------- @@ -146,29 +146,35 @@ class TroubledCellDetector: Matrix of projection for each polynomial degree. stencil_length : int Size of data array. + add_reconstructions: bool, optional + Flag whether reconstructions of the middle cell are included. + Default: True. Returns ------- ndarray - Matrix containing cell averages and reconstructions for initial + Matrix containing cell averages (and reconstructions) for initial projection. """ cell_averages = calculate_approximate_solution( projection, [0], 0, self._basis.get_basis_vector()) - left_reconstructions = calculate_approximate_solution( - projection, [-1], self._polynomial_degree, - self._basis.get_basis_vector()) - right_reconstructions = calculate_approximate_solution( - projection, [1], self._polynomial_degree, - self._basis.get_basis_vector()) - middle_idx = stencil_length//2 - return np.array( - list(map(np.float64, zip(cell_averages[:, :middle_idx], - left_reconstructions[:, middle_idx], - cell_averages[:, middle_idx], - right_reconstructions[:, middle_idx], - cell_averages[:, middle_idx+1:])))) + + if add_reconstructions: + left_reconstructions = calculate_approximate_solution( + projection, [-1], self._polynomial_degree, + self._basis.get_basis_vector()) + right_reconstructions = calculate_approximate_solution( + projection, [1], self._polynomial_degree, + self._basis.get_basis_vector()) + middle_idx = stencil_length//2 + return np.array( + list(map(np.float64, zip(cell_averages[:, :middle_idx], + left_reconstructions[:, middle_idx], + cell_averages[:, middle_idx], + right_reconstructions[:, middle_idx], + cell_averages[:, middle_idx+1:])))) + return np.array(list(map(np.float64, cell_averages))) def plot_results(self, projection, troubled_cell_history, time_history): """Plots results and troubled cells of a projection. @@ -283,9 +289,13 @@ class ArtificialNeuralNetwork(TroubledCellDetector): super()._reset(config) self._stencil_len = config.pop('stencil_len', 3) + self._add_reconstructions = config.pop('add_reconstructions', True) self._model = config.pop('model', 'ThreeLayerReLu') + num_datapoints = self._stencil_len + if self._add_reconstructions: + num_datapoints += 2 self._model_config = config.pop('model_config', { - 'input_size': self._stencil_len+2, 'first_hidden_size': 8, + 'input_size': num_datapoints, 'first_hidden_size': 8, 'second_hidden_size': 4, 'output_size': 2, 'activation_function': 'Softmax', 'activation_config': {'dim': 1}}) model_state = config.pop('model_state', 'Snakemake-Test/trained ' @@ -322,9 +332,9 @@ class ArtificialNeuralNetwork(TroubledCellDetector): # Calculate input data depending on stencil length input_data = torch.from_numpy( - np.vstack([self.calculate_cell_average_and_reconstructions( + np.vstack([self.calculate_cell_average( projection[:, cell-num_ghost_cells:cell+num_ghost_cells+1], - self._stencil_len) + self._stencil_len, self._add_reconstructions) for cell in range(num_ghost_cells, len(projection[0])-num_ghost_cells)])) diff --git a/config.yaml b/config.yaml index edeea1a3771f534960da20ebdf951fdd67048318..c260bc19457e4029a01046941d3ddbf86188acec 100644 --- a/config.yaml +++ b/config.yaml @@ -1,9 +1,9 @@ -data_dir: 'model-Mar01' +data_dir: 'model-Soraya_Mar02' random_seed: 1234 # Parameter for Approximation with Troubled Cell Detection Approximation: - plot_dir: 'fig-Mar01' + plot_dir: 'fig-Soraya_Mar02' schemes: Separation_Test: @@ -21,6 +21,7 @@ Approximation: detector_config: fold_len: 16 whisker_len: 3 + add_reconstructions: False model_state: 'Adam.model.pt' init_cond: 'Sine' @@ -51,6 +52,7 @@ ANN_Data: smooth_troubled_balance: 0.5 stencil_length: 3 + add_reconstructions : False # Initial Conditions for Training Data functions: @@ -85,7 +87,7 @@ ANN_Training: threshold: 1.0e-5 batch_size: 500 model: ThreeLayerReLu - model_config: {} + model_config: {input_size: 3} loss_function: BCELoss optimizer: Adam SGD: @@ -93,7 +95,7 @@ ANN_Training: threshold: 1.0e-5 batch_size: 500 model: ThreeLayerReLu - model_config: {} + model_config: {input_size: 3} loss_function: BCELoss optimizer: SGD diff --git a/workflows/ANN_data.smk b/workflows/ANN_data.smk index 9e29805a8ad5b12cf1106278120043e074759797..c0af4d03a5a3dbdb592250d694d8b193a284b3a5 100644 --- a/workflows/ANN_data.smk +++ b/workflows/ANN_data.smk @@ -22,6 +22,7 @@ rule generate_data: balance = config['smooth_troubled_balance'], stencil_length = config['stencil_length'], sample_number = config['sample_number'], + reconstruction_flag = config['add_reconstructions'], functions = expand('{FUNCTION}', FUNCTION=config['functions']) log: DIR+'/log/generate_data.log' @@ -41,6 +42,7 @@ rule generate_data: initial_conditions=initial_conditions, left_bound=params.left_bound, right_bound=params.right_bound, balance=params.balance, - stencil_length=params.stencil_length, directory=DIR) + stencil_length=params.stencil_length, directory=DIR, + add_reconstructions=params.reconstruction_flag) data = generator.build_training_data( num_samples=params.sample_number) \ No newline at end of file