LCOV - code coverage report
Current view: top level - src/userobjects - SolutionRasterizer.C (source / functions) Hit Total Coverage
Test: idaholab/moose phase_field: #32971 (54bef8) with base c6cf66 Lines: 50 55 90.9 %
Date: 2026-05-29 20:38:39 Functions: 3 3 100.0 %
Legend: Lines: hit not hit

          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 : }

Generated by: LCOV version 1.14