From 4c4c7c45d55341912e0318887a6adc78ff06cad3 Mon Sep 17 00:00:00 2001 From: Magdalena Schreter Date: Wed, 15 May 2024 23:03:58 +0200 Subject: [PATCH] add missing trigonometric and hyperbolic functions for VectorizedArray --- doc/news/changes/minor/20240515Schreter | 4 + include/deal.II/base/vectorization.h | 180 ++++++++++++++++++++++++ tests/base/vectorization_01.cc | 54 +++++++ tests/base/vectorization_01.output | 27 ++++ 4 files changed, 265 insertions(+) create mode 100644 doc/news/changes/minor/20240515Schreter diff --git a/doc/news/changes/minor/20240515Schreter b/doc/news/changes/minor/20240515Schreter new file mode 100644 index 0000000000..fd95882d33 --- /dev/null +++ b/doc/news/changes/minor/20240515Schreter @@ -0,0 +1,4 @@ +New: Added overloads of missing trigonometric functions (acos, asin, atan) and +hyperbolic functions (cosh, sinh, tanh, acosh, asinh, atanh) for VectorizedArray. +
+(Magdalena Schreter-Fleischhacker, Johannes Resch, Martin Kronbichler 2024/05/15) diff --git a/include/deal.II/base/vectorization.h b/include/deal.II/base/vectorization.h index 5c5d0b945c..41c5bb5fac 100644 --- a/include/deal.II/base/vectorization.h +++ b/include/deal.II/base/vectorization.h @@ -6648,6 +6648,186 @@ namespace std + /** + * Compute the arc cosine of a vectorized data field. The result is + * returned as vectorized array in the form {acos(x[0]), acos(x[1]), ..., + * acos(x[size()-1])}. + * + * @relatesalso VectorizedArray + */ + template + inline ::dealii::VectorizedArray + acos(const ::dealii::VectorizedArray &x) + { + ::dealii::VectorizedArray out; + for (unsigned int i = 0; i < dealii::VectorizedArray::size(); + ++i) + out[i] = std::acos(x[i]); + return out; + } + + + + /** + * Compute the arc sine of a vectorized data field. The result is + * returned as vectorized array in the form {asin(x[0]), asin(x[1]), ..., + * asin(x[size()-1])}. + * + * @relatesalso VectorizedArray + */ + template + inline ::dealii::VectorizedArray + asin(const ::dealii::VectorizedArray &x) + { + ::dealii::VectorizedArray out; + for (unsigned int i = 0; i < dealii::VectorizedArray::size(); + ++i) + out[i] = std::asin(x[i]); + return out; + } + + + + /** + * Compute the arc tangent of a vectorized data field. The result is + * returned as vectorized array in the form {atan(x[0]), atan(x[1]), ..., + * atan(x[size()-1])}. + * + * @relatesalso VectorizedArray + */ + template + inline ::dealii::VectorizedArray + atan(const ::dealii::VectorizedArray &x) + { + ::dealii::VectorizedArray out; + for (unsigned int i = 0; i < dealii::VectorizedArray::size(); + ++i) + out[i] = std::atan(x[i]); + return out; + } + + + + /** + * Compute the hyperbolic cosine of a vectorized data field. The result is + * returned as vectorized array in the form {cosh(x[0]), cosh(x[1]), ..., + * cosh(x[size()-1])}. + * + * @relatesalso VectorizedArray + */ + template + inline ::dealii::VectorizedArray + cosh(const ::dealii::VectorizedArray &x) + { + ::dealii::VectorizedArray out; + for (unsigned int i = 0; i < dealii::VectorizedArray::size(); + ++i) + out[i] = std::cosh(x[i]); + return out; + } + + + + /** + * Compute the hyperbolic sine of a vectorized data field. The result is + * returned as vectorized array in the form {sinh(x[0]), sinh(x[1]), ..., + * sinh(x[size()-1])}. + * + * @relatesalso VectorizedArray + */ + template + inline ::dealii::VectorizedArray + sinh(const ::dealii::VectorizedArray &x) + { + ::dealii::VectorizedArray out; + for (unsigned int i = 0; i < dealii::VectorizedArray::size(); + ++i) + out[i] = std::sinh(x[i]); + return out; + } + + + + /** + * Compute the hyperbolic tangent of a vectorized data field. The result is + * returned as vectorized array in the form {tanh(x[0]), tanh(x[1]), ..., + * tanh(x[size()-1])}. + * + * @relatesalso VectorizedArray + */ + template + inline ::dealii::VectorizedArray + tanh(const ::dealii::VectorizedArray &x) + { + ::dealii::VectorizedArray out; + for (unsigned int i = 0; i < dealii::VectorizedArray::size(); + ++i) + out[i] = std::tanh(x[i]); + return out; + } + + + + /** + * Compute the area hyperbolic cosine of a vectorized data field. The result + * is returned as vectorized array in the form {acosh(x[0]), acosh(x[1]), + * ..., acosh(x[size()-1])}. + * + * @relatesalso VectorizedArray + */ + template + inline ::dealii::VectorizedArray + acosh(const ::dealii::VectorizedArray &x) + { + ::dealii::VectorizedArray out; + for (unsigned int i = 0; i < dealii::VectorizedArray::size(); + ++i) + out[i] = std::acosh(x[i]); + return out; + } + + + + /** + * Compute the area hyperbolic sine of a vectorized data field. The result is + * returned as vectorized array in the form {asinh(x[0]), asinh(x[1]), + * ..., asinh(x[size()-1])}. + * + * @relatesalso VectorizedArray + */ + template + inline ::dealii::VectorizedArray + asinh(const ::dealii::VectorizedArray &x) + { + ::dealii::VectorizedArray out; + for (unsigned int i = 0; i < dealii::VectorizedArray::size(); + ++i) + out[i] = std::asinh(x[i]); + return out; + } + + + + /** + * Compute the area hyperbolic tangent of a vectorized data field. The result + * is returned as vectorized array in the form {atanh(x[0]), atanh(x[1]), + * ..., atanh(x[size()-1])}. + * + * @relatesalso VectorizedArray + */ + template + inline ::dealii::VectorizedArray + atanh(const ::dealii::VectorizedArray &x) + { + ::dealii::VectorizedArray out; + for (unsigned int i = 0; i < dealii::VectorizedArray::size(); + ++i) + out[i] = std::atanh(x[i]); + return out; + } + + + /** * Compute the exponential of a vectorized data field. The result is * returned as vectorized array in the form {exp(x[0]), exp(x[1]), ..., diff --git a/tests/base/vectorization_01.cc b/tests/base/vectorization_01.cc index dc359f1d4b..706942e8f5 100644 --- a/tests/base/vectorization_01.cc +++ b/tests/base/vectorization_01.cc @@ -105,18 +105,72 @@ test() AssertThrow(std::fabs(e[i] - std::sin(d[i])) < 10. * std::numeric_limits::epsilon(), ExcInternalError()); + deallog << "OK" << std::endl << "Arc sine: "; + d = std::asin(e); + for (unsigned int i = 0; i < n_vectors; ++i) + AssertThrow(std::fabs(d[i] - std::asin(e[i])) < + 10. * std::numeric_limits::epsilon(), + ExcInternalError()); deallog << "OK" << std::endl << "Cosine: "; e = std::cos(c); for (unsigned int i = 0; i < n_vectors; ++i) AssertThrow(std::fabs(e[i] - std::cos(c[i])) < 10. * std::numeric_limits::epsilon(), ExcInternalError()); + deallog << "OK" << std::endl << "Arc cosine: "; + c = std::acos(e); + for (unsigned int i = 0; i < n_vectors; ++i) + AssertThrow(std::fabs(c[i] - std::acos(e[i])) < + 10. * std::numeric_limits::epsilon(), + ExcInternalError()); deallog << "OK" << std::endl << "Tangent: "; d = std::tan(e); for (unsigned int i = 0; i < n_vectors; ++i) AssertThrow(std::fabs(d[i] - std::tan(e[i])) < 10. * std::numeric_limits::epsilon(), ExcInternalError()); + deallog << "OK" << std::endl << "Arc tangent: "; + d = std::atan(e); + for (unsigned int i = 0; i < n_vectors; ++i) + AssertThrow(std::fabs(d[i] - std::atan(e[i])) < + 10. * std::numeric_limits::epsilon(), + ExcInternalError()); + deallog << "OK" << std::endl << "Hyperbolic cosine: "; + e = std::cosh(c); + for (unsigned int i = 0; i < n_vectors; ++i) + AssertThrow(std::fabs(e[i] - std::cosh(c[i])) < + 10. * std::numeric_limits::epsilon(), + ExcInternalError()); + deallog << "OK" << std::endl << "Area hyperbolic cosine: "; + c = std::acosh(e); + for (unsigned int i = 0; i < n_vectors; ++i) + AssertThrow(std::fabs(c[i] - std::acosh(e[i])) < + 10. * std::numeric_limits::epsilon(), + ExcInternalError()); + deallog << "OK" << std::endl << "Hyperbolic sine: "; + e = std::sinh(d); + for (unsigned int i = 0; i < n_vectors; ++i) + AssertThrow(std::fabs(e[i] - std::sinh(d[i])) < + 10. * std::numeric_limits::epsilon(), + ExcInternalError()); + deallog << "OK" << std::endl << "Area hyperbolic sine: "; + d = std::asinh(e); + for (unsigned int i = 0; i < n_vectors; ++i) + AssertThrow(std::fabs(d[i] - std::asinh(e[i])) < + 10. * std::numeric_limits::epsilon(), + ExcInternalError()); + deallog << "OK" << std::endl << "Hyperbolic tangent: "; + d = std::tanh(e); + for (unsigned int i = 0; i < n_vectors; ++i) + AssertThrow(std::fabs(d[i] - std::tanh(e[i])) < + 10. * std::numeric_limits::epsilon(), + ExcInternalError()); + deallog << "OK" << std::endl << "Area hyperbolic tangent: "; + e = std::atanh(d); + for (unsigned int i = 0; i < n_vectors; ++i) + AssertThrow(std::fabs(e[i] - std::atanh(d[i])) < + 10. * std::numeric_limits::epsilon(), + ExcInternalError()); deallog << "OK" << std::endl << "Exponential: "; d = std::exp(c - a); for (unsigned int i = 0; i < n_vectors; ++i) diff --git a/tests/base/vectorization_01.output b/tests/base/vectorization_01.output index c11369e533..82a7f4bca6 100644 --- a/tests/base/vectorization_01.output +++ b/tests/base/vectorization_01.output @@ -13,8 +13,17 @@ DEAL:double::Absolute value: OK DEAL:double::Maximum value: OK DEAL:double::Minimum value: OK DEAL:double::Sine: OK +DEAL:double::Arc sine: OK DEAL:double::Cosine: OK +DEAL:double::Arc cosine: OK DEAL:double::Tangent: OK +DEAL:double::Arc tangent: OK +DEAL:double::Hyperbolic cosine: OK +DEAL:double::Area hyperbolic cosine: OK +DEAL:double::Hyperbolic sine: OK +DEAL:double::Area hyperbolic sine: OK +DEAL:double::Hyperbolic tangent: OK +DEAL:double::Area hyperbolic tangent: OK DEAL:double::Exponential: OK DEAL:double::Logarithm: OK DEAL:float::Addition: OK @@ -31,8 +40,17 @@ DEAL:float::Absolute value: OK DEAL:float::Maximum value: OK DEAL:float::Minimum value: OK DEAL:float::Sine: OK +DEAL:float::Arc sine: OK DEAL:float::Cosine: OK +DEAL:float::Arc cosine: OK DEAL:float::Tangent: OK +DEAL:float::Arc tangent: OK +DEAL:float::Hyperbolic cosine: OK +DEAL:float::Area hyperbolic cosine: OK +DEAL:float::Hyperbolic sine: OK +DEAL:float::Area hyperbolic sine: OK +DEAL:float::Hyperbolic tangent: OK +DEAL:float::Area hyperbolic tangent: OK DEAL:float::Exponential: OK DEAL:float::Logarithm: OK DEAL:long double::Addition: OK @@ -49,7 +67,16 @@ DEAL:long double::Absolute value: OK DEAL:long double::Maximum value: OK DEAL:long double::Minimum value: OK DEAL:long double::Sine: OK +DEAL:long double::Arc sine: OK DEAL:long double::Cosine: OK +DEAL:long double::Arc cosine: OK DEAL:long double::Tangent: OK +DEAL:long double::Arc tangent: OK +DEAL:long double::Hyperbolic cosine: OK +DEAL:long double::Area hyperbolic cosine: OK +DEAL:long double::Hyperbolic sine: OK +DEAL:long double::Area hyperbolic sine: OK +DEAL:long double::Hyperbolic tangent: OK +DEAL:long double::Area hyperbolic tangent: OK DEAL:long double::Exponential: OK DEAL:long double::Logarithm: OK -- 2.39.5