Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ install(FILES "${CMAKE_CURRENT_BINARY_DIR}/ExaCAconfig.cmake"

# Install data files
file(GLOB MATERIALS examples/Materials/*)
file(GLOB SUBSTRATE examples/Substrate/GrainOrientation*.csv)
file(GLOB SUBSTRATE examples/Substrate/CrystalOrientation*.csv)
install(FILES ${MATERIALS}
DESTINATION ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_DATADIR}/ExaCA)
install(FILES ${SUBSTRATE}
Expand Down
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,9 @@ As detailed further in [examples/README.md](examples/README.md), ExaCA can print
| GrainID | All layers | A unique identifier for each grain in the ExaCA simulation. Positive numbers represent grains from either the initial substrate/baseplate or from a powder layer, while negative numbers represent grains formed via a nucleation event. GrainIDs of 0 are used to identify cells from a powder layer that do not have any associated material (i.e., voids or gas in the powder layer). Each GrainID is linked to a grain orientation through the substrate input file - GrainID = 1 or -1 is associated with the first orientation in the file, GrainID = 2 or -2 with the second orientatation, etc, with orientations reused when the number of grains exceeds the number of orientations in the file (for example, [examples/Substrate/`GrainOrientationVectors.csv](examples/Substrate/GrainOrientationVectors.csv) has 10,000 grain orientations, so a GrainID of 10,001 will share its orientation with the GrainID of 1).
| LayerID | All layers | The final (or most recent) layer in which a given cell undergoes/underwent melting and solidification. Layer numbers start at 0, with -1 used for cells that have not undergone melting/solidification.
| PhaseID | All layers | The solid phase associated with the most recent solidification in a cell. For single phase solidification problems, this will always be 0, while for two phase solidification problems, this will be 0 for cells that solidified as the primary phase and 1 for cells that solidified as the second phase
| GrainMisorientation | All layers | The orientation (in degrees) of the grain's nearest <100> direction to the Z axis (the thermal gradient direction for directional solidification problems, the build/layer offset direction for other problems). Epitaxial grains (from the initial grain structure or powder layer) are assigned (rounded) integer values between 0 and 55, while nucleated grains (not present in the initial grain structure) are assigned values between 100 and 155 (the offset of 100 is simply used to ensure the two types of grains are differentiated, but a nucleated grain with a value of 135 actually has <100> misoriented with Z by 35 degrees). All cells belonging to the same grain (same GrainID value) will have the same GrainMisorientation, as no intra-granular misorientations are currently simulated. Also of note is that for intermediate output files where liquid cells are present, these cells are assigned a value of -1, and that unmelted material (or non-existent material in a powder layer) is assigned a value of 200.
| CrystalMisorientationZ | All layers | The orientation (in degrees) of the grain's nearest <100> direction to the Z axis (the thermal gradient direction for directional solidification problems, the build/layer offset direction for other problems). Epitaxial grains (from the initial grain structure or powder layer) are assigned (rounded) integer values between 0 and 55, while nucleated grains (not present in the initial grain structure) are assigned values between 100 and 155 (the offset of 100 is simply used to ensure the two types of grains are differentiated, but a nucleated grain with a value of 135 actually has <100> misoriented with Z by 35 degrees). All cells belonging to the same grain (same GrainID value) will have the same GrainMisorientation, as no intra-granular misorientations are currently simulated. Also of note is that for intermediate output files where liquid cells are present, these cells are assigned a value of -1, and that unmelted material (or non-existent material in a powder layer) is assigned a value of 200.
| CrystalMisorientationY | All layers | The orientation (in degrees) of the grain's nearest <100> direction to the Y axis
| CrystalMisorientationX | All layers | The orientation (in degrees) of the grain's nearest <100> direction to the X axis
| UndercoolingCurrent | All layers | The current undercooling of a cell (if liquid or active), or the undercooling when a cell was most recently active (if solid). Superheated liquid cells or cells that have not undergone melting and solidification will have a value of 0.
| UndercoolingSolidificationStart | All layers | For cells that are currently undergoing solidification or have finished solidification, the undercooling when solidification started. Will have a value of 0 for all other cells
| MeltPoolEdge | All layers | Value of 1 for cells that were at the edge of the time-temperature history data and converted to active cells, value of 0 for all other cells including cells that became active via a cell capture or nucleation event
Expand Down
25 changes: 13 additions & 12 deletions analysis/bin/runGA.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -117,15 +117,16 @@ int main(int argc, char *argv[]) {
found_layer_id);

// Calculate and if specified, print misorientation data
std::vector<float> grain_misorientation_x_vector =
representativeregion.getGrainMisorientation("X", orientation);
std::vector<float> grain_misorientation_y_vector =
representativeregion.getGrainMisorientation("Y", orientation);
std::vector<float> grain_misorientation_z_vector =
representativeregion.getGrainMisorientation("Z", orientation);
std::vector<float> crystal_misorientation_x_vector =
representativeregion.getCrystalMisorientation("X", orientation);
std::vector<float> crystal_misorientation_y_vector =
representativeregion.getCrystalMisorientation("Y", orientation);
std::vector<float> crystal_misorientation_z_vector =
representativeregion.getCrystalMisorientation("Z", orientation);
if (representativeregion.analysis_options_stats_yn[1])
representativeregion.printMeanMisorientations(
qois, grain_misorientation_x_vector, grain_misorientation_y_vector, grain_misorientation_z_vector);
representativeregion.printMeanMisorientations(qois, crystal_misorientation_x_vector,
crystal_misorientation_y_vector,
crystal_misorientation_z_vector);

// Print mean size data if specified
if (representativeregion.analysis_options_stats_yn[2])
Expand Down Expand Up @@ -165,9 +166,9 @@ int main(int argc, char *argv[]) {
// Write per-grain stats for the analysis types specified to the file
// "[base_filename_this_region]_grains.csv"
if (representativeregion.print_per_grain_stats_yn)
representativeregion.writePerGrainStats(base_filename_this_region, grain_misorientation_x_vector,
grain_misorientation_y_vector, grain_misorientation_z_vector,
build_trans_aspect_ratio, grain_red, grain_green, grain_blue);
representativeregion.writePerGrainStats(
base_filename_this_region, crystal_misorientation_x_vector, crystal_misorientation_y_vector,
crystal_misorientation_z_vector, build_trans_aspect_ratio, grain_red, grain_green, grain_blue);

// ExaConstit print a file named "[base_filename_this_region]_ExaConstit.csv"
if (representativeregion.print_exaconstit_yn) {
Expand All @@ -177,7 +178,7 @@ int main(int argc, char *argv[]) {
// Pole figure print a file named "[base_filename_this_region]_PoleFigureData.txt"
if (representativeregion.print_pole_figure_yn) {
auto go_histogram = representativeregion.getOrientationHistogram(
orientation.n_grain_orientations, grain_id, layer_id, phase_id, num_phases, found_layer_id);
orientation.n_crystal_orientations, grain_id, layer_id, phase_id, num_phases, found_layer_id);
representativeregion.writePoleFigure(base_filename_this_region, orientation, go_histogram);
}

Expand Down
65 changes: 33 additions & 32 deletions analysis/src/GArepresentativeregion.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -455,11 +455,12 @@ struct RepresentativeRegion {
}
}

// Calculate misorientation relative to the specified cardinal direction for each grain and store in the vector
// Calculate <100> misorientation relative to the specified cardinal direction for each grain and store in the
// vector
template <typename MemorySpace>
std::vector<float> getGrainMisorientation(std::string direction, Orientation<MemorySpace> &orientation) {
std::vector<float> getCrystalMisorientation(std::string direction, Orientation<MemorySpace> &orientation) {

std::vector<float> grain_misorientation_vector(number_of_grains);
std::vector<float> crystal_misorientation_vector(number_of_grains);
int direction_int;
if (direction == "X")
direction_int = 0;
Expand All @@ -469,22 +470,22 @@ struct RepresentativeRegion {
direction_int = 2;
else
throw std::runtime_error(
"Error: invalid direction specified in calcGrainMisorientation: should be X, Y, or Z");
auto grain_misorientation = orientation.misorientationCalc(direction_int);
"Error: invalid direction specified in calcCrystalMisorientation: should be X, Y, or Z");
auto crystal_misorientation = orientation.misorientationCalc(direction_int);
for (int n = 0; n < number_of_grains; n++) {
int my_orientation = getGrainOrientation(unique_grain_id_vector[n], orientation.n_grain_orientations);
int my_orientation = getCrystalOrientation(unique_grain_id_vector[n], orientation.n_crystal_orientations);
// Grain misorientation always corresponds to phase 0, even if original crystallographic orientation during
// initial solidification as phase 1 was different
float my_misorientation = grain_misorientation(my_orientation, 0);
grain_misorientation_vector[n] = my_misorientation;
float my_misorientation = crystal_misorientation(my_orientation, 0);
crystal_misorientation_vector[n] = my_misorientation;
}
return grain_misorientation_vector;
return crystal_misorientation_vector;
}

// Create a histogram of orientations for texture determination, using the grain_id values in the volume bounded by
// [XMin,XMax], [YMin,YMax], [ZMin,ZMax] and excluding and cells that did not undergo melting (layer_id = -1)
template <typename ViewTypeInt3dHost, typename ViewTypeShort3dHost>
auto getOrientationHistogram(int n_grain_orientations, ViewTypeInt3dHost grain_id, ViewTypeShort3dHost layer_id,
auto getOrientationHistogram(int n_crystal_orientations, ViewTypeInt3dHost grain_id, ViewTypeShort3dHost layer_id,
ViewTypeShort3dHost phase_id, const int num_phases, bool found_layer_id) {

// Init histogram values to zero
Expand All @@ -494,14 +495,14 @@ struct RepresentativeRegion {
"melting and solidification as they cannot be differentiated from the regions that were simulated"
<< std::endl;
using int_type = typename ViewTypeInt3dHost::value_type;
Kokkos::View<int_type **, Kokkos::HostSpace> go_histogram("go_histogram", n_grain_orientations, num_phases);
Kokkos::View<int_type **, Kokkos::HostSpace> go_histogram("go_histogram", n_crystal_orientations, num_phases);
for (int phase_num = 0; phase_num < num_phases; phase_num++) {
for (int k = z_bounds_cells[0]; k <= z_bounds_cells[1]; k++) {
for (int j = y_bounds_cells[0]; j <= y_bounds_cells[1]; j++) {
for (int i = x_bounds_cells[0]; i <= x_bounds_cells[1]; i++) {
if ((grain_id(k, i, j) != 0) && (layer_id(k, i, j) != -1)) {
short my_phase = phase_id(k, i, j);
int go_val = getGrainOrientation(grain_id(k, i, j), n_grain_orientations);
int go_val = getCrystalOrientation(grain_id(k, i, j), n_crystal_orientations);
go_histogram(go_val, my_phase)++;
}
}
Expand Down Expand Up @@ -632,24 +633,24 @@ struct RepresentativeRegion {
}

// Print average misorientation for the region relative to each direction
void printMeanMisorientations(std::ofstream &qois, std::vector<float> grain_misorientation_x_vector,
std::vector<float> grain_misorientation_y_vector,
std::vector<float> grain_misorientation_z_vector) {
void printMeanMisorientations(std::ofstream &qois, std::vector<float> crystal_misorientation_x_vector,
std::vector<float> crystal_misorientation_y_vector,
std::vector<float> crystal_misorientation_z_vector) {

std::vector<std::string> misorientation_direction_labels = {"misorientationX", "misorientationY",
"misorientationZ"};
std::vector<std::string> misorientation_direction_labels_short = {"+X", "+Y", "+Z"};
float grain_misorientation_sum_x = 0.0;
float grain_misorientation_sum_y = 0.0;
float grain_misorientation_sum_z = 0.0;
float crystal_misorientation_sum_x = 0.0;
float crystal_misorientation_sum_y = 0.0;
float crystal_misorientation_sum_z = 0.0;
for (int n = 0; n < number_of_grains; n++) {
grain_misorientation_sum_x += grain_misorientation_x_vector[n] * grain_size_vector_microns[n];
grain_misorientation_sum_y += grain_misorientation_y_vector[n] * grain_size_vector_microns[n];
grain_misorientation_sum_z += grain_misorientation_z_vector[n] * grain_size_vector_microns[n];
crystal_misorientation_sum_x += crystal_misorientation_x_vector[n] * grain_size_vector_microns[n];
crystal_misorientation_sum_y += crystal_misorientation_y_vector[n] * grain_size_vector_microns[n];
crystal_misorientation_sum_z += crystal_misorientation_z_vector[n] * grain_size_vector_microns[n];
}
float avg_misorientation_x = divideCast<float>(grain_misorientation_sum_x, region_size_microns);
float avg_misorientation_y = divideCast<float>(grain_misorientation_sum_y, region_size_microns);
float avg_misorientation_z = divideCast<float>(grain_misorientation_sum_z, region_size_microns);
float avg_misorientation_x = divideCast<float>(crystal_misorientation_sum_x, region_size_microns);
float avg_misorientation_y = divideCast<float>(crystal_misorientation_sum_y, region_size_microns);
float avg_misorientation_z = divideCast<float>(crystal_misorientation_sum_z, region_size_microns);
std::string temp;
temp = "-- Average misorientation (weighted by size) for grains relative to the X direction (in degrees): " +
std::to_string(avg_misorientation_x) + "\n";
Expand Down Expand Up @@ -806,7 +807,7 @@ struct RepresentativeRegion {
grainplot_pf << "% specimen symmetry: \"43\"" << std::endl;
grainplot_pf << "% phi1 Phi phi2 value" << std::endl;
grainplot_pf << std::fixed << std::setprecision(6);
for (int i = 0; i < orientation.n_grain_orientations; i++) {
for (int i = 0; i < orientation.n_crystal_orientations; i++) {
grainplot_pf << orientation.grain_bunge_euler_host(3 * i, 0) << " "
<< orientation.grain_bunge_euler_host(3 * i + 1, 0) << " "
<< orientation.grain_bunge_euler_host(3 * i + 2, 0) << " "
Expand All @@ -832,7 +833,7 @@ struct RepresentativeRegion {
std::vector<float> getIPFZColor(int color, Orientation<MemorySpace> &orientation) {
std::vector<float> ipfz_color(number_of_grains);
for (int n = 0; n < number_of_grains; n++) {
int my_orientation = getGrainOrientation(unique_grain_id_vector[n], orientation.n_grain_orientations);
int my_orientation = getCrystalOrientation(unique_grain_id_vector[n], orientation.n_crystal_orientations);
ipfz_color[n] = orientation.grain_rgb_ipfz_host(3 * my_orientation + color, 0);
}
return ipfz_color;
Expand Down Expand Up @@ -898,7 +899,7 @@ struct RepresentativeRegion {
throw std::runtime_error("Error: Unknown region_orientation input for WriteIPFColoredCrossSection: "
"should be XY, YZ, or XZ");
// What orientation does this grain id correspond to? Should be between 0 and NumberOfOrientations-1
int go_val = (Kokkos::abs(grain_id(z_loc, x_loc, y_loc)) - 1) % orientation.n_grain_orientations;
int go_val = (Kokkos::abs(grain_id(z_loc, x_loc, y_loc)) - 1) % orientation.n_crystal_orientations;
// Unlike the vtk data which was zero-indexed (the two solid phase ids were 0 and 1), the grain
// structure used by MTEX is phase "1" or "2" - any unindexed points with GOVal = -1 (which are possible
// from regions that didn't undergo melting) are assigned phase "0"
Expand Down Expand Up @@ -949,9 +950,9 @@ struct RepresentativeRegion {
}

// Write a csv file of stats for each grain
void writePerGrainStats(std::string output_filename, std::vector<float> grain_misorientation_x_vector,
std::vector<float> grain_misorientation_y_vector,
std::vector<float> grain_misorientation_z_vector,
void writePerGrainStats(std::string output_filename, std::vector<float> crystal_misorientation_x_vector,
std::vector<float> crystal_misorientation_y_vector,
std::vector<float> crystal_misorientation_z_vector,
std::vector<float> build_trans_aspect_ratio, std::vector<float> grain_red,
std::vector<float> grain_green, std::vector<float> grain_blue) {

Expand Down Expand Up @@ -981,8 +982,8 @@ struct RepresentativeRegion {
for (int n = 0; n < number_of_grains; n++) {
grain_stats << unique_grain_id_vector[n];
if (analysis_options_per_grain_stats_yn[0])
grain_stats << "," << grain_misorientation_x_vector[n] << "," << grain_misorientation_y_vector[n] << ","
<< grain_misorientation_z_vector[n];
grain_stats << "," << crystal_misorientation_x_vector[n] << "," << crystal_misorientation_y_vector[n]
<< "," << crystal_misorientation_z_vector[n];
if (analysis_options_per_grain_stats_yn[1])
grain_stats << "," << grain_size_vector_microns[n];
if (analysis_options_per_grain_stats_yn[2])
Expand Down
Loading
Loading