@@ -3953,6 +3953,71 @@ void AMRSimulation<problem_t>::restartParticleContainerWithRefinement(std::uniqu
39533953 return ;
39543954 }
39553955
3956+ // Handle case where number of MPI processes changed since checkpoint was written
3957+ if (has_level_dirs) {
3958+ const int finest_level = finestLevel ();
3959+ const int num_procs = amrex::ParallelDescriptor::NProcs ();
3960+ if (amrex::ParallelDescriptor::IOProcessor ()) {
3961+ // First, find the highest level that has data
3962+ int source_level = -1 ;
3963+ for (int lev = finest_level; lev >= 0 ; --lev) {
3964+ std::string level_path = pc_path + " /Level_" + std::to_string (lev);
3965+ if (amrex::FileSystem::Exists (level_path)) {
3966+ source_level = lev;
3967+ break ;
3968+ }
3969+ }
3970+ if (source_level >= 0 ) {
3971+ std::string source_level_path = pc_path + " /Level_" + std::to_string (source_level);
3972+ // Count number of DATA files in source level
3973+ int num_source_data_files = 0 ;
3974+ for (int i = 0 ;; ++i) {
3975+ std::string data_file = source_level_path + " /DATA_" + amrex::Concatenate (" " , i, 5 );
3976+ if (amrex::FileSystem::Exists (data_file)) {
3977+ num_source_data_files = i + 1 ;
3978+ } else {
3979+ break ;
3980+ }
3981+ }
3982+ // For each level, ensure it exists and has the correct number of DATA files
3983+ for (int lev = 0 ; lev <= finest_level; ++lev) {
3984+ std::string level_path = pc_path + " /Level_" + std::to_string (lev);
3985+ if (!amrex::FileSystem::Exists (level_path)) {
3986+ // Create the missing level directory by copying from source level
3987+ std::string cp_cmd = " cp -r " + source_level_path + " " + level_path;
3988+ system (cp_cmd.c_str ());
3989+ }
3990+ // Now ensure this level has the correct number of DATA files
3991+ int num_data_files = 0 ;
3992+ for (int i = 0 ;; ++i) {
3993+ std::string data_file = level_path + " /DATA_" + amrex::Concatenate (" " , i, 5 );
3994+ if (amrex::FileSystem::Exists (data_file)) {
3995+ num_data_files = i + 1 ;
3996+ } else {
3997+ break ;
3998+ }
3999+ }
4000+ if (num_data_files < num_procs) {
4001+ // Copy DATA files from source level
4002+ for (int i = num_data_files; i < num_procs; ++i) {
4003+ std::string src_file = level_path + " /DATA_" + amrex::Concatenate (" " , i % num_source_data_files, 5 );
4004+ std::string dst_file = level_path + " /DATA_" + amrex::Concatenate (" " , i, 5 );
4005+ if (!amrex::FileSystem::Exists (dst_file)) {
4006+ std::ifstream src (src_file, std::ios::binary);
4007+ std::ofstream dst (dst_file, std::ios::binary);
4008+ if (src && dst) {
4009+ dst << src.rdbuf ();
4010+ }
4011+ }
4012+ }
4013+ }
4014+ }
4015+ }
4016+ }
4017+ // Synchronize
4018+ amrex::ParallelDescriptor::Barrier ();
4019+ }
4020+
39564021 if (restartRefineFactor_ > 1 ) {
39574022 // Save current geometry for all levels
39584023 amrex::Vector<amrex::Geometry> current_geom (finest_level + 1 );
@@ -4002,6 +4067,8 @@ void AMRSimulation<problem_t>::restartParticleContainerWithRefinement(std::uniqu
40024067 } else {
40034068 // Normal restart without refinement
40044069 particles->Restart (restart_chkfile, particle_type_name);
4070+ // Redistribute particles in case number of processes changed
4071+ particles->Redistribute ();
40054072 }
40064073}
40074074
0 commit comments