https://mooseframework.inl.gov
Loading...
Searching...
No Matches
RefractionRayKernelTest.C
Go to the documentation of this file.
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
11
12#include "RayTracingStudy.h"
13
15
18{
19 auto params = GeneralRayKernel::validParams();
20
21 params.addRequiredCoupledVar("field", "The field variable that denotes the phase");
22
23 params.addParam<Real>("r1", 1.0, "The first index of refraction");
24 params.addParam<Real>("r2", 1.33, "The second index of refraction");
25
26 return params;
27}
28
30 : GeneralRayKernel(params),
31 _field(coupledValue("field")),
32 _grad_field(coupledGradient("field")),
33 _r1(getParam<Real>("r1")),
34 _r2(getParam<Real>("r2")),
35 _has_refracted_data_index(_study.registerRayData("has_refracted"))
36{
37}
38
39void
41{
42 auto & has_refracted = currentRay()->data(_has_refracted_data_index);
43
44 // If this Ray has refracted once already... don't let it refract again
45 // This model is limited in the fact that it only checks the field change (if not 0 or 1) at the
46 // center of the segment, therefore by this check it could refract multiple times when a field
47 // changes over multiple elements. Don't allow this. This is good enough as a test object to test
48 // the physical refraction.
49 if (has_refracted)
50 return;
51
52 if (_field[0] > 0 && _field[0] < 1)
53 {
54 // Normal of the field is determined by the gradient
55 const auto field_normal = _grad_field[0].unit();
56 // Refract at the midpoint
57 const auto refracted_point = 0.5 * (_current_segment_start + _current_segment_end);
58 // Get the refracted direction
59 const auto refracted_direction = refract(currentRay()->direction(), field_normal, _r1, _r2);
60
61 // Refract!
62 changeRayStartDirection(refracted_point, refracted_direction);
63
64 // Note that this Ray has refracted so that it can't again. This is required because we don't
65 // check the phase change in proper manner
66 has_refracted = 1;
67 }
68}
69
70Point
71RefractionRayKernelTest::refract(const Point & direction,
72 const Point & normal,
73 const Real r1,
74 const Real r2) const
75{
76 const Real c = std::abs(normal * direction);
77 if (c > 1.0 - TOLERANCE) // parallel
78 return direction;
79
80 const Real r = r1 / r2;
81 return (r * direction + (r * c - std::sqrt(1 - r * r * (1 - c * c))) * normal).unit();
82}
registerMooseObject("RayTracingTestApp", RefractionRayKernelTest)
static InputParameters validParams()
const Point & _current_segment_start
The start point of the current Ray's segment.
void changeRayStartDirection(const Point &start, const Point &direction)
Changes the current Ray's start point and direction.
const Point & _current_segment_end
The end point of the current Ray's segment.
const std::shared_ptr< Ray > & currentRay() const
Gets the current Ray that this is working on.
Simplified RayKernel that refracts Rays when the phase changes (phase change denoted by a field varia...
virtual void onSegment() override
Called on each segment of a Ray.
const VariableGradient & _grad_field
The gradient of the field variable that notes the phase.
const Real _r1
The first index of refraction.
static InputParameters validParams()
RefractionRayKernelTest(const InputParameters &params)
Point refract(const Point &direction, const Point &normal, const Real r1, const Real r2) const
Computes the refracted direction using Snell's law.
const VariableValue & _field
The field variable that notes the phase.
const Real _r2
The second index of refraction.
const RayDataIndex _has_refracted_data_index
Index of the Ray data that notes if the Ray has refracted or not.