roystgnr / MetaPhysicL

Metaprogramming and operator-overloaded classes for numerical simulations
Other
22 stars 12 forks source link

No type named supertype #80

Closed hugary1995 closed 2 years ago

hugary1995 commented 2 years ago

The following example

#include <Eigen/Dense>
#include "metaphysicl/dualnumber.h"

typedef double Real;
typedef MetaPhysicL::DualNumber<Real, Real> ADReal;
typedef Eigen::Matrix<ADReal, 2, 2> ADTensor;
typedef MetaPhysicL::DualNumber<ADReal, ADTensor> ADRealADTensor;

int
main(int argc, const char * argv[])
{
  ADReal x(1, 1);
  ADTensor I2{{1, 0}, {0, 1}};
  ADRealADTensor xx(x, I2);
  ADRealADTensor xx2 = xx + xx;
  return 0;
}

gives rise to the following compiler error:

/home/gary/.local/include/metaphysicl/compare_types.h: In instantiation of ‘struct MetaPhysicL::SymmetricPlusType<Eigen::Matrix<MetaPhysicL::DualNumber<double, double>, 2, 2>, Eigen::Matrix<MetaPhysicL::DualNumber<double, double>, 2, 2>, false, false>’:
/home/gary/.local/include/metaphysicl/dualnumber_decl.h:347:27:   required from ‘struct MetaPhysicL::PlusType<MetaPhysicL::DualNumber<MetaPhysicL::DualNumber<double, double>, Eigen::Matrix<MetaPhysicL::DualNumber<double, double>, 2, 2> >, MetaPhysicL::DualNumber<MetaPhysicL::DualNumber<double, double>, Eigen::Matrix<MetaPhysicL::DualNumber<double, double>, 2, 2> >, false, void>’
/home/gary/.local/include/metaphysicl/dualnumber.h:464:1:   required by substitution of ‘template<class T, class D, class T2, bool asd> typename MetaPhysicL::PlusType<MetaPhysicL::DualNumber<T, D, asd>, T2, false>::supertype MetaPhysicL::operator+(MetaPhysicL::DualNumber<T, D, asd>&&, const T2&) [with T = MetaPhysicL::DualNumber<double, double>; D = Eigen::Matrix<MetaPhysicL::DualNumber<double, double>, 2, 2>; T2 = MetaPhysicL::DualNumber<MetaPhysicL::DualNumber<double, double>, Eigen::Matrix<MetaPhysicL::DualNumber<double, double>, 2, 2> >; bool asd = false]’
main.C:36:29:   required from here
/home/gary/.local/include/metaphysicl/compare_types.h:486:63: error: no type named ‘supertype’ in ‘struct MetaPhysicL::PlusType<Eigen::Matrix<MetaPhysicL::DualNumber<double, double>, 2, 2>, Eigen::Matrix<MetaPhysicL::DualNumber<double, double>, 2, 2>, true, void>’
  486 |   typedef typename templatename<T,S,!reverseorder>::supertype supertype; \
      |                                                               ^~~~~~~~~
/home/gary/.local/include/metaphysicl/compare_types.h:492:1: note: in expansion of macro ‘Symmetric_definition’
  492 | Symmetric_definition(PlusType);
      | ^~~~~~~~~~~~~~~~~~~~
roystgnr commented 2 years ago

Yeah; we can't support arbitrary mixtures of container types without user intervention, because a priori we don't know what the "outside" container should be. This is obvious when the containers are completely unrelated (should a dualnumber times a vector produce a vector-of-duals or a dual-of-vectors), but even when the containers are related we don't have a great way to deduce what to get when we have a type that nests third-party containers.

If you look in compare_types.h you'll see some macros that get used to declare those template metafunctions for built-in types; you might be able to reuse those to get the metafunctions you need for Eigen types. If you have enough nesting that that's not enough, though, which it looks like you might in this case ... check out the macro at the end of dualnumberarray.h; you'd have to rewrite it rather than just reinvoke it, but something like that would probably be adequate.

hugary1995 commented 2 years ago

Oh, sorry, I completely missed your reply. Thanks, I'll look at compare_types.h and see if I could reuse some of the macros.

hugary1995 commented 2 years ago

This is resolved. For future reference, see https://github.com/idaholab/moose/pull/20408 about the use of the macros for composite types.