Hi Julia people,
I’m currently working on a major update for my package ‘RayTraceHeatTransfer.jl’. I want the updated package to contain the following features (many of which are new):
- 1D/2D/3D geometry (user can define either a 1D, 2D or a 3D geometry (3D will be meshed using TetGen.jl))
- Selective/Uniform geometry-sampling (the selective is for sampling based on boundary conditions, uniform is for uniform accuracy (no apriori knowledge of boundary conditions))
- Uniform/Nonuniform gas properties (affects ray tracing)
- In the case of ‘Uniform gas properties’ I want to include a check for transparency (and for domain convexity), and if below a certain treshold, I want to calculate view factors analytically between surfaces.
I have been considering whether there is an ‘optimal’ way to handle the many possible combinations (I counted at least 12 unique) between the above possibilities? Would the smartest way be to just use multiple dispatch and create separate functions for each case? Or is there a smarter way to go around this?
Kind regards, Nikolaj
Generally, the way is to separate into a few cases, and then have the function that the function itself calls do a few extra dispatches and so on. Multiple dispatch is really flexible. You do not need to have 12 different methods for 12 cases. You can have a few methods that call a few methods that dispatch to the appropriate response.
1 Like
I’d say that multiple dispatch is well suited for this problem but perhaps there is a way to reduce the combinatorial explosion by designing the methods in a clever way.
I’ll try to make an example loosely based on this you described (I don’t know anything about he actual algorithms). Say we have types like this:
abstract type AbstractGeometry end
struct Geometry1D <: AbstractGeometry end
struct Geometry2D <: AbstractGeometry end
struct Geometry3D <: AbstractGeometry end
abstract type AbstractSampling end
struct UniformSampling <: AbstractSampling end
struct SelectiveSampling <: AbstractSampling end
Instead of having 6 methods for each combination of an AbstractGeometry
and AbstractSampling
try to instead write a generic function that describes the sampling procedure and only like “fill in the blanks” with different behavior based on the types passed. So say you want to generate a some ray for tracing, then you might have a single function
function generateRay(::UniformSampling, geometry)
# just choose a random starting point and direction
dims = dimensions(geometry) # this is method that each subtype of AbstractGeometry implements and just gives the number of dimensions
return Ray(randn(d), normalize!(randn(d))
end
function generateRay(::SelectiveSampling, geometry)
# i am assuming that the boundary condition is some property of the geometry
boundary = find_boundary(geometry)
# ... some computation to find starting point
end
So ideally instead of having M*N
combinatorially many methods, so just need M+N
methods which are used to “fill in the blanks” in a generic implementation. I hope that makes sense
3 Likes