Line data Source code
1 : //* This file is part of the MOOSE framework 2 : //* https://mooseframework.inl.gov 3 : //* 4 : //* All rights reserved, see COPYRIGHT for full restrictions 5 : //* https://github.com/idaholab/moose/blob/master/COPYRIGHT 6 : //* 7 : //* Licensed under LGPL 2.1, please see LICENSE for details 8 : //* https://www.gnu.org/licenses/lgpl-2.1.html 9 : 10 : #include "SplitMeshAction.h" 11 : 12 : #include "MooseApp.h" 13 : #include "MooseUtils.h" 14 : #include "MooseMesh.h" 15 : 16 : #include <filesystem> 17 : 18 : #include "libmesh/checkpoint_io.h" 19 : 20 : registerMooseAction("MooseApp", SplitMeshAction, "split_mesh"); 21 : 22 : InputParameters 23 89 : SplitMeshAction::validParams() 24 : { 25 89 : return Action::validParams(); 26 : } 27 : 28 89 : SplitMeshAction::SplitMeshAction(const InputParameters & params) : Action(params) {} 29 : 30 : void 31 89 : SplitMeshAction::act() 32 : { 33 89 : auto mesh = _app.actionWarehouse().mesh(); 34 : 35 : // Keep the mesh unpartitioned until right before the split 36 89 : mesh->getMesh().skip_partitioning(false); 37 : 38 178 : const std::string split_file_arg = _app.parameters().isParamSetByUser("split_file") 39 77 : ? _app.parameters().get<std::string>("split_file") 40 190 : : ""; 41 : 42 89 : if (mesh->getFileName() == "" && split_file_arg == "") 43 0 : mooseError("Output mesh file name must be specified (with --split-file) when splitting " 44 : "non-file-based meshes"); 45 : 46 89 : auto splitstr = _app.parameters().get<std::string>("split_mesh"); 47 89 : std::vector<unsigned int> splits; 48 89 : bool success = MooseUtils::tokenizeAndConvert(splitstr, splits, ", "); 49 89 : if (!success) 50 0 : mooseError("invalid argument for --split-mesh: '", splitstr, "'"); 51 : 52 : // Decide whether to create ASCII or binary splits based on the split_file_arg. We use the 53 : // following rules to decide: 54 : // 1.) No file extension -> ASCII + gzip 55 : // 2.) .cpr file extension -> binary 56 : // 3.) .cpa.gz file extension -> ASCII + gzip 57 : // 4.) Any other file extension -> mooseError 58 : 59 : // Get the file extension without the dot. 60 89 : std::string split_file_arg_ext = MooseUtils::getExtension(split_file_arg); 61 : 62 89 : bool checkpoint_binary_flag = false; 63 : 64 89 : if (split_file_arg_ext != "") 65 : { 66 16 : if (split_file_arg_ext == "cpr") 67 16 : checkpoint_binary_flag = true; 68 0 : else if (split_file_arg_ext == "cpa.gz") 69 0 : checkpoint_binary_flag = false; 70 : else 71 0 : mooseError("The argument to --split-file, ", 72 : split_file_arg, 73 : ", must not end in a file extension other than .cpr or .cpa.gz"); 74 : } 75 : 76 : // To name the split files, we start with the given mesh filename 77 : // (if set) or the argument to --split-file, strip any existing 78 : // extension, and then append either .cpr or .cpa.gz depending on the 79 : // checkpoint_binary_flag. 80 89 : auto fname = mesh->getFileName(); 81 89 : if (fname == "") 82 77 : fname = split_file_arg; 83 89 : fname = MooseUtils::stripExtension(fname) + (checkpoint_binary_flag ? ".cpr" : ".cpa.gz"); 84 : 85 192 : for (std::size_t i = 0; i < splits.size(); i++) 86 : { 87 103 : processor_id_type n = splits[i]; 88 103 : Moose::out << "Splitting " << n << " ways..." << std::endl; 89 : 90 103 : auto cp = libMesh::split_mesh(*mesh, n); 91 103 : Moose::out << " - writing " << cp->current_processor_ids().size() << " files per process..." 92 103 : << std::endl; 93 103 : cp->binary() = checkpoint_binary_flag; 94 : 95 : // different splits will be written into subfolders with n being the folder name 96 103 : cp->write(fname); 97 103 : } 98 : 99 : // Write mesh metadata 100 89 : if (processor_id() == 0) 101 : { 102 56 : const auto filenames = _app.writeRestartableMetaData(MooseApp::MESH_META_DATA, fname); 103 56 : Moose::out << "Mesh meta data written into " 104 56 : << std::filesystem::absolute(filenames[0].parent_path()) << "." << std::endl; 105 56 : } 106 89 : }