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 "SubdomainBoundingBoxGenerator.h" 11 : #include "Conversion.h" 12 : #include "CastUniquePointer.h" 13 : #include "MooseUtils.h" 14 : #include "MooseMeshUtils.h" 15 : 16 : #include "libmesh/elem.h" 17 : 18 : registerMooseObject("MooseApp", SubdomainBoundingBoxGenerator); 19 : 20 : InputParameters 21 16033 : SubdomainBoundingBoxGenerator::validParams() 22 : { 23 48099 : MooseEnum location("INSIDE OUTSIDE", "INSIDE"); 24 : 25 16033 : InputParameters params = MeshGenerator::validParams(); 26 : 27 64132 : params.addRequiredParam<MeshGeneratorName>("input", "The mesh we want to modify"); 28 32066 : params.addClassDescription("Changes the subdomain ID of elements either (XOR) inside or outside " 29 : "the specified box to the specified ID."); 30 64132 : params.addRequiredParam<RealVectorValue>( 31 : "bottom_left", "The bottom left point (in x,y,z with spaces in-between)."); 32 64132 : params.addRequiredParam<RealVectorValue>( 33 : "top_right", "The bottom left point (in x,y,z with spaces in-between)."); 34 64132 : params.addRequiredParam<subdomain_id_type>( 35 : "block_id", "Subdomain id to set for inside/outside the bounding box"); 36 64132 : params.addParam<SubdomainName>( 37 : "block_name", "Subdomain name to set for inside/outside the bounding box (optional)"); 38 64132 : params.addParam<MooseEnum>( 39 : "location", location, "Control of where the subdomain id is to be set"); 40 64132 : params.addParam<std::vector<SubdomainName>>( 41 : "restricted_subdomains", 42 : "Only reset subdomain ID for given subdomains within the bounding box"); 43 : 44 48099 : params.addParam<std::string>("integer_name", 45 : "Element integer to be assigned (default to subdomain ID)"); 46 32066 : return params; 47 16033 : } 48 : 49 6477 : SubdomainBoundingBoxGenerator::SubdomainBoundingBoxGenerator(const InputParameters & parameters) 50 : : MeshGenerator(parameters), 51 6477 : _input(getMesh("input")), 52 6477 : _location(parameters.get<MooseEnum>("location")), 53 6477 : _block_id(parameters.get<subdomain_id_type>("block_id")), 54 12954 : _has_restriction(isParamValid("restricted_subdomains")), 55 6477 : _bounding_box(MooseUtils::buildBoundingBox(parameters.get<RealVectorValue>("bottom_left"), 56 12954 : parameters.get<RealVectorValue>("top_right"))) 57 : { 58 6477 : } 59 : 60 : std::unique_ptr<MeshBase> 61 6117 : SubdomainBoundingBoxGenerator::generate() 62 : { 63 6117 : std::unique_ptr<MeshBase> mesh = std::move(_input); 64 : 65 : // We'll need cached subdomain_ids later 66 6117 : if (!mesh->preparation().has_cached_elem_data) 67 6107 : mesh->cache_elem_data(); 68 : 69 6117 : std::set<SubdomainID> restricted_ids; 70 6117 : if (_has_restriction) 71 : { 72 22 : auto names = getParam<std::vector<SubdomainName>>("restricted_subdomains"); 73 19 : for (auto & name : names) 74 : { 75 : // check that the subdomain exists in the mesh 76 11 : if (!MooseMeshUtils::hasSubdomainName(*mesh, name)) 77 6 : paramError("restricted_subdomains", "The block '", name, "' was not found in the mesh"); 78 : 79 8 : restricted_ids.insert(MooseMeshUtils::getSubdomainID(name, *mesh)); 80 : } 81 8 : } 82 : 83 18342 : if (isParamValid("integer_name")) 84 : { 85 1294 : std::string integer_name = getParam<std::string>("integer_name"); 86 : 87 647 : if (!mesh->has_elem_integer(integer_name)) 88 0 : mooseError("Mesh does not have an element integer names as ", integer_name); 89 : 90 647 : unsigned int id = mesh->get_elem_integer_index(integer_name); 91 : 92 : // Loop over the elements 93 57207 : for (const auto & elem : mesh->active_element_ptr_range()) 94 : { 95 56560 : if (_has_restriction && restricted_ids.count(elem->subdomain_id()) == 0) 96 0 : continue; 97 : 98 56560 : bool contains = _bounding_box.contains_point(elem->vertex_average()); 99 56560 : if ((contains && _location == "INSIDE") || (!contains && _location == "OUTSIDE")) 100 20575 : elem->set_extra_integer(id, _block_id); 101 647 : } 102 647 : } 103 : else 104 : { 105 : // Loop over the elements 106 509023 : for (const auto & elem : mesh->element_ptr_range()) 107 : { 108 503556 : if (_has_restriction && restricted_ids.count(elem->subdomain_id()) == 0) 109 512 : continue; 110 : 111 503044 : bool contains = _bounding_box.contains_point(elem->vertex_average()); 112 503044 : if ((contains && _location == "INSIDE") || (!contains && _location == "OUTSIDE")) 113 192254 : elem->subdomain_id() = _block_id; 114 5467 : } 115 : 116 : // Assign block name, if provided 117 16401 : if (isParamValid("block_name")) 118 1203 : mesh->subdomain_name(_block_id) = getParam<SubdomainName>("block_name"); 119 : } 120 : 121 6114 : mesh->unset_is_prepared(); 122 12228 : return dynamic_pointer_cast<MeshBase>(mesh); 123 6114 : }