Click here to Skip to main content
15,867,453 members
Please Sign up or sign in to vote.
4.00/5 (1 vote)
Hey all, I have the following problem which i am deeply stuck on...

I have created a 3D grid of a cubic structure called material with shape (2,4,4) (so 32 grains each) . As you can see this only contains 0's and 1's. This represents two materials. so there are two layers and each layer contains 4x4 grains. I made an array called STRESS which contains a stress tensor (3x3x3) [these are called either m_1,m_2,m_3,m_4)] for every grain of my cube material (2,4,4). Lets say i computed my STRESS at two increments of my simulation so 1 and 2. This then results in a final STRESS (2, 2, 4, 4, 3, 3) = ((2 increments), (2,4,4 =shape of my cube), 3,3 = 3x3x3 matrix of each grain)). For every iteration i would like to average my stress tensor for each cluster of grains. A cluster can be seen as 8 grains in total. To clarify this with an example: material[0,0,0],material[0,1,0],material[0,0,1],material[0,1,1],material[1,0,0],material[1,1,0],
material[1,0,1],material[1,1,1] form a cluster of 8 grains. The same story hold for the other three clusters in material So in total there are 4 clusters to be made.

I would like to average the different 3x3x3 matrices for each grain in the clusters (hopefully the explanation above is clear enough...) and repeat this process for each iteration (in this case only 2) in the stress tensor called STRESS. So following how a cluster is built my averaged stress tensor would be built like this: clus1_it1 (see code) = sum(STRESS[0,0,0,0]+STRESS[0,0,1,0]+
STRESS[0,0,0,1]+STRESS[0,0,1,1]+STRESS[0,1,0,0]+STRESS[0,1,1,0]+STRESS[0,1,0,1]+
STRESS[0,1,1,1])/8(grains). After i computed this average for this specific cluster, the stress tensors(m_1,m_1,m_1,m_1,m_2, m_2,m_2, m_2) in the old cluster has to be replaced with this newly made stress tensor clus1_it1 for each of the 8 grains belonging to that cluster. This process has to be repeated for the other clusters and also for the other iteration (see it1 and it2 in WANTED_OUTPUT). In the code below obviously i did it by hand. I would really like to automate this process, however i have no idea how to do this (quite new to programming....). I would really appreciate the help! I added an extra example to the bottom in case my brief explanation was too vague, sorry for that..


Python
import numpy as np

material = np.array([[[1, 1, 0, 0],
                      [1, 1, 0, 0],
                      [0, 0, 1, 1],
                      [0, 0, 1, 1]],

                     [[1, 1, 0, 0],
                      [1, 1, 0, 0],
                      [0, 0, 1, 1],
                      [0, 0, 1, 1]]])
      
shape = material.shape          

m_1 =   np.array([[1,1,1], [1,1,1], [1,1,1]])
m_2 =  np.array([[2,2,2], [2,2,2], [2,2,2]])
m_3 =  np.array([[3,3,3], [3,3,3], [3,3,3]])
m_4 =  np.array([[4,4,4],[4,4,4], [4,4,4]])

shape_tensor = m_1.shape
shape_tensor = np.ones(shape_tensor)

#My stress tensor has the shape (2, 2, 4, 4, 3, 3) it contains of 2 iterations, it is a 2x4x4 matrix where each element is a 3x3 matrix
STRESS =   np.array([[[[m_1, m_1, m_2, m_2],
                      [m_1, m_1, m_2, m_2],
                      [m_4, m_4, m_3, m_3],
                      [m_4, m_4, m_3, m_3]],

                    [[m_2, m_2, m_3, m_3],
                      [m_2, m_2, m_3, m_3],
                      [m_3, m_3, m_1, m_1],
                      [m_3, m_3, m_1, m_1]]],

                    [[[m_2, m_2, m_1, m_1],
                      [m_2, m_2, m_1, m_1],
                      [m_3, m_3, m_4, m_4],
                      [m_3, m_3, m_4, m_4]],

                    [[m_3, m_3, m_2, m_2],
                      [m_3, m_3, m_2, m_2],
                      [m_1, m_1, m_3, m_3],
                      [m_1, m_1, m_3, m_3]]]])
                     
shape_STRESS = STRESS.shape 


#HOW MY WANTED OUTPUT SHOULD LOOK LIKE............................
#Did this by hand obviously not what i want....
clus1_it1 = (sum([m_1,m_1,m_1,m_1,m_2, m_2,m_2, m_2])/8)*shape_tensor
clus2_it1 = (sum([m_2,m_2,m_2,m_2,m_3, m_3,m_3, m_3])/8)*shape_tensor
clus3_it1 = (sum([m_4,m_4,m_4,m_4,m_3, m_3,m_3, m_3])/8)*shape_tensor
clus4_it1 = (sum([m_3,m_3,m_3,m_3,m_1, m_1,m_1, m_1])/8)*shape_tensor

clus1_it2 = (sum([m_2,m_2,m_2,m_2,m_3, m_3,m_3, m_3])/8)*shape_tensor
clus2_it2 = (sum([m_1,m_1,m_1,m_1,m_2, m_2,m_2, m_2])/8)*shape_tensor
clus3_it2 = (sum([m_3,m_3,m_3,m_3,m_1, m_1,m_1, m_1])/8)*shape_tensor
clus4_it2 = (sum([m_4,m_4,m_4,m_4,m_3, m_3,m_3, m_3])/8)*shape_tensor                     
 

WANTED_OUTPUT = np.array([[[[clus1_it1, clus1_it1, clus2_it1, clus2_it1],
                            [clus1_it1, clus1_it1, clus2_it1, clus2_it1],
                            [clus3_it1, clus3_it1, clus4_it1, clus4_it1],
                            [clus3_it1, clus3_it1, clus4_it1, clus4_it1]],

                           [[clus1_it1, clus1_it1, clus2_it1, clus2_it1],
                            [clus1_it1, clus1_it1, clus2_it1, clus2_it1],
                            [clus3_it1, clus3_it1, clus4_it1, clus4_it1],
                            [clus3_it1, clus3_it1, clus4_it1, clus4_it1]]],


                           [[[clus1_it2, clus1_it2, clus2_it2, clus2_it2],
                             [clus1_it2, clus1_it2, clus2_it2, clus2_it2],
                             [clus3_it2, clus3_it2, clus4_it2, clus4_it2],
                             [clus3_it2, clus3_it2, clus4_it2, clus4_it2]],

                          [[clus1_it2, clus1_it2, clus2_it2, clus2_it2],
                           [clus1_it2, clus1_it2, clus2_it2, clus2_it2],
                           [clus3_it2, clus3_it2, clus4_it2, clus4_it2],
                           [clus3_it2, clus3_it2, clus4_it2, clus4_it2]]]])



phase_RVE = np.array(
[[[1, 1, 0, 0],
 [1, 1, 0, 0],
 [0, 0, 1, 1],
 [0, 0, 1, 1]],
 [[1, 1, 0, 0],
 [1, 1, 0, 0],
 [0, 0, 1, 1],
 [0, 0, 1, 1]]])

stress_RVE = np.array(
[[[[1, 2, 4, 2],
 [3, 4, 3, 3],
 [5, 5, 2, 2],
 [5, 8, 2, 2]],
 [[1, 1, 4, 4],
 [2, 2, 3, 2],
 [0, 0, 1, 1],
 [0, 0, 1, 4]]],

[[[1, 2, 4, 2],
 [3, 4, 3, 3],
 [5, 5, 2, 2],
 [5, 8, 2, 2]],
 [[1, 1, 4, 4],
 [2, 2, 3, 2],
 [0, 0, 1, 1],
 [0, 0, 1, 4]]]])
        
desired_outcome = np.array(
[[[[2.5, 2.5, 3, 3],
 [2.5, 2.5, 3, 3],
 [5.75, 5.75, 2, 2],
 [5.75, 5.75, 2, 2]],
 [[1.5, 1.5, 3.25, 3.25],
 [1.5, 1.5, 3.25, 3.25],
 [0, 0, 1.75, 1.75],
 [0, 0, 1.75, 1.75]]])


What I have tried:

I have tried to do someting with a simpler example but i am simply struggling with it.

Python
phase_RVE = np.array(
[[[1, 1, 0, 0],
 [1, 1, 0, 0],
 [0, 0, 1, 1],
 [0, 0, 1, 1]],
 [[1, 1, 0, 0],
 [1, 1, 0, 0],
 [0, 0, 1, 1],
 [0, 0, 1, 1]]])

stress_RVE = np.array(
[[[1, 2, 4, 2],
 [3, 4, 3, 3],
 [5, 5, 2, 2],
 [5, 8, 2, 2]],
 [[1, 1, 4, 4],
 [2, 2, 3, 2],
 [0, 0, 1, 1],
 [0, 0, 1, 4]]])

shape = stress_RVE.shape
desired_outcome = np.zeros(shape)

for i in range(0, shape[0]):
    si = slice(i, i + 2)

    for j in range(0, shape[1], 2):
        sj = slice(j, j + 2)

        for k in range(0, shape[2], 2):
            sk = slice(k, k + 2)

            matrix = stress_RVE[si, sj, sk]
            desired_outcome[si, sj, sk] = matrix.mean()
            
            
            
desired_outcome = np.array(
[[[2.5, 2.5, 3, 3],
 [2.5, 2.5, 3, 3],
 [5.75, 5.75, 2, 2],
 [5.75, 5.75, 2, 2]],
 [[1.5, 1.5, 3.25, 3.25],
 [1.5, 1.5, 3.25, 3.25],
 [0, 0, 1.75, 1.75],
 [0, 0, 1.75, 1.75]]])
Posted
Updated 16-Mar-22 11:45am
v2

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900