jaheyns / CfdOF

Computational Fluid Dynamics (CFD) for FreeCAD based on OpenFOAM solver
GNU Lesser General Public License v3.0
442 stars 84 forks source link

Performance issues with complex meshes #147

Open darrengarvey opened 8 months ago

darrengarvey commented 8 months ago

There is more information I can share later but I have been looking into performance issues when using CfdOf on non-trivial meshes. The project has been very useful so far.

I narrowed the issue down to the function processRefinements.

In particular, resolveReferences() and matchFaces() are taking the vast majority of the time. For reference, my example takes 48 hours to write the mesh info (this doesn't include running the mesher).

In my example, I know exactly what faces from the primary (mesh) object are required for the mesh refinement and can select them programmatically. So there is no need for these steps IIUC.

I removed the need to do resolveReferences() in a hacky way (adding an extra object property) which reduces the time down to ~6 hours. I think the matchFaces() calls are irrelevant in my example too. So this 48 hours of processing could be done in about 30-60 seconds if this issue can be resolved.

Before going further, I wondered if I was missing some important logic/requirements.

Firstly, why does ShapeRefs only store the string name of the relevant faces rather than just storing the faces themselves? This is what I changed locally and that removes the huge overhead of needing to go from the string names back to the face objects (saving me ~40 hours per case).

Secondly, I can guess at why matchFaces exists: maybe a user manually selected the face in an object that was used to create a mesh, rather than selecting the face on the mesh object itself. But this resolving process is very expensive (about 6 hours of the remaining 6 hours processing time), and AFAICT isn't needed if creating the case programmatically or if a user is careful in selecting the correct faces when creating a mesh refinement.

I'm new to the code so could be missing something crucial so thought I'd ask before going down the wrong path.

I'm wondering if all of this resolving work could be done only if manually selecting faces and the underlying object properties could contain the raw data needed to quickly generate a mesh. That way if not manually selecting things, most of the processing cost could be skipped.

oliveroxtoby commented 8 months ago

Firstly, why does ShapeRefs only store the string name of the relevant faces rather than just storing the faces themselves? This is what I changed locally and that removes the huge overhead of needing to go from the string names back to the face objects (saving me ~40 hours per case).

That's good to know! No particular reason. I haven't really got to doing any optimisation on this as it hasn't been much of an obstacle in the examples I've run. I'd be interested to see your example in order to understand better, if you can share it.

Secondly, I can guess at why matchFaces exists: maybe a user manually selected the face in an object that was used to create a mesh, rather than selecting the face on the mesh object itself. But this resolving process is very expensive (about 6 hours of the remaining 6 hours processing time), and AFAICT isn't needed if creating the case programmatically or if a user is careful in selecting the correct faces when creating a mesh refinement.

Correct, but I would like to keep this flexibility. Sometimes it's much more convenient to select a face on a simpler object than the full compound that the mesh is composed of. I'd gratefully receive any optimisations though. Presumably we can detect and skip if we see the selection has been made on the primary mesh shape.

I'm new to the code so could be missing something crucial so thought I'd ask before going down the wrong path.

No problem. I sadly have very little time for this project so unfortunately I've erred on the side of adequacy rather than optimality, in many respects.

I'm wondering if all of this resolving work could be done only if manually selecting faces and the underlying object properties could contain the raw data needed to quickly generate a mesh. That way if not manually selecting things, most of the processing cost could be skipped.

Sounds good.