Store tensor history into multidimensional array

7 vues (au cours des 30 derniers jours)
fsgeek
fsgeek le 4 Déc 2016
Modifié(e) : fsgeek le 4 Déc 2016
Dear all,
I read the documentatuin on Multidimensional Arrays and I haven't been able to find a solution to my problem.
I have a tensor history like this:
s11 = [xx1, xx2, xx3];
s22 = [yy1, yy2, yy3];
s33 = [zz1, zz2, zz3];
s12 = [xy1, xy2, xy3];
s13 = [xz1, xz2, xz3];
s23 = [yz1, yz2, yz3];
I want to store these tensor component histories in a single multidimensional array TENSOR, such that each slice of the array is a complete stress tensor at a certain point in time, e.g.;
>>TENSOR(:, :, 1.0)
xx1 xy1 xz1
xy1 yy1 yz1
xz1 yz1 zz1
>>TENSOR(:, :, 2.0)
xx2 xy2 xz2
xy2 yy2 yz2
xz2 yz2 zz2
(and so on)
I know how to create a multidimensional array in individual slices. For example, I could simply define the first slice then use
TENSOR(:, :, n) = [s11(n), s12(n), s13(n); s12(n), s22(n), s23(n); s13(n), s23(n), s33(n)];
To add the next slide. However, I would like to define the array in a single assignment, since the whole point of the exercise is to avoid inefficient loops.
I would greatly appreciate any advice!
Best regards,
Louis
  1 commentaire
fsgeek
fsgeek le 4 Déc 2016
Modifié(e) : fsgeek le 4 Déc 2016
Andrei's solution below works, although I had to make a couple of tweaks to get the behaviour just right so that it works in general for any 3x3xL multidimensional array:
%{
Construct a 3x3xL multidimensional array of the
stress tensor history, where L is the history
length
%}
% Direct stress components
normals = [Sxx; Syy; Szz]';
% Shear stress components
shears = [Txy; Txz; Tyz]';
% Assign normal stress component histories to diagonal terms
diagonals = repmat(eye([3.0, 3.0]), 1.0, 1.0, L);
diagonals(diagonals > 0.0) = normals';
% Assign shear stress component histories to non-diagonal terms
nonDiagonals = repmat(tril(ones(3.0), -1.0), 1.0, 1.0, L);
nonDiagonals(nonDiagonals > 0.0) = shears';
% Combine diagonal and non-diagonal terms
multidimensionalStressTensor = diagonals + nonDiagonals +
permute(nonDiagonals, [2.0, 1.0, 3.0]);
%{
Get the Eigenvalues for each frame of the tensor data. This code
was written by Bruno Luong and can be found on the exchange (File
ID: #27680)
%}
eigenvalues = eig3(multidimensionalStressTensor);
%{
The principal stresses are the maximum, median and
minimum values of the Eigenvector at each tensor
frame
%}
s1 = max(eigenvalues);
s2 = median(eigenvalues);
s3 = min(eigenvalues);
Initial tests indicate that this method is approximately 4 times faster than a FOR loop with 2D matrices.

Connectez-vous pour commenter.

Réponse acceptée

Andrei Bobrov
Andrei Bobrov le 4 Déc 2016
sxx = reshape(1:9,3,[]); % sxx = [s11;s22;s33];
sxyz = reshape(11:19,3,[]); % sxyz = [s12;s13;s23]
s = size(sxx);
D = repmat(eye(s),1,1,s(2));
D(D>0) = sxx;
ND = repmat(tril(ones(s),-1),1,1,s(2));
ND(ND>0) = sxyz;
tenzor1 = D + ND + permute(ND,[2,1,3]);
  1 commentaire
fsgeek
fsgeek le 4 Déc 2016
Thanks Andrei. This works as long as I make the following change to your code:
D(D>0) = sxx';
ND(ND>0) = sxyz';
Otherwise you get tensor histories being assigned to incorrect tensor locations. With the transpose modification it achieves exactly what I wanted. Thanks!
L

Connectez-vous pour commenter.

Plus de réponses (1)

Daniel kiracofe
Daniel kiracofe le 4 Déc 2016
As far as I am aware, it is not possible to do what you want in matlab. There is no such thing as a 3-dimensional array literal, which is what you want. It is possible in some programming languages, such as C++, but not matlab. The only way I can think of do it without loops is to create a 1D array and then reshape it. e.g:
X = [1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27];
y = reshape(X, [3 3 3])
which would give you this output:
y =
ans(:,:,1) =
1 4 7
2 5 8
3 6 9
ans(:,:,2) =
10 13 16
11 14 17
12 15 18
ans(:,:,3) =
19 22 25
20 23 26
21 24 27
Depending on what you are trying to do, you may find this to be useful. I've not used it, and the documentation on their website is sparse, but it is a toolbox for tensor manipulation in matlab which may helpful
  1 commentaire
fsgeek
fsgeek le 4 Déc 2016
I Daniel,
I think it's possible with the solution from Andrei. I'll check out the TensorToolbox though, because it sounds like something which would be very useful to me.
Thanks for the help!
L

Connectez-vous pour commenter.

Catégories

En savoir plus sur Stress and Strain dans Help Center et File Exchange

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by