@
CplusC
Ok, cool :+)
So the motivation for my last post was to make style type suggestions to make code easier and simpler to read, which makes it less error prone in terms of typos and copy/paste errors, and probably easier to debug as well. I guess the hope was to make errors more obvious, alas it looks more debugging required.
Can you make the smallest lattice that has known results, then test your code against that? If it works, make the lattice larger until it starts to fail. Consider writing testing code that prints intermediate results in conjunction with using the debugger. There are ways to break when a loop reaches a certain point, examine the variables then. This is called conditional break points.
Have you got situations where doubles are intentionally converted to
float
at any point? If so, look very carefully at what happens there. If it is supposed to be
double
throughout, consider using braces when initialising, the compiler will complain at compile time if there is a loss of precision. The same for function arguments:
1 2 3 4 5 6 7
|
double a {2.0f} //compiler complains loss of precision
double b {SomeFunctionCall}; //compiler complain if return value is float or int
void FunctionWithDblArgs(double c) { ...}
float c = 3.0f;
FunctionWithDblArgs({c}); // again compiler complains loss of precision because of braces around argument
|
Also try to make constructors
explicit
Consider using the attribute
[[nodiscard]]
everywhere a function returns a value. The compiler will complain if a return value is unused. This is a
very useful thing, use it everywhere.
1 2 3
|
[[nodiscard]]
double Node::Equilibrium(std::shared_ptr<VelocitySet> velSet, int dir)
{ // ....}
|
Edit: Silly me, it's part of the expression above
Just on that point: In Simulation::Collision()
, line 18 (commented out) in the call to Equilibrium
, the return value is not used?
Where is the data coming from? Is it hard coded at compile time, or is it coming from a file or some other source at runtime? If it is the former that can make it easier for debugging because the compiler can reason about more things; there are more things one can do to catch problems at compile time. So this is a good reason to have a minimal amount of hard coded data for testing as mentioned earlier. If the data is available at runtime only, then one has to do more defensive coding, at least: validate raw data; check in-variants*; check denominators for divide by zero or close to zero etc.
* in-variants are things that must remain true throughout the lifetime of the class object.
Another style point: avoid using
i
and
j
or anything else that looks similar like
m
and
n
because that can be anther source of problems that can be very hard to see or detect. Consider changing
[i][j][k]
to
[x][y][z]
if that's what they are. I am not sure how much embuggerance (read nuisance value) that will be for your project size :+)
Also, are you using some sort of version control like git? It makes management of the code base much easier, for example one can roll back to last time the code compiled cleanly (or some other point where one is happy with the code) if one has some sort of naming system for the commits to reflect that. VS has a plugin for git, it's easy to use.
Anyway, Good Luck !!