Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sim doesn't launch with correct avg temperature if mass is changed on Diffusion Screen #284

Closed
Tracked by #1123 ...
Nancy-Salpepi opened this issue Jul 15, 2024 · 16 comments

Comments

@Nancy-Salpepi
Copy link

Nancy-Salpepi commented Jul 15, 2024

Test device
MacBook Air M1 chip

Operating System
14.5

Browser
Safari 17.5

Problem description
For phetsims/qa#1107, in the Studio and State wrappers on the Diffusion Screen changing the Mass of either particle type will result in an incorrect Tavg in the Data Panel when the sim is launched.

Steps to reproduce

  1. In Studio go to the Diffusion screen
  2. Open the Data Panel
  3. Add 20 Red Particles
  4. Change the Mass to 30
  5. Press Test

Visuals
Screenshot 2024-07-15 at 4 37 01 PM
Screenshot 2024-07-15 at 4 37 21 PM

@pixelzoom
Copy link
Contributor

pixelzoom commented Jul 15, 2024

Reproduced in main. Very weird. Tavg should be the same as the Initial Temperature setting. In the launched sim, if I change Initial Temperature to 250, then back to 300, then Tavg is correct. I'm guessing there's an ordering issue with how state is restored that is resulting in a different result.

Tavg is the value of averageTemperatureProperty in DiffusionData. It is updated by calling DiffusionData update when the model is stepped. Relevant code in DiffusionModel:

  protected override stepModelTime( dt: number ): void {
    ...
    this.updateData();
  }

  /**
   * Updates the Data displayed for the left and right sides of the container.
   */
  private updateData(): void {
    this.leftData.update();
    this.rightData.update();
  }

pixelzoom pushed a commit that referenced this issue Jul 15, 2024
pixelzoom added a commit to phetsims/gases-intro that referenced this issue Jul 15, 2024
pixelzoom pushed a commit that referenced this issue Jul 16, 2024
pixelzoom added a commit to phetsims/diffusion that referenced this issue Jul 16, 2024
@pixelzoom
Copy link
Contributor

pixelzoom commented Jul 16, 2024

In the above commits, I tightened up the API for DiffusionData, which is where averageTemperatureProperty lives and is computed. This doesn't fix the problem, but ensures that nothing outside of DiffusionData is changing averageTemperatureProperty. These changes were patched into all 3 sims.

@pixelzoom
Copy link
Contributor

pixelzoom commented Jul 16, 2024

If I omit step 4 (Change the Mass to 30) then Tavg is correct.

If I add this to DiffusionModel, the problem goes away. But this should not be necessary, because stepModelTime calls updateData on every time step.

if ( assert && Tandem.PHET_IO_ENABLED ) {
  phet.phetio.phetioEngine.phetioStateEngine.stateSetEmitter.addListener( () => this.updateData() );
}

@pixelzoom
Copy link
Contributor

pixelzoom commented Jul 16, 2024

Inspecting totalKE computed by DiffusionData update... With the sim running in Studio, totalKE is 74844000. In the Standard wrapper, it's 69854400. Since KE = (1/2) * m * |v|^2 (see Particle getKineticEnergy) this suggests that the mass (m) or speed (|v|) is incorrect in the State wrapper.

@pixelzoom
Copy link
Contributor

pixelzoom commented Jul 16, 2024

DiffusionParticle extends Particle, and adds mass and radius fields. While ParticleIO exists for serializing Particle, we do not currently have DiffusionParticleIO. So the mass and radius fields are not being serialized, and will be incorrect until something occurs in the Standard wrapper (or Downstream sim) to update mass and radius.

Verified with this addition to DiffusionData update. The Standard wrapper reports mass=28 while the control shows a mass of 30.

    else {
      assert && assert( totalKE !== 0, 'totalKE should not be zero when the container is not empty' );
+     console.log( `totalKE=${totalKE} mass=${this.particleSystem.particles2[ 0 ].mass}` );

So we need DiffusionParticleIO. Ugh... This will be a big change.

@pixelzoom
Copy link
Contributor

Looking more closely at ParticleStateObject, I see that it does include mass and radius:

export type ParticleStateObject = {
  mass: number;
  radius: number;
  x: number;
  y: number;
  _previousX: number;
  _previousY: number;
  vx: number;
  vy: number;
};

The difference with DiffusionParticle is that mass and radius are mutable. So something is apparently not setting mass (and radius?) when restoring the state of DiffusionParticle instances.

@pixelzoom
Copy link
Contributor

pixelzoom commented Jul 16, 2024

The problem is in DiffusionParticleSystem, where there's some overly-zealous uses of isSettingPhetioStateProperty that are preventing mass, speed, and radius from being set; see below. Removing these guards should fix the problem, with no need for DiffusionParticleIO.

   Multilink.multilink(
      [ this.particle2Settings.massProperty, this.particle2Settings.initialTemperatureProperty ],
      ( mass, initialTemperature ) => {
        if ( !isSettingPhetioStateProperty.value ) {
          updateMassAndSpeed( mass, initialTemperature, this.particles2 );
        }
      } );

    // Update radii of existing particles.
    this.particle1Settings.radiusProperty.link( radius => {
      if ( !isSettingPhetioStateProperty.value ) {
        updateRadius( radius, this.particles1, container.leftBounds, isPlayingProperty.value );
      }
    } );
    this.particle2Settings.radiusProperty.link( radius => {
      if ( !isSettingPhetioStateProperty.value ) {
        updateRadius( radius, this.particles2, container.rightBounds, isPlayingProperty.value );
      }
    } );

@pixelzoom
Copy link
Contributor

The fix is 470663f, the other commits are patches for the 3 sim branches.

@Nancy-Salpepi please test in main. Leave open for verification in 1.1.0-rc.2.

@pixelzoom pixelzoom assigned Nancy-Salpepi and unassigned pixelzoom Jul 16, 2024
@Nancy-Salpepi
Copy link
Author

Nancy-Salpepi commented Jul 17, 2024

In the State wrapper when I follow similar steps to #284 (comment), the downstream sim will launch with the correct average temperature after pressing Set State Now.
If I then go back to the upstream sim and change the Number of Particles or the Radius and press Set State Now a second time, the average temperature will no longer match.

Steps:

  1. In the State Wrapper set state rate =0
  2. In the upstream sim go to the Diffusion Screen
  3. Add 20 blue particles
  4. Increase the Mass to 30
  5. Open the Data Panel
  6. Press Set State Now -- average temperatures match
  7. In the upstream sim change the radius to 135 (or add some more blue particles)
  8. Press Set State Now -- average temperatures no longer match
Screenshot 2024-07-17 at 7 44 05 AM

@pixelzoom
Copy link
Contributor

pixelzoom commented Jul 17, 2024

Reproduced in main using the steps in #284 (comment).

Noting that this workaround (first mentioned in #284 (comment)) does NOT address this new problem.

    if ( assert && Tandem.PHET_IO_ENABLED ) {
      phet.phetio.phetioEngine.phetioStateEngine.stateSetEmitter.addListener( () => this.updateData() );
    }

@pixelzoom
Copy link
Contributor

pixelzoom commented Jul 17, 2024

I previously noted:

While ParticleIO exists for serializing Particle, we do not currently have DiffusionParticleIO.

ParticleIO does not exist; we have LightParticleIO and HeavyParticleIO, DiffusionParticle1IO and DiffusionParticle2IO. I suspect that there's a serialization problem with DiffusionParticle1IO and DiffusionParticle1IO.

@pixelzoom
Copy link
Contributor

pixelzoom commented Jul 17, 2024

This was indeed a serialization bug in DiffusionParticle1IO and DiffusionParticle2IO. While mass and radius were serialized correctly, there were not deserialized correctly. The mass and radius values that were saved were not being used to create the particle instance during deserialization. For example, here's the fix for DiffusionParticle1:

  /**
   * Deserializes an instance of DiffusionParticle1.
   */
  private static fromStateObject( stateObject: DiffusionParticle1StateObject ): DiffusionParticle1 {
    return new DiffusionParticle1( {
      x: stateObject.x,
      y: stateObject.y,
      previousX: stateObject._previousX,
      previousY: stateObject._previousY,
      vx: stateObject.vx,
-     vy: stateObject.vy
+     vy: stateObject.vy,
+     mass: stateObject.mass,
+     radius: stateObject.radius
    } );
  }

The primary commit is cab2dc5, the others are related to patching release branches for the 3 sims.

I tested both the original problem (#284 (comment)) and the more recent problem (#284 (comment)).

@pixelzoom
Copy link
Contributor

@Nancy-Salpepi please test in main. Leave open for verification in 1.1.0-rc.2.

@Nancy-Salpepi
Copy link
Author

This looks good now on main!

@pixelzoom
Copy link
Contributor

pixelzoom commented Jul 23, 2024

Please verify for phetsims/qa#1123 and phetsims/qa#1125. (This issue is irrelevant for the Gases Intro sim.)

To verify:
(1) Follow "Steps to reproduce" in #284 (comment).
(2) Follow "Steps to reproduce" in #284 (comment).

If everything looks OK, please close this issue.

@Nancy-Salpepi
Copy link
Author

looks good in rc.2 for Gas Properties and Diffusion sims.
Closing

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants