I would like to get folks' thoughts on the following approach, and perhaps even suggest better alternatives.
I have a weather simulation, and I want to be able to calculate specific properties as the simulation progresses. Suppose I have a Base Class WeatherSim
from which different types of simulations derive. So I may have a ConstantTemperatureWeatherSim
or ConstantPressureWeatherSim
, etc..
In the case of ConstantTemperatureWeatherSim
I may be interested in how the average barometric pressure changes with time (iterations in the actual simulation), and so on. I may also run the same simulations, where I want to monitor other properties, such as average velocity field vector, or some arbitrary quantity which I desire.
The thing is, I need to calculate the properties in the most efficient way possible, since these simulations are very computationally expensive. This means that while I can have a vector of property calculating functions, like this:
class ConstTempWeatherSim {
std::vector<std::function<double(Model&)>> properties;
void Iterate() {
// Perform calculations...
// Calculate properties
for(auto& property : properties)
property(model);
}
This approach is very inefficient. For the case of say, average pressure, I can loop though all elements in the model and get the pressure property on every iteration. A much more effective approach is to keep a running average.
The thing is, I don't want to pollute my class with every possible calculable quantity (and frankly I can't even if I wanted to, since I don't know what weird property a user may want to calculate).
My solution to this problem was to use somewhat of a visitor pattern. My WeatherSim
is a Visitable
object, and the property I want to calculate is my Visitor
. I store a vector of Visitors
in my WeatherSim
and each iteration I call the Visitors
to do their thing. Each visitor will accept a reference to WeatherSim
and so they can store their running average internally.
In my mind that is a good way of solving this issue, except there are two other things I need to resolve, which is why I'm here.
Some properties are needed to perform calculations in a specific simulation. So for example, I may need to use pressure in my
ConstantTempWeatherSim
as part of the algorithm. Should I just keep a running average of the required property separately from myVisitors
and use those to augment the properties already computed by theWeatherSim
? Or should I have a private vector ofPropertyVisitors
that I use for the necessary properties and have the user add anything else they need to a separate queue? Is there some other way?After each iteration,
WeatherSim
calls Observers to log the desired information. What's the best way of getting the data from thePropertyVisitors
to theObserver
? I don't think it would be wise to pass in a vector of references to thePropertyVisitors
themselves to theObservers
. I was thinking that in mySimEvent
class, which contains information on the event, I could get the values from all thePropertyVisitors
and store them in a vector inSimEvent
. Or am I barking up the wrong tree?
Perhaps the visitor pattern isn't the best approach to this. I would appreciate thoughts on how to approach this problem.
Thank you all in advance!
Aucun commentaire:
Enregistrer un commentaire