diff --git a/CMakeLists.txt b/CMakeLists.txt index ea66af76..0273a882 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -28,6 +28,17 @@ endmacro() CabanaPD_check_optional( OPTION HDF5 ) CabanaPD_check_optional( OPTION SILO ) +if (${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.24") + cmake_policy(SET CMP0135 NEW) +endif() +find_package(nlohmann_json 3.10.0 QUIET) +if(NOT NLOHMANN_JSON_FOUND) + include(FetchContent) + # Using most recent release here + FetchContent_Declare(json URL https://github.com/nlohmann/json/releases/download/v3.11.2/json.tar.xz) + FetchContent_MakeAvailable(json) +endif() + configure_file(${CMAKE_CURRENT_SOURCE_DIR}/cmake/CabanaPD_Config.cmakein ${CMAKE_CURRENT_BINARY_DIR}/CabanaPD_Config.cmake @ONLY) diff --git a/examples/crack_branching.cpp b/examples/crack_branching.cpp index e4c8ddd0..2d919fef 100644 --- a/examples/crack_branching.cpp +++ b/examples/crack_branching.cpp @@ -29,47 +29,34 @@ int main( int argc, char* argv[] ) using exec_space = Kokkos::DefaultExecutionSpace; using memory_space = typename exec_space::memory_space; - // Plate dimensions (m) - double height = 0.1; - double width = 0.04; - double thickness = 0.002; - - // Domain - std::array num_cell = { 400, 160, 8 }; // 400 x 160 x 8 - double low_x = -0.5 * height; - double low_y = -0.5 * width; - double low_z = -0.5 * thickness; - double high_x = 0.5 * height; - double high_y = 0.5 * width; - double high_z = 0.5 * thickness; - std::array low_corner = { low_x, low_y, low_z }; - std::array high_corner = { high_x, high_y, high_z }; - - // Time - double t_final = 43e-6; - double dt = 5e-8; - double output_frequency = 5; - bool output_reference = true; + CabanaPD::Inputs inputs( argv[1] ); // Material constants - double E = 72e+9; // [Pa] - double nu = 0.25; // unitless - double K = E / ( 3 * ( 1 - 2 * nu ) ); // [Pa] - double rho0 = 2440; // [kg/m^3] - double G0 = 3.8; // [J/m^2] + double E = inputs["elastic_modulus"]; + double nu = 0.25; + double K = E / ( 3 * ( 1 - 2 * nu ) ); + double rho0 = inputs["density"]; + double G0 = inputs["fracture_energy"]; // PD horizon - double delta = 0.001 + 1e-10; + double delta = inputs["horizon"]; + delta += 1e-10; // FIXME: set halo width based on delta + std::array low_corner = inputs["low_corner"]; + std::array high_corner = inputs["high_corner"]; + std::array num_cells = inputs["num_cells"]; int m = std::floor( - delta / ( ( high_corner[0] - low_corner[0] ) / num_cell[0] ) ); - int halo_width = m + 1; + delta / ( ( high_corner[0] - low_corner[0] ) / num_cells[0] ) ); + int halo_width = m + 1; // Just to be safe. // Prenotch + double height = inputs["system_size"][0]; + double thickness = inputs["system_size"][2]; double L_prenotch = height / 2.0; double y_prenotch1 = 0.0; - Kokkos::Array p01 = { low_x, y_prenotch1, low_z }; + Kokkos::Array p01 = { low_corner[0], y_prenotch1, + low_corner[2] }; Kokkos::Array v1 = { L_prenotch, 0, 0 }; Kokkos::Array v2 = { 0, 0, thickness }; Kokkos::Array, 1> notch_positions = { p01 }; @@ -79,16 +66,12 @@ int main( int argc, char* argv[] ) using model_type = CabanaPD::ForceModel; model_type force_model( delta, K, G0 ); - CabanaPD::Inputs<3> inputs( num_cell, low_corner, high_corner, t_final, - dt, output_frequency, output_reference ); - inputs.read_args( argc, argv ); // Create particles from mesh. // Does not set displacements, velocities, etc. auto particles = std::make_shared< CabanaPD::Particles>( - exec_space(), inputs.low_corner, inputs.high_corner, - inputs.num_cells, halo_width ); + exec_space(), low_corner, high_corner, num_cells, halo_width ); // Define particle initialization. auto x = particles->sliceReferencePosition(); @@ -97,14 +80,16 @@ int main( int argc, char* argv[] ) auto rho = particles->sliceDensity(); auto nofail = particles->sliceNoFail(); - // Relying on uniform grid here. double dy = particles->dx[1]; - double b0 = 2e6 / dy; // Pa/m - - CabanaPD::RegionBoundary plane1( low_x, high_x, low_y - dy, low_y + dy, - low_z, high_z ); - CabanaPD::RegionBoundary plane2( low_x, high_x, high_y - dy, - high_y + dy, low_z, high_z ); + double sigma0 = inputs["traction"]; + double b0 = sigma0 / dy; + + CabanaPD::RegionBoundary plane1( low_corner[0], high_corner[0], + low_corner[1] - dy, low_corner[1] + dy, + low_corner[2], high_corner[2] ); + CabanaPD::RegionBoundary plane2( + low_corner[0], high_corner[0], high_corner[1] - dy, + high_corner[1] + dy, low_corner[2], high_corner[2] ); std::vector planes = { plane1, plane2 }; auto bc = createBoundaryCondition( CabanaPD::ForceCrackBranchBCTag{}, @@ -120,7 +105,6 @@ int main( int argc, char* argv[] ) }; particles->updateParticles( exec_space{}, init_functor ); - // FIXME: use createSolver to switch backend at runtime. auto cabana_pd = CabanaPD::createSolverFracture( inputs, particles, force_model, bc, prenotch ); cabana_pd->init_force(); diff --git a/examples/elastic_wave.cpp b/examples/elastic_wave.cpp index 74271326..61c46ed2 100644 --- a/examples/elastic_wave.cpp +++ b/examples/elastic_wave.cpp @@ -25,22 +25,26 @@ int main( int argc, char* argv[] ) { Kokkos::ScopeGuard scope_guard( argc, argv ); - // FIXME: change backend at compile time for now. using exec_space = Kokkos::DefaultExecutionSpace; using memory_space = typename exec_space::memory_space; - std::array num_cell = { 41, 41, 41 }; - std::array low_corner = { -0.5, -0.5, -0.5 }; - std::array high_corner = { 0.5, 0.5, 0.5 }; - double t_final = 0.6; - double dt = 0.01; - int output_frequency = 5; - bool output_reference = true; - double K = 1.0; - double G = 0.5; - double delta = 0.075; + CabanaPD::Inputs inputs( argv[1] ); + + // Material constants + auto K = inputs["bulk_modulus"]; + double G = inputs["shear_modulus"]; + double rho0 = inputs["density"]; + + // PD horizon + double delta = inputs["horizon"]; + delta += 1e-10; + + // FIXME: set halo width based on delta + std::array low_corner = inputs["low_corner"]; + std::array high_corner = inputs["high_corner"]; + std::array num_cells = inputs["num_cells"]; int m = std::floor( - delta / ( ( high_corner[0] - low_corner[0] ) / num_cell[0] ) ); + delta / ( ( high_corner[0] - low_corner[0] ) / num_cells[0] ) ); int halo_width = m + 1; // Just to be safe. // Choose force model type. @@ -51,16 +55,11 @@ int main( int argc, char* argv[] ) CabanaPD::ForceModel; model_type force_model( delta, K, G ); - CabanaPD::Inputs<3> inputs( num_cell, low_corner, high_corner, t_final, - dt, output_frequency, output_reference ); - inputs.read_args( argc, argv ); - // Create particles from mesh. // Does not set displacements, velocities, etc. auto particles = std::make_shared< CabanaPD::Particles>( - exec_space(), inputs.low_corner, inputs.high_corner, - inputs.num_cells, halo_width ); + exec_space(), low_corner, high_corner, num_cells, halo_width ); // Define particle initialization. auto x = particles->sliceReferencePosition(); @@ -86,7 +85,7 @@ int main( int argc, char* argv[] ) u( pid, d ) = a * std::exp( -arg ) * comp; v( pid, d ) = 0.0; } - rho( pid ) = 100.0; + rho( pid ) = rho0; }; particles->updateParticles( exec_space{}, init_functor ); @@ -97,7 +96,7 @@ int main( int argc, char* argv[] ) x = particles->sliceReferencePosition(); u = particles->sliceDisplacement(); - double num_cell_x = inputs.num_cells[0]; + int num_cell_x = num_cells[0]; auto profile = Kokkos::View( Kokkos::ViewAllocateWithoutInitializing( "displacement_profile" ), num_cell_x ); diff --git a/examples/inputs/crack_branching.json b/examples/inputs/crack_branching.json new file mode 100644 index 00000000..d92836f9 --- /dev/null +++ b/examples/inputs/crack_branching.json @@ -0,0 +1,13 @@ +{ + "num_cells" : {"value": [400, 160, 8]}, + "system_size" : {"value": [0.1, 0.04, 0.002], "unit": "m"}, + "density" : {"value": 2440, "unit": "kg/m^3"}, + "elastic_modulus" : {"value": 72e+9, "unit": "Pa"}, + "fracture_energy" : {"value": 3.8, "unit": "J/m^2"}, + "horizon" : {"value": 0.001, "unit": "m"}, + "traction" : {"value": 2e6, "unit": "Pa"}, + "final_time" : {"value": 43e-6, "unit": "s"}, + "timestep" : {"value": 5e-8, "unit": "s"}, + "output_frequency": {"value": 5}, + "output_reference": {"value": true} +} diff --git a/examples/inputs/elastic_wave.json b/examples/inputs/elastic_wave.json new file mode 100644 index 00000000..75f798e9 --- /dev/null +++ b/examples/inputs/elastic_wave.json @@ -0,0 +1,12 @@ +{ + "num_cells" : {"value": [41, 41, 41]}, + "system_size" : {"value": [1.0, 1.0, 1.0], "unit": ""}, + "density" : {"value": 100.0, "unit": ""}, + "bulk_modulus" : {"value": 1.0, "unit": ""}, + "shear_modulus" : {"value": 0.5, "unit": ""}, + "horizon" : {"value": 0.075, "unit": ""}, + "final_time" : {"value": 0.6, "unit": ""}, + "timestep" : {"value": 0.01, "unit": ""}, + "output_frequency": {"value": 5}, + "output_reference": {"value": true} +} diff --git a/examples/inputs/kalthoff_winkler.json b/examples/inputs/kalthoff_winkler.json new file mode 100644 index 00000000..b2a8ba78 --- /dev/null +++ b/examples/inputs/kalthoff_winkler.json @@ -0,0 +1,13 @@ +{ + "num_cells" : {"value": [151, 301, 14]}, + "system_size" : {"value": [0.1, 0.2, 0.009], "unit": "m"}, + "density" : {"value": 8000, "unit": "kg/m^3"}, + "elastic_modulus" : {"value": 191e+9, "unit": "Pa"}, + "fracture_energy" : {"value": 42408, "unit": "J/m^2"}, + "horizon" : {"value": 0.002, "unit": "m"}, + "impactor_velocity" : {"value": 16, "unit": "m/sec"}, + "final_time" : {"value": 70e-6, "unit": "s"}, + "timestep" : {"value": 0.133e-6, "unit": "s"}, + "output_frequency" : {"value": 10}, + "output_reference" : {"value": true} +} diff --git a/examples/kalthoff_winkler.cpp b/examples/kalthoff_winkler.cpp index 4c072975..11479180 100644 --- a/examples/kalthoff_winkler.cpp +++ b/examples/kalthoff_winkler.cpp @@ -25,56 +25,52 @@ int main( int argc, char* argv[] ) { Kokkos::ScopeGuard scope_guard( argc, argv ); - // FIXME: change backend at compile time for now. using exec_space = Kokkos::DefaultExecutionSpace; using memory_space = typename exec_space::memory_space; - // Plate dimension) - double height = 0.1; // [m] (100 mm) - double width = 0.2; // [m] (200 mm) - double thickness = 0.009; // [m] ( 9 mm) - - // Domain - // This is a relatively large example for CPU - reduce the number of - // cells and increase delta if needed. Note this is also a relatively - // small example for GPU. - std::array num_cell = { 151, 301, 14 }; - std::array low_corner = { -0.5 * height, -0.5 * width, - -0.5 * thickness }; - std::array high_corner = { 0.5 * height, 0.5 * width, - 0.5 * thickness }; - double t_final = 70e-6; - double dt = 0.133e-6; - int output_frequency = 10; - bool output_reference = true; + CabanaPD::Inputs inputs( argv[1] ); // Material constants - double E = 191e+9; // [Pa] - double nu = 1.0 / 3.0; // unitless - double K = E / ( 3.0 * ( 1.0 - 2.0 * nu ) ); // [Pa] - double rho0 = 8000; // [kg/m^3] - double G0 = 42408; // [J/m^2] + double E = inputs["elastic_modulus"]; + double nu = 1.0 / 3.0; + double K = E / ( 3.0 * ( 1.0 - 2.0 * nu ) ); + double rho0 = inputs["density"]; + double G0 = inputs["fracture_energy"]; // double G = E / ( 2.0 * ( 1.0 + nu ) ); // Only for LPS. - double v0 = 16; // [m/sec] (Half impactor's velocity) - double L_prenotch = 0.05; // [m] (50 mm) - double y_prenotch1 = -0.025; // [m] (-25 mm) - double y_prenotch2 = 0.025; // [m] ( 25 mm) - Kokkos::Array p01 = { low_corner[0], y_prenotch1, - low_corner[2] }; - Kokkos::Array p02 = { low_corner[0], y_prenotch2, - low_corner[2] }; + // PD horizon + double delta = inputs["horizon"]; + delta += 1e-10; + + // Impactor velocity + double v0 = inputs["impactor_velocity"]; + + // FIXME: set halo width based on delta + std::array low_corner = inputs["low_corner"]; + std::array high_corner = inputs["high_corner"]; + std::array num_cells = inputs["num_cells"]; + int m = std::floor( + delta / ( ( high_corner[0] - low_corner[0] ) / num_cells[0] ) ); + int halo_width = m + 1; // Just to be safe. + + // Prenotches + std::array system_size = inputs["system_size"]; + double height = system_size[0]; + double width = system_size[1]; + double thickness = system_size[2]; + double L_prenotch = height / 2.0; + double y_prenotch1 = -width / 8.0; + double y_prenotch2 = width / 8.0; + double low_x = low_corner[0]; + double low_z = low_corner[2]; + Kokkos::Array p01 = { low_x, y_prenotch1, low_z }; + Kokkos::Array p02 = { low_x, y_prenotch2, low_z }; Kokkos::Array v1 = { L_prenotch, 0, 0 }; Kokkos::Array v2 = { 0, 0, thickness }; Kokkos::Array, 2> notch_positions = { p01, p02 }; CabanaPD::Prenotch<2> prenotch( v1, v2, notch_positions ); - double delta = 0.0020000001; - int m = std::floor( - delta / ( ( high_corner[0] - low_corner[0] ) / num_cell[0] ) ); - int halo_width = m + 1; // Just to be safe. - // Choose force model type. using model_type = CabanaPD::ForceModel; @@ -82,16 +78,12 @@ int main( int argc, char* argv[] ) // using model_type = // CabanaPD::ForceModel; // model_type force_model( delta, K, G, G0 ); - CabanaPD::Inputs<3> inputs( num_cell, low_corner, high_corner, t_final, - dt, output_frequency, output_reference ); - inputs.read_args( argc, argv ); // Create particles from mesh. // Does not set displacements, velocities, etc. auto particles = std::make_shared< CabanaPD::Particles>( - exec_space(), inputs.low_corner, inputs.high_corner, - inputs.num_cells, halo_width ); + exec_space(), low_corner, high_corner, num_cells, halo_width ); // Define particle initialization. auto x = particles->sliceReferencePosition(); @@ -100,7 +92,6 @@ int main( int argc, char* argv[] ) auto rho = particles->sliceDensity(); double dx = particles->dx[0]; - double x_bc = -0.5 * height; CabanaPD::RegionBoundary plane( x_bc - dx, x_bc + dx * 1.25, y_prenotch1 - dx * 0.25, diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 5a72ec8c..970423d8 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -11,6 +11,6 @@ target_include_directories(CabanaPD INTERFACE ${CMAKE_CURRENT_SOURCE_DIR} $ $) -target_link_libraries(CabanaPD INTERFACE Cabana::cabanacore Cabana::Cajita) +target_link_libraries(CabanaPD INTERFACE Cabana::cabanacore Cabana::Cajita nlohmann_json::nlohmann_json) install(TARGETS CabanaPD DESTINATION ${CMAKE_INSTALL_LIBDIR}) diff --git a/src/CabanaPD_Input.hpp b/src/CabanaPD_Input.hpp index 51b28f59..38034a54 100644 --- a/src/CabanaPD_Input.hpp +++ b/src/CabanaPD_Input.hpp @@ -12,102 +12,85 @@ #ifndef INPUTS_H #define INPUTS_H +#include +#include #include -#include +#include namespace CabanaPD { -template class Inputs { public: - std::string output_file = "cabanaPD.out"; - std::string error_file = "cabanaPD.err"; - std::string device_type = "SERIAL"; - - std::array num_cells; - std::array low_corner; - std::array high_corner; - - std::size_t num_steps; - double final_time; - double timestep; - int output_frequency; - bool output_reference; - - bool half_neigh = false; - - Inputs( const std::array nc, std::array lc, - std::array hc, const double t_f, const double dt, - const int of, const bool output_ref ) - : num_cells( nc ) - , low_corner( lc ) - , high_corner( hc ) - , final_time( t_f ) - , timestep( dt ) - , output_frequency( of ) - , output_reference( output_ref ) + Inputs( const std::string filename ) { - num_steps = final_time / timestep; - } - ~Inputs(){}; + // Get user inputs. + inputs = parse( filename ); - void read_args( int argc, char* argv[] ) - { - for ( int i = 1; i < argc; i++ ) + // Add additional derived inputs to json. System size. + auto size = inputs["system_size"]["value"]; + std::string size_unit = inputs["system_size"]["unit"]; + for ( std::size_t d = 0; d < size.size(); d++ ) { - // Help command. - if ( ( strcmp( argv[i], "-h" ) == 0 ) || - ( strcmp( argv[i], "--help" ) == 0 ) ) - { - if ( print_rank() ) - { - log( std::cout, "CabanaPD\n", "Options:" ); - log( std::cout, " -o [FILE] (OR)\n" - " --output-file [FILE]: Provide output " - "file name\n" ); - log( - std::cout, - " -e [FILE] (OR)\n" - " --error-file [FILE]: Provide error file name\n" ); - /* Not yet enabled. - log( - std::cout, - " --device-type [TYPE]: Kokkos device type to run - ", "with\n", " (SERIAL, - PTHREAD, OPENMP, " "CUDA, HIP)" ); - */ - } - } - // Output file names. - else if ( ( strcmp( argv[i], "-o" ) == 0 ) || - ( strcmp( argv[i], "--output-file" ) == 0 ) ) - { - output_file = argv[i + 1]; - ++i; - } - else if ( ( strcmp( argv[i], "-e" ) == 0 ) || - ( strcmp( argv[i], "--error-file" ) == 0 ) ) - { - error_file = argv[i + 1]; - ++i; - } - - // Kokkos device type. - else if ( ( strcmp( argv[i], "--device-type" ) == 0 ) ) - { - device_type = argv[i + 1]; - ++i; - } - - else if ( ( strstr( argv[i], "--kokkos-" ) == NULL ) ) - { - log_err( std::cout, - "Unknown command line argument: ", argv[i] ); - } + double s = size[d]; + inputs["low_corner"]["value"][d] = -0.5 * s; + inputs["low_corner"]["unit"][d] = size_unit; + inputs["high_corner"]["value"][d] = 0.5 * s; + inputs["high_corner"]["unit"][d] = size_unit; } + // Number of steps. + double tf = inputs["final_time"]["value"]; + double dt = inputs["timestep"]["value"]; + int num_steps = tf / dt; + inputs["num_steps"]["value"] = num_steps; + + // Output files. + if ( !inputs.contains( "output_file" ) ) + inputs["output_file"]["value"] = "cabanaPD.out"; + if ( !inputs.contains( "error_file" ) ) + inputs["error_file"]["value"] = "cabanaPD.err"; + inputs["input_file"]["value"] = filename; + + // Save inputs (including derived) to new file. + std::string input_file = "cabanaPD.in.json"; + if ( !inputs.contains( "exported_input_file" ) ) + inputs["exported_input_file"]["value"] = input_file; + std::ofstream in( input_file ); + in << inputs; + + if ( !inputs.contains( "output_reference" ) ) + inputs["output_reference"]["value"] = true; + + // Not yet a user option. + inputs["half_neigh"]["value"] = false; } + ~Inputs() {} + + // Parse JSON file. + inline nlohmann::json parse( const std::string& filename ) + { + std::ifstream stream( filename ); + return nlohmann::json::parse( stream ); + } + + // Get a single input. + auto operator[]( std::string label ) { return inputs[label]["value"]; } + + // Get a single input. + std::string units( std::string label ) + { + if ( inputs[label].contains( "units" ) ) + return inputs[label]["units"]; + else + return ""; + } + + // Check a key exists. + bool contains( std::string label ) { return inputs.contains( label ); } + + protected: + nlohmann::json inputs; }; } // namespace CabanaPD diff --git a/src/CabanaPD_Solver.hpp b/src/CabanaPD_Solver.hpp index 07407f86..ac718b31 100644 --- a/src/CabanaPD_Solver.hpp +++ b/src/CabanaPD_Solver.hpp @@ -112,8 +112,8 @@ class SolverElastic SolverElastic( input_type _inputs, std::shared_ptr _particles, force_model_type force_model ) - : particles( _particles ) - , inputs( std::make_shared( _inputs ) ) + : inputs( _inputs ) + , particles( _particles ) { force_time = 0; integrate_time = 0; @@ -124,12 +124,13 @@ class SolverElastic total_timer.reset(); init_timer.reset(); - num_steps = inputs->num_steps; - output_frequency = inputs->output_frequency; - output_reference = inputs->output_reference; + num_steps = inputs["num_steps"]; + output_frequency = inputs["output_frequency"]; + output_reference = inputs["output_reference"]; // Create integrator. - integrator = std::make_shared( inputs->timestep ); + dt = inputs["timestep"]; + integrator = std::make_shared( dt ); // Add ghosts from other MPI ranks. comm = std::make_shared( *particles ); @@ -148,7 +149,8 @@ class SolverElastic int max_neighbors = Cabana::NeighborList::maxNeighbor( *neighbors ); - force = std::make_shared( inputs->half_neigh, force_model ); + force = + std::make_shared( inputs["half_neigh"], force_model ); print = print_rank(); if ( print ) @@ -157,8 +159,10 @@ class SolverElastic ", Maximum local neighbors: ", max_neighbors ); log( std::cout, "#Timestep/Total-steps Simulation-time" ); - std::ofstream out( inputs->output_file, std::ofstream::app ); - std::ofstream err( inputs->error_file, std::ofstream::app ); + output_file = inputs["output_file"]; + std::ofstream out( output_file, std::ofstream::app ); + error_file = inputs["error_file"]; + std::ofstream err( error_file, std::ofstream::app ); auto time = std::chrono::system_clock::to_time_t( std::chrono::system_clock::now() ); @@ -238,8 +242,8 @@ class SolverElastic neigh_iter_tag() ); step_output( step, W ); - particles->output( step / output_frequency, - step * inputs->timestep, output_reference ); + particles->output( step / output_frequency, step * dt, + output_reference ); } other_time += other_timer.seconds(); } @@ -251,7 +255,7 @@ class SolverElastic void init_output() { // Output after construction and initial forces. - std::ofstream out( inputs->output_file, std::ofstream::app ); + std::ofstream out( output_file, std::ofstream::app ); log( out, "Init-Time(s): ", init_time, "\n" ); log( out, "#Timestep/Total-steps Simulation-time Total-strain-energy " "Run-Time(s) Force-Time(s) Comm-Time(s) Int-Time(s) " @@ -262,18 +266,18 @@ class SolverElastic { if ( print ) { - std::ofstream out( inputs->output_file, std::ofstream::app ); + std::ofstream out( output_file, std::ofstream::app ); log( std::cout, step, "/", num_steps, " ", std::scientific, - std::setprecision( 2 ), step * inputs->timestep ); + std::setprecision( 2 ), step * dt ); total_time = total_timer.seconds(); double rate = 1.0 * particles->n_global * output_frequency / ( total_time - last_time ); log( out, std::fixed, std::setprecision( 6 ), step, "/", num_steps, - " ", std::scientific, std::setprecision( 2 ), - step * inputs->timestep, " ", W, " ", std::fixed, total_time, - " ", force_time, " ", comm_time, " ", integrate_time, " ", - other_time, " ", std::scientific, rate ); + " ", std::scientific, std::setprecision( 2 ), step * dt, " ", + W, " ", std::fixed, total_time, " ", force_time, " ", + comm_time, " ", integrate_time, " ", other_time, " ", + std::scientific, rate ); last_time = total_time; out.close(); } @@ -283,7 +287,7 @@ class SolverElastic { if ( print ) { - std::ofstream out( inputs->output_file, std::ofstream::app ); + std::ofstream out( output_file, std::ofstream::app ); total_time = total_timer.seconds(); double steps_per_sec = 1.0 * num_steps / total_time; double p_steps_per_sec = particles->n_global * steps_per_sec; @@ -307,15 +311,19 @@ class SolverElastic int num_steps; int output_frequency; bool output_reference; + double dt; protected: + input_type inputs; std::shared_ptr particles; - std::shared_ptr inputs; std::shared_ptr comm; std::shared_ptr integrator; std::shared_ptr force; std::shared_ptr neighbors; + std::string output_file; + std::string error_file; + double total_time; double force_time; double integrate_time; @@ -451,8 +459,8 @@ class SolverFracture neigh_iter_tag() ); this->step_output( step, W ); - particles->output( step / output_frequency, - step * inputs->timestep, output_reference ); + particles->output( step / output_frequency, step * dt, + output_reference ); } other_time += other_timer.seconds(); } @@ -461,6 +469,7 @@ class SolverFracture this->final_output(); } + using base_type::dt; using base_type::num_steps; using base_type::output_frequency; using base_type::output_reference; @@ -518,50 +527,6 @@ auto createSolverFracture( InputsType inputs, prenotch ); } -/* -template -std::shared_ptr createSolver( Inputs inputs, - Particles particles ) -{ - std::string device_type = inputs.device_type; - if ( device_type.compare( "SERIAL" ) == 0 ) - { -#ifdef KOKKOS_ENABLE_SERIAL - return std::make_shared, ForceModel>>( - inputs, particles ); -#endif - } - else if ( device_type.compare( "OPENMP" ) == 0 ) - { -#ifdef KOKKOS_ENABLE_OPENMP - return std::make_shared, ForceModel>>( - inputs, particles ); -#endif - } - else if ( device_type.compare( "CUDA" ) == 0 ) - { -#ifdef KOKKOS_ENABLE_CUDA - return std::make_shared, ForceModel>>( - inputs, particles ); -#endif - } - else if ( device_type.compare( "HIP" ) == 0 ) - { -#ifdef KOKKOS_ENABLE_HIP - return std::make_shared< - Solver, - ForceModel>>( inputs, particles ); -#endif - } - - log_err( std::cout, "Unknown backend: ", device_type ); - return nullptr; -} -*/ } // namespace CabanaPD #endif