/// <summary> /// method to move the photon to its next location /// </summary> /// <param name="distance"></param> /// <returns></returns> public bool Move(double distance) { bool willHitBoundary = S >= distance; if (willHitBoundary) { AdjustTrackLength(distance); } DP.Position.X += S * DP.Direction.Ux; DP.Position.Y += S * DP.Direction.Uy; DP.Position.Z += S * DP.Direction.Uz; DP.TotalTime += DetectorBinning.GetTimeDelay(S, _tissue.Regions[CurrentRegionIndex].RegionOP.N); CurrentTrackIndex++; History.SubRegionInfoList[CurrentRegionIndex].PathLength += S; // only increment number of collisions counter if NOT pseudo-collision if (!willHitBoundary) { History.SubRegionInfoList[CurrentRegionIndex].NumberOfCollisions++; } History.AddDPToHistory(DP); return(willHitBoundary); }
/// <summary> /// Method to check for absorption according to analog random walk process /// </summary> public void AbsorbAnalog() { if (_rng.NextDouble() > _tissue.Regions[CurrentRegionIndex].RegionOP.Mus / (_tissue.Regions[CurrentRegionIndex].RegionOP.Mus + _tissue.Regions[CurrentRegionIndex].RegionOP.Mua)) { DP.StateFlag = DP.StateFlag.Add(PhotonStateType.Absorbed); DP.StateFlag = DP.StateFlag.Remove(PhotonStateType.Alive); History.AddDPToHistory(DP); } }
/// <summary> /// Method to test for death of the photon /// </summary> public void TestDeath() { TestWeightAndDistance(); // if VB crossing flagged if (DP.StateFlag.HasFlag(PhotonStateType.PseudoDiffuseReflectanceVirtualBoundary) || DP.StateFlag.HasFlag(PhotonStateType.PseudoDiffuseTransmittanceVirtualBoundary) || DP.StateFlag.HasFlag(PhotonStateType.PseudoSpecularReflectanceVirtualBoundary)) { //todo: revisit performance of the bitwise operations DP.StateFlag = DP.StateFlag.Remove(PhotonStateType.Alive); History.AddDPToHistory(DP); } }
/// <summary> /// Method that kills photon due to Russian Roulette, maximum path length, etc. /// </summary> public void TestWeightAndDistance() { // kill by RR if weight < user-input WEIGHT_LIMIT (=0.0 then no RR) if (DP.Weight < _russianRouletteWeightThreshold) { if (DP.Weight == 0.0) { DP.StateFlag = DP.StateFlag.Add(PhotonStateType.KilledRussianRoulette); DP.StateFlag = DP.StateFlag.Remove(PhotonStateType.Alive); } else if (_rng.NextDouble() < CHANCE) { DP.Weight = DP.Weight / CHANCE; } else { DP.StateFlag = DP.StateFlag.Add(PhotonStateType.KilledRussianRoulette); DP.StateFlag = DP.StateFlag.Remove(PhotonStateType.Alive); } if (DP.StateFlag.HasFlag(PhotonStateType.KilledRussianRoulette)) { History.AddDPToHistory(DP); } } else { // kill photon if it has had too many collisions if (History.HistoryData.Count >= MAX_HISTORY_PTS) { DP.StateFlag = DP.StateFlag.Add(PhotonStateType.KilledOverMaximumCollisions); DP.StateFlag = DP.StateFlag.Remove(PhotonStateType.Alive); History.AddDPToHistory(DP); } // kill photon if it has gone too far if (DP.TotalTime >= MAX_PHOTON_TIME) { DP.StateFlag = DP.StateFlag.Add(PhotonStateType.KilledOverMaximumPathLength); DP.StateFlag = DP.StateFlag.Remove(PhotonStateType.Alive); History.AddDPToHistory(DP); } } }