Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/master' into introduce_heat_so…
Browse files Browse the repository at this point in the history
…urces_work
  • Loading branch information
masterleinad committed Jul 24, 2024
2 parents 6f13c95 + e6cea1d commit 1f5f784
Show file tree
Hide file tree
Showing 20 changed files with 107,185 additions and 170 deletions.
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,8 @@ The following options are available:
* method: name of the method to use for the time integration: forward\_euler,
rk\_third\_order, rk\_fourth\_order, backward\_euler, implicit\_midpoint,
crank\_nicolson, or sdirk2 (required)
* duration: duration of the simulation in seconds (required)
* scan\_path\_for\_duration: if the flag is true, the duration of the simulation is determined by the duration of the scan path. In this case the scan path file needs to contain SCAN\_PATH\_END to terminate the simulation. If the flag is false, the duration of the simulation is determined by the duration input (default value: false)
* duration: duration of the simulation in seconds (required if scan\_path\_for\_duration is false)
* time\_step: length of the time steps used for the simulation in seconds (required)
* for implicit method:
* max\_iteration: mamximum number of the iterations of the linear solver
Expand Down
9 changes: 8 additions & 1 deletion application/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
# Create adamantine executable and link against the static library.
add_executable(adamantine adamantine.cc)
set(Adamantine_app_HEADERS
${CMAKE_CURRENT_SOURCE_DIR}/adamantine.hh
)
set(Adamantine_app_SOURCES
${CMAKE_CURRENT_SOURCE_DIR}/adamantine.cc
)
add_executable(adamantine ${Adamantine_app_SOURCES} ${Adamantine_app_HEADERS})

set_target_properties(adamantine PROPERTIES
CXX_STANDARD 17
CXX_STANDARD_REQUIRED ON
Expand Down
3 changes: 1 addition & 2 deletions application/adamantine.cc
Original file line number Diff line number Diff line change
Expand Up @@ -164,8 +164,7 @@ int main(int argc, char *argv[])

// Read the input.
std::string const filename = map["input-file"].as<std::string>();
// adamantine::wait_for_file(filename, "Waiting for input file: " +
// filename);
adamantine::wait_for_file(filename, "Waiting for input file: " + filename);
boost::property_tree::ptree database;
if (std::filesystem::path(filename).extension().native() == ".json")
{
Expand Down
187 changes: 126 additions & 61 deletions application/adamantine.hh
Original file line number Diff line number Diff line change
Expand Up @@ -758,7 +758,6 @@ run(MPI_Comm const &communicator, boost::property_tree::ptree const &database,
std::unique_ptr<adamantine::ThermalPhysicsInterface<dim, MemorySpaceType>>
thermal_physics;
adamantine::HeatSources<dim, dealii::MemorySpace::Host> heat_sources;
std::vector<std::pair<double, bool>> scan_path_end;
if (use_thermal_physics)
{
// PropertyTreeInput discretization.thermal.fe_degree
Expand All @@ -771,15 +770,6 @@ run(MPI_Comm const &communicator, boost::property_tree::ptree const &database,
fe_degree, quadrature_type, communicator, database, geometry,
material_properties);
heat_sources = thermal_physics->get_heat_sources();

// Store the current end time of each heat source and set a flag that the
// scan path has changed
auto const &scan_paths = heat_sources.get_scan_paths();
for (auto const &scan_path : scan_paths)
{
scan_path_end.emplace_back(scan_path.get_segment_list().back().end_time,
true);
}
post_processor_database.put("thermal_output", true);
}

Expand Down Expand Up @@ -954,8 +944,13 @@ run(MPI_Comm const &communicator, boost::property_tree::ptree const &database,
database.get_child("time_stepping");
// PropertyTreeInput time_stepping.time_step
double time_step = time_stepping_database.get<double>("time_step");
// PropertyTreeInput time_stepping.scan_path_for_duration
bool const scan_path_for_duration =
time_stepping_database.get("scan_path_for_duration", false);
// PropertyTreeInput time_stepping.duration
double const duration = time_stepping_database.get<double>("duration");
double const duration = scan_path_for_duration
? std::numeric_limits<double>::max()
: time_stepping_database.get<double>("duration");

// Extract the refinement database
boost::property_tree::ptree refinement_database =
Expand Down Expand Up @@ -1007,41 +1002,44 @@ run(MPI_Comm const &communicator, boost::property_tree::ptree const &database,
timers[adamantine::add_material_activate].start();
if (time > activation_time_end)
{
double const eps = time_step / 1e10;

// We may need to check if the scan path has been updated. We don't want
// to keep reading the file if it's not going to be updated. Once we
// reach the end of the scan path, we reread the scan path file. If it was
// not updated, we won't try to read it again.
bool scan_path_updated = false;
for (unsigned int s = 0; s < scan_path_end.size(); ++s)
// If we use scan_path_for_duration, we may need to read the scan path
// file once again.
if (scan_path_for_duration)
{
if ((time > scan_path_end[s].first - eps) && (scan_path_end[s].second))
// Check if we have reached the end of current scan path.
bool need_updated_scan_path = false;
auto const &scan_paths = heat_sources.get_scan_paths();
for (auto &scan_path : scan_paths)
{
scan_path_updated = true;
break;
if (time > scan_path.get_segment_list().back().end_time)
{
need_updated_scan_path = true;
break;
}
}
}
if (scan_path_updated)
{
heat_sources.update_scan_paths();

auto const &scan_paths = heat_sources.get_scan_paths();
for (unsigned int s = 0; s < scan_path_end.size(); ++s)
if (need_updated_scan_path)
{
// Update scan_path_end
double new_end_time =
scan_paths[s].get_segment_list().back().end_time;
scan_path_end[s].second = scan_path_end[s].first != new_end_time;
scan_path_end[s].first = new_end_time;
}
// Check if we have reached the end of the file. If not, read the
// updated scan path file
bool scan_path_end = heat_sources.update_scan_paths();

// If we have reached the end of scan path file for all the heat
// sources, we just exit.
if (scan_path_end)
{
break;
}

std::tie(material_deposition_boxes, deposition_times, deposition_cos,
deposition_sin) =
adamantine::create_material_deposition_boxes<dim>(geometry_database,
heat_sources);
std::tie(material_deposition_boxes, deposition_times, deposition_cos,
deposition_sin) =
adamantine::create_material_deposition_boxes<dim>(
geometry_database, heat_sources);
}
}

double const eps = time_step / 1e10;

auto activation_start =
std::lower_bound(deposition_times.begin(), deposition_times.end(),
time - eps) -
Expand Down Expand Up @@ -1480,8 +1478,7 @@ run_ensemble(MPI_Comm const &global_communicator,
checkpoint_database.get<unsigned int>("time_steps_between_checkpoint");
// PropertyTreeInput checkpoint.filename_prefix
checkpoint_filename =
checkpoint_database.get<std::string>("filename_prefix") + '_' +
std::to_string(global_rank);
checkpoint_database.get<std::string>("filename_prefix");
// PropertyTreeInput checkpoint.overwrite_files
checkpoint_overwrite = checkpoint_database.get<bool>("overwrite_files");
}
Expand Down Expand Up @@ -1600,6 +1597,27 @@ run_ensemble(MPI_Comm const &global_communicator,
global_communicator, post_processor_expt_database,
thermal_physics_ensemble[0]->get_dof_handler());

// ----- Initialize time and time stepping counters -----
unsigned int progress = 0;
unsigned int n_time_step = 0;
double time = 0.;
double activation_time_end = -1.;
if (restart == true)
{
if (global_rank == 0)
{
std::cout << "Restarting from file" << std::endl;
}
std::ifstream file{restart_filename + "_time.txt"};
boost::archive::text_iarchive ia{file};
ia >> time;
ia >> n_time_step;
}

// PropertyTreeInput geometry.deposition_time
double const activation_time =
geometry_database.get<double>("deposition_time", 0.);

// ----- Read the experimental data -----
std::vector<std::vector<double>> frame_time_stamps;
std::unique_ptr<adamantine::ExperimentalData<dim>> experimental_data;
Expand Down Expand Up @@ -1655,30 +1673,26 @@ run_ensemble(MPI_Comm const &global_communicator,
thermal_physics_ensemble[0]->get_dof_handler()));
}
}
}
}

// ----- Initialize time and time stepping counters -----
unsigned int progress = 0;
unsigned int n_time_step = 0;
double time = 0.;
double activation_time_end = -1.;
if (restart == true)
{
if (global_rank == 0)
{
std::cout << "Restarting from file" << std::endl;
// Advance the experimental frame counter upon restart, if necessary
if (restart)
{
bool found_frame = false;
while (!found_frame)
{
if (frame_time_stamps[0][experimental_frame_index + 1] < time)
{
experimental_frame_index++;
}
else
{
found_frame = true;
}
}
}
}
std::ifstream file{restart_filename + "_time.txt"};
boost::archive::text_iarchive ia{file};
ia >> time;
ia >> n_time_step;
}

// PropertyTreeInput geometry.deposition_time
double const activation_time =
geometry_database.get<double>("deposition_time", 0.);

// ----- Output the initial solution -----
std::unique_ptr<adamantine::MechanicalPhysics<dim, p_order, MaterialStates,
MemorySpaceType>>
Expand All @@ -1703,8 +1717,13 @@ run_ensemble(MPI_Comm const &global_communicator,
refinement_database.get("time_steps_between_refinement", 10);
// PropertyTreeInput time_stepping.time_step
double time_step = time_stepping_database.get<double>("time_step");
// PropertyTreeInput time_stepping.scan_path_for_duration
bool const scan_path_for_duration =
time_stepping_database.get("scan_path_for_duration", false);
// PropertyTreeInput time_stepping.duration
double const duration = time_stepping_database.get<double>("duration");
double const duration = scan_path_for_duration
? std::numeric_limits<double>::max()
: time_stepping_database.get<double>("duration");
// PropertyTreeInput post_processor.time_steps_between_output
unsigned int const time_steps_output =
post_processor_database.get("time_steps_between_output", 1);
Expand Down Expand Up @@ -1781,6 +1800,52 @@ run_ensemble(MPI_Comm const &global_communicator,
timers[adamantine::add_material_activate].start();
if (time > activation_time_end)
{
// If we use scan_path_for_duration, we may need to read the scan path
// file once again.
if (scan_path_for_duration)
{
// Check if we have reached the end of current scan path.
bool need_updated_scan_path = false;
{
auto const &scan_paths = heat_sources_ensemble[0].get_scan_paths();
for (auto &scan_path : scan_paths)
{
if (time > scan_path.get_segment_list().back().end_time)
{
need_updated_scan_path = true;
break;
}
}
}

if (need_updated_scan_path)
{
// Check if we have reached the end of the file. If not, read the
// updated scan path file. We assume that the scan paths are identical
// for all the heat sources and thus, we can use
// heat_sources_ensemble[0] to get the material deposition boxes and
// times. We still need every ensemble member to read the scan path in
// order to compute the correct heat sources.
bool scan_path_end = true;
for (unsigned int member = 0; member < local_ensemble_size; ++member)
{
scan_path_end &= heat_sources_ensemble[member].update_scan_paths();
}

// If we have reached the end of scan path file for all the heat
// sources, we just exit.
if (scan_path_end)
{
break;
}

std::tie(material_deposition_boxes, deposition_times, deposition_cos,
deposition_sin) =
adamantine::create_material_deposition_boxes<dim>(
geometry_database, heat_sources_ensemble[0]);
}
}

double const eps = time_step / 1e12;
auto activation_start =
std::lower_bound(deposition_times.begin(), deposition_times.end(),
Expand Down
4 changes: 2 additions & 2 deletions ci/jenkins_config
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ pipeline {
..
'''
sh 'make -j8'
sh 'ctest --no-compress-output -R test_ -T Test'
sh 'ctest --timeout 3600 --no-compress-output -R test_ -T Test'
}
}
post {
Expand Down Expand Up @@ -70,7 +70,7 @@ pipeline {
..
'''
sh 'make -j8'
sh 'ctest --no-compress-output -R test_ -T Test'
sh 'ctest --timeout 3600 --no-compress-output -R test_ -T Test'
}
}
post {
Expand Down
2 changes: 1 addition & 1 deletion source/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ set(Adamantine_SOURCES
# Because the Adamantine library is just used to simplify testing, we make it
# static. Thus, once the application is created it can be moved around. The
# other libraries can still be shared.
add_library(Adamantine STATIC ${Adamantine_SOURCES})
add_library(Adamantine STATIC ${Adamantine_SOURCES} ${Adamantine_HEADERS})

DEAL_II_SETUP_TARGET(Adamantine)

Expand Down
Loading

0 comments on commit 1f5f784

Please sign in to comment.