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 "SolutionRasterizer.h" 11 : 12 : #include <fstream> 13 : #include "libmesh/mesh_function.h" 14 : #include "libmesh/exodusII_io.h" 15 : 16 : registerMooseObject("PhaseFieldApp", SolutionRasterizer); 17 : 18 : InputParameters 19 22 : SolutionRasterizer::validParams() 20 : { 21 22 : InputParameters params = SolutionUserObject::validParams(); 22 22 : params.addClassDescription("Process an XYZ file of atomic coordinates and filter atoms via " 23 : "threshold or map variable values."); 24 44 : params.addRequiredParam<FileName>("xyz_input", "XYZ input file."); 25 44 : params.addRequiredParam<FileName>("xyz_output", "XYZ output file."); 26 44 : params.addRequiredParam<std::string>( 27 : "variable", "Variable from the mesh file to use for mapping to or filtering of the atoms."); 28 44 : MooseEnum modeEnum("MAP FILTER", "MAP"); 29 44 : params.addParam<MooseEnum>("raster_mode", modeEnum, "Rasterization mode (MAP|FILTER)."); 30 44 : params.addParam<Real>("threshold", 31 : "Accept atoms with a variable value above this threshold in FILTER mode."); 32 22 : return params; 33 22 : } 34 : 35 11 : SolutionRasterizer::SolutionRasterizer(const InputParameters & parameters) 36 : : SolutionUserObject(parameters), 37 22 : _xyz_input(getParam<FileName>("xyz_input")), 38 11 : _xyz_output(getParam<FileName>("xyz_output")), 39 22 : _variable(getParam<std::string>("variable")), 40 22 : _raster_mode(getParam<MooseEnum>("raster_mode")), 41 11 : _threshold(0.0) 42 : { 43 11 : if (_raster_mode == "FILTER") 44 : { 45 22 : if (!isParamValid("threshold")) 46 0 : mooseError("Please specify 'threshold' parameter for raster_mode = FILTER"); 47 22 : _threshold = getParam<Real>("threshold"); 48 : } 49 11 : } 50 : 51 : void 52 11 : SolutionRasterizer::initialSetup() 53 : { 54 : // only execute once 55 11 : if (_initialized) 56 0 : return; 57 : 58 : // initialize parent class 59 11 : SolutionUserObject::initialSetup(); 60 : 61 : // open input XYZ file 62 11 : std::ifstream stream_in(_xyz_input.c_str()); 63 : 64 : // open output XYZ file 65 11 : std::ofstream stream_out(_xyz_output.c_str()); 66 : 67 : std::string line, dummy; 68 : Real x, y, z; 69 : unsigned int current_line = 0; 70 : unsigned int nfilter = 0, len0 = 0; 71 11033 : while (std::getline(stream_in, line)) 72 : { 73 11022 : if (current_line < 2) 74 : { 75 : // dump header 76 22 : stream_out << line << '\n'; 77 : 78 : // get length of line 0 - the amount of space we have to replace the atom count at the end of 79 : // filtering 80 22 : if (current_line == 0) 81 11 : len0 = line.size(); 82 : } 83 : else 84 : { 85 11000 : std::istringstream iss(line); 86 : 87 22000 : if (iss >> dummy >> x >> y >> z) 88 11000 : switch (_raster_mode) 89 : { 90 : case 0: // MAP 91 0 : stream_out << line << ' ' << pointValue(0.0, Point(x, y, z), _variable) << '\n'; 92 0 : break; 93 11000 : case 1: // FILTER 94 11000 : if (pointValue(0.0, Point(x, y, z), _variable) > _threshold) 95 : { 96 3080 : stream_out << line << '\n'; 97 3080 : nfilter++; 98 : } 99 : break; 100 : } 101 11000 : } 102 : 103 11022 : current_line++; 104 : } 105 : 106 11 : stream_in.close(); 107 11 : stream_out.close(); 108 : 109 : // modify output file to fix atom count in line 0 110 11 : if (_raster_mode == "FILTER") 111 : { 112 : // stringify the new number of atoms 113 11 : std::ostringstream oss; 114 : oss << nfilter; 115 : std::string newline0 = oss.str(); 116 : 117 : // the new number should always be lower -> shorter than the old one, but we check to be sure 118 11 : if (newline0.size() > len0) 119 : { 120 0 : mooseWarning("SolutionRasterizer could not update XYZ atom count in header."); 121 : return; 122 : } 123 : 124 : // pad shorter numbers with spaces 125 22 : while (newline0.size() < len0) 126 : newline0 += ' '; 127 : 128 : // inject new number into the file 129 11 : std::ofstream stream_fix(_xyz_output.c_str(), std::ios::binary | std::ios::in | std::ios::out); 130 : stream_fix << newline0; 131 11 : stream_fix.close(); 132 22 : } 133 11 : }