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

Redefine Trim* and Round* functions in terms of {fmt} #7772

Merged
merged 2 commits into from
Feb 14, 2020

Conversation

lefticus
Copy link
Contributor

Problem:

  • Most of the diffs that come up during replacement of GIO with {fmt}
    involve minor differences in the Round and Trim functions

Proposed Solution:

  • Define Trim and Round functions in terms of the new implementation
  • Resolve all rounding diffs at once
  • Reduce merge difficulty with future GIO removal commits

Expected Diffs:

  • All diffs are due to rounding and trim differences compared to GIO output.

Please Review Numeric Diffs Carefully For Any You Have Concern About During PR Review

After this all future GIO removal PR's should be less difficult.

Pull request overview

  • Purpose: deal with all remaining Round and Trim functions diffs with new IO routines.

Pull Request Author

Add to this list or remove from it as applicable. This is a simple templated set of guidelines.

  • Title of PR should be user-synopsis style (clearly understandable in a standalone changelog context)
  • Label the PR with at least one of: Defect, Refactoring, NewFeature, Performance, and/or DoNoPublish
  • Pull requests that impact EnergyPlus code must also include unit tests to cover enhancement or defect repair
  • Author should provide a "walkthrough" of relevant code changes using a GitHub code review comment process
  • If any diffs are expected, author must demonstrate they are justified using plots and descriptions
  • If changes fix a defect, the fix should be demonstrated in plots and descriptions
  • If any defect files are updated to a more recent version, upload new versions here or on DevSupport
  • If IDD requires transition, transition source, rules, ExpandObjects, and IDFs must be updated, and add IDDChange label
  • If structural output changes, add to output rules file and add OutputChange label
  • If adding/removing any LaTeX docs or figures, update that document's CMakeLists file dependencies

Reviewer

This will not be exhaustively relevant to every PR.

  • Perform a Code Review on GitHub
  • If branch is behind develop, merge develop and build locally to check for side effects of the merge
  • If defect, verify by running develop branch and reproducing defect, then running PR and reproducing fix
  • If feature, test running new feature, try creative ways to break it
  • CI status: all green or justified
  • Check that performance is not impacted (CI Linux results include performance check)
  • Run Unit Test(s) locally
  • Check any new function arguments for performance impacts
  • Verify IDF naming conventions and styles, memos and notes and defaults
  • If new idf included, locally check the err file and other outputs

Problem:

 * Most of the diffs that come up during replacement of GIO with {fmt}
   involve minor differences in the Round and Trim functions

Proposed Solution:

 * Define Trim and Round functions in terms of the new implementation
 * Resolve all rounding diffs at once
 * Reduce merge difficulty with future GIO removal commits
@lefticus lefticus added the Refactoring Includes code changes that don't change the functionality of the program, just perform refactoring label Feb 13, 2020
@mitchute
Copy link
Collaborator

Another good piece of this project.

I don't have any issues with this work directly, however, examining the diffs made me dig into the eio Surface Details Report which raisesed some questions.

From the eio diff file on SolarShadingTest_ImportedShading.idf:

-Shading Surface,ZN002:WALL001:SHADE001,Shading,ZN002:WALL001,None,SHADINGTRANSMITTANCE:0001,0.00,0.00,,0.93,0.93,0.93,180.00,180.00,3.05,0.31,,,,,,,,,,,4
+Shading Surface,ZN002:WALL001:SHADE001,Shading,ZN002:WALL001,None,SHADINGTRANSMITTANCE:0001,0.00,0.00,,0.93,0.93,0.93,180.00,180.00,3.05,0.30,,,,,,,,,,,4

In this case, the height field changed from 0.31 to 0.30. So I checked the IDF to verify the original values.

From the IDF:

  BuildingSurface:Detailed,
    Zn002:Wall001,           !- Name
    ...
    6.096000,6.096000,3.048000,  !- X,Y,Z ==> Vertex 1 {m}
    6.096000,6.096000,0.0000000E+00,  !- X,Y,Z ==> Vertex 2 {m}
    12.19200,6.096000,0.0000000E+00,  !- X,Y,Z ==> Vertex 3 {m}
    12.19200,6.096000,3.048000;  !- X,Y,Z ==> Vertex 4 {m}

  FenestrationSurface:Detailed,
    Zn002:Wall001:Win001,    !- Name
    Window,                  !- Surface Type
    SINGLE PANE HW WINDOW,   !- Construction Name
    Zn002:Wall001,           !- Building Surface Name
    ....
    7.620000,6.248000,2.743000,  !- X,Y,Z ==> Vertex 1 {m}
    7.620000,6.248000,0.3050000,  !- X,Y,Z ==> Vertex 2 {m}
    10.66800,6.248000,0.3050000,  !- X,Y,Z ==> Vertex 3 {m}
    10.66800,6.248000,2.743000;  !- X,Y,Z ==> Vertex 4 {m}

  Shading:Zone:Detailed,
    Zn002:Wall001:Shade001,  !- Name
    Zn002:Wall001,           !- Base Surface Name
    ....
    7.620000,5.791000,2.865000,  !- X,Y,Z ==> Vertex 1 {m}
    7.620000,6.096000,2.865000,  !- X,Y,Z ==> Vertex 2 {m}
    10.66800,6.096000,2.865000,  !- X,Y,Z ==> Vertex 3 {m}
    10.66800,5.791000,2.865000;  !- X,Y,Z ==> Vertex 4 {m}

So, where does the 0.31 (or 0.30) value come from? Likewise for the 3.05 width value? It seems like one came from the window and the other came from the base surface. The OutputDetailsAndExamples.pdf document makes it seem like these should come from the IDF, but perhaps I'm misunderstanding something.

@mjwitte @Myoldmopar thoughts? This work is ready. Feel free to open a separate issue if needed to address my questions above.

@rraustad
Copy link
Contributor

That wall is parallel to the x plane at y position = 6.096 and the window is at y position = 6.248 so the window is offset from the wall by 0.152 m. So what is the modeling intent here? What if the window were offset 1 m from the wall? The shading surface is just above the top of the window by 0.122 m and connects flush to the wall surface. Regardless, I don't see a 0.31 or 0.3 distance here.

@mjwitte
Copy link
Contributor

mjwitte commented Feb 14, 2020

@rraustad That's how a window reveal (setback) is defined. The shading algorithm shades the window with implied solid surfaces the depth of the reveal This shows later in the eio surface list for Zn002:Wall001:Win001, "Reveal" is 0.15.

@mitchute For the shading surfaces, the 3.05 and 0.31 are the"~Width" and "~Height". So, the 0.31 comes from 6.096000 - 5.791000 = 0.305 which seems like it should round to 0.31.

@mitchute
Copy link
Collaborator

@mjwitte thanks for looking at that. It looks like there's some other rounding/trimming going on upstream from where this EIO line is written. See the values for this surface from the debugger below.

Screen Shot 2020-02-14 at 10 05 57 AM

I'm not sure how the old RoundSigDigits was doing it but based on these numbers rounded to two significant digits, 0.30 is correct.

@mjwitte
Copy link
Contributor

mjwitte commented Feb 14, 2020

@mitchute Ok, for outputs like this, it's not a huge deal. The calculations for height and width are probably generalized in some way which could introduce tiny numeric differences.

It appears that the old method had some checks to transform repeating 9s up to 10. This appears to be what's going on in the one file with an err diff, VariableRefrigerantFlow_FluidTCtrl_HR_5Zone:

-   **   ~~~   ** ... Heat Recovery Minimum Outdoor Dry-Bulb Temperature = -20.000
+   **   ~~~   ** ... Heat Recovery Minimum Outdoor Dry-Bulb Temperature = -19.999

The input for this is -20 in the idf:

    -20,                     !- Minimum Outdoor Temperature in Heat Recovery Mode {C}

So, it seems the stored value, even if it's -19.9999999 should round up to 20.000?

@lefticus
Copy link
Contributor Author

lefticus commented Feb 14, 2020

I already know (since I've been working on this for weeks now) that if I adjust it so that 19.999999998576 rounds up to 20.000 it will cause other values to round up and cause different diffs. I can find no consistent way to reproduce what the old system was doing, and have found at least 2 cases that were clear bugs in the rounding of the old system.

For the sake of the knowledge here, I'll get the round 19.99999 rounded up to 20.00000 and show you the difference, and see which version we like better.

Update Note:

The fundamental problem is that the old code would create a string from the float, then round up that string.

This... isn't really how floating point math should work.

@lefticus
Copy link
Contributor Author

lefticus commented Feb 14, 2020

I'm currently building the "round up a bit more" version and will push it and we can see what things are different.

If neither version is satisfactory we'll have to go back to "rounding up of strings" which I strongly do not recommend. This is adding a weird kind of error to floating point computer math which is already error prone.

For those who are not familiar with the issues, see this Compiler Explorer example: https://godbolt.org/z/i8z839

@lefticus
Copy link
Contributor Author

One last note, to address @mjwitte comment:

 -   **   ~~~   ** ... Heat Recovery Minimum Outdoor Dry-Bulb Temperature = -20.000
 +   **   ~~~   ** ... Heat Recovery Minimum Outdoor Dry-Bulb Temperature = -19.999

The input for this is -20 in the idf:

    -20,                     !- Minimum Outdoor Temperature in Heat Recovery Mode {C}

-19.999, when formatted to 0 decimal places, should clearly be rounded to -20

But what if the actual value is -19.9994, when we format it to 3 sigfigs, should it be -19.999 or -20.000? The math would say -19.999, it's more accurate, the human would say -20.000 perhaps?

This is the kind of issue I've been chasing.

Particularly frustrating with this specific issue, the "Dry Bulb Temperature" is actually using "TrimSigDigits" which shouldn't be rounding at all (but was)!

@mjwitte
Copy link
Contributor

mjwitte commented Feb 14, 2020

@lefticus Thanks for the examples. Never would have thought this seemingly simple exercise would be messy. I would agree that -19.9994 should round to -19.999. But I wouldn't expect an input value of 20.0 to be that far away from 20.0.

So, maybe the bigger question is whether TrimSigDigits is useful vs. RoundSigDigits. Why wouldn't one want to always round?

Given the small number of non-substantive diffs, and the explanation that the 19.999 is produced by TrimSigDigits, I'm ok with leaving this PR as-is.

@mitchute
Copy link
Collaborator

@lefticus thanks for the input on this.

@mjwitte I agree, these diffs are justifiable. Merging.

@mitchute mitchute merged commit 9313a70 into develop Feb 14, 2020
@mitchute mitchute deleted the redefine_round_and_trim_in_terms_of_format branch February 14, 2020 20:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Refactoring Includes code changes that don't change the functionality of the program, just perform refactoring
Projects
None yet
Development

Successfully merging this pull request may close these issues.

10 participants