Use Mesh::addCoordinates(location) to initialize Coordinates - #1372
Use Mesh::addCoordinates(location) to initialize Coordinates#1372johnomotani wants to merge 7 commits into
Conversation
|
If we really wanted to avoid changing user code, we could call |
|
I'm not sure if this should be going into master as it seems to suggest users need to change how they do things, which I'd have thought should only change with a non-bug-fix release. On the other hand it is a route to avoiding a known bug. Any thoughts @bendudson and @ZedThree ? |
|
One possibility is to actually go with the brute force method (generate all possible coordinates during startup -- downside memory consumption) as a temporary bug fix for this release and then use the approach in this PR for next as a way of properly side-stepping the issue for the next release? |
|
Agree the brute force as a temporary fix for master is a good idea. Would it be OK to put REQUEST_LOCATION into master as well (although it won't be required to call it) so that code can be compatible with both master and next? [is there a word for the opposite of deprecation? 😉 ] |
3d01892 to
38e1c4e
Compare
e29f449 to
91d464f
Compare
91d464f to
aeee283
Compare
Previously the localmesh was not passed through to the constructor of d2x and d2y in Coordinates::geometry(), so they used the global 'mesh'. Also, when d2x/d2y are read from the mesh, they are at CELL_CENTRE, so we need to interpolate them to the location of the Coordinates.
Could cause bugs, for example in unit tests of BoutMesh where mesh==nullptr.
aeee283 to
a264ed3
Compare
|
I think this is ready now. As @d7919 suggested, this is a temporary work-around to fix the bug without requiring any changes to user code, before #1392 introduces the long-term implementation in I found a couple of small bugs while writing the unit tests for #1392, so I've included the fixes here to go into |
a264ed3 to
f43d78c
Compare
Instead of creating Coordinates objects when Mesh::getCoordinates is called, create them during initialization. As a temporary workaround to maintain backward compatibility, initialize all locations in BoutMesh::load() so that they are always available. Allow the user to explicitly request a location to be available, by calling Mesh::addCoordinates(location) for each location required. This is optional in v4.2 but will be required from v4.3. When Coordinates::geometry() is called, assume that staggered location Coordinates objects need to be recalculated because the user has changed the CELL_CENTRE version. As a temporary workaround, replace geometry() with geometryNoRecalculate() and geometry() now calls geometryNoRecalculate and then recalculates the staggered versions. This means geometry() can be reset back to not recalculating in next (which is OK because we will add the requirement to call addCoordinates() after calling geometry()) without changing the function signature.
Allows Coordinates pointers to be retrieved where necessary in the unit tests.
f43d78c to
f528e6a
Compare
|
I've taken out the |
ZedThree
left a comment
There was a problem hiding this comment.
Sorry John, I hadn't realised this was a bugfix into master. Looks ok, just a few questions
| GridDataSource *source; ///< Source for grid data | ||
|
|
||
| std::map<CELL_LOC, std::shared_ptr<Coordinates> > coords_map; ///< Coordinate systems at different CELL_LOCs | ||
| std::map<CELL_LOC, std::unique_ptr<Coordinates> > coords_map; ///< Coordinate systems at different CELL_LOCs |
There was a problem hiding this comment.
I'm not sure about this change to unique_ptr -- is there a reason for that?
There was a problem hiding this comment.
@ZedThree We were discussing in the thread on #1392 a while ago. I think the conclusion was that unique_ptr makes sense because the Mesh should always keep ownership of the Coordinates objects, but that we should (eventually?) return references rather than pointers. I'm happy to go with whatever you think best on this though; should I change it back?
There was a problem hiding this comment.
Also, even if unique_ptr is the thing to do, it is not a bugfix, so should be in #1392 only, not in this PR. I'll take it out of this one.
There was a problem hiding this comment.
I think we can even go further and just store values. It was originally stored as a pointer because we have to make the Mesh before making a Coordinates so it had to be initialised to nullptr. But as we're now storing multiple instances in a map, we can initialise the map to empty and hand out pointers for now, and references later.
| private: | ||
| /// Allocates default Coordinates objects | ||
| std::shared_ptr<Coordinates> createDefaultCoordinates(const CELL_LOC location); | ||
| std::unique_ptr<Coordinates> createDefaultCoordinates(const CELL_LOC location); |
There was a problem hiding this comment.
The implementation of this was deleted so this should go too
| // Can always add ZLOW Coordinates, since z-interpolation on Field2D is a | ||
| // null operation | ||
| addCoordinates(CELL_ZLOW); | ||
| } |
There was a problem hiding this comment.
This logic is in Coordinates::geometry too -- does it need to be here?
There was a problem hiding this comment.
I think it does need to be here. This code ensures the Coordinates are created at each location initially. The code in Coordinates::geometry() replaces (and therefore re-calculates) the staggered Coordinates objects after the CELL_CENTRE Coordinates is changed by geometry(). The idea is that #1392 will update things so that here we only create the CELL_CENTRE Coordinates (i.e. lines 845-860 are deleted), the user has to call Mesh::addCoordinates(location) for any needed staggered location, and if the user calls geometry() it has to be before the staggered Coordinates are initialized.
Maybe there is a neater way, but I don't think we want to call Coordinates::geometry() here because it would duplicate work already done when geometryNoRecalculate is called as part of the constructor in addCoordinates(CELL_CENTRE).
Also similarly fix comments in Coordinates::geometry() and BoutMesh::load().
Implementation was already removed from Mesh.
|
After quite a bit of discussion, we think this probably isn't the best way forward. The relationship between Instead, let's just not calculate the Christoffel symbols in Doing this would neatly sidestep the root cause of the bug you were seeing, and also have other nice side-effects as it would pave the way for removing them entirely (or at least out to a separate structure). |
|
I think there was also a bug fix for the non-uniform corrections in here -- @johnomotani do you want to put them in another PR? |
|
PS I'll put the bugfix to non-uniform corrections in a separate PR anyway. The fix to |
Instead of creating Coordinates objects when Mesh::getCoordinates is called, require the user to explicitly request them before using staggered fields. Either with REQUEST_LOCATION(location1, ...) macro, which adds coordinates to the global mesh pointer, or by calling Mesh::addCoordinates(location) for each location required.
Fixes #1369.
Staggered grid section of manual and
examples/staggered_gridalso updated.I switched to storing the
Coordinates instd::unique_ptrrather thanstd::shared_ptrbecause we want theMeshobject to be the only owner of theCoordinates. The change might also offer some small performance advantage.