diff --git a/modules/ray_tracing/test/include/userobjects/TestPICRayStudy.h b/modules/ray_tracing/test/include/userobjects/TestPICRayStudy.h new file mode 100644 index 000000000000..c7cf9294bc4b --- /dev/null +++ b/modules/ray_tracing/test/include/userobjects/TestPICRayStudy.h @@ -0,0 +1,52 @@ +//* This file is part of the MOOSE framework +//* https://www.mooseframework.org +//* +//* All rights reserved, see COPYRIGHT for full restrictions +//* https://github.com/idaholab/moose/blob/master/COPYRIGHT +//* +//* Licensed under LGPL 2.1, please see LICENSE for details +//* https://www.gnu.org/licenses/lgpl-2.1.html + +#pragma once + +#include "RayTracingStudy.h" + +/** + * Test study for generating rays for a basic particle-in-cell capability, + * where Rays propagate a bit each time step + */ +class TestPICRayStudy : public RayTracingStudy +{ +public: + TestPICRayStudy(const InputParameters & parameters); + + static InputParameters validParams(); + + virtual void generateRays() override; + +protected: + virtual void postExecuteStudy() override; + +private: + /** + * @return The max distance the given ray should travel at the current time + * + * Uses the current ray position to sample the velocity field in \p velocity_function + */ + Real maxDistance(const Ray & ray) const; + + /// The starting points + const std::vector & _start_points; + + /// The starting directions + const std::vector & _start_directions; + + /// The function that represents the velocity field + const Function & _velocity_function; + + /// Whether or not we've generated rays yet (restartable) + bool & _has_generated; + + /// The banked rays to be used on the next timestep (restartable) + std::vector> & _banked_rays; +}; diff --git a/modules/ray_tracing/test/src/userobjects/TestPICRayStudy.C b/modules/ray_tracing/test/src/userobjects/TestPICRayStudy.C new file mode 100644 index 000000000000..0121de485c55 --- /dev/null +++ b/modules/ray_tracing/test/src/userobjects/TestPICRayStudy.C @@ -0,0 +1,127 @@ +//* This file is part of the MOOSE framework +//* https://www.mooseframework.org +//* +//* All rights reserved, see COPYRIGHT for full restrictions +//* https://github.com/idaholab/moose/blob/master/COPYRIGHT +//* +//* Licensed under LGPL 2.1, please see LICENSE for details +//* https://www.gnu.org/licenses/lgpl-2.1.html + +#include "TestPICRayStudy.h" + +#include "ClaimRays.h" +#include "Function.h" + +registerMooseObject("RayTracingTestApp", TestPICRayStudy); + +InputParameters +TestPICRayStudy::validParams() +{ + auto params = RayTracingStudy::validParams(); + + params.addRequiredParam>("start_points", + "The point(s) where the ray(s) start"); + params.addRequiredParam>( + "start_directions", + "The direction(s) that the ray(s) start in (does not need to be normalized)"); + params.addRequiredParam( + "velocity_function", "A function that describes the velocity field for the ray(s)"); + + // We're not going to use registration because we don't care to name our rays because + // we will have a lot of them + params.set("_use_ray_registration") = false; + + return params; +} + +TestPICRayStudy::TestPICRayStudy(const InputParameters & parameters) + : RayTracingStudy(parameters), + _start_points(getParam>("start_points")), + _start_directions(getParam>("start_directions")), + _velocity_function(getFunction("velocity_function")), + _has_generated(declareRestartableData("has_generated", false)), + _banked_rays( + declareRestartableDataWithContext>>("_banked_rays", this)) +{ + if (_start_points.size() != _start_directions.size()) + paramError("start_directions", "Must be the same size as 'start_points'"); +} + +void +TestPICRayStudy::generateRays() +{ + // We generate rays the first time only, after that we will + // pull from the bank and update velocities/max distances + if (!_has_generated) + { + // The unclaimed rays that we're going to generate + // Here we need to "claim" rays because in parallel, we have + // a list of points but do not know which processor will + // own the point that that ray starts in. So, we duplicate + // the rays on all processors and then let one processor pick them. + // Basically - we fill them here and then pass them to a ClaimRays + // object to do all of the magic. In a real PIC case, we'll just + // generate the rays for the local rays that we care about + // and the claiming probably won't be necessary + std::vector> rays(_start_points.size()); + + // Create a ray for each point/direction/velocity triplet + // Note that instead of keeping track of the velocity, we're + // just going to set the maximum distance that a ray can + // travel based on the timestep * the starting velocity. + for (const auto i : index_range(_start_points)) + { + rays[i] = acquireReplicatedRay(); + rays[i]->setStart(_start_points[i]); + rays[i]->setStartingDirection(_start_directions[i].unit()); + rays[i]->setStartingMaxDistance(maxDistance(*rays[i])); + } + + // Claim the rays + std::vector> claimed_rays; + ClaimRays claim_rays(*this, rays, claimed_rays, false); + claim_rays.claim(); + // ...and then add them to be traced + moveRaysToBuffer(claimed_rays); + } + // Rays are in the bank: reset them and update the velocities / end distance + else + { + // Reset each ray + for (auto & ray : _banked_rays) + { + // Store off the ray's info before we reset it + const auto start_point = ray->currentPoint(); + const auto direction = ray->direction(); + const auto elem = ray->currentElem(); + + // Reset it (this is required to reuse a ray) + ray->resetCounters(); + ray->clearStartingInfo(); + + // And set the new starting information + ray->setStart(start_point, elem); + ray->setStartingDirection(direction); + ray->setStartingMaxDistance(maxDistance(*ray)); + } + // Add the rays to be traced + moveRaysToBuffer(_banked_rays); + _banked_rays.clear(); + } + + _has_generated = true; +} + +void +TestPICRayStudy::postExecuteStudy() +{ + // Copy the rays that are banked in the study into our own bank + _banked_rays = rayBank(); +} + +Real +TestPICRayStudy::maxDistance(const Ray & ray) const +{ + // velocity * dt + return _velocity_function.value(_fe_problem.time(), ray.currentPoint()) * _fe_problem.dt(); +} diff --git a/modules/ray_tracing/test/tests/userobjects/test_pic_ray_study/gold/pic_ray_study_rays.e b/modules/ray_tracing/test/tests/userobjects/test_pic_ray_study/gold/pic_ray_study_rays.e new file mode 100644 index 000000000000..ad90d87a6599 Binary files /dev/null and b/modules/ray_tracing/test/tests/userobjects/test_pic_ray_study/gold/pic_ray_study_rays.e differ diff --git a/modules/ray_tracing/test/tests/userobjects/test_pic_ray_study/gold/pic_ray_study_rays.e-s0001 b/modules/ray_tracing/test/tests/userobjects/test_pic_ray_study/gold/pic_ray_study_rays.e-s0001 new file mode 100644 index 000000000000..78bd8c1220b5 Binary files /dev/null and b/modules/ray_tracing/test/tests/userobjects/test_pic_ray_study/gold/pic_ray_study_rays.e-s0001 differ diff --git a/modules/ray_tracing/test/tests/userobjects/test_pic_ray_study/gold/pic_ray_study_rays.e-s0002 b/modules/ray_tracing/test/tests/userobjects/test_pic_ray_study/gold/pic_ray_study_rays.e-s0002 new file mode 100644 index 000000000000..c7aed944aca0 Binary files /dev/null and b/modules/ray_tracing/test/tests/userobjects/test_pic_ray_study/gold/pic_ray_study_rays.e-s0002 differ diff --git a/modules/ray_tracing/test/tests/userobjects/test_pic_ray_study/gold/pic_ray_study_rays.e-s0003 b/modules/ray_tracing/test/tests/userobjects/test_pic_ray_study/gold/pic_ray_study_rays.e-s0003 new file mode 100644 index 000000000000..6580a0f5a79e Binary files /dev/null and b/modules/ray_tracing/test/tests/userobjects/test_pic_ray_study/gold/pic_ray_study_rays.e-s0003 differ diff --git a/modules/ray_tracing/test/tests/userobjects/test_pic_ray_study/gold/pic_ray_study_rays.e-s0004 b/modules/ray_tracing/test/tests/userobjects/test_pic_ray_study/gold/pic_ray_study_rays.e-s0004 new file mode 100644 index 000000000000..60f0fd6ffd0c Binary files /dev/null and b/modules/ray_tracing/test/tests/userobjects/test_pic_ray_study/gold/pic_ray_study_rays.e-s0004 differ diff --git a/modules/ray_tracing/test/tests/userobjects/test_pic_ray_study/gold/pic_ray_study_rays.e-s0005 b/modules/ray_tracing/test/tests/userobjects/test_pic_ray_study/gold/pic_ray_study_rays.e-s0005 new file mode 100644 index 000000000000..9e3b82256079 Binary files /dev/null and b/modules/ray_tracing/test/tests/userobjects/test_pic_ray_study/gold/pic_ray_study_rays.e-s0005 differ diff --git a/modules/ray_tracing/test/tests/userobjects/test_pic_ray_study/gold/pic_ray_study_rays.e-s0006 b/modules/ray_tracing/test/tests/userobjects/test_pic_ray_study/gold/pic_ray_study_rays.e-s0006 new file mode 100644 index 000000000000..de9adc58a341 Binary files /dev/null and b/modules/ray_tracing/test/tests/userobjects/test_pic_ray_study/gold/pic_ray_study_rays.e-s0006 differ diff --git a/modules/ray_tracing/test/tests/userobjects/test_pic_ray_study/gold/pic_ray_study_rays.e-s0007 b/modules/ray_tracing/test/tests/userobjects/test_pic_ray_study/gold/pic_ray_study_rays.e-s0007 new file mode 100644 index 000000000000..46cba0ba664d Binary files /dev/null and b/modules/ray_tracing/test/tests/userobjects/test_pic_ray_study/gold/pic_ray_study_rays.e-s0007 differ diff --git a/modules/ray_tracing/test/tests/userobjects/test_pic_ray_study/gold/pic_ray_study_rays.e-s0008 b/modules/ray_tracing/test/tests/userobjects/test_pic_ray_study/gold/pic_ray_study_rays.e-s0008 new file mode 100644 index 000000000000..df6290f6e731 Binary files /dev/null and b/modules/ray_tracing/test/tests/userobjects/test_pic_ray_study/gold/pic_ray_study_rays.e-s0008 differ diff --git a/modules/ray_tracing/test/tests/userobjects/test_pic_ray_study/gold/pic_ray_study_rays.e-s0009 b/modules/ray_tracing/test/tests/userobjects/test_pic_ray_study/gold/pic_ray_study_rays.e-s0009 new file mode 100644 index 000000000000..bda2e60532ef Binary files /dev/null and b/modules/ray_tracing/test/tests/userobjects/test_pic_ray_study/gold/pic_ray_study_rays.e-s0009 differ diff --git a/modules/ray_tracing/test/tests/userobjects/test_pic_ray_study/pic_ray_study.i b/modules/ray_tracing/test/tests/userobjects/test_pic_ray_study/pic_ray_study.i new file mode 100644 index 000000000000..598308c9bda0 --- /dev/null +++ b/modules/ray_tracing/test/tests/userobjects/test_pic_ray_study/pic_ray_study.i @@ -0,0 +1,42 @@ +[Mesh/gmg] + type = GeneratedMeshGenerator + dim = 2 + nx = 10 + ny = 10 + xmax = 100 + ymax = 100 +[] + +[UserObjects/study] + type = TestPICRayStudy + start_points = '0 0 0 + 100 100 0 + 1 99 0 + 49 49 0' + start_directions = '1 2 0 + -2 -1 0 + 5 -1 0 + 1 1.1 0' + velocity_function = '11 - t' + execute_on = TIMESTEP_BEGIN + always_cache_traces = true +[] + +[Executioner] + type = Transient + num_steps = 10 +[] + +[Problem] + solve = false +[] + +[RayKernels/kernel] + type = NullRayKernel +[] + +[Outputs/rays] + type = RayTracingExodus + study = study + execute_on = TIMESTEP_BEGIN +[] diff --git a/modules/ray_tracing/test/tests/userobjects/test_pic_ray_study/tests b/modules/ray_tracing/test/tests/userobjects/test_pic_ray_study/tests new file mode 100644 index 000000000000..c10818ef9965 --- /dev/null +++ b/modules/ray_tracing/test/tests/userobjects/test_pic_ray_study/tests @@ -0,0 +1,21 @@ +[Tests] + issues = '#16028 #25521' + design = 'RayTracingStudy.md' + + [pic] + type = 'Exodiff' + input = 'pic_ray_study.i' + exodiff = 'pic_ray_study_rays.e + pic_ray_study_rays.e-s0001 + pic_ray_study_rays.e-s0002 + pic_ray_study_rays.e-s0003 + pic_ray_study_rays.e-s0004 + pic_ray_study_rays.e-s0005 + pic_ray_study_rays.e-s0006 + pic_ray_study_rays.e-s0007 + pic_ray_study_rays.e-s0008 + pic_ray_study_rays.e-s0009' + allow_test_objects = tru + requirement = 'The system shall support the propagation of rays for particle-in-cell capability by tracing rays via a temporally and spatially varying velocity in time' + [] +[]