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 90 : SplitMeshAction::validParams() 24 : { 25 90 : return Action::validParams(); 26 : } 27 : 28 90 : SplitMeshAction::SplitMeshAction(const InputParameters & params) : Action(params) {} 29 : 30 : void 31 90 : SplitMeshAction::act() 32 : { 33 90 : auto mesh = _app.actionWarehouse().mesh(); 34 180 : const std::string split_file_arg = _app.parameters().isParamSetByUser("split_file") 35 78 : ? _app.parameters().get<std::string>("split_file") 36 168 : : ""; 37 : 38 90 : if (mesh->getFileName() == "" && split_file_arg == "") 39 0 : mooseError("Output mesh file name must be specified (with --split-file) when splitting " 40 : "non-file-based meshes"); 41 : 42 90 : auto splitstr = _app.parameters().get<std::string>("split_mesh"); 43 90 : std::vector<unsigned int> splits; 44 90 : bool success = MooseUtils::tokenizeAndConvert(splitstr, splits, ", "); 45 90 : if (!success) 46 0 : mooseError("invalid argument for --split-mesh: '", splitstr, "'"); 47 : 48 : // Decide whether to create ASCII or binary splits based on the split_file_arg. We use the 49 : // following rules to decide: 50 : // 1.) No file extension -> ASCII + gzip 51 : // 2.) .cpr file extension -> binary 52 : // 3.) .cpa.gz file extension -> ASCII + gzip 53 : // 4.) Any other file extension -> mooseError 54 : 55 : // Get the file extension without the dot. 56 90 : std::string split_file_arg_ext = MooseUtils::getExtension(split_file_arg); 57 : 58 90 : bool checkpoint_binary_flag = false; 59 : 60 90 : if (split_file_arg_ext != "") 61 : { 62 16 : if (split_file_arg_ext == "cpr") 63 16 : checkpoint_binary_flag = true; 64 0 : else if (split_file_arg_ext == "cpa.gz") 65 0 : checkpoint_binary_flag = false; 66 : else 67 0 : mooseError("The argument to --split-file, ", 68 : split_file_arg, 69 : ", must not end in a file extension other than .cpr or .cpa.gz"); 70 : } 71 : 72 : // To name the split files, we start with the given mesh filename 73 : // (if set) or the argument to --split-file, strip any existing 74 : // extension, and then append either .cpr or .cpa.gz depending on the 75 : // checkpoint_binary_flag. 76 90 : auto fname = mesh->getFileName(); 77 90 : if (fname == "") 78 78 : fname = split_file_arg; 79 90 : fname = MooseUtils::stripExtension(fname) + (checkpoint_binary_flag ? ".cpr" : ".cpa.gz"); 80 : 81 194 : for (std::size_t i = 0; i < splits.size(); i++) 82 : { 83 104 : processor_id_type n = splits[i]; 84 104 : Moose::out << "Splitting " << n << " ways..." << std::endl; 85 : 86 104 : auto cp = libMesh::split_mesh(*mesh, n); 87 104 : Moose::out << " - writing " << cp->current_processor_ids().size() << " files per process..." 88 104 : << std::endl; 89 104 : cp->binary() = checkpoint_binary_flag; 90 : 91 : // different splits will be written into subfolders with n being the folder name 92 104 : cp->write(fname); 93 104 : } 94 : 95 : // Write mesh metadata 96 90 : if (processor_id() == 0) 97 : { 98 57 : const auto filenames = _app.writeRestartableMetaData(MooseApp::MESH_META_DATA, fname); 99 57 : Moose::out << "Mesh meta data written into " 100 57 : << std::filesystem::absolute(filenames[0].parent_path()) << "." << std::endl; 101 57 : } 102 90 : }