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