void LeastSquaresFitHistory::execute() { if (_x_values.size() != _y_values.size()) mooseError("In LeastSquresFitTimeHistory size of data in x_values and y_values must be equal"); if (_x_values.size() == 0) mooseError("In LeastSquresFitTimeHistory size of data in x_values and y_values must be > 0"); // Create a copy of _x_values that we can modify. std::vector<Real> x_values(_x_values.begin(), _x_values.end()); std::vector<Real> y_values(_y_values.begin(), _y_values.end()); for (MooseIndex(_x_values) i = 0; i < _x_values.size(); ++i) { x_values[i] = (x_values[i] + _x_shift) * _x_scale; y_values[i] = (y_values[i] + _y_shift) * _y_scale; } PolynomialFit pf(x_values, y_values, _order, true); pf.generate(); std::vector<Real> coeffs = pf.getCoefficients(); mooseAssert(coeffs.size() == _coeffs.size(), "Sizes of current coefficients and vector of coefficient vectors must match"); for (MooseIndex(coeffs) i = 0; i < coeffs.size(); ++i) _coeffs[i]->push_back(coeffs[i]); _times->push_back(_t); }
void ComputeInterfaceStress::computeQpProperties() { auto & S = _planar_stress[_qp]; S.zero(); // loop over interface variables for (MooseIndex(_grad_v) i = 0; i < _nvar; ++i) { // compute norm square of the order parameter gradient const Real grad_norm_sq = (*_grad_v[i])[_qp].norm_sq(); // gradient square is zero -> no interface -> no interfacial stress contribution if (grad_norm_sq < libMesh::TOLERANCE) continue; const Real nx = (*_grad_v[i])[_qp](0); const Real ny = (*_grad_v[i])[_qp](1); const Real nz = (*_grad_v[i])[_qp](2); const Real s = _stress[i] / std::sqrt(grad_norm_sq); S(0, 0) += (ny * ny + nz * nz) * s; S(0, 1) += -nx * ny * s; S(1, 1) += (nx * nx + nz * nz) * s; S(0, 2) += -nx * nz * s; S(1, 2) += -ny * nz * s; S(2, 2) += (nx * nx + ny * ny) * s; } // fill in symmetrically S(1, 0) = S(0, 1); S(2, 0) = S(0, 2); S(2, 1) = S(1, 2); }
ComputeInterfaceStress::ComputeInterfaceStress(const InputParameters & parameters) : Material(parameters), _nvar(coupledComponents("v")), _grad_v(_nvar), _op_range(getParam<std::vector<Real>>("op_range")), _stress(getParam<std::vector<Real>>("stress")), _planar_stress( declareProperty<RankTwoTensor>(getParam<MaterialPropertyName>("planar_stress_name"))) { if (_stress.size() == 1) _stress.assign(_nvar, _stress[0]); if (_stress.size() != _nvar) paramError("stress", "Supply either one single stress or one per order parameter"); if (_op_range.size() == 1) _op_range.assign(_nvar, _op_range[0]); if (_op_range.size() != _nvar) paramError("op_range", "Supply either one single op_range or one per order parameter"); for (MooseIndex(_grad_v) i = 0; i < _nvar; ++i) { _grad_v[i] = &coupledGradient("v", i); _stress[i] /= _op_range[i]; } }
void ConditionalEnableControl::execute() { // ENABLE for (MooseIndex(_enable) i = 0; i < _enable.size(); ++i) if (conditionMet(i)) setControllableValueByName<bool>(_enable[i], std::string("enable"), true); else if (_reverse_on_false) setControllableValueByName<bool>(_enable[i], std::string("enable"), false); // DISABLE for (MooseIndex(_disable) i = 0; i < _disable.size(); ++i) if (conditionMet(i)) setControllableValueByName<bool>(_disable[i], std::string("enable"), false); else if (_reverse_on_false) setControllableValueByName<bool>(_disable[i], std::string("enable"), true); }
void StochasticResults::init(Sampler & sampler) { _sampler = &sampler; const std::vector<std::string> & names = _sampler->getSampleNames(); _sample_vectors.resize(names.size()); for (MooseIndex(names) i = 0; i < names.size(); ++i) _sample_vectors[i] = &declareVector(names[i]); }
void StochasticResults::initialize() { mooseAssert(_sampler, "The _sampler pointer must be initialized via the init() method."); // Resize and zero vectors to the correct size, this allows the SamplerPostprocessorTransfer // to set values in the vector directly. std::vector<DenseMatrix<Real>> data = _sampler->getSamples(); for (MooseIndex(data) i = 0; i < data.size(); ++i) _sample_vectors[i]->resize(data[i].m(), 0); }
void SobolSampler::sampleSetUp() { _a_matrix.resize(_num_samples, _distributions.size()); _b_matrix.resize(_num_samples, _distributions.size()); for (std::size_t i = 0; i < _num_samples; ++i) for (MooseIndex(_distributions) j = 0; j < _distributions.size(); ++j) { _a_matrix(i, j) = _distributions[j]->quantile(this->rand(0)); _b_matrix(i, j) = _distributions[j]->quantile(this->rand(1)); } }
Real FauxGrainTracker::getEntityValue(dof_id_type entity_id, FeatureFloodCount::FieldType field_type, std::size_t var_idx) const { if (var_idx == FeatureFloodCount::invalid_size_t) var_idx = 0; mooseAssert(var_idx < _n_vars, "Index out of range"); switch (field_type) { case FieldType::UNIQUE_REGION: case FieldType::VARIABLE_COLORING: { auto entity_it = _entity_id_to_var_num.find(entity_id); if (entity_it != _entity_id_to_var_num.end()) return entity_it->second; else return -1; break; } case FieldType::CENTROID: { if (_periodic_node_map.size()) mooseDoOnce(mooseWarning( "Centroids are not correct when using periodic boundaries, contact the MOOSE team")); // If this element contains the centroid of one of features, return it's index const auto * elem_ptr = _mesh.elemPtr(entity_id); for (MooseIndex(_vars) var_num = 0; var_num < _n_vars; ++var_num) { const auto centroid = _centroid.find(var_num); if (centroid != _centroid.end()) if (elem_ptr->contains_point(centroid->second)) return 1; } return 0; } // We don't want to error here because this should be a drop in replacement for the real grain // tracker. // Instead we'll just return zero and continue default: return 0; } return 0; }
FauxGrainTracker::FauxGrainTracker(const InputParameters & parameters) : FeatureFloodCount(parameters), GrainTrackerInterface(), _grain_count(0), _n_vars(_vars.size()), _tracking_step(getParam<int>("tracking_step")) { // initialize faux data with identity map _op_to_grains.resize(_n_vars); for (MooseIndex(_op_to_grains) i = 0; i < _op_to_grains.size(); ++i) _op_to_grains[i] = i; _empty_var_to_features.resize(_n_vars, FeatureFloodCount::invalid_id); }
void FauxGrainTracker::finalize() { Moose::perf_log.push("finalize()", "FauxGrainTracker"); _communicator.set_union(_variables_used); _communicator.set_union(_entity_id_to_var_num); if (_is_elemental) for (MooseIndex(_vars) var_num = 0; var_num < _n_vars; ++var_num) { /** * Convert elements of the maps into simple values or vector of Real. * libMesh's _communicator.sum() does not work on std::maps */ unsigned int vol_count; std::vector<Real> grain_data(4); const auto count = _vol_count.find(var_num); if (count != _vol_count.end()) vol_count = count->second; const auto vol = _volume.find(var_num); if (vol != _volume.end()) grain_data[0] = vol->second; const auto centroid = _centroid.find(var_num); if (centroid != _centroid.end()) { grain_data[1] = centroid->second(0); grain_data[2] = centroid->second(1); grain_data[3] = centroid->second(2); } // combine centers & volumes from all MPI ranks gatherSum(vol_count); gatherSum(grain_data); _volume[var_num] = grain_data[0]; _centroid[var_num] = {grain_data[1], grain_data[2], grain_data[3]}; _centroid[var_num] /= vol_count; } Moose::perf_log.pop("finalize()", "FauxGrainTracker"); }
std::vector<DenseMatrix<Real>> SobolSampler::sample() { // Create the output vector auto n = _distributions.size() + 2; std::vector<DenseMatrix<Real>> output(n); // Include the A and B matrices output[0] = _a_matrix; output[1] = _b_matrix; // Create the AB matrices for (MooseIndex(_distributions) idx = 2; idx < n; ++idx) { output[idx] = _a_matrix; for (std::size_t i = 0; i < _num_samples; ++i) output[idx](i, idx - 2) = _b_matrix(i, idx - 2); } return output; }
std::vector<DenseMatrix<Real>> Sampler::getSamples() { _generator.restoreState(); sampleSetUp(); std::vector<DenseMatrix<Real>> output = sample(); sampleTearDown(); if (_sample_names.empty()) { _sample_names.resize(output.size()); for (MooseIndex(output) i = 0; i < output.size(); ++i) _sample_names[i] = "sample_" + std::to_string(i); } mooseAssert(output.size() == _sample_names.size(), "The number of sample names must match the number of samples returned."); mooseAssert(output.size() > 0, "It is not acceptable to return an empty vector of sample matrices."); return output; }
void FeatureVolumeVectorPostprocessor::accumulateBoundaryFaces( const Elem * elem, const std::vector<unsigned int> & var_to_features, std::size_t libmesh_dbg_var(num_features), unsigned int side) { unsigned int dominant_feature_id = FeatureFloodCount::invalid_id; Real max_var_value = std::numeric_limits<Real>::lowest(); for (MooseIndex(var_to_features) var_index = 0; var_index < var_to_features.size(); ++var_index) { // Only sample "active" variables if (var_to_features[var_index] != FeatureFloodCount::invalid_id) { auto feature_id = var_to_features[var_index]; mooseAssert(feature_id < num_features, "Feature ID out of range"); auto integral_value = computeFaceIntegral(var_index); if (_single_feature_per_elem) { if (integral_value > max_var_value) { // Update the current dominant feature and associated value max_var_value = integral_value; dominant_feature_id = feature_id; } } // Solution based boundary area/length calculation (integral value) else _feature_volumes[feature_id] += integral_value; } } // Accumulate the boundary area/length into the dominant feature. Do not use the integral value if (_single_feature_per_elem && dominant_feature_id != FeatureFloodCount::invalid_id) _feature_volumes[dominant_feature_id] += elem->side_ptr(side)->volume(); }
void FauxGrainTracker::execute() { Moose::perf_log.push("execute()", "FauxGrainTracker"); for (const auto & current_elem : _mesh.getMesh().active_local_element_ptr_range()) { // Loop over elements or nodes and populate the data structure with the first variable with a // value above a threshold if (_is_elemental) { std::vector<Point> centroid(1, current_elem->centroid()); _fe_problem.reinitElemPhys(current_elem, centroid, 0); auto entity = current_elem->id(); auto insert_pair = moose_try_emplace(_entity_var_to_features, entity, std::vector<unsigned int>(_n_vars, FeatureFloodCount::invalid_id)); auto & vec_ref = insert_pair.first->second; for (MooseIndex(_vars) var_num = 0; var_num < _n_vars; ++var_num) { auto entity_value = _vars[var_num]->sln()[0]; if ((_use_less_than_threshold_comparison && (entity_value >= _threshold)) || (!_use_less_than_threshold_comparison && (entity_value <= _threshold))) { _entity_id_to_var_num[current_elem->id()] = var_num; _variables_used.insert(var_num); _volume[var_num] += current_elem->volume(); _vol_count[var_num]++; // Sum the centroid values for now, we'll average them later _centroid[var_num] += current_elem->centroid(); vec_ref[var_num] = var_num; break; } } } else { unsigned int n_nodes = current_elem->n_vertices(); for (unsigned int i = 0; i < n_nodes; ++i) { const Node * current_node = current_elem->get_node(i); for (MooseIndex(_vars) var_num = 0; var_num < _n_vars; ++var_num) { auto entity_value = _vars[var_num]->getNodalValue(*current_node); if ((_use_less_than_threshold_comparison && (entity_value >= _threshold)) || (!_use_less_than_threshold_comparison && (entity_value <= _threshold))) { _entity_id_to_var_num[current_node->id()] = var_num; _variables_used.insert(var_num); break; } } } } } _grain_count = std::max(_grain_count, _variables_used.size()); Moose::perf_log.pop("execute()", "FauxGrainTracker"); }
void FeatureVolumeVectorPostprocessor::execute() { const auto num_features = _feature_counter.getTotalFeatureCount(); // Reset the variable index and intersect bounds vectors _var_num.assign(num_features, -1); // Invalid _intersects_bounds.assign(num_features, -1); // Invalid _percolated.assign(num_features, -1); // Invalid for (MooseIndex(num_features) feature_num = 0; feature_num < num_features; ++feature_num) { auto var_num = _feature_counter.getFeatureVar(feature_num); if (var_num != FeatureFloodCount::invalid_id) _var_num[feature_num] = var_num; _intersects_bounds[feature_num] = static_cast<unsigned int>(_feature_counter.doesFeatureIntersectBoundary(feature_num)); _percolated[feature_num] = static_cast<unsigned int>(_feature_counter.isFeaturePercolated(feature_num)); } if (_output_centroids) { VectorPostprocessorValue & center_x = declareVector("centroid_x"); center_x.resize(num_features); VectorPostprocessorValue & center_y = declareVector("centroid_y"); center_y.resize(num_features); VectorPostprocessorValue & center_z = declareVector("centroid_z"); center_z.resize(num_features); for (MooseIndex(_var_num) feature_num = 0; feature_num < num_features; ++feature_num) { auto p = _feature_counter.featureCentroid(feature_num); center_x[feature_num] = p(0); center_y[feature_num] = p(1); center_z[feature_num] = p(2); } } // Reset the volume vector _feature_volumes.assign(num_features, 0); // Calculate coverage of a boundary if one has been supplied in the input file if (_is_boundary_restricted) { const std::set<BoundaryID> supplied_bnd_ids = BoundaryRestrictable::boundaryIDs(); for (auto elem_it = _mesh.bndElemsBegin(), elem_end = _mesh.bndElemsEnd(); elem_it != elem_end; ++elem_it) // loop over only boundaries supplied by user in boundary param for (auto & supplied_bnd_id : supplied_bnd_ids) if (((*elem_it)->_bnd_id) == supplied_bnd_id) { const auto & elem = (*elem_it)->_elem; auto rank = processor_id(); if (elem->processor_id() == rank) { _fe_problem.setCurrentSubdomainID(elem, 0); _fe_problem.prepare(elem, 0); _fe_problem.reinitElem(elem, 0); _fe_problem.reinitElemFace(elem, (*elem_it)->_side, (*elem_it)->_bnd_id, 0); const auto & var_to_features = _feature_counter.getVarToFeatureVector(elem->id()); accumulateBoundaryFaces(elem, var_to_features, num_features, (*elem_it)->_side); } } } else // If no boundary is supplied, calculate volumes of features as normal for (const auto & elem : _mesh.getMesh().active_local_element_ptr_range()) { _fe_problem.setCurrentSubdomainID(elem, 0); _fe_problem.prepare(elem, 0); _fe_problem.reinitElem(elem, 0); /** * Here we retrieve the var to features vector on the current element. * We'll use that information to figure out which variables are non-zero * (from a threshold perspective) then we can sum those values into * appropriate grain index locations. */ const auto & var_to_features = _feature_counter.getVarToFeatureVector(elem->id()); accumulateVolumes(elem, var_to_features, num_features); } }
AccumulateAux::AccumulateAux(const InputParameters & parameters) : AuxKernel(parameters), _values(coupledComponents("accumulate_from_variable")) { for (MooseIndex(_values) i = 0; i < _values.size(); ++i) _values[i] = &coupledValue("accumulate_from_variable", i); }