From 391daf04940f58f843e36cb64cdad53ba375b09b Mon Sep 17 00:00:00 2001 From: Sean Engelstad Date: Fri, 22 Nov 2024 09:46:49 -0500 Subject: [PATCH] Expressions for Shell Element in TACS (#116) * add new a2d shell code * update the shell assemble frame * add new mat concat expression * update shell element a2d headers * add test for the matrix rotate frame expression * bug fixes and shell strain fixes * a2d mat rotate frame tests pass! * all shell internal deriv tests pass now * working symMatRotateFrame * fix forward comp * reverse + forward ad compatibility * updated a2d obj include * CUDA compatibility in A2D * update to use A2D_FUNCTION for cuda headers * device compatible sqrt, etc other operations * close #ifndef A2D_FUNCTION CUDA part * clang format * remove a2dmatconcat.h * clang format v3 --- include/a2dcore.h | 7 + include/a2ddefs.h | 8 +- include/ad/a2dgemm.h | 2 +- include/ad/a2dgreenstrain.h | 4 +- include/ad/a2dmatsum.h | 4 + include/ad/a2dmatvecmult.h | 125 +++++ include/ad/a2dobj.h | 160 ++++++ include/ad/a2dstack.h | 3 + include/ad/core/a2dmatinvcore.h | 8 +- include/ad/core/a2dmatveccore.h | 10 + include/ad/shell/a2dmatrotateframe.h | 360 ++++++++++++++ include/ad/shell/a2dshellassembleframe.h | 252 ++++++++++ include/ad/shell/a2dshellstrain.h | 501 +++++++++++++++++++ include/ad/shell/a2dsymmatrotateframe.h | 588 +++++++++++++++++++++++ include/adscalar.h | 144 ++++-- tests/ad/test_ad_expressions.cpp | 4 + 16 files changed, 2122 insertions(+), 58 deletions(-) create mode 100644 include/ad/shell/a2dmatrotateframe.h create mode 100644 include/ad/shell/a2dshellassembleframe.h create mode 100644 include/ad/shell/a2dshellstrain.h create mode 100644 include/ad/shell/a2dsymmatrotateframe.h diff --git a/include/a2dcore.h b/include/a2dcore.h index 660cb53a..fb6fd9c2 100644 --- a/include/a2dcore.h +++ b/include/a2dcore.h @@ -31,4 +31,11 @@ #include "ad/a2dvecouter.h" #include "ad/a2dvecsum.h" +// shell routines +#include "ad/shell/a2dshellassembleframe.h" +// #include "ad/shell/a2dmatconcat.h" +#include "ad/shell/a2dmatrotateframe.h" +#include "ad/shell/a2dshellstrain.h" +#include "ad/shell/a2dsymmatrotateframe.h" + #endif // A2D_CORE_H diff --git a/include/a2ddefs.h b/include/a2ddefs.h index 954ce33b..edce9af1 100644 --- a/include/a2ddefs.h +++ b/include/a2ddefs.h @@ -8,8 +8,14 @@ template using A2D_complex_t = std::complex; +// CUDA headers #ifndef A2D_FUNCTION -#define A2D_FUNCTION // A2D_FUNCTION does nothing in this scenario +#ifdef __CUDACC__ +#define A2D_FUNCTION \ + __host__ __device__ // A2D_FUNCTION does nothing in this scenario +#else // not __CUDACC__ +#define A2D_FUNCTION +#endif #endif namespace A2D { diff --git a/include/ad/a2dgemm.h b/include/ad/a2dgemm.h index 18ecb2c7..58e5322b 100644 --- a/include/ad/a2dgemm.h +++ b/include/ad/a2dgemm.h @@ -119,7 +119,7 @@ class MatMatMultExpr { "Can't perform second order forward with first order objects"); constexpr ADseed seed = conditional_value::value; - if constexpr (adA == ADiffType::ACTIVE) { + if constexpr (adA == ADiffType::ACTIVE && adB == ADiffType::ACTIVE) { constexpr bool additive = true; MatMatMultCore( GetSeed::get_data(A), get_data(B), GetSeed::get_data(C)); diff --git a/include/ad/a2dgreenstrain.h b/include/ad/a2dgreenstrain.h index f42eb4e3..a7512f1e 100644 --- a/include/ad/a2dgreenstrain.h +++ b/include/ad/a2dgreenstrain.h @@ -43,7 +43,9 @@ class MatGreenStrainExpr { static_assert(get_diff_order::order == order, "ADorder does not match"); - A2D_FUNCTION MatGreenStrainExpr(Utype& Ux, Etype& E) : Ux(Ux), E(E) {} + A2D_FUNCTION MatGreenStrainExpr(Utype& Ux, Etype& E) : Ux(Ux), E(E) { + // printf("made mat green strain expression\n"); + } A2D_FUNCTION void eval() { if constexpr (etype == GreenStrainType::LINEAR) { diff --git a/include/ad/a2dmatsum.h b/include/ad/a2dmatsum.h index f1944cdc..1a68b926 100644 --- a/include/ad/a2dmatsum.h +++ b/include/ad/a2dmatsum.h @@ -217,6 +217,8 @@ class MatSumScaleExpr { } } + A2D_FUNCTION void bzero() { B.bzero(); } + A2D_FUNCTION void reverse() { constexpr ADseed seed = ADseed::b; if constexpr (adA == ADiffType::ACTIVE) { @@ -237,6 +239,8 @@ class MatSumScaleExpr { } } + A2D_FUNCTION void hzero() { C.hzero(); } + A2D_FUNCTION void hreverse() { constexpr ADseed seed = ADseed::h; if constexpr (adA == ADiffType::ACTIVE) { diff --git a/include/ad/a2dmatvecmult.h b/include/ad/a2dmatvecmult.h index a895b8d0..e52477aa 100644 --- a/include/ad/a2dmatvecmult.h +++ b/include/ad/a2dmatvecmult.h @@ -214,6 +214,131 @@ A2D_FUNCTION auto MatVecMult(const Atype& A, A2DObj& x, return MatVecMultExpr, A2DObj>(A, x, y); } +// now define MatScale +template +A2D_FUNCTION void MatScale(const T alpha, const Mat& x, + Mat& y) { + MatScaleCore(alpha, get_data(x), get_data(y)); +} + +template +class MatScaleExpr { + public: + // Extract the numeric type to use + typedef typename get_object_numeric_type::type T; + + // Extract the dimensions of the underlying vectors + static constexpr int M = get_matrix_rows::size; + static constexpr int N = get_matrix_columns::size; + static constexpr int size = get_num_matrix_entries::size; + + // Get the differentiation order from the output + static constexpr ADorder order = get_diff_order::order; + + // Get the types of the matrices + static constexpr ADiffType add = get_diff_type::diff_type; + static constexpr ADiffType adA = get_diff_type::diff_type; + + // Make sure the matrix dimensions are consistent + static_assert((get_a2d_object_type::value == + get_a2d_object_type::value), + "Matrices are not all of the same type"); + + A2D_FUNCTION MatScaleExpr(dtype alpha, Atype& A, Btype& B) + : alpha(alpha), A(A), B(B) {} + + A2D_FUNCTION void eval() { + MatScaleCore(get_data(alpha), get_data(A), get_data(B)); + } + + A2D_FUNCTION void bzero() { B.bzero(); } + + template + A2D_FUNCTION void forward() { + constexpr ADseed seed = conditional_value::value; + + if constexpr (add == ADiffType::ACTIVE && adA == ADiffType::ACTIVE) { + MatScaleCore(GetSeed::get_data(alpha), get_data(A), + GetSeed::get_data(B)); + VecAddCore(get_data(alpha), GetSeed::get_data(A), + GetSeed::get_data(B)); + } else if constexpr (add == ADiffType::ACTIVE) { + MatScaleCore(GetSeed::get_data(alpha), get_data(A), + GetSeed::get_data(B)); + } else if constexpr (adA == ADiffType::ACTIVE) { + MatScaleCore(get_data(alpha), GetSeed::get_data(A), + GetSeed::get_data(B)); + } + } + A2D_FUNCTION void reverse() { + constexpr ADseed seed = ADseed::b; + if constexpr (add == ADiffType::ACTIVE) { + GetSeed::get_data(alpha) += + VecDotCore(GetSeed::get_data(B), get_data(A)); + } + if constexpr (adA == ADiffType::ACTIVE) { + VecAddCore(get_data(alpha), GetSeed::get_data(B), + GetSeed::get_data(A)); + } + } + + A2D_FUNCTION void hzero() { B.hzero(); } + + A2D_FUNCTION void hreverse() { + if constexpr (add == ADiffType::ACTIVE) { + GetSeed::get_data(alpha) += + VecDotCore(GetSeed::get_data(B), get_data(A)); + } + if constexpr (adA == ADiffType::ACTIVE) { + VecAddCore(get_data(alpha), GetSeed::get_data(B), + GetSeed::get_data(B)); + } + if constexpr (add == ADiffType::ACTIVE && adA == ADiffType::ACTIVE) { + GetSeed::get_data(alpha) += VecDotCore( + GetSeed::get_data(B), GetSeed::get_data(A)); + VecAddCore(GetSeed::get_data(alpha), + GetSeed::get_data(B), + GetSeed::get_data(A)); + } + } + + dtype alpha; + Atype& A; + Btype& B; +}; + +template +A2D_FUNCTION auto MatScale(ADObj& alpha, ADObj& x, ADObj& y) { + return MatScaleExpr&, ADObj, ADObj>(alpha, x, y); +} + +template +A2D_FUNCTION auto MatScale(const T alpha, ADObj& x, ADObj& y) { + return MatScaleExpr, ADObj>(alpha, x, y); +} + +template +A2D_FUNCTION auto MatScale(ADObj& alpha, const Atype& x, ADObj& y) { + return MatScaleExpr&, const Atype, ADObj>(alpha, x, y); +} + +template +A2D_FUNCTION auto MatScale(A2DObj& alpha, A2DObj& x, + A2DObj& y) { + return MatScaleExpr&, A2DObj, A2DObj>(alpha, x, y); +} + +template +A2D_FUNCTION auto MatScale(const T alpha, A2DObj& x, A2DObj& y) { + return MatScaleExpr, A2DObj>(alpha, x, y); +} + +template +A2D_FUNCTION auto MatScale(A2DObj& alpha, const Atype& x, A2DObj& y) { + return MatScaleExpr&, const Atype, A2DObj>(alpha, x, y); +} + namespace Test { template diff --git a/include/ad/a2dobj.h b/include/ad/a2dobj.h index 8f906817..2b383462 100644 --- a/include/ad/a2dobj.h +++ b/include/ad/a2dobj.h @@ -4,6 +4,7 @@ #include "../a2ddefs.h" #include "a2dmat.h" #include "a2dvec.h" +#include "adscalar.h" namespace A2D { @@ -303,6 +304,11 @@ struct __get_matrix_rows> { static constexpr int size = N; }; +template