1+ function [I ] = AddCBDwMorphology_step (I , w , Pid ,Eid ,Wid ,Nid ,Sid ,Uid ,Lid , Nsimultaneous )
2+ % inputs: I, w, Pid,Eid,Wid,Nid,Sid,Uid,Lid and output: I
3+ % 'I' is Nx.Ny.Nz array with 0 as pore, 1 as active material, 2 as CBD
4+ % 'w' is corresponding morphology (varies between 0 and 1)
5+ % '*id' are 1D indices for each voxel (P) and its neighbors (E,W,N,S,U,L)
6+ % 'Nsimultaneous' many voxels are added in one execution (exact number may
7+ % be smaller)
8+ % __________________________________________________________________________
9+ % Programmed by : Aashutosh Mistry
10+ % Created on : Jul 05, 2020
11+ % Modifications : Aug 29, 2020
12+ % - candidate voxels are void voxels having
13+ % at least one solid neighbor
14+ % __________________________________________________________________________
15+
16+ [Nx ,Ny ,Nz ] = size(I ); % voxels in different directions
17+ N = Nx * Ny * Nz ; % total voxel counts
18+
19+ kmin = 2 ; kmax = Nz - 1 ; normalize_energy = 6 ;
20+ if Nz == 1 % 2D case
21+ kmin = 1 ; kmax = 1 ; normalize_energy = 4 ;
22+ end
23+
24+ % flattening 'I' matrix into 1D array _____________________________________
25+ I1D = zeros(N ,1 );
26+
27+ % for k=1:Nz
28+ % for j=1:Ny
29+ % for i=1:Nx
30+ % I1D(Pid(i,j,k)) = I(i,j,k);
31+ % end
32+ % end
33+ % end
34+ I1D(Pid ) = I ;
35+
36+ % candidate voxels : void voxels with at least one solid neighbor _________
37+ Ncandidate= 0 ;
38+
39+ for k= kmin : kmax
40+ for j= 2 : Ny - 1
41+ for i= 2 : Nx - 1
42+ if I(i ,j ,k )==0
43+ % reinitialize
44+ ngbr1 = 0 ; % active material neighbors
45+ ngbr2 = 0 ; % CBD neighbors
46+
47+ % checking East neighbor
48+ if I1D(Eid(i ,j ,k ))==1
49+ ngbr1 = ngbr1 + 1 ;
50+ elseif I1D(Eid(i ,j ,k ))==2
51+ ngbr2 = ngbr2 + 1 ;
52+ end
53+
54+ % checking West neighbor
55+ if I1D(Wid(i ,j ,k ))==1
56+ ngbr1 = ngbr1 + 1 ;
57+ elseif I1D(Wid(i ,j ,k ))==2
58+ ngbr2 = ngbr2 + 1 ;
59+ end
60+
61+ % checking North neighbor
62+ if I1D(Nid(i ,j ,k ))==1
63+ ngbr1 = ngbr1 + 1 ;
64+ elseif I1D(Nid(i ,j ,k ))==2
65+ ngbr2 = ngbr2 + 1 ;
66+ end
67+
68+ % checking South neighbor
69+ if I1D(Sid(i ,j ,k ))==1
70+ ngbr1 = ngbr1 + 1 ;
71+ elseif I1D(Sid(i ,j ,k ))==2
72+ ngbr2 = ngbr2 + 1 ;
73+ end
74+
75+ % checking Upper neighbor
76+ if I1D(Uid(i ,j ,k ))==1
77+ ngbr1 = ngbr1 + 1 ;
78+ elseif I1D(Uid(i ,j ,k ))==2
79+ ngbr2 = ngbr2 + 1 ;
80+ end
81+
82+ % checking Lower neighbor
83+ if I1D(Lid(i ,j ,k ))==1
84+ ngbr1 = ngbr1 + 1 ;
85+ elseif I1D(Lid(i ,j ,k ))==2
86+ ngbr2 = ngbr2 + 1 ;
87+ end
88+
89+ % if there are solid neighbors, qualifies as a candidate voxel
90+ if (ngbr1 + ngbr2 )>0
91+ Ncandidate = Ncandidate + 1 ;
92+ Qid(Ncandidate ) = Pid(i ,j ,k ); % index of candidate voxel
93+ Energy(Ncandidate ) = (ngbr2 * w / normalize_energy ) + (ngbr1 *(1 - w )/normalize_energy ); % eneregy gain with deposition
94+ if Ncandidate > 1
95+ cumEnergy(Ncandidate ) = cumEnergy(Ncandidate - 1 ) + Energy(Ncandidate );
96+ else
97+ cumEnergy(Ncandidate ) = Energy(Ncandidate );
98+ end
99+ end
100+ end
101+ end
102+ end
103+ end
104+
105+ % selecting deposition voxels based on energy map _________________________
106+ % Selected_energy = zeros(Nsimultaneous,1) - 1;
107+ for m= 1 : Nsimultaneous
108+ target_cumEnergy = cumEnergy(Ncandidate )*rand();
109+
110+ for n= 2 : Ncandidate
111+ if ((target_cumEnergy > cumEnergy(n - 1 )) && (target_cumEnergy <= cumEnergy(n )))
112+ I1D(Qid(n )) = 2 ;
113+ % Selected_energy(m,1) = Energy(n);
114+ break ;
115+ end
116+ end
117+ end
118+ % Selected_energy( Selected_energy==-1) = []; % Remove non assigned value
119+ % mean(Selected_energy) / mean(Energy) % > 1 means selected voxel on average have higher than average energy deposition
120+
121+
122+ % converting back to 3D 'I' matrix ________________________________________
123+ % for k=1:Nz
124+ % for j=1:Ny
125+ % for i=1:Nx
126+ % I(i,j,k) = I1D(Pid(i,j,k));
127+ % end
128+ % end
129+ % end
130+ I = I1D(Pid );
131+
132+ end
0 commit comments