Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/tdegeus/gmattensor

Tensor definitions supporting several GMat models
https://github.com/tdegeus/gmattensor

algebra gmat tensors

Last synced: 11 days ago
JSON representation

Tensor definitions supporting several GMat models

Awesome Lists containing this project

README

        

# GMatTensor

[![CI](https://github.com/tdegeus/GMatTensor/workflows/CI/badge.svg)](https://github.com/tdegeus/GMatTensor/actions)
[![Doxygen -> gh-pages](https://github.com/tdegeus/GMatTensor/workflows/gh-pages/badge.svg)](https://tdegeus.github.io/GMatTensor)
[![Conda Version](https://img.shields.io/conda/vn/conda-forge/gmattensor.svg)](https://anaconda.org/conda-forge/gmattensor)
[![Conda Version](https://img.shields.io/conda/vn/conda-forge/python-gmattensor.svg)](https://anaconda.org/conda-forge/python-gmattensor)

Tensor definitions supporting several GMat models.

- Getting started: this readme.
- Documentation: https://tdegeus.github.io/GMatTensor

# Disclaimer

This library is free to use under the
[MIT license](https://github.com/tdegeus/GMatTensor/blob/master/LICENSE).
Any additions are very much appreciated, in terms of suggested functionality, code,
documentation, testimonials, word-of-mouth advertisement, etc.
Bug reports or feature requests can be filed on
[GitHub](https://github.com/tdegeus/GMatTensor).
As always, the code comes with no guarantee.
None of the developers can be held responsible for possible mistakes.

Download:
[.zip file](https://github.com/tdegeus/GMatTensor/zipball/master) |
[.tar.gz file](https://github.com/tdegeus/GMatTensor/tarball/master).

(c - [MIT](https://github.com/tdegeus/GMatTensor/blob/master/LICENSE))
T.W.J. de Geus (Tom) | [email protected] | www.geus.me |
[github.com/tdegeus/GMatTensor](https://github.com/tdegeus/GMatTensor)

# Functionality

## Unit tensors

This library implements for a Cartesian coordinate frame in 2d or in 3d:

* Second (`I2`) and fourth (`I4`) order null tensors:
- 0ik = `02`ij *A*jk
- 0ij = `04`ijkl *A*lk
* Second (`I2`) and fourth (`I4`) order unit tensors:
- *A*ik = `I2`ij *A*jk
- *A*ij = `I4`ijkl *A*lk
* Fourth order projection tensors: symmetric, deviatoric, right- and left-transposed:
- tr(*A*) = `I2`ij *A*ji
- dev(*A*) = `I4d`ijkl *A*lk
- sym(*A*) = `I4s`ijkl *A*lk
- transpose(*A*) = `I4rt`ijkl *A*lk

For convenience also find:

* Second (`I2`) and fourth (`I4`) order random tensors,
with each component drawn from a normal distribution.

In addition it provides an `Array` of unit tensors.
Suppose that the array is rank three, with shape (R, S, T), then the output is:

* Second order tensors: (R, S, T, d, d), with `d` the number of dimensions (2 or 3).
* Fourth order tensors: (R, S, T, d, d, d, d).

E.g.
```cpp
auto A = GMatTensor::Array<3>({4, 5, 6}).O2();
auto A = GMatTensor::Array<3>({4, 5, 6}).O4();
auto A = GMatTensor::Array<3>({4, 5, 6}).I2();
auto A = GMatTensor::Array<3>({4, 5, 6}).I4();
auto A = GMatTensor::Array<3>({4, 5, 6}).II();
auto A = GMatTensor::Array<3>({4, 5, 6}).I4d();
auto A = GMatTensor::Array<3>({4, 5, 6}).I4s();
auto A = GMatTensor::Array<3>({4, 5, 6}).I4rt();
auto A = GMatTensor::Array<3>({4, 5, 6}).I4lt();
```

Given that the arrays are row-major, the tensors or each array component are thus
stored contiguously in the memory.
This is heavily used to expose all operations below to nd-arrays of tensors.
In particular, all operations are available on raw pointers to a tensor,
or for nd-arrays of (x)tensors (include a 'plain' tensor with array rank 0).

## Tensor operations

* Input: 2nd-order tensor (e.g. `(R, S, T, d, d)`).
Returns: scalar (e.g. `(R, S, T)`).
- tr(*A*) = `Trace(A)`
- tr(*A*) / *d* = `Hydrostatic(A)`
- det(*A*) = `Det(A)`
- *A*ij Bji = *A* : *B* = `A2_ddot_B2(A, B)`
- *A*ij Bji = *A* : *B* = `A2s_ddot_B2s(A, B)`
(both tensors assumed symmetric, no assertion).
- dev(*A*)ij dev(A)ji = `Norm_deviatoric(A)`
* Input: 2nd-order tensor (e.g. `(R, S, T, d, d)`).
Returns: 2nd-order tensor (e.g. `(R, S, T, d, d)`).
- dev(*A*) = `A` - `Hydrostatic(A)` * `I2`
- dev(*A*) = `Deviatoric(A)`
- sym(*A*) = `Sym(A)`
- *A*-1 = `Inv(A)`
- log(*A*) = `Logs(A)`
(tensor assumed symmetric, no assertion).
- *C*ik *A*ij Akj = *A* . *A*T
= `A2_dot_A2T(A, B)`
- *C*ik *A*ij Bjk = *A* . *B* = `A2_dot_B2(A, B)`
- *C*ij *A*ijkl Blk = *A* : *B* = `A4_ddot_B2(A, B)`
* Input: 2nd-order tensor (e.g. `(R, S, T, d, d)`)
or 4th-order tensor (e.g. `(R, S, T, d, d, d)`).
Returns: 4th-order tensor (e.g. `(R, S, T, d, d, d)`).
- *C*ijkl *A*ij Bkl = *A* * *B* = `A2_dyadic_B2(A, B)`
- *C*ijkm *A*ijkl Blm = *A* . *B* = `A4_dot_B2(A, B)`

Note that the output has:

- In the case of an input tensor `(d, d)` the output can be a rank-zero matrix.
To get a scalar do e.g. `Hydrostatic(A)()`.

Furthermore note that:

* Functions whose name starts with a capital letter allocate and return their output.
* Functions whose name starts with a small letter require their output as final
input parameter(s), which is changed in-place.

## Tensor operations (semi-public API)

A semi-public API exists that is mostly aimed to support *GMat* implementation.
These involve pure-tensor operations based the input (and the output) as a pointer,
using the following storage convention:

* Cartesian2d: (xx, xy, yx, yy).
* Cartesian3d: (xx, xy, xz, yx, yy, yz, zx, zy, zz).

This part of the API does not support arrays of tensors.
In addition to the pointer equivalent (or in fact core) of the above function,
the following functions are available:

* `Hydrostatic_deviatoric`: Return the hydrostatic part of a tensor,
and write the deviatoric part to a pointer.
* `A4_ddot_B4_ddot_C4`: *A* : *B* : *C*
* `A2_dot_B2_dot_C2T`: *A* . *B* . *C*T
* `eigs`: Compute the eigen values and eigen vectors for a symmetric 2nd order tensor
(no assertion on symmetry).
* `from_eigs`: The reverse operation from `eigs`, for a symmetric 2nd order tensor
(no assertion on symmetry).

# Implementation

## C++ and Python

The code is a C++ header-only library (see installation notes),
but a Python module is also provided (see installation notes).
The interfaces are identical except:

+ All *xtensor* objects (`xt::xtensor<...>`) are *NumPy* arrays in Python.
Overloading based on rank is also available in Python.
+ The Python module cannot change output objects in-place:
only functions whose name starts with a capital letter are included, see below.
+ All `::` in C++ are `.` in Python.

# Installation

## C++ headers

### Using conda

```bash
conda install -c conda-forge gmattensor
```

### From source

```bash
# Download GMatTensor
git checkout https://github.com/tdegeus/GMatTensor.git
cd GMatTensor

# Install headers, CMake and pkg-config support
cmake -Bbuild .
cd build
make install
```

## Python module

### Using conda

```bash
conda install -c conda-forge python-gmattensor
```

Note that *xsimd* and hardware optimisation are **not enabled**.
To enable them you have to compile on your system, as is discussed next.

### From source

> You need *xtensor*, *xtensor-python* and optionally *xsimd* as prerequisites.
> In addition *scikit-build* is needed to control the build from Python.
> The easiest is to use *conda* to get the prerequisites:
>
> ```bash
> conda install -c conda-forge xtensor-python
> conda install -c conda-forge xsimd
> conda install -c conda-forge scikit-build
> ```
>
> If you then compile and install with the same environment
> you should be good to go.
> Otherwise, a bit of manual labour might be needed to
> treat the dependencies.

```bash
# Download GMatTensor
git checkout https://github.com/tdegeus/GMatTensor.git
cd GMatTensor

# Only if you want to use hardware optization:
export CMAKE_ARGS="-DUSE_SIMD=1"

# Compile and install the Python module
# (-vv can be omitted as is controls just the verbosity)
python setup.py install --build-type Release -vv

# OR, Compile and install the Python module with hardware optimisation
# (with scikit-build CMake options can just be added as command-line arguments)
python setup.py install --build-type Release -DUSE_SIMDD=1 -vv
```

# Compiling user-code

## Using CMake

### Example

Using *GMatTensor* your `CMakeLists.txt` can be as follows

```cmake
cmake_minimum_required(VERSION 3.1)
project(example)
find_package(GMatTensor REQUIRED)
add_executable(example example.cpp)
target_link_libraries(example PRIVATE GMatTensor)
```

### Targets

The following targets are available:

* `GMatTensor`
Includes *GMatTensor* and the *xtensor* dependency.

* `GMatTensor::assert`
Enables assertions by defining `GMATTENSOR_ENABLE_ASSERT`.

* `GMatTensor::debug`
Enables all assertions by defining
`GMATTENSOR_ENABLE_ASSERT` and `XTENSOR_ENABLE_ASSERT`.

* `GMatTensor::compiler_warings`
Enables compiler warnings (generic).

### Optimisation

It is advised to think about compiler optimisation and enabling *xsimd*.
Using *CMake* this can be done using the `xtensor::optimize` and `xtensor::use_xsimd` targets.
The above example then becomes:

```cmake
cmake_minimum_required(VERSION 3.1)
project(example)
find_package(GMatTensor REQUIRED)
find_package(xtensor REQUIRED)
find_package(xsimd REQUIRED)
add_executable(example example.cpp)
target_link_libraries(example PRIVATE GMatTensor xtensor::optimize xtensor::use_xsimd)
```

See the [documentation of xtensor](https://xtensor.readthedocs.io/en/latest/) concerning optimisation.

## By hand

Presuming that the compiler is `c++`, compile using:

```
c++ -I/path/to/GMatTensor/include ...
```

Note that you have to take care of the *xtensor* dependency, the C++ version, optimisation,
enabling *xsimd*, ...

## Using pkg-config

Presuming that the compiler is `c++`, compile using:

```
c++ `pkg-config --cflags GMatTensor` ...
```

Note that you have to take care of the *xtensor* dependency, the C++ version, optimization,
enabling *xsimd*, ...

# Change-log

## v0.10.1

* Extra functions to get version information

## v0.10.0

* [python] Array: unit tensors -> properties
* Updating Catch2

## v0.9.0

* Type alias `xt::xtensor`: allows full API to use `xt::pytensor` (#44)
* [BREAKING CHANGE] Python: `shape*`: function -> property (#44)
* [BREAKING CHANGE] Remove view_tensor* (re-rolls #41) (#44)
* [docs] Adding update script

## v0.8.0

* [BREAKING CHANGE] Moving "allocate" to public namespace (#42)
* Array of tensors: returning underlying shape/size (#43)
* Array: adding function to 'view' a tensor (rank 2 or 4) (#41)
* auto-format (#40)
* [Python] Adding 0d array

## v0.7.5

* Switching to scikit-build (#37)

## v0.7.4

* Allow xsimd from setup.py using `CMAKE_ARGS` (#36)

## v0.7.3

* Adding cross-compilation features (#35)
* Updating doxystyle
* Removing xtensor-python work-around

## v0.7.2

* Bugfix: type recognition for xtensor-fixed.

## v0.7.1

* Using xtensor-python to speed-up Python API, and to allow in-place output.
* [CI] Using micromamba for efficiency.

## v0.7.0

* [CI] Fixing typos
* [docs] Minor updates
* [docs] Using dark-style documentation
* [CMake] Simplifying implementation
* [Python] Reducing deps
* Minor reorganization

## v0.6.0

* [docs] Adding doxygen docs published on GitHub pages.
* [docs] Minor readme updates.
* [CMake] Small tweaks.
* [CMake] Relaxing C++17 requirement.
* Using setuptools_scm for versioning.

## v0.5.0

* Extending tests.
* Added `Sym`.
* Added `A2_dot_B2` to *Cartesian2d*.
* API change: **all** functions that return output, including scalars, now start
with a capital letter.
* Updated readme.

## v0.4.0

* Adding "logs".
* Unit tensors: now all using pointer API.
* Porting all public APIs to array of tensors.
* Pointer API: less aggressive templating.
* API change: Renaming "equivalent_deviatioric" -> "norm_deviatoric".
* Introducing null tensors `GMatTensor::Cartesian3d::O2` and `GMatTensor::Cartesian3d::O4`
(also for Cartesian2d).
* Adding several new tensor operations / products.
* Adding more public xtensor interface for tensor products.
The aim is mostly to allow the user to be quick and dirty, e.g. when testing.
* Formatting tests with the latter new API.

## v0.3.0

* Relaxing assumption on symmetry for dev(A) : dev(A).
* Adding symmetric only function `A2s_ddot_B2s` to pointer API.

## v0.2.0

**Pointer API**

* Making pointer explicit (template `T` -> `T*`).
* Adding zero and unit tensors.
* Add dyadic product between two second order tensors.

## v0.1.2

* Adding stride members to `Array`.

## v0.1.1

* Improved sub-classing support

## v0.1.0

Transfer from other libraries.