LCOV - code coverage report
Current view: top level - src/userobjects - PolycrystalCircles.C (source / functions) Hit Total Coverage
Test: idaholab/moose phase_field: #31405 (292dce) with base fef103 Lines: 88 103 85.4 %
Date: 2025-09-04 07:55:36 Functions: 6 6 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 "PolycrystalCircles.h"
      11             : #include "MooseMesh.h"
      12             : #include "MooseVariable.h"
      13             : 
      14             : #include "libmesh/utility.h"
      15             : #include <fstream>
      16             : 
      17             : registerMooseObject("PhaseFieldApp", PolycrystalCircles);
      18             : 
      19             : InputParameters
      20          24 : PolycrystalCircles::validParams()
      21             : {
      22          24 :   InputParameters params = PolycrystalUserObjectBase::validParams();
      23          24 :   params.addClassDescription(
      24             :       "Polycrystal circles generated from a vector input or read from a file");
      25          48 :   params.addParam<bool>("read_from_file",
      26          48 :                         false,
      27             :                         "Set to true to read the position and radius "
      28             :                         "vectors from a file rather than inputing them "
      29             :                         "manually");
      30          48 :   params.addParam<bool>(
      31          48 :       "columnar_3D", false, "3D microstructure will be columnar in the z-direction?");
      32          48 :   params.addParam<std::vector<Real>>("x_positions", "x coordinate for each circle center");
      33          48 :   params.addParam<std::vector<Real>>("y_positions", "y coordinate for each circle center");
      34          48 :   params.addParam<std::vector<Real>>("z_positions", "z coordinate for each circle center");
      35          48 :   params.addParam<std::vector<Real>>("radii", "The radius for each circle");
      36          48 :   params.addParam<FileName>("file_name", "File containing circle centers and radii");
      37          48 :   params.addParam<Real>("int_width", 0.0, "Width of diffuse interface");
      38             : 
      39          24 :   return params;
      40           0 : }
      41             : 
      42          12 : PolycrystalCircles::PolycrystalCircles(const InputParameters & parameters)
      43             :   : PolycrystalUserObjectBase(parameters),
      44          12 :     _columnar_3D(getParam<bool>("columnar_3D")),
      45          24 :     _int_width(getParam<Real>("int_width")),
      46          24 :     _grain_num(0)
      47             : {
      48          12 : }
      49             : 
      50             : void
      51     1274834 : PolycrystalCircles::getGrainsBasedOnPoint(const Point & point,
      52             :                                           std::vector<unsigned int> & grains) const
      53             : {
      54     1274834 :   unsigned int n_grains = _centerpoints.size();
      55     1274834 :   grains.resize(0);
      56             : 
      57    11473506 :   for (unsigned int i = 0; i < n_grains; ++i)
      58             :   {
      59             :     Real distance = 0;
      60             : 
      61    10198672 :     if (_columnar_3D)
      62             :     {
      63           0 :       Real d_x = (point(0) - _centerpoints[i](0)) * (point(0) - _centerpoints[i](0));
      64           0 :       Real d_y = (point(1) - _centerpoints[i](1)) * (point(1) - _centerpoints[i](1));
      65           0 :       distance = std::sqrt(d_x + d_y);
      66             :     }
      67             :     else
      68    10198672 :       distance = _mesh.minPeriodicDistance(_vars[0]->number(), _centerpoints[i], point);
      69             : 
      70    10198672 :     if (distance < _radii[i] + _int_width)
      71     1233781 :       grains.push_back(i);
      72             :   }
      73     1274834 : }
      74             : 
      75             : Real
      76     1224056 : PolycrystalCircles::getVariableValue(unsigned int op_index, const Point & p) const
      77             : {
      78             :   std::vector<unsigned int> grain_ids;
      79     1224056 :   getGrainsBasedOnPoint(p, grain_ids);
      80             : 
      81     1224056 :   unsigned int active_grain_on_op = invalid_id;
      82     2159693 :   for (auto grain_id : grain_ids)
      83     1143179 :     if (op_index == _grain_to_op.at(grain_id))
      84             :     {
      85      207542 :       active_grain_on_op = grain_id;
      86      207542 :       break;
      87             :     }
      88             : 
      89     2448112 :   return active_grain_on_op != invalid_id ? computeDiffuseInterface(p, active_grain_on_op) : 0.0;
      90     1224056 : }
      91             : 
      92             : void
      93          12 : PolycrystalCircles::precomputeGrainStructure()
      94             : {
      95          24 :   bool readfromfile = getParam<bool>("read_from_file");
      96          12 :   if (readfromfile)
      97             :   {
      98             :     // Read file
      99           8 :     const FileName file_name = getParam<FileName>("file_name");
     100           8 :     MooseUtils::DelimitedFileReader txt_reader(file_name, &_communicator);
     101             : 
     102           8 :     txt_reader.read();
     103           8 :     std::vector<std::string> col_names = txt_reader.getNames();
     104           8 :     std::vector<std::vector<Real>> data = txt_reader.getData();
     105           8 :     _grain_num = data[0].size();
     106           8 :     _centerpoints.resize(_grain_num);
     107             : 
     108             :     std::array<int, 4> col_map = {{-1, -1, -1, -1}};
     109             : 
     110          40 :     for (unsigned int i = 0; i < col_names.size(); ++i)
     111             :     {
     112             :       // Check vector lengths
     113          32 :       if (data[i].size() != _grain_num)
     114           0 :         mooseError("Columns in ", file_name, " do not have uniform lengths.");
     115             : 
     116             :       // Map columns to variables
     117          32 :       if (col_names[i] == "x")
     118           8 :         col_map[X] = i;
     119          24 :       else if (col_names[i] == "y")
     120           8 :         col_map[Y] = i;
     121          16 :       else if (col_names[i] == "z")
     122           8 :         col_map[Z] = i;
     123           8 :       else if (col_names[i] == "r")
     124           8 :         col_map[R] = i;
     125             :     }
     126             : 
     127             :     // Check all columns are included
     128           8 :     if (col_map[X] == -1)
     129           0 :       mooseError("No column 'x' in ", file_name, ".");
     130           8 :     if (col_map[Y] == -1)
     131           0 :       mooseError("No column 'y' in ", file_name, ".");
     132           8 :     if (col_map[Z] == -1)
     133           0 :       mooseError("No column 'z' in ", file_name, ".");
     134           8 :     if (col_map[R] == -1)
     135           0 :       mooseError("No column 'r' in ", file_name, ".");
     136             : 
     137             :     // Write data to variables
     138           8 :     _radii.assign(data[col_map[R]].begin(), data[col_map[R]].end());
     139          72 :     for (unsigned int i = 0; i < _grain_num; ++i)
     140             :     {
     141          64 :       _centerpoints[i](0) = data[col_map[X]][i];
     142          64 :       _centerpoints[i](1) = data[col_map[Y]][i];
     143          64 :       _centerpoints[i](2) = data[col_map[Z]][i];
     144             :     }
     145           8 :   }
     146             :   else // if (readfromfile)
     147             :   {
     148             :     // Read vectors
     149           8 :     std::vector<Real> x_c = getParam<std::vector<Real>>("x_positions");
     150           8 :     std::vector<Real> y_c = getParam<std::vector<Real>>("y_positions");
     151           8 :     std::vector<Real> z_c = getParam<std::vector<Real>>("z_positions");
     152          12 :     std::vector<Real> r_c = getParam<std::vector<Real>>("radii");
     153             : 
     154           4 :     _grain_num = r_c.size();
     155           4 :     _centerpoints.resize(_grain_num);
     156             : 
     157             :     // Check vector lengths
     158           4 :     if (_grain_num != x_c.size())
     159           0 :       mooseError("The vector length of x_positions does not match the length of radii");
     160           4 :     else if (_grain_num != y_c.size())
     161           0 :       mooseError("The vector length of y_positions does not match the length of radii");
     162           4 :     else if (_grain_num != z_c.size())
     163           0 :       mooseError("The vector length of z_positions does not match the length of radii");
     164             : 
     165             :     // Assign values
     166           4 :     _radii.assign(r_c.begin(), r_c.end());
     167          36 :     for (unsigned int i = 0; i < _grain_num; ++i)
     168             :     {
     169          32 :       _centerpoints[i](0) = x_c[i];
     170          32 :       _centerpoints[i](1) = y_c[i];
     171          32 :       _centerpoints[i](2) = z_c[i];
     172             :     }
     173           4 :   }
     174          12 : }
     175             : 
     176             : Real
     177      207542 : PolycrystalCircles::computeDiffuseInterface(const Point & p, const unsigned int & i) const
     178             : {
     179      207542 :   if (_int_width == 0)
     180             :     return 1.0;
     181             : 
     182             :   Real d = 0;
     183             : 
     184      207542 :   if (_columnar_3D)
     185             :   {
     186           0 :     Real d_x = (p(0) - _centerpoints[i](0)) * (p(0) - _centerpoints[i](0));
     187           0 :     Real d_y = (p(1) - _centerpoints[i](1)) * (p(1) - _centerpoints[i](1));
     188           0 :     d = std::sqrt(d_x + d_y);
     189             :   }
     190             :   else
     191      207542 :     d = _mesh.minPeriodicDistance(_vars[0]->number(), _centerpoints[i], p);
     192             : 
     193      207542 :   return 0.5 * (1 - std::tanh(2.0 * (d - _radii[i]) / _int_width));
     194             : }

Generated by: LCOV version 1.14