refactor(DisBaseType): make abstract, use interfaces and deferred procs #1417
+450
−767
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Motivation
DisBaseType
hosts shared logic and specifies the interface discretizations should implement, but does not fully define a discretization and so should not be instantiated. To reflect this, this PR makes it abstract, replacing stubs which raised not implemented errors with interfaces and deferred procedures.Calling overridden procedures from children
A consequence here is that child types can no longer call the abstract parent's procedure if the child overrides it. The language standard allows routines in derived types extending an abstract parent to call non-overridden procedures but not overridden ones. For discussion see:
I think the standard could support this — explicitly identifying the parent keeps the binding unambiguous. This makes it sound like there is no technical obstacle, just a desire not to depart from existing semantics.
There are a few ways around it. This PR demos two:
foo_default
, rebind it to a generic name e.g.foo => foo_default
(and likewise with the override in the child) so external callers can continue to use e.g.dis%foo()
, and have children usethis%foo_default()
— recommended in the discourse link, used forallocate_scalars
andallocate_arrays
call foo(this)
instead ofthis%foo()
, as recommended in the Intel thread — used fordis_da
A third option (also in the discourse link) is to introduce a concrete grandparent (
DisBaseSharedType
?) for procedures whose implementation is shared by all children, extend it with an intermediate abstract parent containing deferred procs, have all the children extend the intermediate, and call from children with e.g.this%DisBaseSharedType%foo()
.Whichever approach is deemed best, the PR can be updated to use consistently, if any of this is even worth it. Maybe it's not. But maybe there is a case for letting the compiler enforce constraints instead of runtime programmer errors.
At first I wondered if this is relevant to
FlowModelInterfaceType
too but that's a more complete abstraction and maybe there could be situations calling for its direct use without extension.Miscellany
Also some minor edits in
DiscretizationBase.f90
.return
statementspublic
modifiers from type-bound procedure listingsThe same could be done in dis/disv/disu but thought best to wait so the changes here are easier to see.