From 98085bd1ba78302e521e437d37170f32a18c9db9 Mon Sep 17 00:00:00 2001 From: David Knezevic Date: Wed, 18 Dec 2024 17:54:38 -0500 Subject: [PATCH 1/4] Added option to normalize RB solution snapshots --- include/reduced_basis/rb_construction_base.h | 8 ++ include/reduced_basis/rb_eim_construction.h | 7 ++ src/reduced_basis/rb_construction.C | 14 ++++ src/reduced_basis/rb_construction_base.C | 1 + src/reduced_basis/rb_eim_construction.C | 87 ++++++++++++-------- 5 files changed, 84 insertions(+), 33 deletions(-) diff --git a/include/reduced_basis/rb_construction_base.h b/include/reduced_basis/rb_construction_base.h index 5adbdcbc0ec..d109f7a6d6f 100644 --- a/include/reduced_basis/rb_construction_base.h +++ b/include/reduced_basis/rb_construction_base.h @@ -266,6 +266,14 @@ class RBConstructionBase : public Base, public RBParametrized */ bool serial_training_set; + /** + * Set this boolean to true if we want to normalize solution snapshots + * used in training to have norm of 1. This is relevant if snapshots + * have differing magnitudes and we want to approximate them all with + * equal accuracy. + */ + bool normalize_solution_snapshots; + /** * We keep an extra temporary vector that is useful for * performing inner products (avoids unnecessary memory diff --git a/include/reduced_basis/rb_eim_construction.h b/include/reduced_basis/rb_eim_construction.h index 21d231c8f10..28ec783bd30 100644 --- a/include/reduced_basis/rb_eim_construction.h +++ b/include/reduced_basis/rb_eim_construction.h @@ -164,6 +164,13 @@ class RBEIMConstruction : public RBConstructionBase */ virtual void print_info(); + /** + * Rescale solution snapshots so that they all have unity norm. This is relevant + * if training samples have differing magnitudes and we want to approximate them + * all with equal accuracy. + */ + void apply_normalization_to_solution_snapshots(); + /** * Generate the EIM approximation for the specified parametrized function * using either POD or the Greedy Algorithm. Return the final tolerance. diff --git a/src/reduced_basis/rb_construction.C b/src/reduced_basis/rb_construction.C index 83da33ad5e0..46363ee543b 100644 --- a/src/reduced_basis/rb_construction.C +++ b/src/reduced_basis/rb_construction.C @@ -1453,6 +1453,20 @@ void RBConstruction::train_reduced_basis_with_POD() } libMesh::out << std::endl; + if (normalize_solution_snapshots) + { + std::cout << "Normalizing solution snapshots" << std::endl; + for (unsigned int i=0; ivector_mult( + *inner_product_storage_vector, *POD_snapshots[i]); + Real norm = std::sqrt(std::real(POD_snapshots[i]->dot(*inner_product_storage_vector))); + + if (norm > 0.) + POD_snapshots[i]->scale(1./norm); + } + } + // Set up the "correlation matrix" DenseMatrix correlation_matrix(n_snapshots,n_snapshots); for (unsigned int i=0; i::RBConstructionBase (EquationSystems & es, : Base(es, name_in, number_in), quiet_mode(true), serial_training_set(false), + normalize_solution_snapshots(false), _training_parameters_initialized(false), _first_local_index(0), _n_local_training_samples(0), diff --git a/src/reduced_basis/rb_eim_construction.C b/src/reduced_basis/rb_eim_construction.C index a3753ca834b..4c45fee9eb4 100644 --- a/src/reduced_basis/rb_eim_construction.C +++ b/src/reduced_basis/rb_eim_construction.C @@ -87,21 +87,6 @@ void add(DataMap & u, const Number k, const DataMap & v) } } -// Implement u <- k*u -template -void scale(DataMap & u, const Number k) -{ - for (auto & it : u) - { - std::vector> & outer_vec = it.second; - for (auto & inner_vec : outer_vec) - for (auto & value : inner_vec) - { - value *= k; - } - } -} - void add_node_data_map(RBEIMConstruction::NodeDataMap & u, const Number k, const RBEIMConstruction::NodeDataMap & v) { for (auto & [key, vec_u] : u) @@ -117,18 +102,6 @@ void add_node_data_map(RBEIMConstruction::NodeDataMap & u, const Number k, const } } -void scale_node_data_map(RBEIMConstruction::NodeDataMap & u, const Number k) -{ - for (auto & it : u) - { - std::vector & vec = it.second; - for (auto & value : vec) - { - value *= k; - } - } -} - } RBEIMConstruction::RBEIMConstruction (EquationSystems & es, @@ -434,6 +407,9 @@ void RBEIMConstruction::set_rb_construction_parameters(unsigned int n_training_s Real RBEIMConstruction::train_eim_approximation() { + if (normalize_solution_snapshots) + apply_normalization_to_solution_snapshots(); + if(best_fit_type_flag == POD_BEST_FIT) { train_eim_approximation_with_POD(); @@ -644,6 +620,51 @@ Real RBEIMConstruction::train_eim_approximation_with_greedy() return greedy_error; } +void RBEIMConstruction::apply_normalization_to_solution_snapshots() +{ + LOG_SCOPE("apply_normalization_to_solution_snapshots()", "RBEIMConstruction"); + + std::cout << "Normalizing solution snapshots" << std::endl; + + bool apply_comp_scaling = !get_rb_eim_evaluation().scale_components_in_enrichment().empty(); + unsigned int n_snapshots = get_n_training_samples(); + RBEIMEvaluation & rbe = get_rb_eim_evaluation(); + + for (unsigned int i=0; i 0.) + scale_parametrized_function(_local_side_parametrized_functions_for_training[i], 1./norm_val); + } + else if (rbe.get_parametrized_function().on_mesh_nodes()) + { + Number norm_val = std::sqrt(std::real(node_inner_product( + _local_node_parametrized_functions_for_training[i], + _local_node_parametrized_functions_for_training[i], + apply_comp_scaling))); + + if (norm_val > 0.) + scale_node_parametrized_function(_local_node_parametrized_functions_for_training[i], 1./norm_val); + } + else + { + Real norm_val = std::sqrt(std::real(inner_product( + _local_parametrized_functions_for_training[i], + _local_parametrized_functions_for_training[i], + apply_comp_scaling))); + + if (norm_val > 0.) + scale_parametrized_function(_local_parametrized_functions_for_training[i], 1./norm_val); + } + } +} + Real RBEIMConstruction::train_eim_approximation_with_POD() { LOG_SCOPE("train_eim_approximation_with_POD()", "RBEIMConstruction"); @@ -823,13 +844,13 @@ Real RBEIMConstruction::train_eim_approximation_with_POD() if (!is_zero_bf) { - scale(v, 0.); + scale_parametrized_function(v, 0.); for ( unsigned int i=0; i Date: Mon, 6 Jan 2025 16:53:17 -0500 Subject: [PATCH 2/4] std::cout --> libMesh::out --- src/reduced_basis/rb_construction.C | 2 +- src/reduced_basis/rb_eim_construction.C | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/reduced_basis/rb_construction.C b/src/reduced_basis/rb_construction.C index 46363ee543b..7743ac99128 100644 --- a/src/reduced_basis/rb_construction.C +++ b/src/reduced_basis/rb_construction.C @@ -1455,7 +1455,7 @@ void RBConstruction::train_reduced_basis_with_POD() if (normalize_solution_snapshots) { - std::cout << "Normalizing solution snapshots" << std::endl; + libMesh::out << "Normalizing solution snapshots" << std::endl; for (unsigned int i=0; ivector_mult( diff --git a/src/reduced_basis/rb_eim_construction.C b/src/reduced_basis/rb_eim_construction.C index 4c45fee9eb4..2dc486f0a11 100644 --- a/src/reduced_basis/rb_eim_construction.C +++ b/src/reduced_basis/rb_eim_construction.C @@ -624,7 +624,7 @@ void RBEIMConstruction::apply_normalization_to_solution_snapshots() { LOG_SCOPE("apply_normalization_to_solution_snapshots()", "RBEIMConstruction"); - std::cout << "Normalizing solution snapshots" << std::endl; + libMesh::out << "Normalizing solution snapshots" << std::endl; bool apply_comp_scaling = !get_rb_eim_evaluation().scale_components_in_enrichment().empty(); unsigned int n_snapshots = get_n_training_samples(); From 6fdd81b9e71d5cc7538a6816a0e44be28a924eba Mon Sep 17 00:00:00 2001 From: David Knezevic Date: Tue, 7 Jan 2025 09:45:48 -0500 Subject: [PATCH 3/4] Fix for --enable-complex compilation error --- src/reduced_basis/rb_eim_construction.C | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/reduced_basis/rb_eim_construction.C b/src/reduced_basis/rb_eim_construction.C index 2dc486f0a11..46adab5f439 100644 --- a/src/reduced_basis/rb_eim_construction.C +++ b/src/reduced_basis/rb_eim_construction.C @@ -644,7 +644,7 @@ void RBEIMConstruction::apply_normalization_to_solution_snapshots() } else if (rbe.get_parametrized_function().on_mesh_nodes()) { - Number norm_val = std::sqrt(std::real(node_inner_product( + Real norm_val = std::sqrt(std::real(node_inner_product( _local_node_parametrized_functions_for_training[i], _local_node_parametrized_functions_for_training[i], apply_comp_scaling))); From 6dd327c070aa5ca17edbe78fe52ee2db82c30a29 Mon Sep 17 00:00:00 2001 From: David Knezevic Date: Tue, 7 Jan 2025 12:29:21 -0500 Subject: [PATCH 4/4] Added a setter --- include/reduced_basis/rb_construction_base.h | 8 +++++++- src/reduced_basis/rb_construction.C | 2 +- src/reduced_basis/rb_construction_base.C | 8 +++++++- src/reduced_basis/rb_eim_construction.C | 2 +- 4 files changed, 16 insertions(+), 4 deletions(-) diff --git a/include/reduced_basis/rb_construction_base.h b/include/reduced_basis/rb_construction_base.h index d109f7a6d6f..b313ccb1ce4 100644 --- a/include/reduced_basis/rb_construction_base.h +++ b/include/reduced_basis/rb_construction_base.h @@ -106,6 +106,12 @@ class RBConstructionBase : public Base, public RBParametrized bool is_quiet() const { return this->quiet_mode; } + /** + * Set the boolean option that indicates if we normalization + * solution snapshots or not. + */ + void set_normalize_solution_snapshots(bool value); + /** * Get the number of global training samples. */ @@ -272,7 +278,7 @@ class RBConstructionBase : public Base, public RBParametrized * have differing magnitudes and we want to approximate them all with * equal accuracy. */ - bool normalize_solution_snapshots; + bool _normalize_solution_snapshots; /** * We keep an extra temporary vector that is useful for diff --git a/src/reduced_basis/rb_construction.C b/src/reduced_basis/rb_construction.C index 7743ac99128..5d477a8cdbe 100644 --- a/src/reduced_basis/rb_construction.C +++ b/src/reduced_basis/rb_construction.C @@ -1453,7 +1453,7 @@ void RBConstruction::train_reduced_basis_with_POD() } libMesh::out << std::endl; - if (normalize_solution_snapshots) + if (_normalize_solution_snapshots) { libMesh::out << "Normalizing solution snapshots" << std::endl; for (unsigned int i=0; i::RBConstructionBase (EquationSystems & es, : Base(es, name_in, number_in), quiet_mode(true), serial_training_set(false), - normalize_solution_snapshots(false), + _normalize_solution_snapshots(false), _training_parameters_initialized(false), _first_local_index(0), _n_local_training_samples(0), @@ -143,6 +143,12 @@ void RBConstructionBase::get_global_max_error_pair(const Parallel::Communi communicator.broadcast(error_pair.first, proc_ID_index); } +template +void RBConstructionBase::set_normalize_solution_snapshots(bool value) +{ + _normalize_solution_snapshots = value; +} + template numeric_index_type RBConstructionBase::get_n_training_samples() const { diff --git a/src/reduced_basis/rb_eim_construction.C b/src/reduced_basis/rb_eim_construction.C index 46adab5f439..4b94e8ffa20 100644 --- a/src/reduced_basis/rb_eim_construction.C +++ b/src/reduced_basis/rb_eim_construction.C @@ -407,7 +407,7 @@ void RBEIMConstruction::set_rb_construction_parameters(unsigned int n_training_s Real RBEIMConstruction::train_eim_approximation() { - if (normalize_solution_snapshots) + if (_normalize_solution_snapshots) apply_normalization_to_solution_snapshots(); if(best_fit_type_flag == POD_BEST_FIT)