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 "FauxGrainTracker.h" 11 : 12 : // MOOSE includes 13 : #include "MooseMesh.h" 14 : #include "MooseVariable.h" 15 : #include "Assembly.h" 16 : 17 : registerMooseObject("PhaseFieldApp", FauxGrainTracker); 18 : 19 : InputParameters 20 110 : FauxGrainTracker::validParams() 21 : { 22 110 : InputParameters params = GrainTrackerInterface::validParams(); 23 110 : params.addClassDescription("Fake grain tracker object for cases where the number of grains is " 24 : "equal to the number of order parameters."); 25 : 26 110 : return params; 27 0 : } 28 : 29 55 : FauxGrainTracker::FauxGrainTracker(const InputParameters & parameters) 30 : : FeatureFloodCount(parameters), 31 : GrainTrackerInterface(), 32 55 : _grain_count(0), 33 55 : _n_vars(_vars.size()), 34 110 : _tracking_step(getParam<int>("tracking_step")) 35 : { 36 : // initialize faux data with identity map 37 55 : _op_to_grains.resize(_n_vars); 38 363 : for (MooseIndex(_op_to_grains) i = 0; i < _op_to_grains.size(); ++i) 39 308 : _op_to_grains[i] = i; 40 : 41 55 : _empty_var_to_features.resize(_n_vars, FeatureFloodCount::invalid_id); 42 55 : } 43 : 44 275 : FauxGrainTracker::~FauxGrainTracker() {} 45 : 46 : Real 47 121954 : FauxGrainTracker::getEntityValue(dof_id_type entity_id, 48 : FeatureFloodCount::FieldType field_type, 49 : std::size_t var_idx) const 50 : { 51 : if (var_idx == FeatureFloodCount::invalid_size_t) 52 : var_idx = 0; 53 : 54 : mooseAssert(var_idx < _n_vars, "Index out of range"); 55 : 56 121954 : switch (field_type) 57 : { 58 114479 : case FieldType::UNIQUE_REGION: 59 : case FieldType::VARIABLE_COLORING: 60 : { 61 : auto entity_it = _entity_id_to_var_num.find(entity_id); 62 : 63 114479 : if (entity_it != _entity_id_to_var_num.end()) 64 85024 : return entity_it->second; 65 : else 66 : return -1; 67 : break; 68 : } 69 : 70 7475 : case FieldType::CENTROID: 71 : { 72 7475 : if (_periodic_node_map.size()) 73 0 : mooseDoOnce(mooseWarning( 74 : "Centroids are not correct when using periodic boundaries, contact the MOOSE team")); 75 : 76 : // If this element contains the centroid of one of features, return it's index 77 7475 : const auto * elem_ptr = _mesh.elemPtr(entity_id); 78 17459 : for (MooseIndex(_vars) var_num = 0; var_num < _n_vars; ++var_num) 79 : { 80 10049 : const auto centroid = _centroid.find(var_num); 81 10049 : if (centroid != _centroid.end()) 82 10049 : if (elem_ptr->contains_point(centroid->second)) 83 : return 1; 84 : } 85 : 86 : return 0; 87 : } 88 : 89 : // We don't want to error here because this should be a drop in replacement for the real grain 90 : // tracker. 91 : // Instead we'll just return zero and continue 92 : default: 93 : return 0; 94 : } 95 : 96 : return 0; 97 : } 98 : 99 : const std::vector<unsigned int> & 100 501325 : FauxGrainTracker::getVarToFeatureVector(dof_id_type elem_id) const 101 : { 102 : const auto pos = _entity_var_to_features.find(elem_id); 103 501325 : if (pos != _entity_var_to_features.end()) 104 : { 105 : mooseAssert(pos->second.size() == _n_vars, "Variable to feature vector not sized properly"); 106 501325 : return pos->second; 107 : } 108 : else 109 0 : return _empty_var_to_features; 110 : } 111 : 112 : unsigned int 113 51 : FauxGrainTracker::getFeatureVar(unsigned int feature_id) const 114 : { 115 51 : return feature_id; 116 : } 117 : 118 : std::size_t 119 0 : FauxGrainTracker::getNumberActiveGrains() const 120 : { 121 0 : return _variables_used.size(); 122 : } 123 : 124 : std::size_t 125 194 : FauxGrainTracker::getTotalFeatureCount() const 126 : { 127 194 : return _grain_count; 128 : } 129 : 130 : Point 131 8121876 : FauxGrainTracker::getGrainCentroid(unsigned int grain_index) const 132 : { 133 : const auto grain_center = _centroid.find(grain_index); 134 : mooseAssert(grain_center != _centroid.end(), 135 : "Grain " << grain_index << " does not exist in data structure"); 136 : 137 8121876 : return grain_center->second; 138 : } 139 : 140 : void 141 100 : FauxGrainTracker::initialize() 142 : { 143 : _entity_id_to_var_num.clear(); 144 : _entity_var_to_features.clear(); 145 : _variables_used.clear(); 146 100 : if (_is_elemental) 147 : { 148 : _volume.clear(); 149 : _vol_count.clear(); 150 : _centroid.clear(); 151 : } 152 100 : } 153 : 154 : void 155 100 : FauxGrainTracker::execute() 156 : { 157 200 : TIME_SECTION("execute", 2, "Executing grain tracker"); 158 : 159 266722 : for (const auto & current_elem : _mesh.getMesh().active_local_element_ptr_range()) 160 : { 161 : // Loop over elements or nodes and populate the data structure with the first variable with a 162 : // value above a threshold 163 133261 : if (_is_elemental) 164 : { 165 121386 : std::vector<Point> centroid(1, current_elem->vertex_average()); 166 121386 : _fe_problem.reinitElemPhys(current_elem, centroid, 0); 167 : 168 121386 : auto entity = current_elem->id(); 169 : auto insert_pair = 170 121386 : moose_try_emplace(_entity_var_to_features, 171 : entity, 172 242772 : std::vector<unsigned int>(_n_vars, FeatureFloodCount::invalid_id)); 173 : auto & vec_ref = insert_pair.first->second; 174 : 175 306378 : for (MooseIndex(_vars) var_num = 0; var_num < _n_vars; ++var_num) 176 : { 177 302101 : auto entity_value = _vars[var_num]->sln()[0]; 178 : 179 302101 : if ((_use_less_than_threshold_comparison && (entity_value >= _threshold)) || 180 0 : (!_use_less_than_threshold_comparison && (entity_value <= _threshold))) 181 : { 182 117109 : _entity_id_to_var_num[current_elem->id()] = var_num; 183 117109 : _variables_used.insert(var_num); 184 117109 : _volume[var_num] += _assembly.elementVolume(current_elem); 185 117109 : _vol_count[var_num]++; 186 : // Sum the centroid values for now, we'll average them later 187 117109 : _centroid[var_num] += current_elem->vertex_average(); 188 117109 : vec_ref[var_num] = var_num; 189 117109 : break; 190 : } 191 : } 192 121386 : } 193 : else 194 : { 195 11875 : unsigned int n_nodes = current_elem->n_vertices(); 196 59375 : for (unsigned int i = 0; i < n_nodes; ++i) 197 : { 198 47500 : const Node * current_node = current_elem->node_ptr(i); 199 : 200 242270 : for (MooseIndex(_vars) var_num = 0; var_num < _n_vars; ++var_num) 201 : { 202 241802 : auto entity_value = _vars[var_num]->getNodalValue(*current_node); 203 241802 : if ((_use_less_than_threshold_comparison && (entity_value >= _threshold)) || 204 0 : (!_use_less_than_threshold_comparison && (entity_value <= _threshold))) 205 : { 206 47032 : _entity_id_to_var_num[current_node->id()] = var_num; 207 47032 : _variables_used.insert(var_num); 208 47032 : break; 209 : } 210 : } 211 : } 212 : } 213 100 : } 214 : 215 148 : _grain_count = std::max(_grain_count, _variables_used.size()); 216 100 : } 217 : 218 : void 219 100 : FauxGrainTracker::finalize() 220 : { 221 200 : TIME_SECTION("finalize", 2, "Finalizing grain tracker"); 222 : 223 100 : _communicator.set_union(_variables_used); 224 100 : _communicator.set_union(_entity_id_to_var_num); 225 : 226 100 : if (_is_elemental) 227 474 : for (MooseIndex(_vars) var_num = 0; var_num < _n_vars; ++var_num) 228 : { 229 : /** 230 : * Convert elements of the maps into simple values or vector of Real. 231 : * libMesh's _communicator.sum() does not work on std::maps 232 : */ 233 : unsigned int vol_count; 234 399 : std::vector<Real> grain_data(4); 235 : 236 399 : const auto count = _vol_count.find(var_num); 237 399 : if (count != _vol_count.end()) 238 385 : vol_count = count->second; 239 : 240 399 : const auto vol = _volume.find(var_num); 241 399 : if (vol != _volume.end()) 242 385 : grain_data[0] = vol->second; 243 : 244 399 : const auto centroid = _centroid.find(var_num); 245 399 : if (centroid != _centroid.end()) 246 : { 247 385 : grain_data[1] = centroid->second(0); 248 385 : grain_data[2] = centroid->second(1); 249 385 : grain_data[3] = centroid->second(2); 250 : } 251 : // combine centers & volumes from all MPI ranks 252 : gatherSum(vol_count); 253 : gatherSum(grain_data); 254 399 : _volume[var_num] = grain_data[0]; 255 399 : _centroid[var_num] = {grain_data[1], grain_data[2], grain_data[3]}; 256 399 : _centroid[var_num] /= vol_count; 257 399 : } 258 100 : } 259 : 260 : Real 261 100 : FauxGrainTracker::getValue() const 262 : { 263 100 : return static_cast<Real>(_variables_used.size()); 264 : } 265 : 266 : bool 267 51 : FauxGrainTracker::doesFeatureIntersectBoundary(unsigned int /*feature_id*/) const 268 : { 269 51 : mooseDoOnce(mooseWarning("FauxGrainTracker::doesFeatureIntersectboundary() is unimplemented")); 270 : 271 51 : return false; 272 : }