Line data Source code
1 : //* This file is part of the MOOSE framework 2 : //* https://mooseframework.inl.gov 3 : //* 4 : //* All rights reserved, see COPYRIGHT for full restrictions 5 : //* https://github.com/idaholab/moose/blob/master/COPYRIGHT 6 : //* 7 : //* Licensed under LGPL 2.1, please see LICENSE for details 8 : //* https://www.gnu.org/licenses/lgpl-2.1.html 9 : 10 : #include "EulerAngleProvider2RGBAux.h" 11 : #include "GrainTracker.h" 12 : #include "EulerAngleProvider.h" 13 : #include "Euler2RGB.h" 14 : #include "EBSDReader.h" 15 : 16 : registerMooseObject("PhaseFieldApp", EulerAngleProvider2RGBAux); 17 : 18 : InputParameters 19 174 : EulerAngleProvider2RGBAux::validParams() 20 : { 21 174 : InputParameters params = AuxKernel::validParams(); 22 174 : params.addClassDescription("Output RGB representation of crystal orientation from user object to " 23 : "an AuxVariable. The entire domain must have the same crystal " 24 : "structure."); 25 348 : params.addParam<unsigned int>("phase", "The phase to use for all queries."); 26 348 : MooseEnum sd_enum = MooseEnum("100=1 010=2 001=3", "001"); 27 348 : params.addParam<MooseEnum>("sd", sd_enum, "Reference sample direction"); 28 : MooseEnum structure_enum = MooseEnum( 29 348 : "cubic=43 hexagonal=62 tetragonal=42 trigonal=32 orthorhombic=22 monoclinic=2 triclinic=1"); 30 348 : params.addRequiredParam<MooseEnum>( 31 : "crystal_structure", structure_enum, "Crystal structure of the material"); 32 348 : MooseEnum output_types = MooseEnum("red green blue scalar", "scalar"); 33 348 : params.addParam<MooseEnum>("output_type", output_types, "Type of value that will be outputted"); 34 348 : params.addRequiredParam<UserObjectName>("euler_angle_provider", 35 : "Name of Euler angle provider user object"); 36 348 : params.addRequiredParam<UserObjectName>("grain_tracker", 37 : "The GrainTracker UserObject to get values from."); 38 174 : params.addParam<Point>( 39 : "no_grain_color", 40 174 : Point(0, 0, 0), 41 : "RGB value of color used to represent area with no grains, defaults to black"); 42 174 : return params; 43 174 : } 44 : 45 93 : EulerAngleProvider2RGBAux::EulerAngleProvider2RGBAux(const InputParameters & parameters) 46 : : AuxKernel(parameters), 47 165 : _phase(isParamValid("phase") ? getParam<unsigned int>("phase") : libMesh::invalid_uint), 48 186 : _sd(getParam<MooseEnum>("sd")), 49 186 : _xtal_class(getParam<MooseEnum>("crystal_structure")), 50 186 : _output_type(getParam<MooseEnum>("output_type")), 51 93 : _euler(getUserObject<EulerAngleProvider>("euler_angle_provider")), 52 186 : _ebsd_reader(isParamValid("phase") ? dynamic_cast<const EBSDReader *>(&_euler) : nullptr), 53 93 : _grain_tracker(dynamic_cast<const GrainTrackerInterface &>(getUserObjectBase("grain_tracker"))), 54 279 : _no_grain_color(getParam<Point>("no_grain_color")) 55 : { 56 93 : } 57 : 58 : unsigned int 59 145326 : EulerAngleProvider2RGBAux::getNumGrains() const 60 : { 61 145326 : if (_phase != libMesh::invalid_uint) 62 97617 : return _ebsd_reader->getGrainNum(_phase); 63 : else 64 47709 : return _euler.getGrainNum(); 65 : } 66 : 67 : void 68 157260 : EulerAngleProvider2RGBAux::precalculateValue() 69 : { 70 : const auto grain_id = 71 157260 : _grain_tracker.getEntityValue(isNodal() ? _current_node->id() : _current_elem->id(), 72 : FeatureFloodCount::FieldType::UNIQUE_REGION, 73 : 0); 74 : 75 : // Recover Euler angles for current grain and assign correct RGB value either 76 : // from Euler2RGB or from _no_grain_color 77 : Point RGB; 78 157260 : if (grain_id < 0) 79 11934 : RGB = _no_grain_color; 80 : else 81 : { 82 : /* The grain index retrieved from FeatureFloodCount is the "global_id" unless 83 : the "phase" option is used in the simulation. For the phase dependent case, 84 : the returned grain index is the "local_id." This must be converted to a 85 : "global_id" using the getGlobalID function of EBSDREader before the Euler 86 : Angles are retrieved. */ 87 : 88 : auto global_id = 89 145326 : _phase != libMesh::invalid_uint ? _ebsd_reader->getGlobalID(_phase, grain_id) : grain_id; 90 145326 : const auto num_grns = getNumGrains(); 91 145326 : if (global_id > num_grns) 92 0 : mooseError(" global_id ", global_id, " out of index range"); 93 : 94 : // Retrieve Euler Angle values from the EulerAngleProvider 95 145326 : const RealVectorValue & angles = _euler.getEulerAngles(global_id); 96 : 97 : // Convert Euler Angle values to RGB colorspace for visualization purposes 98 145326 : RGB = euler2RGB(_sd, 99 145326 : angles(0) / 180.0 * libMesh::pi, 100 145326 : angles(1) / 180.0 * libMesh::pi, 101 145326 : angles(2) / 180.0 * libMesh::pi, 102 : 1.0, 103 145326 : _xtal_class); 104 : } 105 : 106 : // Create correct scalar output 107 157260 : if (_output_type < 3) 108 157260 : _value = RGB(_output_type); 109 0 : else if (_output_type == 3) 110 : { 111 : Real RGBint = 0.0; 112 0 : for (unsigned int i = 0; i < 3; ++i) 113 0 : RGBint = 256 * RGBint + (RGB(i) >= 1 ? 255 : std::floor(RGB(i) * 256.0)); 114 0 : _value = RGBint; 115 : } 116 : else 117 0 : mooseError("Incorrect value for output_type in EulerAngleProvider2RGBAux"); 118 157260 : } 119 : 120 : Real 121 629040 : EulerAngleProvider2RGBAux::computeValue() 122 : { 123 629040 : return _value; 124 : }