Skip to content

Commit cb6caaf

Browse files
authored
Merge pull request #4045 from dknez/eim_normalization_option
Added option to normalize RB solution snapshots
2 parents c544498 + 6dd327c commit cb6caaf

5 files changed

Lines changed: 96 additions & 33 deletions

File tree

include/reduced_basis/rb_construction_base.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,12 @@ class RBConstructionBase : public Base, public RBParametrized
106106
bool is_quiet() const
107107
{ return this->quiet_mode; }
108108

109+
/**
110+
* Set the boolean option that indicates if we normalization
111+
* solution snapshots or not.
112+
*/
113+
void set_normalize_solution_snapshots(bool value);
114+
109115
/**
110116
* Get the number of global training samples.
111117
*/
@@ -266,6 +272,14 @@ class RBConstructionBase : public Base, public RBParametrized
266272
*/
267273
bool serial_training_set;
268274

275+
/**
276+
* Set this boolean to true if we want to normalize solution snapshots
277+
* used in training to have norm of 1. This is relevant if snapshots
278+
* have differing magnitudes and we want to approximate them all with
279+
* equal accuracy.
280+
*/
281+
bool _normalize_solution_snapshots;
282+
269283
/**
270284
* We keep an extra temporary vector that is useful for
271285
* performing inner products (avoids unnecessary memory

include/reduced_basis/rb_eim_construction.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,13 @@ class RBEIMConstruction : public RBConstructionBase<System>
164164
*/
165165
virtual void print_info();
166166

167+
/**
168+
* Rescale solution snapshots so that they all have unity norm. This is relevant
169+
* if training samples have differing magnitudes and we want to approximate them
170+
* all with equal accuracy.
171+
*/
172+
void apply_normalization_to_solution_snapshots();
173+
167174
/**
168175
* Generate the EIM approximation for the specified parametrized function
169176
* using either POD or the Greedy Algorithm. Return the final tolerance.

src/reduced_basis/rb_construction.C

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1453,6 +1453,20 @@ void RBConstruction::train_reduced_basis_with_POD()
14531453
}
14541454
libMesh::out << std::endl;
14551455

1456+
if (_normalize_solution_snapshots)
1457+
{
1458+
libMesh::out << "Normalizing solution snapshots" << std::endl;
1459+
for (unsigned int i=0; i<n_snapshots; i++)
1460+
{
1461+
get_non_dirichlet_inner_product_matrix_if_avail()->vector_mult(
1462+
*inner_product_storage_vector, *POD_snapshots[i]);
1463+
Real norm = std::sqrt(std::real(POD_snapshots[i]->dot(*inner_product_storage_vector)));
1464+
1465+
if (norm > 0.)
1466+
POD_snapshots[i]->scale(1./norm);
1467+
}
1468+
}
1469+
14561470
// Set up the "correlation matrix"
14571471
DenseMatrix<Number> correlation_matrix(n_snapshots,n_snapshots);
14581472
for (unsigned int i=0; i<n_snapshots; i++)

src/reduced_basis/rb_construction_base.C

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ RBConstructionBase<Base>::RBConstructionBase (EquationSystems & es,
9898
: Base(es, name_in, number_in),
9999
quiet_mode(true),
100100
serial_training_set(false),
101+
_normalize_solution_snapshots(false),
101102
_training_parameters_initialized(false),
102103
_first_local_index(0),
103104
_n_local_training_samples(0),
@@ -142,6 +143,12 @@ void RBConstructionBase<Base>::get_global_max_error_pair(const Parallel::Communi
142143
communicator.broadcast(error_pair.first, proc_ID_index);
143144
}
144145

146+
template <class Base>
147+
void RBConstructionBase<Base>::set_normalize_solution_snapshots(bool value)
148+
{
149+
_normalize_solution_snapshots = value;
150+
}
151+
145152
template <class Base>
146153
numeric_index_type RBConstructionBase<Base>::get_n_training_samples() const
147154
{

src/reduced_basis/rb_eim_construction.C

Lines changed: 54 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -87,21 +87,6 @@ void add(DataMap & u, const Number k, const DataMap & v)
8787
}
8888
}
8989

90-
// Implement u <- k*u
91-
template <typename DataMap>
92-
void scale(DataMap & u, const Number k)
93-
{
94-
for (auto & it : u)
95-
{
96-
std::vector<std::vector<Number>> & outer_vec = it.second;
97-
for (auto & inner_vec : outer_vec)
98-
for (auto & value : inner_vec)
99-
{
100-
value *= k;
101-
}
102-
}
103-
}
104-
10590
void add_node_data_map(RBEIMConstruction::NodeDataMap & u, const Number k, const RBEIMConstruction::NodeDataMap & v)
10691
{
10792
for (auto & [key, vec_u] : u)
@@ -117,18 +102,6 @@ void add_node_data_map(RBEIMConstruction::NodeDataMap & u, const Number k, const
117102
}
118103
}
119104

120-
void scale_node_data_map(RBEIMConstruction::NodeDataMap & u, const Number k)
121-
{
122-
for (auto & it : u)
123-
{
124-
std::vector<Number> & vec = it.second;
125-
for (auto & value : vec)
126-
{
127-
value *= k;
128-
}
129-
}
130-
}
131-
132105
}
133106

134107
RBEIMConstruction::RBEIMConstruction (EquationSystems & es,
@@ -434,6 +407,9 @@ void RBEIMConstruction::set_rb_construction_parameters(unsigned int n_training_s
434407

435408
Real RBEIMConstruction::train_eim_approximation()
436409
{
410+
if (_normalize_solution_snapshots)
411+
apply_normalization_to_solution_snapshots();
412+
437413
if(best_fit_type_flag == POD_BEST_FIT)
438414
{
439415
train_eim_approximation_with_POD();
@@ -644,6 +620,51 @@ Real RBEIMConstruction::train_eim_approximation_with_greedy()
644620
return greedy_error;
645621
}
646622

623+
void RBEIMConstruction::apply_normalization_to_solution_snapshots()
624+
{
625+
LOG_SCOPE("apply_normalization_to_solution_snapshots()", "RBEIMConstruction");
626+
627+
libMesh::out << "Normalizing solution snapshots" << std::endl;
628+
629+
bool apply_comp_scaling = !get_rb_eim_evaluation().scale_components_in_enrichment().empty();
630+
unsigned int n_snapshots = get_n_training_samples();
631+
RBEIMEvaluation & rbe = get_rb_eim_evaluation();
632+
633+
for (unsigned int i=0; i<n_snapshots; i++)
634+
{
635+
if (rbe.get_parametrized_function().on_mesh_sides())
636+
{
637+
Real norm_val = std::sqrt(std::real(side_inner_product(
638+
_local_side_parametrized_functions_for_training[i],
639+
_local_side_parametrized_functions_for_training[i],
640+
apply_comp_scaling)));
641+
642+
if (norm_val > 0.)
643+
scale_parametrized_function(_local_side_parametrized_functions_for_training[i], 1./norm_val);
644+
}
645+
else if (rbe.get_parametrized_function().on_mesh_nodes())
646+
{
647+
Real norm_val = std::sqrt(std::real(node_inner_product(
648+
_local_node_parametrized_functions_for_training[i],
649+
_local_node_parametrized_functions_for_training[i],
650+
apply_comp_scaling)));
651+
652+
if (norm_val > 0.)
653+
scale_node_parametrized_function(_local_node_parametrized_functions_for_training[i], 1./norm_val);
654+
}
655+
else
656+
{
657+
Real norm_val = std::sqrt(std::real(inner_product(
658+
_local_parametrized_functions_for_training[i],
659+
_local_parametrized_functions_for_training[i],
660+
apply_comp_scaling)));
661+
662+
if (norm_val > 0.)
663+
scale_parametrized_function(_local_parametrized_functions_for_training[i], 1./norm_val);
664+
}
665+
}
666+
}
667+
647668
Real RBEIMConstruction::train_eim_approximation_with_POD()
648669
{
649670
LOG_SCOPE("train_eim_approximation_with_POD()", "RBEIMConstruction");
@@ -823,13 +844,13 @@ Real RBEIMConstruction::train_eim_approximation_with_POD()
823844

824845
if (!is_zero_bf)
825846
{
826-
scale(v, 0.);
847+
scale_parametrized_function(v, 0.);
827848

828849
for ( unsigned int i=0; i<n_snapshots; ++i )
829850
add(v, U.el(i, j), _local_side_parametrized_functions_for_training[i] );
830851

831852
Real norm_v = std::sqrt(sigma(j));
832-
scale(v, 1./norm_v);
853+
scale_parametrized_function(v, 1./norm_v);
833854
}
834855

835856
libmesh_try
@@ -889,13 +910,13 @@ Real RBEIMConstruction::train_eim_approximation_with_POD()
889910

890911
if (!is_zero_bf)
891912
{
892-
scale_node_data_map(v, 0.);
913+
scale_node_parametrized_function(v, 0.);
893914

894915
for ( unsigned int i=0; i<n_snapshots; ++i )
895916
add_node_data_map(v, U.el(i, j), _local_node_parametrized_functions_for_training[i] );
896917

897918
Real norm_v = std::sqrt(sigma(j));
898-
scale_node_data_map(v, 1./norm_v);
919+
scale_node_parametrized_function(v, 1./norm_v);
899920
}
900921

901922
libmesh_try
@@ -955,13 +976,13 @@ Real RBEIMConstruction::train_eim_approximation_with_POD()
955976

956977
if (!is_zero_bf)
957978
{
958-
scale(v, 0.);
979+
scale_parametrized_function(v, 0.);
959980

960981
for ( unsigned int i=0; i<n_snapshots; ++i )
961982
add(v, U.el(i, j), _local_parametrized_functions_for_training[i] );
962983

963984
Real norm_v = std::sqrt(sigma(j));
964-
scale(v, 1./norm_v);
985+
scale_parametrized_function(v, 1./norm_v);
965986
}
966987

967988
libmesh_try

0 commit comments

Comments
 (0)