diff --git a/js/chart-intro/model/ChartIntroModel.ts b/js/chart-intro/model/ChartIntroModel.ts index 390b06f..d5edd26 100644 --- a/js/chart-intro/model/ChartIntroModel.ts +++ b/js/chart-intro/model/ChartIntroModel.ts @@ -16,6 +16,7 @@ import BANConstants from '../../common/BANConstants.js'; import ParticleAtom from '../../../../shred/js/model/ParticleAtom.js'; import Property from '../../../../axon/js/Property.js'; import NuclideChartCellModel from './NuclideChartCellModel.js'; +import DecayEquationModel from './DecayEquationModel.js'; // types export type SelectedChartType = 'partial' | 'zoom'; @@ -41,7 +42,10 @@ class ChartIntroModel extends BANModel { public readonly particleNucleus: ParticleNucleus; public readonly miniParticleAtom: ParticleAtom; public readonly selectedNuclideChartProperty: Property; - public static cellModelArray = POPULATED_CELLS.map( ( row, rowIndex ) => row.map( column => new NuclideChartCellModel( rowIndex, column ) ) ); + + // There's not an entry for all the neutron values, see POPULATED_CELLS + public static cellModelArray = POPULATED_CELLS.map( ( neutronCountList, protonCount ) => neutronCountList.map( neutronCount => new NuclideChartCellModel( protonCount, neutronCount ) ) ); + public readonly decayEquationModel: DecayEquationModel; public constructor() { @@ -56,6 +60,8 @@ class ChartIntroModel extends BANModel { this.miniParticleAtom = new ParticleAtom(); this.selectedNuclideChartProperty = new Property( 'partial' ); + + this.decayEquationModel = new DecayEquationModel( ChartIntroModel.cellModelArray, this.particleNucleus.protonCountProperty, this.particleNucleus.massNumberProperty ); } /** diff --git a/js/chart-intro/model/DecayEquationModel.ts b/js/chart-intro/model/DecayEquationModel.ts new file mode 100644 index 0000000..f6fccaa --- /dev/null +++ b/js/chart-intro/model/DecayEquationModel.ts @@ -0,0 +1,87 @@ +// Copyright 2023, University of Colorado Boulder + +/** + * Node that represents the model of a decay equation. + * + * @author Luisa Vargas + * @author Marla Schulz (PhET Interactive Simulations) + */ + +import buildANucleus from '../../buildANucleus.js'; +import NuclideChartCellModel from './NuclideChartCellModel.js'; +import TReadOnlyProperty from '../../../../axon/js/TReadOnlyProperty.js'; +import DecayType from '../../common/view/DecayType.js'; +import NumberProperty from '../../../../axon/js/NumberProperty.js'; +import Property from '../../../../axon/js/Property.js'; + +class DecayEquationModel { + private readonly initialProtonNumberProperty: TReadOnlyProperty; + private readonly initialMassNumberProperty: TReadOnlyProperty; + private readonly finalProtonNumberProperty: Property; + private readonly finalMassNumberProperty: Property; + + public constructor( cellModelArray: NuclideChartCellModel[][], protonCountProperty: TReadOnlyProperty, massNumberProperty: TReadOnlyProperty ) { + + this.initialProtonNumberProperty = protonCountProperty; + this.initialMassNumberProperty = massNumberProperty; + + // TODO: if at 0 protons and 0 neutrons, or if decay type is unknown, don't show the decay equation + this.finalProtonNumberProperty = new NumberProperty( -1 ); + this.finalMassNumberProperty = new NumberProperty( -1 ); + + this.initialMassNumberProperty.link( () => { + const currentCell = this.getCurrentCellModel( cellModelArray, protonCountProperty.value, massNumberProperty.value ); + console.log( cellModelArray ); + if ( !currentCell || !currentCell.decayType ) { + // TODO: for stable decay types set this, is it alright? + this.finalProtonNumberProperty.value = this.initialProtonNumberProperty.value; + this.finalMassNumberProperty.value = this.initialMassNumberProperty.value; + return; + } + console.log( currentCell.decayType ); + switch( currentCell.decayType ) { + case DecayType.NEUTRON_EMISSION: + this.finalProtonNumberProperty.value = this.initialProtonNumberProperty.value; + this.finalMassNumberProperty.value = this.initialMassNumberProperty.value - 1; + break; + case DecayType.PROTON_EMISSION: + this.finalProtonNumberProperty.value = this.initialProtonNumberProperty.value - 1; + this.finalMassNumberProperty.value = this.initialMassNumberProperty.value - 1; + break; + case DecayType.BETA_PLUS_DECAY: + this.finalProtonNumberProperty.value = this.initialProtonNumberProperty.value - 1; + this.finalMassNumberProperty.value = this.initialMassNumberProperty.value; + break; + case DecayType.BETA_MINUS_DECAY: + this.finalProtonNumberProperty.value = this.initialProtonNumberProperty.value + 1; + this.finalMassNumberProperty.value = this.initialMassNumberProperty.value; + break; + case DecayType.ALPHA_DECAY: + this.finalProtonNumberProperty.value = this.initialProtonNumberProperty.value - 2; + this.finalMassNumberProperty.value = this.initialMassNumberProperty.value - 4; + break; + default: + assert && assert( false, 'No valid decay type found: ' + currentCell.decayType ); + } + + } ); + + this.initialMassNumberProperty.link( initialMassNumber => { + console.log( 'initialMassNumber = ' + initialMassNumber ); + console.log( 'initialProtonNumber = ' + this.initialProtonNumberProperty.value ); + console.log( 'finalMassNumber = ' + this.finalMassNumberProperty.value ); + console.log( 'finalProtonNumber = ' + this.finalProtonNumberProperty.value ); + } ); + + } + + /** + * Return the current NuclideChartCellModel for the current proton number and mass number, if there exists one. + */ + private getCurrentCellModel( cellModelArray: NuclideChartCellModel[][], protonNumber: number, massNumber: number ): NuclideChartCellModel | undefined { + return _.find( cellModelArray[ protonNumber ], cellModel => cellModel.neutronNumber === massNumber - protonNumber ); + } +} + +buildANucleus.register( 'DecayEquationModel', DecayEquationModel ); +export default DecayEquationModel; \ No newline at end of file diff --git a/js/common/view/DecayType.ts b/js/common/view/DecayType.ts index cf93466..97ecc75 100644 --- a/js/common/view/DecayType.ts +++ b/js/common/view/DecayType.ts @@ -15,26 +15,32 @@ import BANColors from '../BANColors.js'; class DecayType extends EnumerationValue { - public static readonly ALPHA_DECAY = new DecayType( BuildANucleusStrings.alphaDecay, BANColors.alphaColorProperty ); + public static readonly ALPHA_DECAY = new DecayType( BuildANucleusStrings.alphaDecay, BANColors.alphaColorProperty, 4, 2, 'α' ); - public static readonly BETA_MINUS_DECAY = new DecayType( BuildANucleusStrings.betaMinusDecay, BANColors.betaMinusColorProperty ); + public static readonly BETA_MINUS_DECAY = new DecayType( BuildANucleusStrings.betaMinusDecay, BANColors.betaMinusColorProperty, 0, -1, 'β' ); - public static readonly BETA_PLUS_DECAY = new DecayType( BuildANucleusStrings.betaPlusDecay, BANColors.betaPlusColorProperty ); + public static readonly BETA_PLUS_DECAY = new DecayType( BuildANucleusStrings.betaPlusDecay, BANColors.betaPlusColorProperty, 0, 1, 'β' ); - public static readonly PROTON_EMISSION = new DecayType( BuildANucleusStrings.protonEmission, BANColors.protonEmissionColorProperty ); + public static readonly PROTON_EMISSION = new DecayType( BuildANucleusStrings.protonEmission, BANColors.protonEmissionColorProperty, 0, 1, 'e' ); - public static readonly NEUTRON_EMISSION = new DecayType( BuildANucleusStrings.neutronEmission, BANColors.neutronEmissionColorProperty ); + public static readonly NEUTRON_EMISSION = new DecayType( BuildANucleusStrings.neutronEmission, BANColors.neutronEmissionColorProperty, 1, 0, 'n' ); public static readonly enumeration = new Enumeration( DecayType ); public readonly label: string; public readonly colorProperty: ProfileColorProperty; + public readonly massNumber: number; + public readonly protonNumber: number; + public readonly decaySymbol: string; - public constructor( label: string, colorProperty: ProfileColorProperty ) { + public constructor( label: string, colorProperty: ProfileColorProperty, massNumber: number, protonNumber: number, decaySymbol: string ) { super(); this.label = label; this.colorProperty = colorProperty; + this.massNumber = massNumber; + this.protonNumber = protonNumber; + this.decaySymbol = decaySymbol; } }