Skip to content

Commit

Permalink
fix problem where split photons were not getting to detectors at the …
Browse files Browse the repository at this point in the history
…same time, see #65
  • Loading branch information
jbphet committed Dec 18, 2024
1 parent 3f6cde3 commit e7c267c
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 24 deletions.
6 changes: 4 additions & 2 deletions js/photons/model/Photon.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ export const RIGHT = new Vector2( 1, 0 );
// the resulting states will either be measured as vertical or horizontal.
export type PossiblePolarizationResult = 'vertical' | 'horizontal';

export default class Photon {
class Photon {

// the angle of polarization for this photon, in degrees
public polarizationAngle: number;
Expand Down Expand Up @@ -139,4 +139,6 @@ export type PhotonStateObject = {
possibleMotionStates: PhotonMotionState[];
};

quantumMeasurement.register( 'Photon', Photon );
quantumMeasurement.register( 'Photon', Photon );

export default Photon;
11 changes: 6 additions & 5 deletions js/photons/model/PhotonDetector.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,9 +82,10 @@ class PhotonDetector implements TPhotonInteraction {
position.plus( new Vector2( -this.apertureDiameter / 2, 0 ) ),
position.plus( new Vector2( this.apertureDiameter / 2, 0 ) )
);
const apertureLineYOffset = this.detectionDirection === 'up' ? this.apertureHeight : -this.apertureHeight;
this.absorptionLine = new Line(
position.plus( new Vector2( -this.apertureDiameter / 2, this.detectionDirection === 'up' ? this.apertureHeight : -this.apertureHeight ) ),
position.plus( new Vector2( this.apertureDiameter / 2, this.detectionDirection === 'up' ? this.apertureHeight : -this.apertureHeight ) )
position.plus( new Vector2( -this.apertureDiameter / 2, apertureLineYOffset ) ),
position.plus( new Vector2( this.apertureDiameter / 2, apertureLineYOffset ) )
);

this.detectionRateProperty = new AveragingCounterNumberProperty( {
Expand Down Expand Up @@ -130,15 +131,15 @@ class PhotonDetector implements TPhotonInteraction {

// If, by any chance, the photon would cross BOTH the detection and absorption lines, we'll consider it to be
// detected and absorbed.
if ( detectionIntersectionPoint !== null && absorptionIntersectionPoint !== null ) {
if ( detectionIntersectionPoint && absorptionIntersectionPoint ) {
mapOfStatesToInteractions.set( photonState, { interactionType: 'detectedAndAbsorbed', detectionInfo: { detector: this } } );
}
// If the photon would cross the detection line, but not the absorption line, we'll consider it to be detected.
else if ( detectionIntersectionPoint !== null ) {
else if ( detectionIntersectionPoint ) {
mapOfStatesToInteractions.set( photonState, { interactionType: 'detected', detectionInfo: { detector: this } } );
}
// If the photon would cross the absorption line, but not the detection line, we'll consider it to be absorbed.
else if ( absorptionIntersectionPoint !== null ) {
else if ( absorptionIntersectionPoint ) {
mapOfStatesToInteractions.set( photonState, { interactionType: 'absorbed' } );
}
} );
Expand Down
41 changes: 24 additions & 17 deletions js/photons/model/PhotonsExperimentSceneModel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import Mirror from './Mirror.js';
import Photon, { PHOTON_SPEED } from './Photon.js';
import { PhotonCollection } from './PhotonCollection.js';
import PhotonDetector, { COUNT_RANGE } from './PhotonDetector.js';
import { PhotonMotionState } from './PhotonMotionState.js';
import PolarizingBeamSplitter from './PolarizingBeamSplitter.js';
import { TPhotonInteraction } from './TPhotonInteraction.js';

Expand Down Expand Up @@ -236,13 +237,17 @@ export default class PhotonsExperimentSceneModel {
// beam splitter, mirror, and photon detectors.
this.photonCollection.photons.forEach( photon => {

let interactionCount = 0;
const hadInteractionMap: Map<PhotonMotionState, boolean> = new Map<PhotonMotionState, boolean>();

for ( const potentiallyInteractingElement of potentialInteractors ) {

// Test for interactions with the potential interactors.
const interactions = potentiallyInteractingElement.testForPhotonInteraction( photon, dt );

interactions.forEach( ( interaction, photonState ) => {
hadInteractionMap.set( photonState, true );
} );

// For each of the interactions, update the photon state.
for ( const [ photonState, interaction ] of interactions ) {

Expand All @@ -263,11 +268,8 @@ export default class PhotonsExperimentSceneModel {

// Step the photon the remaining time.
photonState.step( dt - dtToReflectionPoint );

interactionCount++;
}

if ( interaction.interactionType === 'split' ) {
else if ( interaction.interactionType === 'split' ) {

assert && assert( interaction.splitInfo, 'split info missing' );
assert && assert( photon.possibleMotionStates.length === 1, 'there should be 1 motion state' );
Expand All @@ -287,9 +289,13 @@ export default class PhotonsExperimentSceneModel {
interaction.splitInfo!.splitStates[ 1 ].direction,
interaction.splitInfo!.splitStates[ 1 ].probability
);
}

if ( interaction.interactionType === 'detected' || interaction.interactionType === 'detectedAndAbsorbed' ) {
hadInteractionMap.set( photon.possibleMotionStates[ 1 ], true );

// Step the motion states the remaining time.
photon.possibleMotionStates.forEach( state => state.step( dt - dtToSplitPoint ) );
}
else if ( interaction.interactionType === 'detected' || interaction.interactionType === 'detectedAndAbsorbed' ) {

const detector = interaction.detectionInfo!.detector;

Expand All @@ -300,31 +306,32 @@ export default class PhotonsExperimentSceneModel {
photon.setMotionStateProbability( photonState, 1 );
detector.detectionCountProperty.value = Math.min( detector.detectionCountProperty.value + 1, COUNT_RANGE.max );
detector.detectionRateProperty.countEvent();

}
else {

// If this photon state does not trigger the detector the associated probability goes to 0%, which will make
// the other state's probability 100%.
// If this photon state does not trigger the detector the associated probability goes to 0, which will
// make the other state's probability 1.
photon.setMotionStateProbability( photonState, 0 );
}
}

if ( interaction.interactionType === 'absorbed' || interaction.interactionType === 'detectedAndAbsorbed' ) {
photonState.step( dt );
}
else if ( interaction.interactionType === 'absorbed' || interaction.interactionType === 'detectedAndAbsorbed' ) {

// This interaction indicates that the photon was absorbed, so it should be removed from the photon
// collection.
photonsToRemove.push( photon );

interactionCount++;
}
}
}
}

if ( interactionCount === 0 ) {
photon.step( dt );
}
// If there were no interactions, step the photon forward in time.
photon.possibleMotionStates.forEach( state => {
if ( !hadInteractionMap.get( state ) ) {
state.step( dt );
}
} );
} );

// Remove any photons that were absorbed by something.
Expand Down

0 comments on commit e7c267c

Please sign in to comment.