@@ -279,7 +279,11 @@ std::vector<double> MinimalRationalInterpolation::FindMaxError(std::size_t N) co
279279 // }
280280
281281 // Fall back to sampling Q on discrete points if no roots exist in [start, end].
282- // TODO: currently we always us this. Consider other optimization above again.
282+ //
283+ // TODO: Currently we always use this brute for sampling and we could optimize this more.
284+ // Also, the case of N>1 samples is not very useful below. It will typically give us
285+ // multiple sample points right next to each other in the same local maximum, rather than
286+ // N separate local maxima.
283287
284288 // We could use priority queue here to keep the N lowest values. However, we don't use
285289 // std::priority_queue class since we want to have access to the vector and also binary
@@ -289,6 +293,10 @@ std::vector<double> MinimalRationalInterpolation::FindMaxError(std::size_t N) co
289293 queue.reserve (N);
290294
291295 const std::size_t nr_sample = 1.0e6 ; // must be >= N
296+ MFEM_VERIFY (N < nr_sample,
297+ fmt::format (" Number of location of error maximum N={} needs to be less than "
298+ " the fine sampling grid nr_sample={}." ,
299+ N, nr_sample));
292300 const auto delta = (end - start) / nr_sample;
293301 for (double z_sample = start; z_sample <= end; z_sample += delta)
294302 {
@@ -348,7 +356,7 @@ RomOperator::RomOperator(const IoData &iodata, SpaceOperator &space_op,
348356 max_prom_size += space_op.GetLumpedPortOp ().Size (); // Lumped ports are real fields
349357 }
350358
351- // Reserve empty vectors but don't pre-allocate actual memory size due to overhead .
359+ // Reserve empty vectors.
352360 V.reserve (max_prom_size);
353361 v_node_label.reserve (max_prom_size);
354362
@@ -362,7 +370,7 @@ RomOperator::RomOperator(const IoData &iodata, SpaceOperator &space_op,
362370void RomOperator::SetExcitationIndex (int excitation_idx)
363371{
364372 // Return if cached. Ctor constructs with excitation_idx_cache = 0 which is not a valid
365- // expiation index, so this is triggered the first time it is called in drivensolver.
373+ // excitation index, so this is triggered the first time it is called in drivensolver.
366374 if (excitation_idx_cache == excitation_idx)
367375 {
368376 return ;
@@ -442,27 +450,30 @@ void RomOperator::UpdatePROM(const ComplexVector &u, std::string_view node_label
442450
443451 orth_R.conservativeResizeLike (Eigen::MatrixXd::Zero (dim_V_new, dim_V_new));
444452
445- auto add_real_vector_to_basis = [this ](const Vector &vector, std::string_view full_label )
453+ auto add_real_vector_to_basis = [this ](const Vector &vector)
446454 {
447455 auto dim_V = V.size ();
448- V.push_back (vector);
449- OrthogonalizeColumn (orthog_type, space_op.GetComm (), V, V.back (),
450- orth_R.col (dim_V).data (), dim_V);
451- orth_R (dim_V, dim_V) = linalg::Norml2 (space_op.GetComm (), V.back ());
452- V.back () *= 1.0 / orth_R (dim_V, dim_V);
453- v_node_label.emplace_back (full_label);
456+ auto &v = V.emplace_back (vector);
457+ OrthogonalizeColumn (orthog_type, space_op.GetComm (), V, v, orth_R.col (dim_V).data (),
458+ dim_V);
459+ orth_R (dim_V, dim_V) = linalg::Norml2 (space_op.GetComm (), v);
460+ v *= 1.0 / orth_R (dim_V, dim_V);
454461 };
455462
456463 if (has_real)
457464 {
458- add_real_vector_to_basis (u.Real (), fmt::format (" {}_re" , node_label));
465+ add_real_vector_to_basis (u.Real ());
466+ v_node_label.emplace_back (fmt::format (" {}_re" , node_label));
459467 }
460468 if (has_imag)
461469 {
462- add_real_vector_to_basis (u.Imag (), fmt::format (" {}_im" , node_label));
470+ add_real_vector_to_basis (u.Imag ());
471+ v_node_label.emplace_back (fmt::format (" {}_im" , node_label));
463472 }
464473
465- // Update reduced-order operators.
474+ // Update reduced-order operators. Resize preserves the upper dim0 x dim0 block of each
475+ // matrix and first dim0 entries of each vector and the projection uses the values
476+ // computed for the unchanged basis vectors.
466477 Kr.conservativeResize (dim_V_new, dim_V_new);
467478 ProjectMatInternal (comm, V, *K, Kr, r, dim_V_old);
468479 if (C)
@@ -561,10 +572,14 @@ std::vector<std::complex<double>> RomOperator::ComputeEigenvalueEstimates() cons
561572
562573void RomOperator::PrintPROMMatrices (const Units &units, const fs::path &post_dir) const
563574{
575+ if (!Mpi::Root (space_op.GetComm ()))
576+ {
577+ return ;
578+ }
564579 auto print_table = [post_dir, labels = this ->v_node_label ](const Eigen::MatrixXd &mat,
565580 std::string_view filename)
566581 {
567- MFEM_VERIFY (labels.size () == mat.cols (), " Insonsistent PROM size!" );
582+ MFEM_VERIFY (labels.size () == mat.cols (), " Inconsistent PROM size!" );
568583 auto out = TableWithCSVFile (post_dir / filename);
569584 out.table .col_options .float_precision = 17 ;
570585 for (long i = 0 ; i < mat.cols (); i++)
0 commit comments