LCOV - code coverage report
Current view: top level - src/userobjects - PerElementParticleInitializer.C (source / functions) Hit Total Coverage
Test: idaholab/salamander: 762d38 Lines: 31 33 93.9 %
Date: 2025-07-22 20:51:44 Functions: 3 3 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //* This file is part of SALAMANDER: Software for Advanced Large-scale Analysis of MAgnetic confinement for Numerical Design, Engineering & Research,
       2             : //* A multiphysics application for modeling plasma facing components
       3             : //* https://github.com/idaholab/salamander
       4             : //* https://mooseframework.inl.gov/salamander
       5             : //*
       6             : //* SALAMANDER is powered by the MOOSE Framework
       7             : //* https://www.mooseframework.inl.gov
       8             : //*
       9             : //* Licensed under LGPL 2.1, please see LICENSE for details
      10             : //* https://www.gnu.org/licenses/lgpl-2.1.html
      11             : //*
      12             : //* Copyright 2025, Battelle Energy Alliance, LLC
      13             : //* ALL RIGHTS RESERVED
      14             : //*
      15             : 
      16             : #include "PerElementParticleInitializer.h"
      17             : #include "MooseRandom.h"
      18             : #include "ElementSampler.h"
      19             : 
      20             : registerMooseObject("SalamanderApp", PerElementParticleInitializer);
      21             : 
      22             : InputParameters
      23         553 : PerElementParticleInitializer::validParams()
      24             : {
      25         553 :   auto params = ParticleInitializerBase::validParams();
      26         553 :   params.addClassDescription(
      27             :       "Particle initializer that uniformly distributes a specified number of particles per "
      28             :       "element and calculates the corresponding particle weight based on the requested number "
      29             :       "density, particles per element, and the elements \"volume\".");
      30        1106 :   params.addRangeCheckedParam<unsigned int>(
      31             :       "particles_per_element",
      32             :       "particles_per_element != 0",
      33             :       "The number of computational particles that should be placed in each element");
      34             : 
      35        1106 :   params.addRangeCheckedParam<Real>("number_density",
      36             :                                     "number_density > 0.0",
      37             :                                     "The number density of particles you want to represent");
      38         553 :   return params;
      39           0 : }
      40             : 
      41         276 : PerElementParticleInitializer::PerElementParticleInitializer(const InputParameters & parameters)
      42             :   : ParticleInitializerBase(parameters),
      43         275 :     _number_density(getParam<Real>("number_density")),
      44         826 :     _particles_per_element(getParam<unsigned int>("particles_per_element"))
      45             : {
      46         275 : }
      47             : 
      48             : std::vector<InitialParticleData>
      49          91 : PerElementParticleInitializer::getParticleData() const
      50             : {
      51             : 
      52             :   // counting the number of elements this process is responsible for
      53             :   // this will allow us to allocated data structures of the appropriate length
      54          91 :   const auto & elem_range = *_fe_problem.mesh().getActiveLocalElementRange();
      55             :   const auto num_local_elements = std::distance(elem_range.begin(), elem_range.end());
      56             :   // if there are no elements for this processor: do nothing
      57          91 :   if (num_local_elements == 0)
      58           0 :     return {};
      59             : 
      60             :   std::vector<InitialParticleData> data =
      61          91 :       std::vector<InitialParticleData>(num_local_elements * _particles_per_element);
      62             : 
      63             :   // random number generator to be used for sampling the elements
      64             :   MooseRandom generator;
      65          91 :   SALAMANDER::ElementSampler sampler = SALAMANDER::ElementSampler(_fe_problem, _seed, generator);
      66             :   // This will store the uniformly distributed points within the reference elements
      67             :   uint elem_count = 0;
      68        4203 :   for (const auto elem : *_fe_problem.mesh().getActiveLocalElementRange())
      69             :   {
      70             : 
      71             :     // now that all of the particle locations have been placed we need to
      72             :     // set up the data they will need to be made into actual rays
      73        4113 :     const auto & physical_points = sampler.sampleElement(elem, _particles_per_element);
      74        4112 :     Real weight = _number_density * elem->volume() / (_particles_per_element);
      75       45232 :     for (const auto i : make_range(_particles_per_element))
      76             :     {
      77       41120 :       uint particle_index = elem_count * _particles_per_element + i;
      78       41120 :       data[particle_index].elem = elem;
      79       41120 :       data[particle_index].weight = weight;
      80       41120 :       data[particle_index].species = _species;
      81       41120 :       data[particle_index].mass = _mass;
      82       41120 :       data[particle_index].charge = _charge;
      83       41120 :       data[particle_index].position = physical_points[i];
      84       41120 :       data[particle_index].velocity = Point();
      85      164480 :       for (const auto i : make_range(uint(3)))
      86      123360 :         data[particle_index].velocity(i) = _velocity_distributions[i]->quantile(generator.rand());
      87             :     }
      88        4112 :     elem_count++;
      89             :   }
      90             :   return data;
      91         180 : }

Generated by: LCOV version 1.14