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 : #pragma once 11 : 12 : // MOOSE includes 13 : #include "GeneralVectorPostprocessor.h" 14 : #include "SamplerBase.h" 15 : #include "BlockRestrictable.h" 16 : #include "Assembly.h" 17 : #include "MooseMesh.h" 18 : #include "SwapBackSentinel.h" 19 : #include "FEProblem.h" 20 : 21 : // libMesh includes 22 : #include "libmesh/quadrature.h" 23 : 24 : // Forward Declarations 25 : class MooseMesh; 26 : 27 : /** 28 : * This is a base class for sampling material properties for the 29 : * integration points in all elements in a block of a 1-D mesh. 30 : * The positions of those points are output in x, y, z coordinates. 31 : * Derived classes can be created to sample arbitrary types of 32 : * material properties. 33 : */ 34 : template <typename T> 35 : class Sampler1DBase : public GeneralVectorPostprocessor, 36 : public SamplerBase, 37 : public BlockRestrictable 38 : { 39 : public: 40 : /** 41 : * Class constructor 42 : * Sets up variables for output based on the properties to be output 43 : * @param parameters The input parameters 44 : */ 45 : Sampler1DBase(const InputParameters & parameters); 46 : 47 : /** 48 : * Initialize 49 : * Calls through to base class's initialize() 50 : */ 51 : virtual void initialize() override; 52 : 53 : /** 54 : * Loops through all elements in a block and samples their material properties. 55 : */ 56 : virtual void execute() override; 57 : 58 : /** 59 : * Finalize 60 : * Calls through to base class's finalize() 61 : */ 62 : virtual void finalize() override; 63 : 64 : /** 65 : * Reduce the material property to a scalar for output 66 : * @param property The material property 67 : * @param curr_point The point corresponding to this material property 68 : * @return A scalar value from this material property to be output 69 : */ 70 : virtual Real getScalarFromProperty(const T & property, const Point & curr_point) = 0; 71 : 72 : protected: 73 : /// The material properties to be output 74 : std::vector<const MaterialProperty<T> *> _material_properties; 75 : 76 : /// The mesh 77 : MooseMesh & _mesh; 78 : 79 : /// The quadrature rule 80 : const QBase * const & _qrule; 81 : 82 : /// The quadrature points 83 : const MooseArray<Point> & _q_point; 84 : 85 : public: 86 : static InputParameters validParams(); 87 : }; 88 : 89 : template <typename T> 90 19 : Sampler1DBase<T>::Sampler1DBase(const InputParameters & parameters) 91 : : GeneralVectorPostprocessor(parameters), 92 : SamplerBase(parameters, this, _communicator), 93 : BlockRestrictable(this), 94 19 : _mesh(_subproblem.mesh()), 95 19 : _qrule(_assembly.qRule()), 96 19 : _q_point(_assembly.qPoints()) 97 : { 98 38 : std::vector<std::string> material_property_names = getParam<std::vector<std::string>>("property"); 99 38 : for (unsigned int i = 0; i < material_property_names.size(); ++i) 100 : { 101 19 : if (!hasMaterialProperty<T>(material_property_names[i])) 102 0 : mooseError("In Sampler1DBase material property: " + material_property_names[i] + 103 : " does not exist."); 104 19 : _material_properties.push_back(&getMaterialProperty<T>(material_property_names[i])); 105 : } 106 : 107 19 : SamplerBase::setupVariables(material_property_names); 108 19 : } 109 : 110 : template <typename T> 111 : void 112 14 : Sampler1DBase<T>::initialize() 113 : { 114 14 : SamplerBase::initialize(); 115 14 : } 116 : 117 : template <typename T> 118 : void 119 14 : Sampler1DBase<T>::execute() 120 : { 121 14 : std::vector<Real> values(_material_properties.size()); 122 : 123 : std::unordered_set<unsigned int> needed_mat_props; 124 14 : const auto & mp_deps = getMatPropDependencies(); 125 14 : needed_mat_props.insert(mp_deps.begin(), mp_deps.end()); 126 14 : _fe_problem.setActiveMaterialProperties(needed_mat_props, _tid); 127 : 128 14 : ConstElemRange & elem_range = *(_mesh.getActiveLocalElementRange()); 129 104 : for (typename ConstElemRange::const_iterator el = elem_range.begin(); el != elem_range.end(); 130 : ++el) 131 : { 132 45 : const Elem * elem = *el; 133 : 134 45 : if (elem->processor_id() != processor_id()) 135 0 : continue; 136 : 137 45 : if (!hasBlocks(elem->subdomain_id())) 138 0 : continue; 139 : 140 45 : _subproblem.setCurrentSubdomainID(elem, _tid); 141 45 : _subproblem.prepare(elem, _tid); 142 45 : _subproblem.reinitElem(elem, _tid); 143 : 144 : // Set up Sentinel class so that, even if reinitMaterials() throws, we 145 : // still remember to swap back during stack unwinding. 146 45 : SwapBackSentinel sentinel(_fe_problem, &FEProblem::swapBackMaterials, _tid); 147 45 : _fe_problem.reinitMaterials(elem->subdomain_id(), _tid); 148 : 149 135 : for (unsigned int qp = 0; qp < _qrule->n_points(); ++qp) 150 : { 151 180 : for (unsigned int j = 0; j < _material_properties.size(); ++j) 152 90 : values[j] = getScalarFromProperty((*_material_properties[j])[qp], _q_point[qp]); 153 : 154 : // use the "x" coordinate as the "id"; at this time, it is not used for anything 155 90 : addSample(_q_point[qp], _q_point[qp](0), values); 156 : } 157 : } 158 14 : _fe_problem.clearActiveMaterialProperties(_tid); 159 14 : } 160 : 161 : template <typename T> 162 : void 163 14 : Sampler1DBase<T>::finalize() 164 : { 165 14 : SamplerBase::finalize(); 166 14 : }