-
Notifications
You must be signed in to change notification settings - Fork 0
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: Add particles #1
base: master
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Overall looks pretty cool! I like the design. I include below a number of random comments that came to mind as I skimmed this.
containers_["base"] = std::make_shared<Container<T>>(); // always add "base" container | ||
// Always add "base" containers | ||
containers_["base"] = std::make_shared<Container<T>>(); | ||
swarm_containers_["base"] = std::make_shared<SwarmContainer>(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm... My intuition is to say that the containers should own swarms, rather than a container collection owning a bunch of swarm containers. Is there a reason not to go that route?
The big complication I see is that the particles might move on different timesteps than the particles, in which case, the stages might need to be decoupled. Is that why you went this route?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's a lot going on in the current swarm hierarchy that I sort of guessed at so this should probably change somehow. I'm not sold on containers owning swarms though, since the container seemed specialized to fields when I looked through the code. Now that I think about it I take your point though.
I think particles and fields evolving with different time integration stages, different timesteps etc., is a good motivation though for keeping swarm containers at the same level as containers ("field containers"?). I hadn't thought of this. Anyway this should probably keep getting brought up for a while.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perhaps container
should be renamed field_container
;)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
could also be called not_swarm_container
enum class PARTICLE_TYPE { | ||
INT, REAL, STRING | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a need for INT
and STRING
particle types? Can they not all be Real
? That would be easier code-wise.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Indices of the cell the particle is currently living in are I think best handled with integer particle values. PARTICLE_TYPE
could be misleading (I think this enum is deprecated in favor of new Metadata flags now), this is just the type of one data field for each particle (so one scalar per particle).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm... Fair enough. I would lean on getting rid of strings, though. They will be difficult to translate onto GPU.
enum class PARTICLE_STATUS { | ||
UNALLOCATED, ALIVE, DEAD | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As we discussed, I think I'd just make dead particles have zero weight. Not sure about unallocated. Maybe this is still useful for a whole swarm?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There'll be some interplay between particles that are dead and regions of the pool that have never been allocated or are beyond the maximum living particle, I think. Some notion of UNALLOCATED
may be useful here, but this is very much in flux at the moment.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A negative weight or something could be used to denote that. I admit that might be confusing, though.
src/interface/swarm.hpp
Outdated
std::vector<std::string> _labelArray; | ||
std::vector<PARTICLE_TYPE> _typeArray; | ||
std::shared_ptr<ParArrayND<PARTICLE_STATUS>> _pstatus; | ||
ParticleVariableVector<int> _intVector; | ||
std::vector<std::shared_ptr<ParArrayND<Real>>> _realVector; | ||
std::vector<std::shared_ptr<ParArrayND<std::string>>> _stringVector; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Something to note about the ParArrayND
design: ParArrayND
already has a label. Which may mean that the array of labels isn't really necessary. I'm not sure.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also as I mentioned above, do you need string and int fields for particles? Is that necessary?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes labelArray
and typeArray
can go away, these are from an earlier iteration and I forgot to delete them.
if (intMap_.find(label) != intMap_.end() || | ||
realMap_.find(label) != realMap_.end() || | ||
stringMap_.find(label) != stringMap_.end()) { | ||
throw std::invalid_argument ("swarm variable " + label + " already enrolled during Add()!"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we're moving towards turning all these throws in the interface into more primitive code dying mechanisms. Since exception handling is slow.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd be happy to turn these into exits, maybe a FAIL
macro that automatically prints __FILE__
and __LINE__
? :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you wrote such a macro and contributed it upstream, I think there would be interest. :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Cool... I'm still tempted to call it assertions.hpp
though (Draco has an Assert.hh
and I never could think of another appropriate name for such a file, maybe you have suggestions)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
error_handling.hpp
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ooh perfect
src/interface/swarm.cpp
Outdated
if (intMap_.find(label) != intMap_.end() || | ||
realMap_.find(label) != realMap_.end() || | ||
stringMap_.find(label) != stringMap_.end()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
instead of map_.find
I might use map.count(label) > 0
. I find that to be more intuitive.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes I like that better. map_.find
is just what came up first in google.
//Public Methods | ||
//----------------- | ||
// Constructor does nothing | ||
SwarmContainer() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
SwarmContainer() { | |
SwarmContainer() = default; |
/// Get a swarm from the container | ||
/// @param label the name of the swarm | ||
/// @return the Swarm if found or throw exception | ||
Swarm& Get(std::string label) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't linear search the vector. Use the map.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh right, leftover code, good catch :)
Oh one more thought. Weight will probably always be wanted, even if it's just 1 or 0. So maybe every swarm should start with a weight field. |
I was wondering what default fields should be, if any. |
Hmm a good point. I guess we should lean on zero default fields until we start writing the communication code, etc., and then discover we need some of them. |
PR Summary
Add particles to parthenon. This PR shows what has changed relative to
master
PR Checklist