nutofem / nuto

NuTo - yet another finite element library
https://nuto.readthedocs.io
Boost Software License 1.0
17 stars 5 forks source link

Library organization #147

Open Psirus opened 6 years ago

Psirus commented 6 years ago

Going forward, things like constitutive laws and PDEs are not needed by everybody, and therefore it should not be necessary to compile them if I don't use them. How do we want to handle these in the future:

Personally, I'd vote for header-only, because

joergfunger commented 6 years ago

I think we should definitely store them in a central repo that is directly linked to NuTo (if we were to use a different repo than changing an interface in NuTo might directly invalidate all test files in the integrand repo). Thus, I would either vote for option header only or separate lib in NuTo. I tend more towards separate lib since implementing complex integrands in a header feels sub-optimal, but maybe this is personal preference (both options are fine with me).

Psirus commented 6 years ago

Header only doesn't necessarily mean you loose the ability to separate declaration and definition. In a header, you can still do

class MomentumBalance
{
public:
    Eigen::VectorXd Equilibrium(const CellData&, const CellIpData&);
};

Eigen::VectorXd MomentumBalance::Equilibrium(const CellData& cellData,
                                             const CellIpData& cellIpData)
{
    // your implementation here
}

// or even
#include "MomentumBalanceImplementation.h"

Does that address what you meant by "feels sub-optimal"?

joergfunger commented 6 years ago

The reason is primarily due to the fact that we might have to implement also general subroutines somewhere, say return mapping for plasticity models, or the momentum balance for mechanics laws (should the standard user that wants just to modify his mechanics law implement his own momentum balance equation?). Or when we think about random field interpolations (the material parameter is then not constant, but a function of the spatial location). All these methods are certainly not part of the NuTo-core numerics lib, but they might also generally be used by more than a single integrand. Making all this header only is certainly possible (even with separate definition and implementation), but last time when we were talking about the integrand extensions, I had the impression that at least for a little bit more complex implementations the header only variant was not favored by the many developers.

TTitscher commented 6 years ago

1) I vote for the same repo - for the same reasons as listed above.

2) I am not sure about header-only or lib. I always have this little performance thing in mind. So for big explicit calculations, I would prefer static polymorphism that requires header-only. Regarding compile times, I prefer the libIntegrands.so. In header-only, I have to compile my integrand on every change in my main file. With the lib, I compile everything once (maybe grab a coffee) and be done with it. Or am I missing something?

So the only advantage of header-only for me is the performance aspect. Since this is a rare case and could be done in my main files, so I prefer a h/cpp split.

vhirtham commented 6 years ago

I also vote for same repo.

For the header only discussion: I could live with both. I don't think that the compile time hit really matters that much, since you are usually just compiling a single file and not the whole lib. I think we are talking about a few (probably single digits) seconds. On the other hand we can probably spare some code and do some optimizations by using templates. This static polymorphism stuff looks quiet interesting too. I am not sure if I have thought everything trough but if I had to decide for one way, I would tend towards header only (for now).

Psirus commented 6 years ago

One of the big advantages of PDE was supposed to be that I don't have to compile all the possible PDEs and constitutive laws that we have accumulated over the years. A libIntegrands.so would negate that; just because I want to use one of them, I have to compile them all.

As for

In header-only, I have to compile my integrand on every change in my main file.

No one is stopping you from separating them into h/cpp, just that you then need

add_executable(application application.cpp CompiledIntegrand.cpp)

instead of

add_executable(application application.cpp)
target_link_libraries(application IntegrandLib)

or am I missing something?

vhirtham commented 6 years ago

One of the big advantages of PDE was supposed to be that I don't have to compile all the possible PDEs and constitutive laws that we have accumulated over the years. A libIntegrands.so would negate that; just because I want to use one of them, I have to compile them all.

Good point. As I said before: I think the "user" usually just compiles his own main file and not all the examples and tests. Therefore 1-2 more seconds (probably less) during every compilation won't hurt. Even if he does compile all tests and examples. Ideally every law just needs one test and has a maximum of one example. So in the worst case most laws gets compiled twice. It's not like before where everything gets compiled in every test because everything is included by the structure.

@Psirus: If we compile all of them into object libs, we can just use the object targets and the multi compilation issue vanishes.