├── README.md └── dream2abahex.m /README.md: -------------------------------------------------------------------------------- 1 | ## dream2abahex.m 2 | 3 | MATLAB script to write ABAQUS hexahedral mesh for a given Dream.3D microstructure grid 4 | 5 | The script 6 | 7 | - Reads grid information from a text file generated in Dream.3D 8 | - Wriites ABAQUS hexahedral (C3D8) mesh to an inp file 9 | - Writes Euler angles for each element to a text file 10 | 11 | Read more about the script [here](https://latmarat.github.io/blog/dream2abahex/) 12 | 13 | ![Comparison of phases](https://farm6.staticflickr.com/5822/21680572513_8eec239e12_o_d.png) 14 | -------------------------------------------------------------------------------- /dream2abahex.m: -------------------------------------------------------------------------------- 1 | function dream2abahex(voxFileName, inpFileName) 2 | % *dream2abahex* generates ABAQUS input file 3 | % containing C3D8 (brick) mesh and a text file with 4 | % grain orientations of a microstructure synthesized 5 | % in Dream.3D by reading Los Alamos FFT file 6 | % 7 | % % Syntax 8 | % dream2abahex(voxFileName, inpFileName) 9 | % 10 | % % Input 11 | % voxFileName - full path to Los Alamos FFT file written by Dream.3D 12 | % inpFileName - desired path to Abaqus input file 13 | % % Example: 14 | % dream2abahex('dp_64x64x64.vox', 'dp_64x64x64-aba.inp') 15 | % 16 | % % Result 17 | % ABAQUS input file containing C3D8 mesh with 18 | % - element sets with individual phases 19 | % - sections with individual phases 20 | % - element sets with grains 21 | % - node sets of faces for easier assignment of BCs 22 | % and orientations (tex) file containing 23 | % Euler angle sets for each element in the mesh 24 | % 25 | % Read more at http://latmarat.net/blog/scripts/dream2abahex/ 26 | 27 | % -------------------------- 28 | % written by 29 | % Marat I. Latypov while at POSTECH 30 | % latmarat@postech.edu 31 | % September 2014 32 | % -------------------------- 33 | 34 | tic 35 | %% Digest data from Los Alamos FFT file generated in Dream.3D 36 | 37 | % open FFT file 38 | fid = fopen(voxFileName,'rt'); 39 | rawData = textscan(fid, '%f %f %f %f %f %f %d %d','delimiter',' '); 40 | fclose(fid); 41 | 42 | % load euler angles, coordinates, grain and phase IDs 43 | euler = cell2mat(rawData(1:3)); 44 | xyz = cell2mat(rawData(4:6)); 45 | grains = cell2mat(rawData(7)); 46 | phases = cell2mat(rawData(8)); 47 | [~,order] = sortrows(xyz,[1,3,2]); 48 | 49 | % reorder grain IDs, phase IDs, and Euler angles according to abaqus convention 50 | grains = grains(order); 51 | phases = phases(order); 52 | euler = euler(order,:); 53 | 54 | % get the number of vox along x, y, z 55 | xVox = size(unique(xyz(:,1)),1); 56 | yVox = size(unique(xyz(:,2)),1); 57 | zVox = size(unique(xyz(:,3)),1); 58 | 59 | % get step size and boundaries for the mesh 60 | step = zeros(1,3); 61 | boxmin = zeros(1,3); 62 | boxmax = zeros(1,3); 63 | for ii = 1:3 64 | step(ii) = min(diff(unique(xyz(:,ii)))); 65 | boxmin(ii) = xyz(1,ii)-step(ii)/2; 66 | boxmax(ii) = xyz(end,ii)+step(ii)/2; 67 | end 68 | 69 | %% Generate 3D mesh 70 | % generate nodes 71 | [x,y,z] = meshgrid(boxmin(1):step(1):boxmax(1),boxmin(2):step(2):boxmax(2),boxmin(3):step(3):boxmax(3)); 72 | numNodes = numel(x); 73 | coord = [reshape(x,numNodes,1), reshape(y,numNodes,1), reshape(z,numNodes,1)]; 74 | nodes = [(1:numNodes)', sortrows(coord,[1,3,2])]; 75 | 76 | % allocate array for elements 77 | elem = zeros(size(xyz,1),9); 78 | count = 1; 79 | 80 | % start loop over voxel dimensions 81 | for ix = 1:xVox 82 | for iz = 1:zVox 83 | for iy = 1:yVox 84 | 85 | % get element label 86 | elem(count,1) = count; 87 | 88 | % nodes on the plane with lower x 89 | elem(count,2) = iy + (iz-1)*(yVox+1) + (ix-1)*(yVox+1)*(zVox+1); 90 | elem(count,3) = elem(count,2) + 1; 91 | elem(count,4) = elem(count,3) + yVox + 1; 92 | elem(count,5) = elem(count,2) + yVox + 1; 93 | 94 | % nodes on the plane with higher x 95 | elem(count,6) = iy + (iz-1)*(yVox+1) + ix*(yVox+1)*(zVox+1); 96 | elem(count,7) = elem(count,6) + 1; 97 | elem(count,8) = elem(count,7) + yVox + 1; 98 | elem(count,9) = elem(count,6) + yVox + 1; 99 | 100 | count = count+1; 101 | end 102 | end 103 | end 104 | 105 | %% Write inp file 106 | % open inp file and write keywords 107 | inpFile = fopen(inpFileName,'wt'); 108 | fprintf(inpFile,'** Generated by: dream2abahex.m\n'); 109 | fprintf(inpFile,'**PARTS\n**\n'); 110 | fprintf(inpFile,'*Part, name=DREAM\n'); 111 | 112 | % write nodes 113 | fprintf(inpFile,'*NODE, NSET=AllNodes\n'); 114 | fprintf(inpFile,'%d,\t%e,\t%e, \t%e\n',nodes'); 115 | 116 | % write elements 117 | fprintf(inpFile,'*Element, type=C3D8, ELSET=AllElements\n'); 118 | fprintf(inpFile,'%d,\t%d,\t%d,\t%d,\t%d,\t%d,\t%d,\t%d,\t%d\n',elem'); 119 | 120 | % create element sets containing grains 121 | for ii = 1:numel(unique(grains)) 122 | fprintf(inpFile,'\n*Elset, elset=Grain-%d\n',ii); 123 | fprintf(inpFile,'%d, %d, %d, %d, %d, %d, %d, %d, %d\n',elem(grains==ii)'); 124 | end 125 | 126 | % create element sets containing phases 127 | uniPhases = unique(phases); 128 | for ii = 1:numel(unique(phases)) 129 | fprintf(inpFile,'\n*Elset, elset=Phase-%d\n',ii); 130 | fprintf(inpFile,'%d, %d, %d, %d, %d, %d, %d, %d, %d\n',elem(phases==uniPhases(ii))'); 131 | end 132 | 133 | % create sections for phases 134 | for ii = 1:numel(uniPhases) 135 | fprintf(inpFile,'\n**Section: Section_Phase-%d\n*Solid Section, elset=Phase-%d, material=Phase-%d\n',ii,ii,ii); 136 | fprintf(inpFile,'%d, %d, %d, %d, %d, %d, %d, %d, %d\n',elem(phases==uniPhases(ii))'); 137 | end 138 | fprintf(inpFile,'\n'); 139 | 140 | % create node sets containing surface nodes for BCs 141 | for ii = 1:3 142 | fprintf(inpFile,'\n**\n*Nset, nset=NODES-%d\n',ii); 143 | fprintf(inpFile,'%d, %d, %d, %d, %d, %d, %d, %d, %d\n',nodes(nodes(:,ii+1)==boxmin(ii))'); 144 | fprintf(inpFile,'\n**\n*Nset, nset=NODES+%d\n',ii); 145 | fprintf(inpFile,'%d, %d, %d, %d, %d, %d, %d, %d, %d\n',nodes(nodes(:,ii+1)==boxmax(ii))'); 146 | end 147 | 148 | % write a closing keyword 149 | fprintf(inpFile,'\n**\n*End Part\n'); 150 | 151 | % close the file 152 | fclose(inpFile); 153 | 154 | 155 | %% Write aeuler file 156 | [inpFileDir,fileName,fileExt] = fileparts(inpFileName); 157 | if strcmp(inpFileDir,'') == 0 158 | eulFileName = [inpFileDir '\' fileName '.tex']; 159 | else 160 | eulFileName = [fileName '.tex']; 161 | end 162 | eulFile = fopen(eulFileName,'wt'); 163 | 164 | fprintf(eulFile,'# Euler angle sets (phi1, Phi, phi2) for C3D8 mesh in %s\n', [fileName fileExt]); 165 | fprintf(eulFile,'# Euler angle sets are sorted according to element labels\n'); 166 | fprintf(eulFile,'# 1 element in mesh - 1 set of Euler angles. Generated by dream2abahex.m\n'); 167 | fprintf(eulFile,'B\t%d\n', size(euler,1)); 168 | fprintf(eulFile,'%13.4f%13.4f%13.4f\n', euler'); 169 | fclose(inpFile); 170 | 171 | fprintf('***dream2abahex.m completed***\n'); 172 | fprintf('ABAQUS mesh is written to %s\n', inpFileName); 173 | fprintf('Orientations are written to %s\n', eulFileName); 174 | 175 | toc 176 | end 177 | --------------------------------------------------------------------------------