9#ifndef GMATTENSOR_CARTESIAN2D_HPP
10#define GMATTENSOR_CARTESIAN2D_HPP
16namespace Cartesian2d {
19using GMatTensor::detail::impl_A2;
20using GMatTensor::detail::impl_A4;
89template <
class T,
class R>
90inline void trace(
const T& A, R& ret)
92 return detail::impl_A2<T, 2>::ret0(A, ret, [](
const auto& a) {
return pointer::Trace(a); });
98 return detail::impl_A2<T, 2>::ret0(A, [](
const auto& a) {
return pointer::Trace(a); });
101template <
class T,
class R>
104 return detail::impl_A2<T, 2>::ret0(
114template <
class T,
class R>
117 return detail::impl_A2<T, 2>::B2_ret0(
124 return detail::impl_A2<T, 2>::B2_ret0(
128template <
class T,
class R>
131 return detail::impl_A2<T, 2>::B2_ret0(
138 return detail::impl_A2<T, 2>::B2_ret0(
142template <
class T,
class R>
145 return detail::impl_A2<T, 2>::ret0(
152 return detail::impl_A2<T, 2>::ret0(
156template <
class T,
class R>
159 return detail::impl_A2<T, 2>::ret2(
166 return detail::impl_A2<T, 2>::ret2(
170template <
class T,
class R>
171inline void sym(
const T& A, R& ret)
173 return detail::impl_A2<T, 2>::ret2(
174 A, ret, [](
const auto& a,
const auto& r) {
return pointer::sym(a, r); });
178inline auto Sym(
const T& A)
180 return detail::impl_A2<T, 2>::ret2(
181 A, [](
const auto& a,
const auto& r) {
return pointer::sym(a, r); });
184template <
class T,
class R>
187 return detail::impl_A2<T, 2>::B2_ret2(
188 A, B, ret, [](
const auto& a,
const auto& b,
const auto& r) {
196 return detail::impl_A2<T, 2>::B2_ret2(A, B, [](
const auto& a,
const auto& b,
const auto& r) {
201template <
class T,
class R>
204 return detail::impl_A2<T, 2>::B2_ret4(
205 A, B, ret, [](
const auto& a,
const auto& b,
const auto& r) {
213 return detail::impl_A2<T, 2>::B2_ret4(A, B, [](
const auto& a,
const auto& b,
const auto& r) {
218template <
class T,
class U,
class R>
221 return detail::impl_A4<T, 2>::B2_ret2(
222 A, B, ret, [](
const auto& a,
const auto& b,
const auto& r) {
227template <
class T,
class U>
230 return detail::impl_A4<T, 2>::B2_ret2(A, B, [](
const auto& a,
const auto& b,
const auto& r) {
238inline void O2(T* ret)
240 std::fill(ret, ret + 4, T(0));
244inline void O4(T* ret)
246 std::fill(ret, ret + 16, T(0));
250inline void I2(T* ret)
259inline void II(T* ret)
261 std::fill(ret, ret + 16, T(0));
263 for (
size_t i = 0; i < 2; ++i) {
264 for (
size_t j = 0; j < 2; ++j) {
265 for (
size_t k = 0; k < 2; ++k) {
266 for (
size_t l = 0; l < 2; ++l) {
267 if (i == j && k == l) {
268 ret[i * 8 + j * 4 + k * 2 + l] = 1.0;
277inline void I4(T* ret)
279 std::fill(ret, ret + 16, T(0));
281 for (
size_t i = 0; i < 2; ++i) {
282 for (
size_t j = 0; j < 2; ++j) {
283 for (
size_t k = 0; k < 2; ++k) {
284 for (
size_t l = 0; l < 2; ++l) {
285 if (i == l && j == k) {
286 ret[i * 8 + j * 4 + k * 2 + l] = 1.0;
297 std::fill(ret, ret + 16, T(0));
299 for (
size_t i = 0; i < 2; ++i) {
300 for (
size_t j = 0; j < 2; ++j) {
301 for (
size_t k = 0; k < 2; ++k) {
302 for (
size_t l = 0; l < 2; ++l) {
303 if (i == k && j == l) {
304 ret[i * 8 + j * 4 + k * 2 + l] = 1.0;
317 std::array<double, 16> i4rt;
320 std::transform(ret, ret + 16, &i4rt[0], ret, std::plus<T>());
322 std::transform(ret, ret + 16, ret, std::bind(std::multiplies<T>(), std::placeholders::_1, 0.5));
330 std::array<double, 16> ii;
334 &ii[0], &ii[0] + 16, &ii[0], std::bind(std::multiplies<T>(), std::placeholders::_1, 0.5));
336 std::transform(ret, ret + 16, &ii[0], ret, std::minus<T>());
348 return T(0.5) *
Trace(A);
352inline void sym(
const T* A, T* ret)
355 ret[1] = 0.5 * (A[1] + A[2]);
375 return (A[0] - m) * (A[0] - m) + (A[3] - m) * (A[3] - m) + T(2) * A[1] * A[2];
387 return A[0] * B[0] + A[3] * B[3] + A[1] * B[2] + A[2] * B[1];
393 return A[0] * B[0] + A[3] * B[3] + T(2) * A[1] * B[1];
399 for (
size_t i = 0; i < 2; ++i) {
400 for (
size_t j = 0; j < 2; ++j) {
401 for (
size_t k = 0; k < 2; ++k) {
402 for (
size_t l = 0; l < 2; ++l) {
403 ret[i * 8 + j * 4 + k * 2 + l] = A[i * 2 + j] * B[k * 2 + l];
413 ret[0] = A[1] * B[2] + A[0] * B[0];
414 ret[1] = A[0] * B[1] + A[1] * B[3];
415 ret[2] = A[2] * B[0] + A[3] * B[2];
416 ret[3] = A[2] * B[1] + A[3] * B[3];
422 std::fill(ret, ret + 4, T(0));
424 for (
size_t i = 0; i < 2; i++) {
425 for (
size_t j = 0; j < 2; j++) {
426 for (
size_t k = 0; k < 2; k++) {
427 for (
size_t l = 0; l < 2; l++) {
428 ret[i * 2 + j] += A[i * 8 + j * 4 + k * 2 + l] * B[l * 2 + k];
void I4d(T *ret)
See Cartesian2d::I4d()
void I4(T *ret)
See Cartesian2d::I4()
T Deviatoric_ddot_deviatoric(const T *A)
Double tensor contraction of the tensor's deviator.
void I2(T *ret)
See Cartesian2d::I2()
T A2_ddot_B2(const T *A, const T *B)
See Cartesian2d::A2_ddot_B2()
void I4rt(T *ret)
See Cartesian2d::I4rt()
T Trace(const T *A)
See Cartesian2d::Trace()
void A4_ddot_B2(const T *A, const T *B, T *ret)
See Cartesian2d::A4_ddot_B2()
void A2_dot_B2(const T *A, const T *B, T *ret)
See Cartesian2d::A2_dot_B2()
void A2_dyadic_B2(const T *A, const T *B, T *ret)
See Cartesian2d::A2_dyadic_B2()
void I4s(T *ret)
See Cartesian2d::I4s()
T A2s_ddot_B2s(const T *A, const T *B)
See Cartesian2d::A2s_ddot_B2s()
T Norm_deviatoric(const T *A)
See Cartesian2d::Norm_deviatoric()
void sym(const T *A, T *ret)
See Cartesian2d::Sym()
void II(T *ret)
See Cartesian2d::II()
T Hydrostatic_deviatoric(const T *A, T *ret)
Returns Cartesian2d::Hydrostatic() and computes Cartesian2d::Deviatoric()
T Hydrostatic(const T *A)
See Cartesian2d::Hydrostatic()
array_type::tensor< double, 4 > Random4()
Random 4th-order tensor (for example for use in testing).
array_type::tensor< double, 2 > O2()
2nd-order null tensor (all components equal to zero).
array_type::tensor< double, 2 > I2()
2nd-order identity tensor.
auto Deviatoric(const T &A)
Deviatoric part of a tensor:
auto Norm_deviatoric(const T &A)
Norm of the tensor's deviator:
auto Hydrostatic(const T &A)
Hydrostatic part of a tensor.
void hydrostatic(const T &A, R &ret)
Same as Hydrostatic() but writes to externally allocated output.
auto Sym(const T &A)
Symmetric part of a tensor:
array_type::tensor< double, 4 > II()
Result of the dyadic product of two 2nd-order identity tensors (see I2()).
void deviatoric(const T &A, R &ret)
Same as Deviatoric() but writes to externally allocated output.
array_type::tensor< double, 4 > I4()
Fourth order unit tensor.
auto A2_ddot_B2(const T &A, const T &B)
Double tensor contraction.
void sym(const T &A, R &ret)
Same as Sym() but writes to externally allocated output.
auto A4_ddot_B2(const T &A, const U &B)
Double tensor contraction.
void norm_deviatoric(const T &A, R &ret)
Same as Norm_deviatoric() but writes to externally allocated output.
void trace(const T &A, R &ret)
Same as Trace() but writes to externally allocated output.
array_type::tensor< double, 4 > I4s()
Fourth order symmetric projection.
auto Trace(const T &A)
Trace or 2nd-order tensor.
array_type::tensor< double, 2 > Random2()
Random 2nd-order tensor (for example for use in testing).
auto A2_dot_B2(const T &A, const T &B)
Dot-product (single tensor contraction)
array_type::tensor< double, 4 > O4()
4th-order null tensor (all components equal to zero).
array_type::tensor< double, 4 > I4rt()
Right-transposed fourth order unit tensor.
array_type::tensor< double, 4 > I4d()
Fourth order deviatoric projection.
auto A2s_ddot_B2s(const T &A, const T &B)
Same as A2_ddot_B2(const T& A, const T& B, R& ret) but for symmetric tensors.
auto A2_dyadic_B2(const T &A, const T &B)
Dyadic product.
xt::xtensor< T, N > tensor
Fixed (static) rank array.
Tensor products / operations.