exasim-project / NeoFOAM

WIP Prototype of a modern CFD core
20 stars 1 forks source link

Document the compatibility with openfoam #27

Closed MarcelKoch closed 3 months ago

MarcelKoch commented 4 months ago

This is a first draft for the compatiblity with OpenFOAM. Most of the details are from a conversation I had with @greole. I'm referencing some specific parts of OpenFOAM based on that conversation, so if anything is wrong there, feel free to comment.

I'm also working on getting a 'full' set of openfoam API that is required to build the simpleFoam solver. This can be done using clang's tooling, or at least that's what I hope. I will give some more details when I'm further along.

BTW: I'm using one sentence per line in my writing. This page https://sembr.org/ gives a good overview on the concept. Maybe that is something that could be adapted for all the documentation.

MarcelKoch commented 4 months ago

A little example regarding clang's tooling to figure out the required API:

Assuming there is a compilation_database.json (build openfoam with -with-bear) you can run clang-query:

clang-query --extra-arg=-w -p PATH/TO/COMPILATION_DATABASE applications/solvers/incompressible/simpleFoam/simpleFoam.C

This will build the AST for simpleFoam (and only simpleFoam). Then in the REPL:

m cxxRecordDecl(hasName("DirectFieldMapper"))

should result in 0 matches, even though this class is defined in src/OpenFoam/fields/Fields/Field, while

 cxxRecordDecl(hasName("FieldMapper"))

will give some results.

This shows that not everything that is defined in src/OpenFoam needs to be implemented in NeoFOAM.

MarcelKoch commented 4 months ago

An example output (still WIP):

{
  "types": {
    "Foam::Field": "src/OpenFOAM/fields/Fields/Field/Field.H",
    "Foam::FieldBase": "src/OpenFOAM/fields/Fields/Field/Field.H",
    "Foam::FieldMapper": "src/OpenFOAM/fields/Fields/Field/Field.H",
    "Foam::SubField": "src/OpenFOAM/fields/Fields/Field/Field.H",
    "Foam::dictionary": "src/OpenFOAM/fields/Fields/Field/Field.H",
    "Foam::entry": "src/OpenFOAM/fields/Fields/Field/Field.H",
    "Foam::oneField": "src/OpenFOAM/fields/Fields/oneField/oneField.H",
    "Foam::reuseTmp": "src/OpenFOAM/fields/Fields/Field/FieldReuseFunctions.H",
    "Foam::reuseTmpTmp": "src/OpenFOAM/fields/Fields/Field/FieldReuseFunctions.H",
    "Foam::zeroField": "src/OpenFOAM/fields/Fields/zeroField/zeroField.H",
    "specializations": {
      "Foam::Field<_Bool>": "src/OpenFOAM/fields/Fields/Field/Field.H",
      "Foam::Field<class Foam::SymmTensor<double>>": "src/OpenFOAM/fields/Fields/Field/Field.H",
      "Foam::Field<class Foam::Tensor<double>>": "src/OpenFOAM/fields/Fields/Field/Field.H",
      "Foam::Field<class Foam::Vector<double>>": "src/OpenFOAM/fields/Fields/Field/Field.H",
      "Foam::Field<class Foam::Vector<float>>": "src/OpenFOAM/fields/Fields/Field/Field.H",
      "Foam::Field<double>": "src/OpenFOAM/fields/Fields/Field/Field.H",
      "Foam::Field<int>": "src/OpenFOAM/fields/Fields/Field/Field.H",
      "Foam::SubField<class Foam::SymmTensor<double>>": "src/OpenFOAM/fields/Fields/Field/Field.H",
      "Foam::SubField<class Foam::Vector<double>>": "src/OpenFOAM/fields/Fields/Field/Field.H",
      "Foam::SubField<double>": "src/OpenFOAM/fields/Fields/Field/Field.H",
      "Foam::reuseTmp<class Foam::SymmTensor<double>, class Foam::SymmTensor<double>>": "src/OpenFOAM/fields/Fields/Field/FieldReuseFunctions.H",
      "Foam::reuseTmp<class Foam::Vector<double>, class Foam::Vector<double>>": "src/OpenFOAM/fields/Fields/Field/FieldReuseFunctions.H",
      "Foam::reuseTmp<class Foam::Vector<double>, double>": "src/OpenFOAM/fields/Fields/Field/FieldReuseFunctions.H",
      "Foam::reuseTmp<double, double>": "src/OpenFOAM/fields/Fields/Field/FieldReuseFunctions.H",
      "Foam::reuseTmp<type-parameter-0-0, type-parameter-0-0>": "src/OpenFOAM/fields/Fields/Field/FieldReuseFunctions.H",
      "Foam::reuseTmpTmp<double, double, double, double>": "src/OpenFOAM/fields/Fields/Field/FieldReuseFunctions.H",
      "Foam::reuseTmpTmp<type-parameter-0-0, type-parameter-0-0, type-parameter-0-0, type-parameter-0-0>": "src/OpenFOAM/fields/Fields/Field/FieldReuseFunctions.H",
      "Foam::reuseTmpTmp<type-parameter-0-0, type-parameter-0-0, type-parameter-0-0, type-parameter-0-1>": "src/OpenFOAM/fields/Fields/Field/FieldReuseFunctions.H",
      "Foam::reuseTmpTmp<type-parameter-0-0, type-parameter-0-1, type-parameter-0-2, type-parameter-0-0>": "src/OpenFOAM/fields/Fields/Field/FieldReuseFunctions.H"
    }
  }
}

These are all the types used by simpleFoam that are defined under src/OpenFOAM/fields/Fields.

MarcelKoch commented 4 months ago

I think there might be an issue with API compatibility. If we provide our own headers with replacements for OpenFOAM parts that user should include, then there might be ODR violations. The user code will most likely include other headers, maybe OpenFOAM headers that have no replacements, and those might include the original OpenFOAM types. Now there are two different definitions for the same type.

I guess this comes down to the question how the NeoFOAM types can be propagated throughout the user code. Either this will require code changes (either manual or automatic) or the ABI compatibility needs to be revisited.

greole commented 4 months ago

I think there might be an issue with API compatibility. If we provide our own headers with replacements for OpenFOAM parts that user should include, then there might be ODR violations. The user code will most likely include other headers, maybe OpenFOAM headers that have no replacements, and those might include the original OpenFOAM types. Now there are two different definitions for the same type.

Yes, that could be a potential problem, especially when we provide adapters. But I guess keeping even the adapters in a separate namespace should avoid the problem. I.e. having a Time definition in NeoFOAM::Time. This would however make some modification of the OpenFOAM sources necessary.

I guess this comes down to the question how the NeoFOAM types can be propagated throughout the user code. Either this will require code changes (either manual or automatic) or the ABI compatibility needs to be revisited.

I guess ABI compatibility will cause even more headaches.

MarcelKoch commented 3 months ago

Here is a JSON file with all openfoam functions, types, and variables, that are used in the icoFOAM solver. This was created with a tool that uses the clang-tools-extra infrastructure. I think it's possible to just use the binaries I compiled, otherwise it would be necessary to compile all of llvm+clang. Even it this might not be as useful as I thought initially, I think the clang tooling framework can be used to automate refactorings of user code to use neofoam.

For reference, the tool is implemented here: https://github.com/MarcelKoch/llvm-project/blob/openfoam-tool/clang-tools-extra/openfoam/openfoam.cpp

decls.json