@@ -187,7 +187,6 @@ CSolver::~CSolver(void) {
187187 delete [] Restart_Data;
188188
189189 delete VerificationSolution;
190-
191190}
192191
193192void CSolver::GetPeriodicCommCountAndType (const CConfig* config,
@@ -4212,3 +4211,93 @@ void CSolver::BasicLoadRestart(CGeometry *geometry, const CConfig *config, const
42124211 string (" It could be empty lines at the end of the file." ), CURRENT_FUNCTION);
42134212 }
42144213}
4214+
4215+ void CSolver::SavelibROM (CGeometry *geometry, CConfig *config, bool converged) {
4216+
4217+ #if defined(HAVE_LIBROM) && !defined(CODI_FORWARD_TYPE) && !defined(CODI_REVERSE_TYPE)
4218+ const bool unsteady = config->GetTime_Domain ();
4219+ const string filename = config->GetlibROMbase_FileName ();
4220+ const unsigned long TimeIter = config->GetTimeIter ();
4221+ const unsigned long nTimeIter = config->GetnTime_Iter ();
4222+ const int maxBasisDim = config->GetMax_BasisDim ();
4223+ const int save_freq = config->GetRom_SaveFreq ();
4224+ int dim = int (nPointDomain * nVar);
4225+ bool incremental = false ;
4226+
4227+ if (!u_basis_generator) {
4228+
4229+ /* --- Define SVD basis generator ---*/
4230+ auto timesteps = static_cast <int >(nTimeIter - TimeIter);
4231+ CAROM::Options svd_options = CAROM::Options (dim, timesteps, -1 ,
4232+ false , true ).setMaxBasisDimension (int (maxBasisDim));
4233+
4234+ if (config->GetKind_PODBasis () == POD_KIND::STATIC) {
4235+ if (rank == MASTER_NODE) std::cout << " Creating static basis generator." << std::endl;
4236+
4237+ if (unsteady) {
4238+ if (rank == MASTER_NODE) std::cout << " Incremental basis generator recommended for unsteady simulations." << std::endl;
4239+ }
4240+ }
4241+ else {
4242+ if (rank == MASTER_NODE) std::cout << " Creating incremental basis generator." << std::endl;
4243+
4244+ svd_options.setIncrementalSVD (1.0e-3 , config->GetDelta_UnstTime (),
4245+ 1.0e-2 , config->GetDelta_UnstTime ()*nTimeIter, true ).setDebugMode (false );
4246+ incremental = true ;
4247+ }
4248+
4249+ u_basis_generator.reset (new CAROM::BasisGenerator (
4250+ svd_options, incremental,
4251+ filename));
4252+
4253+ // Save mesh ordering
4254+ std::ofstream f;
4255+ f.open (filename + " _mesh_" + to_string (rank) + " .csv" );
4256+ for (unsigned long iPoint = 0 ; iPoint < nPointDomain; iPoint++) {
4257+ unsigned long globalPoint = geometry->nodes ->GetGlobalIndex (iPoint);
4258+ auto Coord = geometry->nodes ->GetCoord (iPoint);
4259+
4260+ for (unsigned long iDim; iDim < nDim; iDim++) {
4261+ f << Coord[iDim] << " , " ;
4262+ }
4263+ f << globalPoint << " \n " ;
4264+ }
4265+ f.close ();
4266+ }
4267+
4268+ if (unsteady && (TimeIter % save_freq == 0 )) {
4269+ // give solution and time steps to libROM:
4270+ su2double dt = config->GetDelta_UnstTime ();
4271+ su2double t = config->GetCurrent_UnstTime ();
4272+ u_basis_generator->takeSample (const_cast <su2double*>(base_nodes->GetSolution ().data ()), t, dt);
4273+ }
4274+
4275+ /* --- End collection of data and save POD ---*/
4276+
4277+ if (converged) {
4278+
4279+ if (!unsteady) {
4280+ // dt is different for each node, so just use a placeholder dt
4281+ su2double dt = base_nodes->GetDelta_Time (0 );
4282+ su2double t = dt*TimeIter;
4283+ u_basis_generator->takeSample (const_cast <su2double*>(base_nodes->GetSolution ().data ()), t, dt);
4284+ }
4285+
4286+ if (config->GetKind_PODBasis () == POD_KIND::STATIC) {
4287+ u_basis_generator->writeSnapshot ();
4288+ }
4289+
4290+ if (rank == MASTER_NODE) std::cout << " Computing SVD" << std::endl;
4291+ int rom_dim = u_basis_generator->getSpatialBasis ()->numColumns ();
4292+
4293+ if (rank == MASTER_NODE) std::cout << " Basis dimension: " << rom_dim << std::endl;
4294+ u_basis_generator->endSamples ();
4295+
4296+ if (rank == MASTER_NODE) std::cout << " ROM Sampling ended" << std::endl;
4297+ }
4298+
4299+ #else
4300+ SU2_MPI::Error (" SU2 was not compiled with libROM support." , CURRENT_FUNCTION);
4301+ #endif
4302+
4303+ }
0 commit comments