-
Notifications
You must be signed in to change notification settings - Fork 92
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
WIP: Topologies using CollectionOfVectors #965
Conversation
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #965 +/- ##
==========================================
- Coverage 93.69% 91.94% -1.75%
==========================================
Files 36 38 +2
Lines 5438 5713 +275
==========================================
+ Hits 5095 5253 +158
- Misses 343 460 +117 ☔ View full report in Codecov by Sentry. |
How does this compare to @termi-official s stuff in the distributed repo? |
The topology construction in the distributed implementation (CoverTopology) is very similar to the topology in Ferrite. The standard queries in should be essentially constant time. |
Edit: Outdated
I did this a bit for fun to see how it would work. The dict-approach is quite nice when building the information, since it makes it quite easy to place everything right.
One idea would be to use |
As pointed out by @termi-official on Slack, this could also be useful for saving cell states in a continuous vector. Of course, this might also belong in a different package, but that could perhaps be done in the future if we choose to use this strategy. |
not sure how much the self mapping in the last case of |
In any case a fast-lookup datastructure is nice, and any of the proposed constructors are fine IMO since they have a few 100 allocations. Adding the Yes, I would also aim to replace I'll make a separate PR for that, just to keep these other "ideas" around. |
Some random comments / questions: The reason for CollectionOfVectors is to allow for more general outer collections? But couldn't we use ArrayofArrays if we store the general outer collection as a mapping to a linear index that we then use for the vector. So like (in pseudocodeish):
For matrices, you would only have to store the number of rows to do the linear index computation. Also, when is a Dict interface needed at all? Are there some sparsity that we didn't exploit before when using a It's a bit hard to get an overview of what is changed here since it isn't a diff for the existing implementation. Is it all new or is most of the previous implementation possible to reuse? Ideally, the data structure should be swappable without too much changes to the implementation of the functions since they should have a similar API? The construction benchmarks looks good but would also be good to see query benchmarks. |
Sorry about that: Basically all access function should be almost the same, and most part of the construction algorithms are the same, except that it does
For the indexing part, yes that would be similar, but gives an additional redirection AFAIU. But for the construction, I could not see how this would be done for
For the topology of different elements, there may be some differences (e.g. Hexahedron with 8 vertices vs Tetrahedron with 4). The initial thought with the There are other use-cases, I think @termi-official mentioned state-variable storage (when you have different cells in the grid) and dof-distribution as places where the Dict-indexing would be beneficial. So to conclude - if someone has an idea for an efficient construction of |
For the accessor time, aren't @koehlerson's timings here what you ask for @KristofferC ? |
for reproducing the timings: diff --git a/src/CollectionOfVectors.jl b/src/CollectionOfVectors.jl
index 163cebfa4..93b38a520 100644
--- a/src/CollectionOfVectors.jl
+++ b/src/CollectionOfVectors.jl
@@ -4,6 +4,7 @@ struct CollectionOfVectors{IT<:Union{AbstractArray{UnitRange{Int}}, AbstractDict
end
Base.getindex(cv::CollectionOfVectors, index) = view(cv.data, cv.indices[index])
+Base.getindex(cv::CollectionOfVectors, index...) = view(cv.data, cv.indices[index...])
Base.keys(cv::CollectionOfVectors) = keys(cv.indcies)
Base.values(cv::CollectionOfVectors) = (view(cv.data, idx) for idx in values(cv.indices))
nonempty_values(cv::CollectionOfVectors) = (view(cv.data, idx) for idx in values(cv.indices) if !isempty(idx))
diff --git a/src/Grid/topology2.jl b/src/Grid/topology2.jl
index 51118b431..974dbf64d 100644
--- a/src/Grid/topology2.jl
+++ b/src/Grid/topology2.jl
@@ -272,6 +272,14 @@ function ExclusiveTopology2(grid::AbstractGrid{sdim}) where sdim
return ExclusiveTopology2(vertex_to_cell, cell_neighbor, face_face_neighbor, edge_edge_neighbor, vertex_vertex_neighbor, nothing, nothing, nothing)
end
+function getneighborhood(top::ExclusiveTopology2, grid::AbstractGrid, faceidx::FaceIndex, include_self=false)
+ if include_self
+ return [top.face_face_neighbor[faceidx[1],faceidx[2]]; faceidx]
+ else
+ return top.face_face_neighbor[faceidx[1],faceidx[2]]
+ end
+end
+ |
Superseded by #974 |
Introduces the type
CollectionOfVectors
which basically allows you to either indexing via a hash like for anOrderedDict
or withInt
s orCartesianIndex
into anArray
of predefined size, to get data stored in a linear Vector as a view. Each entry can have different lengths.Then use this to create topologies, for now demonstrated by the following topologies
ExclusiveTopology2
: Same asExclusiveTopology
, but storage byCollectionOfVectors
to reduce the number of small vectorsCoverTopology
: Same asCoverTopology
inFerriteDistributed
(not tested, but just to check that reuse is possible)EntityTopology
: Another test where the instancesBoundaryIndex
es of a unique entity is indexed by looking up the unique entity, e.g. by indexing with the tuplesortface_fast
.(Not all methods implemented yet, but that should be relatively straight forward)
Timing showing stable construction time
Difference from ArrayOfArrays
The difference from
ArrayOfArrays.VectorOfArrays
is that the content is always anAbstractVector
(specifically aview(::Vector{Float64}, ::UnitRange{Int})
), but the outer type can act as aVector
,Matrix
,Array
, orOrderedDict
allowing different indexing.Old notes
While following the discussion on Slack today, I played around with this idea which doesn't allocate many small vectors. It also uses the unique representations of entities to get the indices.
It is also a bit fast on construction, but slower in usage since it uses hashes to lookup. But the main point is that has much fewer allocations, and
ExclusiveTopology
brings my computer to a halt due to when creating it twice for a large grid...ExclusiveTopology2
andCoverTopology
have similar time for construction.xrefs: #827