Examples and functions to compute derivatives of tensor-valued equations with Sacado
Check the repo "Automatic_differentiation_for_material_modelling-dealii"! This docu is out of order and we only use the some parts of the functions.
In this version, in contrast "Automatic_differentiation_for_material_modelling-dealii", we create a new data type and define member functions, which is very user-friendly. For compatibily (tensor operations, switching from analytical to AutoDiff-tangent, ...) this code design will most likely be changed and be replaced for instance by separate functions. Moreover, new features will be introduced (use Sacado also locally in qp-level iterations for tangents, ...), so stay tuned. Nevertheless, the current setup is operational and in use.
The aim is to compute e. g. the tangent
as a fourth order tensor on the material point level (quadrature point) based on the implementation of the stress-equation sigma=sigma(eps,phi) only. Similarly, we can compute the tangent in combination with a scalar variable, such as the scalar damage phi and compute second derivatives (see feature list).
The here shown code only implements functions (and finally the Wrapper) to pack the derivatives related to tensors into a nice format, pass them to Sacado to compute the derivatives and unpack the results back into tensors.
This approach might be useful when you want to compute e. g. the tangent modulus at quadrature points and keep everything in an enclosed material model function/file. An example: You developed or found a material model, lets say elasto-plasticity with some saturated hardening, and want to implement this model to compare it to another one. So you implement the equations and possibly subiterations on the material point level into your material model that gets the strain and the history variables as inputs. Now you would need to derive the tangents (e.g. d_stress/d_strain) to be able to assemble the tangent. However, the latter can take some effort especially for more complicated models or if the equations are still being developed as we speak. With the Sacado_Wrapper you implement the equations (e.g. stress equation) as you would normally do, change the data types (when you use templated functions here, that is done automatically) and set the dofs as shown in the documentation. In the end you call get_tangent() and there you have your tangent (quadratic convergence without effort). When you're satisfied with the material model, you can derive the tangent by hand and simply change the data types back and replace the get_tangent() call with your analytical tangent equation. To sum up, the Wrapper enables you keep the standard material model framework and still use the power (and beauty) of automatic differentation.
It will probably be significantly more efficient if possible to assemble the residuum and compute its derivatives as shown in, for instance, the deal.ii tutorial 33 https://www.dealii.org/current/doxygen/deal.II/step_33.html with already implemented deal.ii-functionality. Also keep in mind that by automatically computing the tangent from the residuum you don't have to derive the linearisation of the residuum by hand, which can be advantageous for complicated PDEs. When you use this Wrapper, you still have to derive the linearisation of the residuum by hand and fill it with the tangents from the material model.
The Doxygen documentation for the code can be found here https://jfriedlein.github.io/Sacado_Tensors_dealII/html/index.html. It shows a few examples and describes how to use the Sacado_Wrapper.
(2nd order symmetric tensor, here: strain tensor)
(scalar, here: global damage variable)
(4th order sym. tensor, here: consistent tangent moduli)
- Compute derivatives of equations with respect to a single scalar.
- Compute tangents from equations with respect to a single SymmetricTensor<2,dim>. (Example 3B)
- Compute tangents from equations with respect to a single SymmetricTensor<2,dim> and a single scalar. (Example 4)
- Compute second derivatives of equations with respect to a single SymmetricTensor<2,dim> and a single scalar. (Example 7, 8)
- First you should check whether the herin described concepts and examples fit your needs. The easiest way to do this is by looking at the Doxygen documentation linked above and the list of current features.
- If you're interested in the details and want to get a look under the hood of the Sacado_Wrapper, then please consider the examples 1, 2, 3, 6 and 7
- If you right away want to use the Sacado_Wrapper, then consider the examples 3b, 4 and 8 and follow the instructions on how to get the Wrapper into your own code.
- Download the file "Sacado_Wrapper.h" and place it into your working directory, e.g. where your main code such as Sacado_examples.cc is.
- Include the .h file with your other headers in your code via '#include "Sacado_Wrapper.h"'.
- Copy one of the examples into your code for testing.
- Compile, run and play around with the code.
- Currently it is not possible to use "Vector<fad_double>" or similar Sacado data types. You would probably have to first create instances of "Vector" for the desired data type as described here https://www.dealii.org/current/doxygen/deal.II/Instantiations.html. To avoid this you can simply use "std::vector<fad_double>".
-
add the uncommented program to the end of the documentation
-
maybe add the init to zero for the constructors of the SW data types
-
add a note on the "reset_its_deriv" and "reset_other_deriv" issue
-
add note on initialisation of value AND derivative via evolution equations with zero values
-
check whether we can temporarily add Sacado dofs to the variable to e.g. compute some intermediate derivative and then later on delete these derivatives.
-
template the Sacado data type e.g. Sacado::Fad::DFad (most flexible), Sacado::Fad::SFad (most efficient) [according to https://docs.trilinos.org/latest-release/packages/sacado/doc/html/index.html]
-
instead of using Dofs SymTensor+double+double+double, check using SymTensor+std::vector
-
find a more suitable name
-
enable LaTeX equations in the documentation hosted via GitHub
-
Rework the design and structure of the Wrapper
-
implement more data types (e.g. Vector, nonsym tensor) and compatibility with more combinations (e.g. vector-vector, vector-double).
-
add some text that: Every variable computed from the variables set as dofs contains the derivatives as shown in the figure. Hence, you can compute the tangents for every variable.
-
add note on the efficiency/computation time
-
update links in the documentation
-
add link to https://arxiv.org/pdf/1811.05031.pdf
-
remove todo for factor 0.5 in the beginning
- ..