Skip to content

Commit

Permalink
added pressure to state, see #296
Browse files Browse the repository at this point in the history
  • Loading branch information
jbphet committed Jun 19, 2020
1 parent 3a88e25 commit eb6522e
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 17 deletions.
21 changes: 9 additions & 12 deletions js/common/model/MultipleParticleModel.js
Original file line number Diff line number Diff line change
Expand Up @@ -503,10 +503,8 @@ class MultipleParticleModel extends PhetioObject {
// remove all atoms
this.removeAllAtoms();

// Reinitialize the model parameters, but not if this is a phet-io setState operation.
if ( !phet.joist.sim.isSettingPhetioStateProperty.value ) {
this.initializeModelParameters();
}
// Reinitialize the model parameters.
this.initializeModelParameters();

// Set the model parameters that are dependent upon the substance being simulated.
switch( substance ) {
Expand Down Expand Up @@ -549,11 +547,8 @@ class MultipleParticleModel extends PhetioObject {
throw( new Error( 'unsupported substance' ) ); // should never happen, debug if it does
}

// In most cases, the container size is reset at this point, but when the substance is being updated using phet-io
// the container size is *not* reset, since doing so may overwrite a size that was specifically set by the user.
if ( !phet.joist.sim.isSettingPhetioStateProperty.value ) {
this.containerHeightProperty.reset();
}
// Reset the container height.
this.containerHeightProperty.reset();

// Make sure the normalized container dimensions are correct for the substance and the current non-normalize size.
this.updateNormalizedContainerDimensions();
Expand Down Expand Up @@ -1457,7 +1452,8 @@ class MultipleParticleModel extends PhetioObject {
gravitationalAcceleration: this.gravitationalAcceleration,
normalizedLidVelocityY: this.normalizedLidVelocityY,
heatingCoolingAmount: this.heatingCoolingAmountProperty.value,
moleculeDataSet: MoleculeForceAndMotionDataSetIO.toStateObject( this.moleculeDataSet )
moleculeDataSet: MoleculeForceAndMotionDataSetIO.toStateObject( this.moleculeDataSet ),
moleculeForcesAndMotionCalculatorPressure: this.moleculeForceAndMotionCalculator.pressureProperty.value
}
};
}
Expand All @@ -1476,7 +1472,8 @@ class MultipleParticleModel extends PhetioObject {
containerHeight: stateObject.private.containerHeight,
normalizedLidVelocityY: stateObject.private.normalizedLidVelocityY,
heatingCoolingAmount: stateObject.private.heatingCoolingAmount,
moleculeDataSet: MoleculeForceAndMotionDataSetIO.fromStateObject( stateObject.private.moleculeDataSet )
moleculeDataSet: MoleculeForceAndMotionDataSetIO.fromStateObject( stateObject.private.moleculeDataSet ),
moleculeForcesAndMotionCalculatorPressure: stateObject.private.moleculeForcesAndMotionCalculatorPressure
};
}

Expand All @@ -1494,10 +1491,10 @@ class MultipleParticleModel extends PhetioObject {
this.gravitationalAcceleration = state.gravitationalAcceleration;
this.normalizedLidVelocityY = state.normalizedLidVelocityY;
this.moleculeDataSet = state.moleculeDataSet;
this.moleculeForceAndMotionCalculator.presetPressure( state.moleculeForcesAndMotionCalculatorPressure );
}
}


// static constants
MultipleParticleModel.PARTICLE_CONTAINER_WIDTH = CONTAINER_WIDTH;
MultipleParticleModel.PARTICLE_CONTAINER_INITIAL_HEIGHT = CONTAINER_INITIAL_HEIGHT;
Expand Down
11 changes: 8 additions & 3 deletions js/common/model/TimeSpanDataQueue.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,18 +14,20 @@ function TimeSpanDataQueue( length, maxTimeSpan ) {
this.length = length;
this.maxTimeSpan = maxTimeSpan;

// allocate a fixed-size array so that subsequent allocations are not needed
// @private - array where entries are kept
this.dataQueue = new Array( length );

// initialize the data array with a set of reusable objects so that subsequent allocations are not needed
for ( let i = 0; i < length; i++ ) {
this.dataQueue[ i ] = { deltaTime: 0, value: null };
}

// initialize the variables used to make this thing work
// @public (read-only) {number} - the total of all values currently in the queue
this.total = 0;

// @private - variables used to make this thing work
this.head = 0;
this.tail = 0;
this.total = 0;
this.timeSpan = 0;
}

Expand All @@ -38,6 +40,7 @@ inherit( Object, TimeSpanDataQueue, {
* span, and also updates the total value and the current time span
* @param value
* @param dt
* @public
*/
add: function( value, dt ) {

Expand All @@ -61,6 +64,7 @@ inherit( Object, TimeSpanDataQueue, {
while ( this.timeSpan > this.maxTimeSpan ) {
const nextTail = ( this.tail + 1 ) % this.length;
if ( nextTail === nextHead ) {

// nothing more can be removed, so bail
assert && assert( false, 'time span exceeded, but nothing appears to be in the queue - probably a bug' );
break;
Expand All @@ -73,6 +77,7 @@ inherit( Object, TimeSpanDataQueue, {

/**
* clear all data from the queue
* @public
*/
clear: function() {
this.head = 0;
Expand Down
30 changes: 28 additions & 2 deletions js/common/model/engine/AbstractVerletAlgorithm.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ import TimeSpanDataQueue from '../TimeSpanDataQueue.js';
// Constants that control the pressure calculation. The size of the pressure accumulator assumes a max sim rate of
// 1 / 60, which derives from the standard 60 FPS rate at which browsers currently run. May need to go up someday.
const PRESSURE_CALC_TIME_WINDOW = 12; // in seconds, empirically determined to be responsive but not jumpy
const PRESSURE_ACCUMULATOR_LENGTH = Math.ceil( PRESSURE_CALC_TIME_WINDOW / ( 1 / 60 ) * 1.1 );
const NOMINAL_DT = 1 / 60; // in seconds, assuming 60 fps
const PRESSURE_ACCUMULATOR_LENGTH = Math.ceil( PRESSURE_CALC_TIME_WINDOW / NOMINAL_DT * 1.1 );

// constants that control when the container explodes
const EXPLOSION_PRESSURE = 41; // in model units, empirically determined
Expand Down Expand Up @@ -45,7 +46,7 @@ function AbstractVerletAlgorithm( multipleParticleModel ) {
// during execution of the Verlet algorithm, must be cleared by the client.
this.lidChangedParticleVelocity = false;

// @private, moving time window queue for tracking the pressure data
// @private {TimeSpanDataQueue}, moving time window queue for tracking the pressure data
this.pressureAccumulatorQueue = new TimeSpanDataQueue( PRESSURE_ACCUMULATOR_LENGTH, PRESSURE_CALC_TIME_WINDOW );

// @private, tracks time above the explosion threshold
Expand Down Expand Up @@ -292,6 +293,31 @@ inherit( Object, AbstractVerletAlgorithm, {
}
},

/**
* This method allows the caller to set an initial value for the pressure. It was added in support of phet-io state
* setting so that the pressure calculation could be set to an initial value above zero that reflected the state
* extracted from another instance of the simulation.
* @param {number} pressure
*/
presetPressure: function( pressure ) {

assert && assert(
phet.joist.sim.isSettingPhetioStateProperty.value,
'this method is intended for use during state setting only'
);

// get rid of any accumulated values
this.pressureAccumulatorQueue.clear();

// calculate the instantaneous sample value needed to make the overall pressure be the needed value
const pressureSampleInstantaneousValue = pressure * PRESSURE_CALC_TIME_WINDOW / PRESSURE_ACCUMULATOR_LENGTH;

// add the entries to the accumulator
_.times( PRESSURE_ACCUMULATOR_LENGTH, () => {
this.pressureAccumulatorQueue.add( pressureSampleInstantaneousValue, NOMINAL_DT );
} );
},

// static final
PARTICLE_INTERACTION_DISTANCE_THRESH_SQRD: 6.25,

Expand Down

0 comments on commit eb6522e

Please sign in to comment.