From 9502e341339e321445a85ebb07e166778a3b085b Mon Sep 17 00:00:00 2001 From: Ian Bell <ian.bell@nist.gov> Date: Fri, 2 Apr 2021 10:15:25 -0400 Subject: [PATCH] Move more methods into their own namespace --- include/teqp/derivs.hpp | 67 ++++++++++++++++------------------ interface/pybind11_wrapper.cpp | 10 +++++ 2 files changed, 42 insertions(+), 35 deletions(-) diff --git a/include/teqp/derivs.hpp b/include/teqp/derivs.hpp index 6114e5c..0233b2b 100644 --- a/include/teqp/derivs.hpp +++ b/include/teqp/derivs.hpp @@ -62,48 +62,45 @@ typename ContainerType::value_type derivrhoi(const FuncType& f, TType T, const C return f(T, rhocom).imag() / h; } +enum class ADBackends { autodiff, multicomplex, complex_step }; +template<typename Model, typename Scalar = double, typename VectorType = Eigen::ArrayXd> +struct TDXDerivatives { - - -template <typename Model, typename TType, typename RhoType, typename ContainerType> -typename ContainerType::value_type get_Ar10(const Model& model, const TType T, const RhoType &rho, const ContainerType& molefrac) { - double h = 1e-100; - return -T*model.alphar(std::complex<TType>(T, h), rho, molefrac).imag()/h; // Complex step derivative -} - -enum class ADBackends { autodiff, multicomplex, complex_step } ; - -template <ADBackends be = ADBackends::autodiff, typename Model, typename TType, typename RhoType, typename MoleFracType> -auto get_Ar01(const Model& model, const TType &T, const RhoType &rho, const MoleFracType& molefrac) { - if constexpr(be == ADBackends::complex_step){ + static auto get_Ar10(const Model& model, const Scalar &T, const Scalar &rho, const VectorType& molefrac) { double h = 1e-100; - auto der = model.alphar(T, std::complex<double>(rho, h), molefrac).imag() / h; - return der*rho; + return -T*model.alphar(std::complex<Scalar>(T, h), rho, molefrac).imag()/h; // Complex step derivative } - else if constexpr(be == ADBackends::multicomplex){ - using fcn_t = std::function<mcx::MultiComplex<double>(const mcx::MultiComplex<double>&)>; - bool and_val = true; - fcn_t f = [&model, &T, &molefrac](const auto& rho_) { return model.alphar(T, rho_, molefrac); }; - auto ders = diff_mcx1(f, rho, 1, and_val); - return ders[1] * rho; + + template<ADBackends be = ADBackends::autodiff> + static auto get_Ar01(const Model& model, const Scalar&T, const Scalar &rho, const VectorType& molefrac) { + if constexpr(be == ADBackends::complex_step){ + double h = 1e-100; + auto der = model.alphar(T, std::complex<Scalar>(rho, h), molefrac).imag() / h; + return der*rho; + } + else if constexpr(be == ADBackends::multicomplex){ + using fcn_t = std::function<mcx::MultiComplex<Scalar>(const mcx::MultiComplex<Scalar>&)>; + bool and_val = true; + fcn_t f = [&model, &T, &molefrac](const auto& rho_) { return model.alphar(T, rho_, molefrac); }; + auto ders = diff_mcx1(f, rho, 1, and_val); + return ders[1] * rho; + } + else if constexpr(be == ADBackends::autodiff){ + autodiff::dual rhodual = rho; + auto f = [&model, &T, &molefrac](const auto& rho_) { return eval(model.alphar(T, rho_, molefrac)); }; + auto der = derivative(f, wrt(rhodual), at(rhodual)); + return der * rho; + } } - else if constexpr(be == ADBackends::autodiff){ - autodiff::dual rhodual = rho; + + static auto get_Ar02(const Model& model, const Scalar& T, const Scalar& rho, const VectorType& molefrac) { + autodiff::dual2nd rhodual = rho; auto f = [&model, &T, &molefrac](const auto& rho_) { return eval(model.alphar(T, rho_, molefrac)); }; - auto der = derivative(f, wrt(rhodual), at(rhodual)); - return der * rho; + auto ders = derivatives(f, wrt(rhodual), at(rhodual)); + return ders[2]*rho*rho; } -} - -template <typename Model, typename TType, typename RhoType, typename MoleFracType> -auto get_Ar02(const Model& model, const TType& T, const RhoType& rho, const MoleFracType& molefrac) { - autodiff::dual2nd rhodual = rho; - auto f = [&model, &T, &molefrac](const auto& rho_) { return eval(model.alphar(T, rho_, molefrac)); }; - auto ders = derivatives(f, wrt(rhodual), at(rhodual)); - return ders[2]*rho*rho; -} - +}; template<typename Model, typename Scalar = double, typename VectorType = Eigen::ArrayXd> struct VirialDerivatives { diff --git a/interface/pybind11_wrapper.cpp b/interface/pybind11_wrapper.cpp index 4130038..ace9256 100644 --- a/interface/pybind11_wrapper.cpp +++ b/interface/pybind11_wrapper.cpp @@ -9,6 +9,15 @@ namespace py = pybind11; +template<typename Model> +void add_TDx_derivatives(py::module& m) { + using id = TDXDerivatives<Model, double, Eigen::Array<double, Eigen::Dynamic, 1> >; + //m.def("get_Ar00", &id::get_Ar00, py::arg("model"), py::arg("T"), py::arg("rho"), py::arg("molefrac")); + m.def("get_Ar10", &id::get_Ar10, py::arg("model"), py::arg("T"), py::arg("rho"), py::arg("molefrac")); + m.def("get_Ar01", &id::get_Ar01<ADBackends::autodiff>, py::arg("model"), py::arg("T"), py::arg("rho"), py::arg("molefrac")); + m.def("get_Ar02", &id::get_Ar02, py::arg("model"), py::arg("T"), py::arg("rho"), py::arg("molefrac")); +} + template<typename Model> void add_virials(py::module& m) { using vd = VirialDerivatives<Model>; @@ -30,6 +39,7 @@ void add_derivatives(py::module &m) { m.def("build_Psir_gradient_autodiff", &id::build_Psir_gradient_autodiff, py::arg("model"), py::arg("T"), py::arg("rho")); add_virials<Model>(m); + add_TDx_derivatives<Model>(m); } -- GitLab