20 #include "axom/core.hpp"
28 #include "smith/infrastructure/application_manager.hpp"
34 #include "smith/smith_config.hpp"
46 inlet.addDouble(
"t_final",
"Final time for simulation.").defaultValue(1.0);
47 inlet.addDouble(
"dt",
"Time step.").defaultValue(0.25);
50 auto& mesh_table = inlet.addStruct(
"main_mesh",
"The main mesh for the problem");
54 auto& solid_solver_table = inlet.addStruct(
"solid",
"Finite deformation solid mechanics module");
58 auto& heat_transfer_solver_table = inlet.addStruct(
"heat_transfer",
"Heat transfer module");
62 if (!inlet.verify()) {
63 SLIC_ERROR_ROOT(
"Input file failed to verify.");
83 int dim,
int order, std::optional<smith::SolidMechanicsInputOptions> solid_mechanics_options,
84 std::optional<smith::HeatTransferInputOptions> heat_transfer_options, std::string mesh_tag,
int cycle,
double t)
86 std::unique_ptr<smith::BasePhysics> main_physics;
88 if (solid_mechanics_options) {
92 std::make_unique<smith::SolidMechanics<1, 2>>(*solid_mechanics_options,
"smith", mesh_tag, cycle, t);
93 }
else if (dim == 3) {
95 std::make_unique<smith::SolidMechanics<1, 3>>(*solid_mechanics_options,
"smith", mesh_tag, cycle, t);
97 }
else if (order == 2) {
100 std::make_unique<smith::SolidMechanics<2, 2>>(*solid_mechanics_options,
"smith", mesh_tag, cycle, t);
101 }
else if (dim == 3) {
103 std::make_unique<smith::SolidMechanics<2, 3>>(*solid_mechanics_options,
"smith", mesh_tag, cycle, t);
105 }
else if (order == 3) {
108 std::make_unique<smith::SolidMechanics<3, 2>>(*solid_mechanics_options,
"smith", mesh_tag, cycle, t);
109 }
else if (dim == 3) {
111 std::make_unique<smith::SolidMechanics<3, 3>>(*solid_mechanics_options,
"smith", mesh_tag, cycle, t);
114 }
else if (heat_transfer_options) {
117 main_physics = std::make_unique<smith::HeatTransfer<1, 2>>(*heat_transfer_options,
"smith", mesh_tag, cycle, t);
118 }
else if (dim == 3) {
119 main_physics = std::make_unique<smith::HeatTransfer<1, 3>>(*heat_transfer_options,
"smith", mesh_tag, cycle, t);
121 }
else if (order == 2) {
123 main_physics = std::make_unique<smith::HeatTransfer<2, 2>>(*heat_transfer_options,
"smith", mesh_tag, cycle, t);
124 }
else if (dim == 3) {
125 main_physics = std::make_unique<smith::HeatTransfer<2, 3>>(*heat_transfer_options,
"smith", mesh_tag, cycle, t);
127 }
else if (order == 3) {
129 main_physics = std::make_unique<smith::HeatTransfer<3, 2>>(*heat_transfer_options,
"smith", mesh_tag, cycle, t);
130 }
else if (dim == 3) {
131 main_physics = std::make_unique<smith::HeatTransfer<3, 3>>(*heat_transfer_options,
"smith", mesh_tag, cycle, t);
135 SLIC_ERROR_ROOT(
"Neither solid or heat_transfer blocks specified in the input file.");
148 int getOrder(std::optional<smith::SolidMechanicsInputOptions> solid_mechanics_options,
149 std::optional<smith::HeatTransferInputOptions> heat_transfer_options)
152 if (solid_mechanics_options) {
153 order = solid_mechanics_options->order;
154 }
else if (heat_transfer_options) {
155 order = heat_transfer_options->order;
157 SLIC_ERROR_ROOT(
"Neither solid or heat_transfer blocks specified in the input file.");
159 SLIC_ERROR_ROOT_IF(order < 1 || order > 3,
160 axom::fmt::format(
"Invalid solver order '{0}' given. Valid values are 1, 2, or 3.", order));
172 int main(
int argc,
char* argv[])
177 std::unordered_map<std::string, std::string> cli_opts =
182 bool print_version = cli_opts.find(
"version") != cli_opts.end();
193 std::string input_file_path =
"";
194 auto search = cli_opts.find(
"input-file");
195 if (search != cli_opts.end()) {
196 input_file_path = search->second;
205 std::string output_directory =
"";
206 search = cli_opts.find(
"output-directory");
207 if (search != cli_opts.end()) {
208 output_directory = search->second;
210 axom::utilities::filesystem::makeDirsForPath(output_directory);
212 search = cli_opts.find(
"paraview-directory");
214 std::optional<std::string> paraview_output_dir = {};
215 if (search != cli_opts.end()) {
216 paraview_output_dir = search->second;
217 axom::utilities::filesystem::makeDirsForPath(*paraview_output_dir);
221 std::optional<int> restart_cycle;
222 if (
auto cycle = cli_opts.find(
"restart-cycle"); cycle != cli_opts.end()) {
223 restart_cycle = std::stoi(cycle->second);
227 axom::sidre::DataStore datastore;
237 bool create_input_file_docs = cli_opts.find(
"create-input-file-docs") != cli_opts.end();
238 if (create_input_file_docs) {
239 std::string input_docs_path = axom::utilities::filesystem::joinPath(output_directory,
"smith_input.rst");
240 inlet.write(axom::inlet::SphinxWriter(input_docs_path));
245 if (cli_opts.find(
"print-unused") != cli_opts.end()) {
246 const std::vector<std::string> all_unexpected_names = inlet.unexpectedNames();
247 if (all_unexpected_names.size() != 0) {
248 SLIC_INFO(
"Printing unused entries in input file:");
249 for (
auto& x : all_unexpected_names) {
253 SLIC_INFO(
"No unused entries in input file.");
259 std::string input_values_path = axom::utilities::filesystem::joinPath(output_directory,
"smith_input_values.json");
260 datastore.getRoot()->getGroup(
"input_file")->save(input_values_path,
"json");
264 double t_final = inlet[
"t_final"];
265 double dt = inlet[
"dt"];
268 std::string mesh_tag{
"mesh"};
271 if (!restart_cycle) {
274 if (
const auto file_opts = std::get_if<smith::mesh::FileInputOptions>(&mesh_options.extra_options)) {
275 file_opts->absolute_mesh_file_name =
283 cycle = *restart_cycle;
287 std::optional<smith::SolidMechanicsInputOptions> solid_mechanics_options;
288 std::optional<smith::HeatTransferInputOptions> heat_transfer_options;
291 if (inlet.isUserProvided(
"solid")) {
294 if (inlet.isUserProvided(
"heat_transfer")) {
300 SLIC_ERROR_ROOT_IF(dim < 2 || dim > 3,
301 axom::fmt::format(
"Invalid mesh dimension '{0}' provided. Valid values are 2 or 3.", dim));
302 int order =
getOrder(solid_mechanics_options, heat_transfer_options);
305 auto main_physics =
createPhysics(dim, order, solid_mechanics_options, heat_transfer_options, mesh_tag, cycle, t);
308 main_physics->completeSetup();
310 main_physics->initializeSummary(datastore, t_final, dt);
313 bool last_step =
false;
316 smith::logger::flush();
319 double dt_real =
std::min(dt, t_final - t);
325 SLIC_INFO_ROOT(
"step " << cycle <<
", t = " << t);
328 main_physics->advanceTimestep(dt_real);
331 main_physics->outputStateToDisk(paraview_output_dir);
334 main_physics->saveSummary(datastore, t);
337 last_step = (t >= t_final - 1e-8 * dt);
This file contains the interface used for retrieving information about how the driver is configured.
RAII Application Manager class. Initializes MPI and other important libraries as well as automaticall...
static mfem::ParMesh & setMesh(std::unique_ptr< mfem::ParMesh > pmesh, const std::string &mesh_tag)
Gives ownership of mesh to StateManager.
static double load(const int cycle_to_load, const std::string &mesh_tag)
Loads an existing DataCollection.
static mfem::ParMesh & mesh(const std::string &mesh_tag)
Returns a non-owning reference to mesh held by StateManager.
static void initialize(axom::sidre::DataStore &ds, const std::string &output_directory)
Initializes the StateManager with a sidre DataStore (into which state will be written/read)
This file contains the all the necessary functions and macros required for interacting with the comma...
This file contains the declaration of an equation solver wrapper.
An object containing the solver for a heat transfer PDE.
This file contains the all the necessary functions and macros required for logging as well as a helpe...
This file contains helper functions for importing and managing various mesh objects.
std::unordered_map< std::string, std::string > defineAndParse(int argc, char *argv[], std::string app_description)
Defines command line options and parses the found values.
void printGiven(std::unordered_map< std::string, std::string > &cli_opts)
Prints all given command line options to the screen.
std::unique_ptr< mfem::ParMesh > buildParallelMesh(const InputOptions &options, const MPI_Comm comm)
Constructs an MFEM parallel mesh from a set of input options.
void outputSummary(const axom::sidre::DataStore &datastore, const std::string &output_directory, const FileFormat file_format)
Outputs simulation summary data from the datastore to the given file only on rank 0.
Accelerator functionality.
std::string about()
Returns a string about the configuration of Smith.
void defineInputFileSchema(axom::inlet::Inlet &inlet)
Define the input file structure for the driver code.
SMITH_HOST_DEVICE auto min(dual< gradient_type > a, double b)
Implementation of min for dual numbers.
void printRunInfo()
Outputs basic run information to the screen.
This file contains the all the necessary functions for outputting simulation data.
std::unique_ptr< smith::BasePhysics > createPhysics(int dim, int order, std::optional< smith::SolidMechanicsInputOptions > solid_mechanics_options, std::optional< smith::HeatTransferInputOptions > heat_transfer_options, std::string mesh_tag, int cycle, double t)
Constructs the appropriate physics object using the input file options.
int main(int argc, char *argv[])
The main smith driver code.
int getOrder(std::optional< smith::SolidMechanicsInputOptions > solid_mechanics_options, std::optional< smith::HeatTransferInputOptions > heat_transfer_options)
Return and check correctness of the order of discretization.
Tools for tagging a set of components of a vector field for boundary condition enforcement.
This file contains the declaration of the StateManager class.