https://mooseframework.inl.gov
Public Types | Public Member Functions | Static Public Member Functions | Public Attributes | Static Public Attributes | Protected Member Functions | Static Protected Member Functions | Protected Attributes | List of all members
PatternedHexMeshGenerator Class Reference

This PatternedHexMeshGenerator source code assembles hexagonal meshes into a hexagonal grid and optionally forces the outer boundary to be hexagonal and/or adds a duct. More...

#include <PatternedHexMeshGenerator.h>

Inheritance diagram for PatternedHexMeshGenerator:
[legend]

Public Types

enum  PolygonSizeStyle { PolygonSizeStyle::apothem, PolygonSizeStyle::radius }
 An enum class for style of input polygon size. More...
 
enum  MESH_TYPE { CORNER_MESH = 1, BOUNDARY_MESH = 2, INNER_MESH = 3 }
 
enum  RETURN_TYPE { ANGLE_DEGREE = 1, ANGLE_TANGENT = 2 }
 
enum  INTRISIC_SUBDOMAIN_ID : subdomain_id_type { PERIPHERAL_ID_SHIFT = 1000, TRANSITION_LAYER_DEFAULT = 10000 }
 
enum  INTRINSIC_SIDESET_ID : boundary_id_type {
  OUTER_SIDESET_ID = 10000, OUTER_SIDESET_ID_ALT = 15000, SLICE_BEGIN = 30000, SLICE_END = 31000,
  SLICE_ALT = 30500
}
 
enum  INTRINSIC_NUM_SIDES { HEXAGON_NUM_SIDES = 6, SQUARE_NUM_SIDES = 4 }
 
enum  TRI_ELEM_TYPE { TRI_ELEM_TYPE::TRI3, TRI_ELEM_TYPE::TRI6, TRI_ELEM_TYPE::TRI7 }
 
enum  QUAD_ELEM_TYPE { QUAD_ELEM_TYPE::QUAD4, QUAD_ELEM_TYPE::QUAD8, QUAD_ELEM_TYPE::QUAD9 }
 
typedef DataFileName DataFileParameterType
 

Public Member Functions

 PatternedHexMeshGenerator (const InputParameters &parameters)
 
std::unique_ptr< MeshBase > generate () override
 
std::unique_ptr< MeshBase > generateInternal ()
 
const std::set< MeshGeneratorName > & getRequestedMeshGenerators () const
 
const std::set< MeshGeneratorName > & getRequestedMeshGeneratorsForSub () const
 
void addParentMeshGenerator (const MeshGenerator &mg, const AddParentChildKey)
 
void addChildMeshGenerator (const MeshGenerator &mg, const AddParentChildKey)
 
const std::set< const MeshGenerator *, Comparator > & getParentMeshGenerators () const
 
const std::set< const MeshGenerator *, Comparator > & getChildMeshGenerators () const
 
const std::set< const MeshGenerator *, Comparator > & getSubMeshGenerators () const
 
bool isParentMeshGenerator (const MeshGeneratorName &name, const bool direct=true) const
 
bool isChildMeshGenerator (const MeshGeneratorName &name, const bool direct=true) const
 
bool isNullMeshName (const MeshGeneratorName &name) const
 
bool hasSaveMesh () const
 
bool hasOutput () const
 
const std::string & getSavedMeshName () const
 
bool hasGenerateData () const
 
bool isDataOnly () const
 
virtual bool enabled () const
 
std::shared_ptr< MooseObjectgetSharedPtr ()
 
std::shared_ptr< const MooseObjectgetSharedPtr () const
 
MooseAppgetMooseApp () const
 
const std::string & type () const
 
virtual const std::string & name () const
 
std::string typeAndName () const
 
std::string errorPrefix (const std::string &error_type) const
 
void callMooseError (std::string msg, const bool with_prefix) const
 
MooseObjectParameterName uniqueParameterName (const std::string &parameter_name) const
 
const InputParametersparameters () const
 
MooseObjectName uniqueName () const
 
const T & getParam (const std::string &name) const
 
std::vector< std::pair< T1, T2 > > getParam (const std::string &param1, const std::string &param2) const
 
const T * queryParam (const std::string &name) const
 
const T & getRenamedParam (const std::string &old_name, const std::string &new_name) const
 
getCheckedPointerParam (const std::string &name, const std::string &error_string="") const
 
bool isParamValid (const std::string &name) const
 
bool isParamSetByUser (const std::string &nm) const
 
void paramError (const std::string &param, Args... args) const
 
void paramWarning (const std::string &param, Args... args) const
 
void paramInfo (const std::string &param, Args... args) const
 
void connectControllableParams (const std::string &parameter, const std::string &object_type, const std::string &object_name, const std::string &object_parameter) const
 
void mooseError (Args &&... args) const
 
void mooseErrorNonPrefixed (Args &&... args) const
 
void mooseDocumentedError (const std::string &repo_name, const unsigned int issue_num, Args &&... args) const
 
void mooseWarning (Args &&... args) const
 
void mooseWarningNonPrefixed (Args &&... args) const
 
void mooseDeprecated (Args &&... args) const
 
void mooseInfo (Args &&... args) const
 
std::string getDataFileName (const std::string &param) const
 
std::string getDataFileNameByName (const std::string &relative_path) const
 
std::string getDataFilePath (const std::string &relative_path) const
 
const Parallel::Communicator & comm () const
 
processor_id_type n_processors () const
 
processor_id_type processor_id () const
 

Static Public Member Functions

static InputParameters validParams ()
 
static bool hasGenerateData (const InputParameters &params)
 
static void setHasGenerateData (InputParameters &params)
 

Public Attributes

const ConsoleStream _console
 

Static Public Attributes

static const std::string data_only_param
 
static constexpr auto SYSTEM
 
static constexpr auto NAME
 

Protected Member Functions

void addPeripheralMesh (ReplicatedMesh &mesh, const unsigned int pattern, const Real pitch, const std::vector< Real > &extra_dist, const std::vector< unsigned int > &num_sectors_per_side_array, const std::vector< unsigned int > &peripheral_duct_intervals, const Real rotation_angle, const unsigned int mesh_type)
 Adds background and duct region mesh to stitched hexagon meshes. More...
 
void positionSetup (std::vector< std::pair< Real, Real >> &positions_inner, std::vector< std::pair< Real, Real >> &d_positions_outer, const Real extra_dist_in, const Real extra_dist_out, const Real pitch, const unsigned int radial_index) const
 Computes the inner and outer node positions of the peripheral region for a single layer. More...
 
void addReportingIDs (MeshBase &mesh, const std::vector< std::unique_ptr< ReplicatedMesh >> &from_meshes) const
 Adds the reporting IDs onto the input mesh. More...
 
std::unique_ptr< ReplicatedMeshbuildSimpleSlice (std::vector< Real > ring_radii, const std::vector< unsigned int > ring_layers, const std::vector< Real > ring_radial_biases, const multiBdryLayerParams &ring_inner_boundary_layer_params, const multiBdryLayerParams &ring_outer_boundary_layer_params, std::vector< Real > ducts_center_dist, const std::vector< unsigned int > ducts_layers, const std::vector< Real > duct_radial_biases, const multiBdryLayerParams &duct_inner_boundary_layer_params, const multiBdryLayerParams &duct_outer_boundary_layer_params, const Real pitch, const unsigned int num_sectors_per_side, const unsigned int background_intervals, const Real background_radial_bias, const singleBdryLayerParams &background_inner_boundary_layer_params, const singleBdryLayerParams &background_outer_boundary_layer_params, dof_id_type &node_id_background_meta, const unsigned int side_number, const unsigned int side_index, const std::vector< Real > azimuthal_tangent=std::vector< Real >(), const subdomain_id_type block_id_shift=0, const bool quad_center_elements=false, const Real center_quad_factor=0.0, const bool create_inward_interface_boundaries=false, const bool create_outward_interface_boundaries=true, const boundary_id_type boundary_id_shift=0, const bool generate_side_specific_boundaries=true, const TRI_ELEM_TYPE tri_elem_type=TRI_ELEM_TYPE::TRI3, const QUAD_ELEM_TYPE quad_elem_type=QUAD_ELEM_TYPE::QUAD4)
 Creates a mesh of a slice that corresponds to a single side of the polygon to be generated. More...
 
std::unique_ptr< ReplicatedMeshbuildGeneralSlice (std::vector< Real > ring_radii, const std::vector< unsigned int > ring_layers, const std::vector< Real > ring_radial_biases, const multiBdryLayerParams &ring_inner_boundary_layer_params, const multiBdryLayerParams &ring_outer_boundary_layer_params, std::vector< Real > ducts_center_dist, const std::vector< unsigned int > ducts_layers, const std::vector< Real > duct_radial_biases, const multiBdryLayerParams &duct_inner_boundary_layer_params, const multiBdryLayerParams &duct_outer_boundary_layer_params, const Real primary_side_length, const Real secondary_side_length, const unsigned int num_sectors_per_side, const unsigned int background_intervals, const Real background_radial_bias, const singleBdryLayerParams &background_inner_boundary_layer_params, const singleBdryLayerParams &background_outer_boundary_layer_params, dof_id_type &node_id_background_meta, const Real azimuthal_angle, const std::vector< Real > azimuthal_tangent, const unsigned int side_index, const bool quad_center_elements, const Real center_quad_factor, const Real rotation_angle, const bool generate_side_specific_boundaries=true)
 Creates a mesh of a general polygon slice with a triangular shape and circular regions on one of its vertex. More...
 
std::unique_ptr< ReplicatedMeshbuildSlice (std::vector< Real > ring_radii, const std::vector< unsigned int > ring_layers, const std::vector< Real > ring_radial_biases, const multiBdryLayerParams &ring_inner_boundary_layer_params, const multiBdryLayerParams &ring_outer_boundary_layer_params, std::vector< Real > ducts_center_dist, const std::vector< unsigned int > ducts_layers, const std::vector< Real > duct_radial_biases, const multiBdryLayerParams &duct_inner_boundary_layer_params, const multiBdryLayerParams &duct_outer_boundary_layer_params, const Real pitch, const unsigned int num_sectors_per_side, const unsigned int background_intervals, const Real background_radial_bias, const singleBdryLayerParams &background_inner_boundary_layer_params, const singleBdryLayerParams &background_outer_boundary_layer_params, dof_id_type &node_id_background_meta, const Real virtual_side_number, const unsigned int side_index, const std::vector< Real > azimuthal_tangent=std::vector< Real >(), const subdomain_id_type block_id_shift=0, const bool quad_center_elements=false, const Real center_quad_factor=0.0, const bool create_inward_interface_boundaries=false, const bool create_outward_interface_boundaries=true, const boundary_id_type boundary_id_shift=0, const Real pitch_scale_factor=1.0, const bool generate_side_specific_boundaries=true, const TRI_ELEM_TYPE tri_elem_type=TRI_ELEM_TYPE::TRI3, const QUAD_ELEM_TYPE quad_elem_type=QUAD_ELEM_TYPE::QUAD4)
 Generates a mesh of a polygon slice, which is the foundation of both buildGeneralSlice and buildSimpleSlice. More...
 
void centerNodes (ReplicatedMesh &mesh, const Real virtual_side_number, const unsigned int div_num, const Real ring_radii_0, std::vector< std::vector< Node *>> &nodes) const
 Creates nodes of the very central mesh layer of the polygon for quad central elements. More...
 
void ringNodes (ReplicatedMesh &mesh, const std::vector< Real > ring_radii, const std::vector< unsigned int > ring_layers, const std::vector< std::vector< Real >> biased_terms, const unsigned int num_sectors_per_side, const Real corner_p[2][2], const Real corner_to_corner, const std::vector< Real > azimuthal_tangent=std::vector< Real >()) const
 Creates nodes for the ring-geometry region of a single slice. More...
 
void backgroundNodes (ReplicatedMesh &mesh, const unsigned int num_sectors_per_side, const unsigned int background_intervals, const std::vector< Real > biased_terms, const Real background_corner_distance, const Real background_corner_radial_interval_length, const Real corner_p[2][2], const Real corner_to_corner, const Real background_in, const std::vector< Real > azimuthal_tangent=std::vector< Real >()) const
 Creates nodes for the ring-to-polygon transition region (i.e., background) of a single slice. More...
 
void ductNodes (ReplicatedMesh &mesh, std::vector< Real > *const ducts_center_dist, const std::vector< unsigned int > ducts_layers, const std::vector< std::vector< Real >> biased_terms, const unsigned int num_sectors_per_side, const Real corner_p[2][2], const Real corner_to_corner, const std::vector< Real > azimuthal_tangent=std::vector< Real >()) const
 Creates nodes for the duct-geometry region of a single slice. More...
 
void cenQuadElemDef (ReplicatedMesh &mesh, const unsigned int div_num, const subdomain_id_type block_id_shift, const bool create_outward_interface_boundaries, const boundary_id_type boundary_id_shift, std::vector< std::vector< Node *>> &nodes, const bool assign_external_boundary=false, const unsigned int side_index=0, const bool generate_side_specific_boundaries=true, const QUAD_ELEM_TYPE quad_elem_type=QUAD_ELEM_TYPE::QUAD4) const
 Defines quad elements in the very central region of the polygon. More...
 
void cenTriElemDef (ReplicatedMesh &mesh, const unsigned int num_sectors_per_side, const std::vector< Real > azimuthal_tangent=std::vector< Real >(), const subdomain_id_type block_id_shift=0, const bool create_outward_interface_boundaries=true, const boundary_id_type boundary_id_shift=0, const bool assign_external_boundary=false, const unsigned int side_index=0, const bool generate_side_specific_boundaries=true, const TRI_ELEM_TYPE tri_elem_type=TRI_ELEM_TYPE::TRI3) const
 Defines triangular elements in the very central region of the polygon. More...
 
void quadElemDef (ReplicatedMesh &mesh, const unsigned int num_sectors_per_side, const std::vector< unsigned int > subdomain_rings, const unsigned int side_index, const std::vector< Real > azimuthal_tangent=std::vector< Real >(), const subdomain_id_type block_id_shift=0, const dof_id_type nodeid_shift=0, const bool create_inward_interface_boundaries=false, const bool create_outward_interface_boundaries=true, const boundary_id_type boundary_id_shift=0, const bool generate_side_specific_boundaries=true, const QUAD_ELEM_TYPE quad_elem_type=QUAD_ELEM_TYPE::QUAD4) const
 Defines general quad elements for the polygon. More...
 
std::unique_ptr< ReplicatedMeshbuildSimplePeripheral (const unsigned int num_sectors_per_side, const unsigned int peripheral_invervals, const std::vector< std::pair< Real, Real >> &position_inner, const std::vector< std::pair< Real, Real >> &d_position_outer, const subdomain_id_type id_shift, const QUAD_ELEM_TYPE quad_elem_type, const bool create_inward_interface_boundaries=false, const bool create_outward_interface_boundaries=true)
 Creates peripheral area mesh for the patterned hexagon mesh. More...
 
void adjustPeripheralQuadraticElements (MeshBase &out_mesh, const QUAD_ELEM_TYPE boundary_quad_elem_type) const
 Adjusts the mid-edge node locations in boundary regions when using quadratic elements with uniform boundary node spacing enabled. More...
 
std::pair< Real, RealpointInterpolate (const Real pi_1_x, const Real pi_1_y, const Real po_1_x, const Real po_1_y, const Real pi_2_x, const Real pi_2_y, const Real po_2_x, const Real po_2_y, const unsigned int i, const unsigned int j, const unsigned int num_sectors_per_side, const unsigned int peripheral_intervals) const
 Calculates the point coordinates of within a parallelogram region using linear interpolation. More...
 
void nodeCoordRotate (Real &x, Real &y, const Real theta) const
 Calculates x and y coordinates after rotating by theta angle. More...
 
void cutOffPolyDeform (MeshBase &mesh, const Real orientation, const Real y_max_0, const Real y_max_n, const Real y_min, const unsigned int mesh_type, const Real unit_angle=60.0, const Real tols=1E-5) const
 Deforms peripheral region when the external side of a polygon assembly of stitched meshes cuts off the stitched meshes. More...
 
std::pair< Real, RealfourPointIntercept (const std::pair< Real, Real > &p1, const std::pair< Real, Real > &p2, const std::pair< Real, Real > &p3, const std::pair< Real, Real > &p4) const
 Finds the center of a quadrilateral based on four vertices. More...
 
std::vector< RealazimuthalAnglesCollector (ReplicatedMesh &mesh, std::vector< Point > &boundary_points, const Real lower_azi=-30.0, const Real upper_azi=30.0, const unsigned int return_type=ANGLE_TANGENT, const unsigned int num_sides=6, const boundary_id_type bid=OUTER_SIDESET_ID, const bool calculate_origin=true, const Real input_origin_x=0.0, const Real input_origin_y=0.0, const Real tol=1.0E-10) const
 Collects sorted azimuthal angles of the external boundary. More...
 
std::vector< RealazimuthalAnglesCollector (ReplicatedMesh &mesh, const Real lower_azi=-30.0, const Real upper_azi=30.0, const unsigned int return_type=ANGLE_TANGENT, const unsigned int num_sides=6, const boundary_id_type bid=OUTER_SIDESET_ID, const bool calculate_origin=true, const Real input_origin_x=0.0, const Real input_origin_y=0.0, const Real tol=1.0E-10) const
 Collects sorted azimuthal angles of the external boundary. More...
 
std::vector< std::vector< Real > > biasTermsCalculator (const std::vector< Real > radial_biases, const std::vector< unsigned int > intervals, const multiBdryLayerParams inner_boundary_layer_params, const multiBdryLayerParams outer_boundary_layer_params) const
 Creates bias terms for multiple blocks. More...
 
std::vector< RealbiasTermsCalculator (const Real radial_bias, const unsigned int intervals, const singleBdryLayerParams inner_boundary_layer_params={0.0, 0.0, 0, 1.0}, const singleBdryLayerParams outer_boundary_layer_params={0.0, 0.0, 0, 1.0}) const
 Creates bias terms for a single block. More...
 
void setSectorExtraIDs (MeshBase &mesh, const std::string id_name, const unsigned int num_sides, const std::vector< unsigned int > num_sectors_per_side)
 assign sector extra ids to polygon mesh More...
 
void setRingExtraIDs (MeshBase &mesh, const std::string id_name, const unsigned int num_sides, const std::vector< unsigned int > num_sectors_per_side, const std::vector< unsigned int > ring_intervals, const bool ring_wise_id, const bool quad_center_elements)
 assign ring extra ids to polygon mesh More...
 
void reassignBoundaryIDs (MeshBase &mesh, const boundary_id_type id_shift, const std::set< boundary_id_type > &boundary_ids, const bool reverse=false)
 reassign interface boundary IDs on the input mesh by applying the boundary ID shift More...
 
std::set< boundary_id_typegetInterfaceBoundaryIDs (const std::vector< std::vector< unsigned int >> &pattern, const std::vector< std::vector< boundary_id_type >> &interface_boundary_id_shift_pattern, const std::set< boundary_id_type > &boundary_ids, const std::vector< std::set< boundary_id_type >> &input_interface_boundary_ids, const bool use_interface_boundary_id_shift, const bool create_interface_boundary_id, const unsigned int num_extra_layers) const
 returns a list of interface boundary IDs on the mesh generated by this mesh generator More...
 
multiBdryLayerParams modifiedMultiBdryLayerParamsCreator (const multiBdryLayerParams &original_multi_bdry_layer_params, const unsigned int order) const
 Modifies the input multi boundary layer parameters for node generation, especially for the quadratic elements. More...
 
singleBdryLayerParams modifiedSingleBdryLayerParamsCreator (const singleBdryLayerParams &original_single_bdry_layer_params, const unsigned int order) const
 Modifies the input single boundary layer parameters for node generation, especially for the quadratic elements. More...
 
std::string pitchMetaDataErrorGenerator (const std::vector< MeshGeneratorName > &input_names, const std::vector< Real > &metadata_vals, const std::string &metadata_name) const
 Generate a string that contains the detailed metadata information for inconsistent input mesh metadata error messages. More...
 
virtual void generateData ()
 
T & copyMeshProperty (const std::string &target_data_name, const std::string &source_data_name, const std::string &source_mesh)
 
T & copyMeshProperty (const std::string &source_data_name, const std::string &source_mesh)
 
std::unique_ptr< MeshBase > & getMesh (const std::string &param_name, const bool allow_invalid=false)
 
std::vector< std::unique_ptr< MeshBase > *> getMeshes (const std::string &param_name)
 
std::unique_ptr< MeshBase > & getMeshByName (const MeshGeneratorName &mesh_generator_name)
 
std::vector< std::unique_ptr< MeshBase > *> getMeshesByName (const std::vector< MeshGeneratorName > &mesh_generator_names)
 
void declareMeshForSub (const std::string &param_name)
 
void declareMeshesForSub (const std::string &param_name)
 
void declareMeshForSubByName (const MeshGeneratorName &mesh_generator_name)
 
void declareMeshesForSubByName (const std::vector< MeshGeneratorName > &mesh_generator_names)
 
std::unique_ptr< MeshBase > buildMeshBaseObject (unsigned int dim=libMesh::invalid_uint)
 
std::unique_ptr< ReplicatedMesh > buildReplicatedMesh (unsigned int dim=libMesh::invalid_uint)
 
std::unique_ptr< DistributedMesh > buildDistributedMesh (unsigned int dim=libMesh::invalid_uint)
 
void addMeshSubgenerator (const std::string &type, const std::string &name, Ts... extra_input_parameters)
 
void addMeshSubgenerator (const std::string &type, const std::string &name, InputParameters params)
 
void declareNullMeshName (const MeshGeneratorName &name)
 
const T & getMeshProperty (const std::string &data_name, const std::string &prefix)
 
const T & getMeshProperty (const std::string &data_name)
 
bool hasMeshProperty (const std::string &data_name, const std::string &prefix) const
 
bool hasMeshProperty (const std::string &data_name, const std::string &prefix) const
 
bool hasMeshProperty (const std::string &data_name) const
 
bool hasMeshProperty (const std::string &data_name) const
 
std::string meshPropertyName (const std::string &data_name) const
 
T & declareMeshProperty (const std::string &data_name, Args &&... args)
 
T & declareMeshProperty (const std::string &data_name, const T &data_value)
 
T & declareMeshProperty (const std::string &data_name, Args &&... args)
 
T & declareMeshProperty (const std::string &data_name, const T &data_value)
 
T & setMeshProperty (const std::string &data_name, Args &&... args)
 
T & setMeshProperty (const std::string &data_name, const T &data_value)
 
T & setMeshProperty (const std::string &data_name, Args &&... args)
 
T & setMeshProperty (const std::string &data_name, const T &data_value)
 

Static Protected Member Functions

static void addRingAndSectorIDParams (InputParameters &params)
 Add InputParameters which are used by ring and sector IDs. More...
 
static std::string meshPropertyName (const std::string &data_name, const std::string &prefix)
 

Protected Attributes

const std::vector< std::unique_ptr< MeshBase > * > _mesh_ptrs
 The input meshes. More...
 
const std::vector< MeshGeneratorName > & _input_names
 Names of input meshes. More...
 
const std::vector< std::vector< unsigned int > > & _pattern
 2D vector of the hexagonal pattern More...
 
const MooseEnum _pattern_boundary
 Type of the external boundary shape. More...
 
const bool _generate_core_metadata
 Whether a reactor core mesh with core metadata is generated. More...
 
const unsigned int _background_intervals
 Number of radial intervals in the background region. More...
 
const bool _has_assembly_duct
 Whether the hexagonal pattern has external duct(s) More...
 
std::vector< Real_duct_sizes
 Size parameter(s) of duct(s) More...
 
const PolygonSizeStyle _duct_sizes_style
 Style of the duct size parameter(s) More...
 
const std::vector< unsigned int_duct_intervals
 Number(s) of radial intervals of duct layer(s) More...
 
const bool _uniform_mesh_on_sides
 Whether the nodes on the external boundary are uniformly distributed. More...
 
const bool _generate_control_drum_positions_file
 Whether a text file containing control drum positions is generated. More...
 
const bool _assign_control_drum_id
 Wheter control drum IDs are assigned as an extra element integer. More...
 
const Real _rotate_angle
 The mesh rotation angle after mesh generation. More...
 
const std::vector< subdomain_id_type_duct_block_ids
 Subdomain IDs of the duct layers. More...
 
const std::vector< SubdomainName > _duct_block_names
 Subdomain Names of the duct layers. More...
 
const boundary_id_type _external_boundary_id
 Boundary ID of mesh's external boundary. More...
 
const BoundaryName _external_boundary_name
 Boundary name of mesh's external boundary. More...
 
const bool _create_inward_interface_boundaries
 Whether inward interface boundaries are created. More...
 
const bool _create_outward_interface_boundaries
 Whether outward interface boundaries are created. More...
 
const PolygonSizeStyle _hexagon_size_style
 Style of the polygon size parameter. More...
 
const bool _deform_non_circular_region
 Whether the non-circular region (outside the rings) can be deformed. More...
 
Real _pattern_pitch
 Pitch size of the input assembly mesh. More...
 
std::vector< subdomain_id_type_peripheral_block_ids
 Subdomain IDs of the peripheral regions. More...
 
std::vector< SubdomainName > _peripheral_block_names
 Subdomain Names of the peripheral regions. More...
 
const bool _use_reporting_id
 Whether reporting ID is added to mesh. More...
 
std::vector< std::string > _reporting_id_names
 names of reporting ID More...
 
std::vector< ReportingIDGeneratorUtils::AssignType_assign_types
 reporting ID assignment type More...
 
const bool _use_exclude_id
 flag to indicate if exclude_id is defined More...
 
std::vector< bool > _exclude_ids
 vector indicating which ids in the pattern to exclude (true at pattern positions to exclude) More...
 
std::map< std::string, std::vector< std::vector< dof_id_type > > > _id_patterns
 hold ID patterns for each manual reporting ID. Individual ID pattern contains ID values for each pattern cell. More...
 
const bool _use_interface_boundary_id_shift
 whether the interface boundary ids from input meshes are shifted, using a user-defined pattern of values for each pattern cell More...
 
std::vector< std::vector< boundary_id_type > > _interface_boundary_id_shift_pattern
 hold user-defined shift values for each pattern cell More...
 
QUAD_ELEM_TYPE _boundary_quad_elem_type
 Type of quadrilateral elements to be generated in the periphery region. More...
 
const bool _allow_unused_inputs
 Whether to allow additional assembly types to be passed to "inputs" parameter without being used in lattice. More...
 
MooseMesh *const _mesh
 
const bool & _enabled
 
MooseApp_app
 
const std::string _type
 
const std::string _name
 
const InputParameters_pars
 
Factory_factory
 
ActionFactory_action_factory
 
const Parallel::Communicator & _communicator
 

Detailed Description

This PatternedHexMeshGenerator source code assembles hexagonal meshes into a hexagonal grid and optionally forces the outer boundary to be hexagonal and/or adds a duct.

Definition at line 20 of file PatternedHexMeshGenerator.h.

Member Enumeration Documentation

◆ INTRINSIC_NUM_SIDES

Enumerator
HEXAGON_NUM_SIDES 
SQUARE_NUM_SIDES 

Definition at line 75 of file PolygonMeshGeneratorBase.h.

◆ INTRINSIC_SIDESET_ID

◆ INTRISIC_SUBDOMAIN_ID

◆ MESH_TYPE

◆ PolygonSizeStyle

An enum class for style of input polygon size.

Enumerator
apothem 
radius 

Definition at line 41 of file PolygonMeshGeneratorBase.h.

42  {
43  apothem,
44  radius
45  };
const Real radius

◆ QUAD_ELEM_TYPE

Enumerator
QUAD4 
QUAD8 
QUAD9 

Definition at line 88 of file PolygonMeshGeneratorBase.h.

89  {
90  QUAD4,
91  QUAD8,
92  QUAD9
93  };
QUAD8
QUAD4
QUAD9

◆ RETURN_TYPE

Enumerator
ANGLE_DEGREE 
ANGLE_TANGENT 

Definition at line 54 of file PolygonMeshGeneratorBase.h.

◆ TRI_ELEM_TYPE

Enumerator
TRI3 
TRI6 
TRI7 

Definition at line 81 of file PolygonMeshGeneratorBase.h.

82  {
83  TRI3,
84  TRI6,
85  TRI7
86  };
TRI3
TRI6
TRI7

Constructor & Destructor Documentation

◆ PatternedHexMeshGenerator()

PatternedHexMeshGenerator::PatternedHexMeshGenerator ( const InputParameters parameters)

Definition at line 150 of file PatternedHexMeshGenerator.C.

152  _mesh_ptrs(getMeshes("inputs")),
153  _input_names(getParam<std::vector<MeshGeneratorName>>("inputs")),
154  _pattern(getParam<std::vector<std::vector<unsigned int>>>("pattern")),
155  _pattern_boundary(getParam<MooseEnum>("pattern_boundary")),
156  _generate_core_metadata(getParam<bool>("generate_core_metadata")),
157  _background_intervals(getParam<unsigned int>("background_intervals")),
158  _has_assembly_duct(isParamValid("duct_sizes")),
159  _duct_sizes(isParamValid("duct_sizes") ? getParam<std::vector<Real>>("duct_sizes")
160  : std::vector<Real>()),
161  _duct_sizes_style(getParam<MooseEnum>("duct_sizes_style").template getEnum<PolygonSizeStyle>()),
162  _duct_intervals(isParamValid("duct_intervals")
163  ? getParam<std::vector<unsigned int>>("duct_intervals")
164  : std::vector<unsigned int>()),
165  _uniform_mesh_on_sides(getParam<bool>("uniform_mesh_on_sides")),
166  _generate_control_drum_positions_file(getParam<bool>("generate_control_drum_positions_file")),
167  _assign_control_drum_id(getParam<bool>("assign_control_drum_id")),
168  _rotate_angle(getParam<Real>("rotate_angle")),
169  _duct_block_ids(isParamValid("duct_block_ids")
170  ? getParam<std::vector<subdomain_id_type>>("duct_block_ids")
171  : std::vector<subdomain_id_type>()),
172  _duct_block_names(getParam<std::vector<SubdomainName>>("duct_block_names")),
173  _external_boundary_id(isParamValid("external_boundary_id")
174  ? getParam<boundary_id_type>("external_boundary_id")
175  : 0),
176  _external_boundary_name(getParam<BoundaryName>("external_boundary_name")),
177  _create_inward_interface_boundaries(getParam<bool>("create_inward_interface_boundaries")),
178  _create_outward_interface_boundaries(getParam<bool>("create_outward_interface_boundaries")),
180  getParam<MooseEnum>("hexagon_size_style").template getEnum<PolygonSizeStyle>()),
181  _deform_non_circular_region(getParam<bool>("deform_non_circular_region")),
182  _use_reporting_id(isParamValid("id_name")),
183  _use_exclude_id(isParamValid("exclude_id")),
184  _use_interface_boundary_id_shift(isParamValid("interface_boundary_id_shift_pattern")),
186  getParam<MooseEnum>("boundary_region_element_type").template getEnum<QUAD_ELEM_TYPE>()),
187  _allow_unused_inputs(getParam<bool>("allow_unused_inputs"))
188 {
189  declareMeshProperty("pattern_pitch_meta", 0.0);
190  declareMeshProperty("input_pitch_meta", 0.0);
191  declareMeshProperty<bool>("is_control_drum_meta", false);
192  declareMeshProperty<std::vector<Point>>("control_drum_positions", std::vector<Point>());
193  declareMeshProperty<std::vector<Real>>("control_drum_angles", std::vector<Real>());
194  declareMeshProperty<std::vector<std::vector<Real>>>("control_drums_azimuthal_meta",
195  std::vector<std::vector<Real>>());
196  declareMeshProperty<std::string>("position_file_name", getParam<std::string>("position_file"));
197  declareMeshProperty<bool>("hexagon_peripheral_trimmability", !_generate_core_metadata);
198  declareMeshProperty<bool>("hexagon_center_trimmability", true);
199  declareMeshProperty<bool>("peripheral_modifier_compatible", _pattern_boundary == "hexagon");
200 
201  const unsigned int n_pattern_layers = _pattern.size();
202  declareMeshProperty("pattern_size", n_pattern_layers);
203  if (n_pattern_layers % 2 == 0)
204  paramError(
205  "pattern",
206  "The length (layer number) of this parameter must be odd to ensure a hexagonal shape.");
207  if (n_pattern_layers == 1)
208  paramError("pattern", "The length (layer number) of this parameter must be larger than unity.");
209  std::vector<unsigned int> pattern_max_array;
210  std::vector<unsigned int> pattern_1d;
211  for (unsigned int i = 0; i <= n_pattern_layers / 2; i++)
212  {
213  pattern_max_array.push_back(*std::max_element(_pattern[i].begin(), _pattern[i].end()));
214  pattern_max_array.push_back(*std::max_element(_pattern[n_pattern_layers - 1 - i].begin(),
215  _pattern[n_pattern_layers - 1 - i].end()));
216  pattern_1d.insert(pattern_1d.end(), _pattern[i].begin(), _pattern[i].end());
217  pattern_1d.insert(pattern_1d.end(),
218  _pattern[n_pattern_layers - 1 - i].begin(),
219  _pattern[n_pattern_layers - 1 - i].end());
220  if (_pattern[i].size() != n_pattern_layers / 2 + i + 1 ||
221  _pattern[n_pattern_layers - 1 - i].size() != n_pattern_layers / 2 + i + 1)
222  paramError(
223  "pattern",
224  "The two-dimentional array parameter pattern must have a correct hexagonal shape.");
225  }
226  if (*std::max_element(pattern_max_array.begin(), pattern_max_array.end()) >= _input_names.size())
227  paramError("pattern",
228  "Elements of this parameter must be smaller than the length of input_name.");
229  if (std::set<unsigned int>(pattern_1d.begin(), pattern_1d.end()).size() < _input_names.size() &&
231  paramError("pattern",
232  "All the meshes provided in inputs must be used in the lattice pattern. To bypass "
233  "this requirement, set 'allow_unused_inputs = true'");
234 
235  if (isParamValid("background_block_id"))
236  {
237  _peripheral_block_ids.push_back(getParam<subdomain_id_type>("background_block_id"));
238  _peripheral_block_ids.insert(
240  }
241  else if (!_duct_block_ids.empty())
242  paramError("background_block_id",
243  "This parameter and duct_block_ids must be "
244  "provided simultaneously.");
245  if (isParamValid("background_block_name"))
246  {
247  _peripheral_block_names.push_back(getParam<SubdomainName>("background_block_name"));
250  }
251  else if (!_duct_block_names.empty())
252  paramError("background_block_name",
253  "This parameter and duct_block_names must be provided simultaneously.");
254 
255  if (_pattern_boundary == "hexagon")
256  {
257  for (unsigned int i = 1; i < _duct_sizes.size(); i++)
258  if (_duct_sizes[i] <= _duct_sizes[i - 1])
259  paramError("duct_sizes", "This parameter must be strictly ascending.");
260  if (!_peripheral_block_ids.empty() && _peripheral_block_ids.size() != _duct_sizes.size() + 1)
261  paramError("duct_block_ids",
262  "This parameter, if provided, must have a length equal to length of duct_sizes.");
263  if (!_peripheral_block_names.empty() &&
264  _peripheral_block_names.size() != _duct_sizes.size() + 1)
265  paramError("duct_block_names",
266  "This parameter, if provided, must have a length equal to length of duct_sizes.");
267  }
268  else
269  {
270  if (!_peripheral_block_ids.empty() || !_peripheral_block_names.empty())
271  paramError("background_block_id",
272  "This parameter and background_block_name must not be set when the "
273  "pattern_boundary is none.");
274  }
275 
277  {
278  // check "interface_boundary_id_shift_pattern" parameter
280  getParam<std::vector<std::vector<boundary_id_type>>>("interface_boundary_id_shift_pattern");
281  if (_interface_boundary_id_shift_pattern.size() != _pattern.size())
282  paramError("interface_boundary_id_shift_pattern",
283  "This parameter, if provided, should have the same two-dimensional array shape as "
284  "the 'pattern' parameter. First dimension does not match");
285  for (const auto i : make_range(_pattern.size()))
286  if (_interface_boundary_id_shift_pattern[i].size() != _pattern[i].size())
287  paramError("interface_boundary_id_shift_pattern",
288  "This parameter, if provided, should have the same two-dimensional array shape "
289  "as the 'pattern' parameter.");
290  }
291  // declare metadata for internal interface boundaries
292  declareMeshProperty<bool>("interface_boundaries", false);
293  declareMeshProperty<std::set<boundary_id_type>>("interface_boundary_ids", {});
294 
295  if (_use_reporting_id)
296  {
297  // get reporting id name input
298  _reporting_id_names = getParam<std::vector<std::string>>("id_name");
299  const unsigned int num_reporting_ids = _reporting_id_names.size();
300  // get reporting id assign type input
301  const auto input_assign_types = getParam<std::vector<MooseEnum>>("assign_type");
302  if (input_assign_types.size() != num_reporting_ids)
303  paramError("assign_type", "This parameter must have a length equal to length of id_name.");
304  // list of reporting id names using manual id patterns;
305  std::vector<std::string> manual_ids;
306  for (const auto i : make_range(num_reporting_ids))
307  {
308  _assign_types.push_back(
309  input_assign_types[i].getEnum<ReportingIDGeneratorUtils::AssignType>());
311  manual_ids.push_back(_reporting_id_names[i]);
312  }
313  // processing "id_pattern" input parameter
314  if (manual_ids.size() > 0 && !isParamValid("id_pattern"))
315  paramError("id_pattern", "required when 'manual' is defined in \"assign_type\"");
316  if (isParamValid("id_pattern"))
317  {
318  const auto input_id_patterns =
319  getParam<std::vector<std::vector<std::vector<dof_id_type>>>>("id_pattern");
320  if (input_id_patterns.size() != manual_ids.size())
321  paramError("id_pattern",
322  "The number of patterns must be equal to the number of 'manual' types defined "
323  "in \"assign_type\".");
324  for (unsigned int i = 0; i < manual_ids.size(); ++i)
325  _id_patterns[manual_ids[i]] = input_id_patterns[i];
326  }
327  // processing exlude id
328  _exclude_ids.resize(_input_names.size());
329  if (_use_exclude_id)
330  {
331  std::vector<MeshGeneratorName> exclude_id_name =
332  getParam<std::vector<MeshGeneratorName>>("exclude_id");
333  for (unsigned int i = 0; i < _input_names.size(); ++i)
334  {
335  _exclude_ids[i] = false;
336  for (auto input_name : exclude_id_name)
337  if (_input_names[i] == input_name)
338  {
339  _exclude_ids[i] = true;
340  break;
341  }
342  }
343  }
344  else
345  for (unsigned int i = 0; i < _input_names.size(); ++i)
346  _exclude_ids[i] = false;
347  }
348 }
const bool _use_reporting_id
Whether reporting ID is added to mesh.
const PolygonSizeStyle _duct_sizes_style
Style of the duct size parameter(s)
const std::vector< unsigned int > _duct_intervals
Number(s) of radial intervals of duct layer(s)
std::vector< std::string > _reporting_id_names
names of reporting ID
const bool _allow_unused_inputs
Whether to allow additional assembly types to be passed to "inputs" parameter without being used in l...
const MooseEnum _pattern_boundary
Type of the external boundary shape.
const bool _has_assembly_duct
Whether the hexagonal pattern has external duct(s)
const unsigned int _background_intervals
Number of radial intervals in the background region.
assign IDs based on user-defined mapping
std::vector< SubdomainName > _peripheral_block_names
Subdomain Names of the peripheral regions.
const bool _assign_control_drum_id
Wheter control drum IDs are assigned as an extra element integer.
const std::vector< std::vector< unsigned int > > & _pattern
2D vector of the hexagonal pattern
const PolygonSizeStyle _hexagon_size_style
Style of the polygon size parameter.
const bool _create_inward_interface_boundaries
Whether inward interface boundaries are created.
const bool _create_outward_interface_boundaries
Whether outward interface boundaries are created.
std::vector< std::vector< boundary_id_type > > _interface_boundary_id_shift_pattern
hold user-defined shift values for each pattern cell
const std::vector< MeshGeneratorName > & _input_names
Names of input meshes.
bool isParamValid(const std::string &name) const
const Real _rotate_angle
The mesh rotation angle after mesh generation.
const std::vector< SubdomainName > _duct_block_names
Subdomain Names of the duct layers.
std::vector< ReportingIDGeneratorUtils::AssignType > _assign_types
reporting ID assignment type
const bool _uniform_mesh_on_sides
Whether the nodes on the external boundary are uniformly distributed.
QUAD_ELEM_TYPE _boundary_quad_elem_type
Type of quadrilateral elements to be generated in the periphery region.
std::vector< Real > _duct_sizes
Size parameter(s) of duct(s)
const std::vector< std::unique_ptr< MeshBase > * > _mesh_ptrs
The input meshes.
const bool _use_exclude_id
flag to indicate if exclude_id is defined
const std::vector< subdomain_id_type > _duct_block_ids
Subdomain IDs of the duct layers.
const boundary_id_type _external_boundary_id
Boundary ID of mesh&#39;s external boundary.
const T & getParam(const std::string &name) const
const bool _deform_non_circular_region
Whether the non-circular region (outside the rings) can be deformed.
const bool _generate_control_drum_positions_file
Whether a text file containing control drum positions is generated.
std::vector< std::unique_ptr< MeshBase > *> getMeshes(const std::string &param_name)
void paramError(const std::string &param, Args... args) const
std::vector< subdomain_id_type > _peripheral_block_ids
Subdomain IDs of the peripheral regions.
const bool _use_interface_boundary_id_shift
whether the interface boundary ids from input meshes are shifted, using a user-defined pattern of val...
IntRange< T > make_range(T beg, T end)
const InputParameters & parameters() const
T & declareMeshProperty(const std::string &data_name, Args &&... args)
const BoundaryName _external_boundary_name
Boundary name of mesh&#39;s external boundary.
std::vector< bool > _exclude_ids
vector indicating which ids in the pattern to exclude (true at pattern positions to exclude) ...
PolygonMeshGeneratorBase(const InputParameters &parameters)
std::map< std::string, std::vector< std::vector< dof_id_type > > > _id_patterns
hold ID patterns for each manual reporting ID. Individual ID pattern contains ID values for each patt...
const bool _generate_core_metadata
Whether a reactor core mesh with core metadata is generated.

Member Function Documentation

◆ addPeripheralMesh()

void PatternedHexMeshGenerator::addPeripheralMesh ( ReplicatedMesh &  mesh,
const unsigned int  pattern,
const Real  pitch,
const std::vector< Real > &  extra_dist,
const std::vector< unsigned int > &  num_sectors_per_side_array,
const std::vector< unsigned int > &  peripheral_duct_intervals,
const Real  rotation_angle,
const unsigned int  mesh_type 
)
protected

Adds background and duct region mesh to stitched hexagon meshes.

Note that the function works for single unit hexagon mesh (corner or edge) separately before stitching.

Parameters
meshinput mesh to add the peripheral region onto
patternindex of the input mesh for patterning
pitchpitch size of the input mesh
extra_distextra distances from inner boundary to define background and ducts layer locations that are needed to create the peripheral region
num_sectors_per_side_arraynumbers of azimuthal intervals of all input unit meshes
peripheral_duct_intervalsnumbers of radial intervals of the duct regions
rotation_angleangle that the generated mesh will be rotated by
mesh_typewhether the peripheral region is for a corner or a side hexagon mesh
Returns
a mesh of the hexagon unit mesh with peripheral region added.

Definition at line 1030 of file PatternedHexMeshGenerator.C.

Referenced by generate().

1039 {
1040  std::vector<std::pair<Real, Real>> positions_inner;
1041  std::vector<std::pair<Real, Real>> d_positions_outer;
1042 
1043  std::vector<std::vector<unsigned int>> peripheral_point_index;
1044  std::vector<std::pair<Real, Real>> sub_positions_inner;
1045  std::vector<std::pair<Real, Real>> sub_d_positions_outer;
1046 
1047  if (mesh_type == CORNER_MESH)
1048  // corner mesh has three sides that need peripheral meshes.
1049  // each element has three sub-elements, representing beginning, middle, and ending azimuthal
1050  // points
1051  peripheral_point_index = {{0, 1, 2}, {2, 3, 4}, {4, 5, 6}};
1052  else
1053  // side mesh has two sides that need peripheral meshes.
1054  peripheral_point_index = {{0, 1, 2}, {2, 7, 8}};
1055 
1056  // extra_dist includes background and ducts.
1057  // Loop to calculate the positions of the boundaries.
1058  for (unsigned int i = 0; i < extra_dist.size(); i++)
1059  {
1060  positionSetup(positions_inner,
1061  d_positions_outer,
1062  i == 0 ? 0.0 : extra_dist[i - 1],
1063  extra_dist[i],
1064  pitch,
1065  i);
1066 
1067  // Loop for all applicable sides that need peripheral mesh (3 for corner and 2 for edge)
1068  for (unsigned int peripheral_index = 0; peripheral_index < peripheral_point_index.size();
1069  peripheral_index++)
1070  {
1071  // Loop for beginning, middle and ending positions of a side
1072  for (unsigned int vector_index = 0; vector_index < 3; vector_index++)
1073  {
1074  sub_positions_inner.push_back(
1075  positions_inner[peripheral_point_index[peripheral_index][vector_index]]);
1076  sub_d_positions_outer.push_back(
1077  d_positions_outer[peripheral_point_index[peripheral_index][vector_index]]);
1078  }
1079  auto meshp0 = buildSimplePeripheral(num_sectors_per_side_array[pattern],
1080  peripheral_duct_intervals[i],
1081  sub_positions_inner,
1082  sub_d_positions_outer,
1083  i,
1086  (i != extra_dist.size() - 1) &&
1088 
1089  // The other_mesh must be prepared before stitching
1090  meshp0->prepare_for_use();
1091 
1092  // rotate the peripheral mesh to the desired side of the hexagon.
1093  MeshTools::Modification::rotate(*meshp0, rotation_angle, 0, 0);
1094  mesh.stitch_meshes(*meshp0, OUTER_SIDESET_ID, OUTER_SIDESET_ID, TOLERANCE, true, false);
1095  sub_positions_inner.resize(0);
1096  sub_d_positions_outer.resize(0);
1097  }
1098  }
1099 }
void positionSetup(std::vector< std::pair< Real, Real >> &positions_inner, std::vector< std::pair< Real, Real >> &d_positions_outer, const Real extra_dist_in, const Real extra_dist_out, const Real pitch, const unsigned int radial_index) const
Computes the inner and outer node positions of the peripheral region for a single layer...
MeshBase & mesh
const bool _create_inward_interface_boundaries
Whether inward interface boundaries are created.
const bool _create_outward_interface_boundaries
Whether outward interface boundaries are created.
static const std::string pitch
QUAD_ELEM_TYPE _boundary_quad_elem_type
Type of quadrilateral elements to be generated in the periphery region.
std::unique_ptr< ReplicatedMesh > buildSimplePeripheral(const unsigned int num_sectors_per_side, const unsigned int peripheral_invervals, const std::vector< std::pair< Real, Real >> &position_inner, const std::vector< std::pair< Real, Real >> &d_position_outer, const subdomain_id_type id_shift, const QUAD_ELEM_TYPE quad_elem_type, const bool create_inward_interface_boundaries=false, const bool create_outward_interface_boundaries=true)
Creates peripheral area mesh for the patterned hexagon mesh.

◆ addReportingIDs()

void PatternedHexMeshGenerator::addReportingIDs ( MeshBase &  mesh,
const std::vector< std::unique_ptr< ReplicatedMesh >> &  from_meshes 
) const
protected

Adds the reporting IDs onto the input mesh.

Parameters
meshinput mesh to add the reporting IDs onto
from_meshesmeshes to take reporting IDs from

Definition at line 1212 of file PatternedHexMeshGenerator.C.

Referenced by generate().

1214 {
1215  const unsigned int num_reporting_ids = _reporting_id_names.size();
1216  for (unsigned int i = 0; i < num_reporting_ids; ++i)
1217  {
1218  const std::string element_id_name = _reporting_id_names[i];
1219  unsigned int extra_id_index;
1220  if (!mesh.has_elem_integer(element_id_name))
1221  extra_id_index = mesh.add_elem_integer(element_id_name);
1222  else
1223  {
1224  extra_id_index = mesh.get_elem_integer_index(element_id_name);
1225  paramWarning(
1226  "id_name", "An element integer with the name '", element_id_name, "' already exists");
1227  }
1228 
1229  // assign reporting IDs to individual elements
1230  // NOTE: background block id should be set "PERIPHERAL_ID_SHIFT" because this function is called
1231  // before assigning the user-defined background block id
1232  std::set<subdomain_id_type> background_block_ids =
1233  (isParamValid("background_block_id")) ? std::set<subdomain_id_type>({PERIPHERAL_ID_SHIFT})
1234  : std::set<subdomain_id_type>();
1235 
1236  const bool using_manual_id =
1239  extra_id_index,
1240  _assign_types[i],
1242  _exclude_ids,
1243  _pattern_boundary == "hexagon",
1244  background_block_ids,
1245  from_meshes,
1246  _pattern,
1247  (using_manual_id)
1248  ? _id_patterns.at(element_id_name)
1249  : std::vector<std::vector<dof_id_type>>());
1250  }
1251 }
std::vector< std::string > _reporting_id_names
names of reporting ID
const MooseEnum _pattern_boundary
Type of the external boundary shape.
void assignReportingIDs(MeshBase &mesh, const unsigned int extra_id_index, const ReportingIDGeneratorUtils::AssignType assign_type, const bool use_exclude_id, const std::vector< bool > &exclude_ids, const bool has_assembly_boundary, const std::set< subdomain_id_type > background_block_ids, const std::vector< std::unique_ptr< libMesh::ReplicatedMesh >> &input_meshes, const std::vector< std::vector< unsigned int >> &pattern, const std::vector< std::vector< dof_id_type >> &id_pattern)
assign the reporting IDs to the output mesh from the cartesian or hexagonal patterned mesh generator ...
assign IDs based on user-defined mapping
const std::vector< std::vector< unsigned int > > & _pattern
2D vector of the hexagonal pattern
MeshBase & mesh
bool isParamValid(const std::string &name) const
std::vector< ReportingIDGeneratorUtils::AssignType > _assign_types
reporting ID assignment type
const bool _use_exclude_id
flag to indicate if exclude_id is defined
void paramWarning(const std::string &param, Args... args) const
std::vector< bool > _exclude_ids
vector indicating which ids in the pattern to exclude (true at pattern positions to exclude) ...
std::map< std::string, std::vector< std::vector< dof_id_type > > > _id_patterns
hold ID patterns for each manual reporting ID. Individual ID pattern contains ID values for each patt...

◆ addRingAndSectorIDParams()

void PolygonMeshGeneratorBase::addRingAndSectorIDParams ( InputParameters params)
staticprotectedinherited

Add InputParameters which are used by ring and sector IDs.

Parameters
paramsInputParameters to be modified with the added params

Definition at line 1598 of file PolygonMeshGeneratorBase.C.

Referenced by PolygonConcentricCircleMeshGeneratorBase::validParams(), and TriPinHexAssemblyGenerator::validParams().

1599 {
1600  params.addParam<std::string>("sector_id_name",
1601  "Name of integer (reporting) ID for sector regions to use the "
1602  "reporting ID for azimuthal sector regions of ring geometry block.");
1603  params.addParam<std::string>("ring_id_name",
1604  "Name of integer (reporting) ID for ring regions to use the "
1605  "reporting ID for annular regions of ring geometry block.");
1606  MooseEnum ring_id_option("block_wise ring_wise", "block_wise");
1607  params.addParam<MooseEnum>(
1608  "ring_id_assign_type", ring_id_option, "Type of ring ID assignment: block_wise or ring_wise");
1609  params.addParamNamesToGroup("sector_id_name ring_id_name ring_id_assign_type", "Ring/Sector IDs");
1610 }
void addParam(const std::string &name, const std::initializer_list< typename T::value_type > &value, const std::string &doc_string)
void addParamNamesToGroup(const std::string &space_delim_names, const std::string group_name)

◆ adjustPeripheralQuadraticElements()

void PolygonMeshGeneratorBase::adjustPeripheralQuadraticElements ( MeshBase out_mesh,
const QUAD_ELEM_TYPE  boundary_quad_elem_type 
) const
protectedinherited

Adjusts the mid-edge node locations in boundary regions when using quadratic elements with uniform boundary node spacing enabled.

Parameters
out_meshmesh to be adjusted.
boundary_quad_elem_typeboundary quad element type.

Definition at line 1253 of file PolygonMeshGeneratorBase.C.

Referenced by generate(), and PatternedCartesianMeshGenerator::generate().

1255 {
1256  const auto side_list = out_mesh.get_boundary_info().build_side_list();
1257 
1258  // select out elements on outer boundary
1259  // std::set used to filter duplicate elem_ids
1260  std::set<dof_id_type> elem_set;
1261  for (auto side_item : side_list)
1262  {
1263  boundary_id_type boundary_id = std::get<2>(side_item);
1264  dof_id_type elem_id = std::get<0>(side_item);
1265 
1266  if (boundary_id == OUTER_SIDESET_ID)
1267  elem_set.insert(elem_id);
1268  }
1269 
1270  // adjust nodes for outer boundary elements
1271  for (const auto elem_id : elem_set)
1272  {
1273  Elem * elem = out_mesh.elem_ptr(elem_id);
1274 
1275  // adjust right side mid-edge node
1276  Point pt_5 = (elem->point(1) + elem->point(2)) / 2.0;
1277  out_mesh.add_point(pt_5, elem->node_ptr(5)->id());
1278 
1279  // adjust left side mid-edge node
1280  Point pt_7 = (elem->point(0) + elem->point(3)) / 2.0;
1281  out_mesh.add_point(pt_7, elem->node_ptr(7)->id());
1282 
1283  // adjust central node when using QUAD9
1284  if (boundary_quad_elem_type == QUAD_ELEM_TYPE::QUAD9)
1285  {
1286  Point pt_8 = elem->true_centroid();
1287  out_mesh.add_point(pt_8, elem->node_ptr(8)->id());
1288  }
1289  }
1290 }
virtual Point true_centroid() const
const BoundaryInfo & get_boundary_info() const
virtual Node * add_point(const Point &p, const dof_id_type id=DofObject::invalid_id, const processor_id_type proc_id=DofObject::invalid_processor_id)=0
void build_side_list(std::vector< dof_id_type > &element_id_list, std::vector< unsigned short int > &side_list, std::vector< boundary_id_type > &bc_id_list) const
int8_t boundary_id_type
dof_id_type id() const
virtual const Elem * elem_ptr(const dof_id_type i) const=0
const Node * node_ptr(const unsigned int i) const
const Point & point(const unsigned int i) const
uint8_t dof_id_type

◆ azimuthalAnglesCollector() [1/2]

std::vector<Real> PolygonMeshGeneratorBase::azimuthalAnglesCollector ( ReplicatedMesh &  mesh,
std::vector< Point > &  boundary_points,
const Real  lower_azi = -30.0,
const Real  upper_azi = 30.0,
const unsigned int  return_type = ANGLE_TANGENT,
const unsigned int  num_sides = 6,
const boundary_id_type  bid = OUTER_SIDESET_ID,
const bool  calculate_origin = true,
const Real  input_origin_x = 0.0,
const Real  input_origin_y = 0.0,
const Real  tol = 1.0E-10 
) const
protectedinherited

Collects sorted azimuthal angles of the external boundary.

Parameters
meshinput mesh whose boundary node azimuthal angles need to be collected
boundary_pointsreference vector to contain the Points corresponding to the collected azimuthal angles
lower_azilower boundary of the azimuthal angles to be collected
upper_aziupper boundary of the azimuthal angles to be collected
return_typewhether angle values or tangent values are returned
num_sidesnumber of sides of the input mesh (only used if return type is ANGLE_TANGENT)
bidid of the boundary of which the nodes' azimuthal angles are collected
calculate_originwhether the mesh origin is calculated based on the centroid position
input_origin_xprecalculated mesh origin coordinate x
input_origin_yprecalculated mesh origin coordinate y
toltolerance that the minimum azimuthal angle is
Returns
the list of azimuthal angles of all the nodes on the external grain boundary within the given range

Referenced by AzimuthalBlockSplitGenerator::generate(), PolygonConcentricCircleMeshGeneratorBase::generate(), and PatternedPolygonPeripheralModifierBase::generate().

◆ azimuthalAnglesCollector() [2/2]

std::vector<Real> PolygonMeshGeneratorBase::azimuthalAnglesCollector ( ReplicatedMesh &  mesh,
const Real  lower_azi = -30.0,
const Real  upper_azi = 30.0,
const unsigned int  return_type = ANGLE_TANGENT,
const unsigned int  num_sides = 6,
const boundary_id_type  bid = OUTER_SIDESET_ID,
const bool  calculate_origin = true,
const Real  input_origin_x = 0.0,
const Real  input_origin_y = 0.0,
const Real  tol = 1.0E-10 
) const
protectedinherited

Collects sorted azimuthal angles of the external boundary.

Parameters
meshinput mesh whose boundary node azimuthal angles need to be collected
lower_azilower boundary of the azimuthal angles to be collected
upper_aziupper boundary of the azimuthal angles to be collected
return_typewhether angle values or tangent values are returned
num_sidesnumber of sides of the input mesh (only used if return type is ANGLE_TANGENT)
bidid of the boundary of which the nodes' azimuthal angles are collected
calculate_originwhether the mesh origin is calculated based on the centroid position
input_origin_xprecalculated mesh origin coordinate x
input_origin_yprecalculated mesh origin coordinate y
toltolerence that the minimum azimuthal angle is
Returns
the list of azimuthal angles of all the nodes on the external grain boundary within the given range

◆ backgroundNodes()

void PolygonMeshGeneratorBase::backgroundNodes ( ReplicatedMesh mesh,
const unsigned int  num_sectors_per_side,
const unsigned int  background_intervals,
const std::vector< Real biased_terms,
const Real  background_corner_distance,
const Real  background_corner_radial_interval_length,
const Real  corner_p[2][2],
const Real  corner_to_corner,
const Real  background_in,
const std::vector< Real azimuthal_tangent = std::vector<Real>() 
) const
protectedinherited

Creates nodes for the ring-to-polygon transition region (i.e., background) of a single slice.

Parameters
meshinput mesh to add the nodes onto
num_sectors_per_sidenumber of azimuthal intervals
background_intervalsnumber of radial intervals of the background region
biased_termsnormalized spacing values used for radial meshing biasing in background region
background_corner_distancecenter to duct (innermost duct) corner distance
background_corner_radial_interval_lengthradial interval distance
corner_p[2][2]array contains the coordinates of the corner positions
corner_to_cornerdiameter of the circumscribed circle of the polygon
background_inradius of the inner boundary of the background region
azimuthal_tangentvector of tangent values of the azimuthal angles as reference for adaptive boundary matching
Returns
a mesh with background region nodes created

Definition at line 720 of file PolygonMeshGeneratorBase.C.

Referenced by PolygonMeshGeneratorBase::buildSlice().

730 {
731  unsigned int angle_number =
732  azimuthal_tangent.size() == 0 ? num_sectors_per_side : (azimuthal_tangent.size() - 1);
733  for (unsigned int k = 0; k < (background_intervals); k++)
734  {
735  const Real background_corner_p_x =
736  background_corner_distance / (0.5 * corner_to_corner) * corner_p[0][0] *
737  (background_in +
738  biased_terms[k] * background_intervals * background_corner_radial_interval_length) /
739  background_corner_distance;
740  const Real background_corner_p_y =
741  background_corner_distance / (0.5 * corner_to_corner) * corner_p[0][1] *
742  (background_in +
743  biased_terms[k] * background_intervals * background_corner_radial_interval_length) /
744  background_corner_distance;
745 
746  // background_corner_p(s) are the points in the background region, on the bins towards the six
747  // corners, at different intervals
748  mesh.add_point(Point(background_corner_p_x, background_corner_p_y, 0.0));
749 
750  for (unsigned int j = 1; j <= angle_number; j++)
751  {
752  const Real cell_boundary_p_x =
753  background_corner_distance / (0.5 * corner_to_corner) *
754  (corner_p[0][0] + (corner_p[1][0] - corner_p[0][0]) *
755  (azimuthal_tangent.size() == 0 ? ((Real)j / (Real)angle_number)
756  : (azimuthal_tangent[j] / 2.0)));
757  const Real cell_boundary_p_y =
758  background_corner_distance / (0.5 * corner_to_corner) *
759  (corner_p[0][1] + (corner_p[1][1] - corner_p[0][1]) *
760  (azimuthal_tangent.size() == 0 ? ((Real)j / (Real)angle_number)
761  : (azimuthal_tangent[j] / 2.0)));
762  // cell_boundary_p(s) are the points on the cell's six boundaries (flat sides) at different
763  // azimuthal angles
764  const Real pin_boundary_p_x =
765  cell_boundary_p_x * background_in /
766  std::sqrt(Utility::pow<2>(cell_boundary_p_x) + Utility::pow<2>(cell_boundary_p_y));
767  const Real pin_boundary_p_y =
768  cell_boundary_p_y * background_in /
769  std::sqrt(Utility::pow<2>(cell_boundary_p_x) + Utility::pow<2>(cell_boundary_p_y));
770  // pin_boundary_p(s) are the points on pin boundary (outside ring) at different azimuthal
771  // angles
772  const Real background_radial_interval =
773  std::sqrt(Utility::pow<2>(cell_boundary_p_x - pin_boundary_p_x) +
774  Utility::pow<2>(cell_boundary_p_y - pin_boundary_p_y)) /
775  background_intervals;
776  const Real background_azimuthal_p_x =
777  cell_boundary_p_x *
778  (background_in + biased_terms[k] * background_intervals * background_radial_interval) /
779  std::sqrt(Utility::pow<2>(cell_boundary_p_x) + Utility::pow<2>(cell_boundary_p_y));
780  const Real background_azimuthal_p_y =
781  cell_boundary_p_y *
782  (background_in + biased_terms[k] * background_intervals * background_radial_interval) /
783  std::sqrt(Utility::pow<2>(cell_boundary_p_x) + Utility::pow<2>(cell_boundary_p_y));
784  // background_azimuthal_p are the points on the bins towards different azimuthal angles, at
785  // different intervals; excluding the ones produced by background_corner_p
786  mesh.add_point(Point(background_azimuthal_p_x, background_azimuthal_p_y, 0.0));
787  }
788  }
789 }
MeshBase & mesh
virtual Node * add_point(const Point &p, const dof_id_type id=DofObject::invalid_id, const processor_id_type proc_id=DofObject::invalid_processor_id)=0
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
static const std::complex< double > j(0, 1)
Complex number "j" (also known as "i")
static const std::string k
Definition: NS.h:130

◆ biasTermsCalculator() [1/2]

std::vector< std::vector< Real > > PolygonMeshGeneratorBase::biasTermsCalculator ( const std::vector< Real radial_biases,
const std::vector< unsigned int intervals,
const multiBdryLayerParams  inner_boundary_layer_params,
const multiBdryLayerParams  outer_boundary_layer_params 
) const
protectedinherited

Creates bias terms for multiple blocks.

Parameters
radial_biasesbias growth factors of the elements within the main regions of the blocks
intervalsradial interval numbers of the main regions of the blocks
inner_boundary_layer_paramswidths, radial fractions, radial sectors, and growth factors of the inner boundary layers
outer_boundary_layer_paramswidths, radial fractions, radial sectors, and growth factors of the outer boundary layers
Returns
bias list of terms describing the cumulative radial fractions of the nodes within multiple blocks

Definition at line 1523 of file PolygonMeshGeneratorBase.C.

Referenced by PolygonMeshGeneratorBase::buildSlice(), and PeripheralRingMeshGenerator::generate().

1528 {
1529  std::vector<std::vector<Real>> bias_terms_vec;
1530  for (unsigned int i = 0; i < radial_biases.size(); i++)
1531  bias_terms_vec.push_back(biasTermsCalculator(radial_biases[i],
1532  intervals[i],
1533  {0.0,
1534  inner_boundary_layer_params.fractions[i],
1535  inner_boundary_layer_params.intervals[i],
1536  inner_boundary_layer_params.biases[i]},
1537  {0.0,
1538  outer_boundary_layer_params.fractions[i],
1539  outer_boundary_layer_params.intervals[i],
1540  outer_boundary_layer_params.biases[i]}));
1541  return bias_terms_vec;
1542 }
std::vector< std::vector< Real > > biasTermsCalculator(const std::vector< Real > radial_biases, const std::vector< unsigned int > intervals, const multiBdryLayerParams inner_boundary_layer_params, const multiBdryLayerParams outer_boundary_layer_params) const
Creates bias terms for multiple blocks.

◆ biasTermsCalculator() [2/2]

std::vector< Real > PolygonMeshGeneratorBase::biasTermsCalculator ( const Real  radial_bias,
const unsigned int  intervals,
const singleBdryLayerParams  inner_boundary_layer_params = {0.0, 0.0, 0, 1.0},
const singleBdryLayerParams  outer_boundary_layer_params = {0.0, 0.0, 0, 1.0} 
) const
protectedinherited

Creates bias terms for a single block.

Parameters
radial_biasbias growth factor of the elements within the main region of the block
intervalsradial interval number of the main region of the block
inner_boundary_layer_paramswidth, radial fraction, radial sector, and growth factor of the inner boundary layer
outer_boundary_layer_paramswidth, radial fraction, radial sector, and growth factor of the outer boundary layer
Returns
bias terms describing the cumulative radial fractions of the nodes within a single block

Definition at line 1545 of file PolygonMeshGeneratorBase.C.

1550 {
1551  // To get biased indices:
1552  // If no bias is involved, namely bias factor = 1.0, the increment in indices is uniform.
1553  // Thus, (i + 1) is used to get such linearly increasing indices.
1554  // If a non-trivial bias factor q is used, the increment in the indices is geometric
1555  // progression. So, if first (i = 0) increment is 1.0, second (i = 1) is q, third (i = 2) is
1556  // q^2,..., last or n_interval'th is q^(n_interval - 1). Then, the summation of the first (i +
1557  // 1) increments over the summation of all n_interval increments is the (i + 1)th index The
1558  // summation of the first (i + 1) increments is (1.0 - q^(i + 1)) / (1 - q); The summation of
1559  // all n_interval increments is (1.0 - q^n_interval) / (1 - q); Thus, the index is (1.0 - q^(i +
1560  // 1)) / (1.0 - q^n_interval)
1561  // This approach is used by inner boundary layer, main region, outer boundary layer separately.
1562 
1563  std::vector<Real> biased_terms;
1564  for (unsigned int i = 0; i < inner_boundary_layer_params.intervals; i++)
1565  biased_terms.push_back(
1566  MooseUtils::absoluteFuzzyEqual(inner_boundary_layer_params.bias, 1.0)
1567  ? ((Real)(i + 1) * inner_boundary_layer_params.fraction /
1568  (Real)inner_boundary_layer_params.intervals)
1569  : ((1.0 - std::pow(inner_boundary_layer_params.bias, (Real)(i + 1))) /
1570  (1.0 - std::pow(inner_boundary_layer_params.bias,
1571  (Real)(inner_boundary_layer_params.intervals))) *
1572  inner_boundary_layer_params.fraction));
1573  for (unsigned int i = 0; i < intervals; i++)
1574  biased_terms.push_back(inner_boundary_layer_params.fraction +
1575  (MooseUtils::absoluteFuzzyEqual(radial_bias, 1.0)
1576  ? ((Real)(i + 1) *
1577  (1.0 - inner_boundary_layer_params.fraction -
1578  outer_boundary_layer_params.fraction) /
1579  (Real)intervals)
1580  : ((1.0 - std::pow(radial_bias, (Real)(i + 1))) /
1581  (1.0 - std::pow(radial_bias, (Real)(intervals))) *
1582  (1.0 - inner_boundary_layer_params.fraction -
1583  outer_boundary_layer_params.fraction))));
1584  for (unsigned int i = 0; i < outer_boundary_layer_params.intervals; i++)
1585  biased_terms.push_back(
1586  1.0 - outer_boundary_layer_params.fraction +
1587  (MooseUtils::absoluteFuzzyEqual(outer_boundary_layer_params.bias, 1.0)
1588  ? ((Real)(i + 1) * outer_boundary_layer_params.fraction /
1589  (Real)outer_boundary_layer_params.intervals)
1590  : ((1.0 - std::pow(outer_boundary_layer_params.bias, (Real)(i + 1))) /
1591  (1.0 - std::pow(outer_boundary_layer_params.bias,
1592  (Real)(outer_boundary_layer_params.intervals))) *
1593  outer_boundary_layer_params.fraction)));
1594  return biased_terms;
1595 }
bool absoluteFuzzyEqual(const T &var1, const T2 &var2, const T3 &tol=libMesh::TOLERANCE *libMesh::TOLERANCE)
MooseUnits pow(const MooseUnits &, int)

◆ buildGeneralSlice()

std::unique_ptr< ReplicatedMesh > PolygonMeshGeneratorBase::buildGeneralSlice ( std::vector< Real ring_radii,
const std::vector< unsigned int ring_layers,
const std::vector< Real ring_radial_biases,
const multiBdryLayerParams ring_inner_boundary_layer_params,
const multiBdryLayerParams ring_outer_boundary_layer_params,
std::vector< Real ducts_center_dist,
const std::vector< unsigned int ducts_layers,
const std::vector< Real duct_radial_biases,
const multiBdryLayerParams duct_inner_boundary_layer_params,
const multiBdryLayerParams duct_outer_boundary_layer_params,
const Real  primary_side_length,
const Real  secondary_side_length,
const unsigned int  num_sectors_per_side,
const unsigned int  background_intervals,
const Real  background_radial_bias,
const singleBdryLayerParams background_inner_boundary_layer_params,
const singleBdryLayerParams background_outer_boundary_layer_params,
dof_id_type node_id_background_meta,
const Real  azimuthal_angle,
const std::vector< Real azimuthal_tangent,
const unsigned int  side_index,
const bool  quad_center_elements,
const Real  center_quad_factor,
const Real  rotation_angle,
const bool  generate_side_specific_boundaries = true 
)
protectedinherited

Creates a mesh of a general polygon slice with a triangular shape and circular regions on one of its vertex.

Parameters
ring_radiiradii of the ring regions
ring_layersnumbers of radial intervals of the ring regions
ring_radial_biasesvalues used for radial meshing biasing in ring regions
ring_inner_boundary_layer_paramswidths, radial fractions, radial sectors, and growth factors of the inner boundary layer of the ring regions
ring_outer_boundary_layer_paramswidths, radial fractions, radial sectors, and growth factors of the outer boundary layer of the ring regions
ducts_center_distdistance parameters of the duct regions
ducts_layersnumbers of radial intervals of the duct regions
duct_radial_biasesvalues used for radial meshing biasing in duct regions
duct_inner_boundary_layer_paramswidths, radial fractions, radial sectors, and growth factors of the inner boundary layer of the duct regions
duct_outer_boundary_layer_paramswidths, radial fractions, radial sectors, and growth factors of the outer boundary layer of the duct regions
primary_side_lengthlength of the first side (i.e., the side that is parallel to y-axis when rotation_angle is zero) that involves the ring center vertex
secondary_side_lengthlength of the second side (obtained by clockwise rotating the fist side by azimuthal_angle) that involves the ring center vertex
num_sectors_per_sidenumber of azimuthal intervals
background_intervalsnumber of radial intervals of the background region
background_radial_biasvalue used for radial meshing biasing in background region
background_inner_boundary_layer_paramswidth, radial sectors, and growth factor of the inner boundary layer of the background region
background_outer_boundary_layer_paramswidth, radial sectors, and growth factor of the outer boundary layer of the background region
node_id_background_metapointer to the first node's id of the background region
azimuthal_anglethe angle defined by the primary and secondary sides
azimuthal_tangentvector of tangent values of the azimuthal angles as reference for adaptive boundary matching
side_indexindex of the polygon side
quad_center_elementswhether the central region contains quad elements or not
center_quad_factorA fractional radius factor used to determine the radial positions of transition nodes in the center region meshed by quad elements (default is 1.0 - 1.0/div_num)
rotation_angleazimuthal angle of the primary side
generate_side_specific_boundarieswhether the side-specific external boundaries are generated or not
Returns
a mesh of a general slice

Definition at line 42 of file PolygonMeshGeneratorBase.C.

Referenced by TriPinHexAssemblyGenerator::buildSinglePinSection().

68 {
69  const Real virtual_pitch = 2.0 * primary_side_length * cos(azimuthal_angle / 360.0 * M_PI);
70  const Real virtual_side_number = 360.0 / azimuthal_angle;
71  const Real pitch_scale_factor = secondary_side_length / primary_side_length;
72 
73  auto mesh = buildSlice(ring_radii,
74  ring_layers,
75  ring_radial_biases,
76  ring_inner_boundary_layer_params,
77  ring_outer_boundary_layer_params,
78  ducts_center_dist,
79  ducts_layers,
80  duct_radial_biases,
81  duct_inner_boundary_layer_params,
82  duct_outer_boundary_layer_params,
83  virtual_pitch,
84  num_sectors_per_side,
85  background_intervals,
86  background_radial_bias,
87  background_inner_boundary_layer_params,
88  background_outer_boundary_layer_params,
89  node_id_background_meta,
90  virtual_side_number,
91  side_index,
92  azimuthal_tangent,
93  0,
94  quad_center_elements,
95  center_quad_factor,
96  false,
97  true,
98  0,
99  pitch_scale_factor,
100  generate_side_specific_boundaries);
101  MeshTools::Modification::rotate(*mesh, rotation_angle, 0, 0);
102  return mesh;
103 }
std::unique_ptr< ReplicatedMesh > buildSlice(std::vector< Real > ring_radii, const std::vector< unsigned int > ring_layers, const std::vector< Real > ring_radial_biases, const multiBdryLayerParams &ring_inner_boundary_layer_params, const multiBdryLayerParams &ring_outer_boundary_layer_params, std::vector< Real > ducts_center_dist, const std::vector< unsigned int > ducts_layers, const std::vector< Real > duct_radial_biases, const multiBdryLayerParams &duct_inner_boundary_layer_params, const multiBdryLayerParams &duct_outer_boundary_layer_params, const Real pitch, const unsigned int num_sectors_per_side, const unsigned int background_intervals, const Real background_radial_bias, const singleBdryLayerParams &background_inner_boundary_layer_params, const singleBdryLayerParams &background_outer_boundary_layer_params, dof_id_type &node_id_background_meta, const Real virtual_side_number, const unsigned int side_index, const std::vector< Real > azimuthal_tangent=std::vector< Real >(), const subdomain_id_type block_id_shift=0, const bool quad_center_elements=false, const Real center_quad_factor=0.0, const bool create_inward_interface_boundaries=false, const bool create_outward_interface_boundaries=true, const boundary_id_type boundary_id_shift=0, const Real pitch_scale_factor=1.0, const bool generate_side_specific_boundaries=true, const TRI_ELEM_TYPE tri_elem_type=TRI_ELEM_TYPE::TRI3, const QUAD_ELEM_TYPE quad_elem_type=QUAD_ELEM_TYPE::QUAD4)
Generates a mesh of a polygon slice, which is the foundation of both buildGeneralSlice and buildSimpl...
MeshBase & mesh
CTSub CT_OPERATOR_BINARY CTMul CTCompareLess CTCompareGreater CTCompareEqual _arg template cos(_arg) *_arg.template D< dtag >()) CT_SIMPLE_UNARY_FUNCTION(cos
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
static const std::string ring_radii

◆ buildSimplePeripheral()

std::unique_ptr< ReplicatedMesh > PolygonMeshGeneratorBase::buildSimplePeripheral ( const unsigned int  num_sectors_per_side,
const unsigned int  peripheral_invervals,
const std::vector< std::pair< Real, Real >> &  position_inner,
const std::vector< std::pair< Real, Real >> &  d_position_outer,
const subdomain_id_type  id_shift,
const QUAD_ELEM_TYPE  quad_elem_type,
const bool  create_inward_interface_boundaries = false,
const bool  create_outward_interface_boundaries = true 
)
protectedinherited

Creates peripheral area mesh for the patterned hexagon mesh.

Note that the function create the peripheral area for each side of the unit hexagon mesh before stitching. An edge unit hexagon has two sides that need peripheral areas, whereas a corner unit hexagon has three such sides. The positions of the inner and outer boundary nodes are pre-calculated as positions_inner and d_positions_outer; This function performs interpolation to generate the mesh grid.

Parameters
meshinput mesh to create the peripheral area mesh onto
num_sectors_per_sidenumber of azimuthal intervals
peripheral_invervalsnumber of radial intervals of the peripheral region
position_innerkey positions of the inner side of the peripheral region
d_position_outerkey inremental positions of the outer side of the peripheral region
id_shiftshift of subdomain id of the peripheral region
create_inward_interface_boundarieswhether inward interface boundary sidesets are created
create_outward_interface_boundarieswhether outward interface boundary sidesets are created
quad_elem_typetype of quad element to be created
Returns
a mesh with the peripheral region added to a hexagon input mesh

Definition at line 1153 of file PolygonMeshGeneratorBase.C.

Referenced by addPeripheralMesh(), and PatternedCartesianMeshGenerator::addPeripheralMesh().

1162 {
1163  auto mesh = buildReplicatedMesh(2);
1164  std::pair<Real, Real> positions_p;
1165 
1166  // generate node positions
1167  for (unsigned int i = 0; i <= peripheral_invervals; i++)
1168  {
1169  for (unsigned int j = 0; j <= num_sectors_per_side / 2; j++)
1170  {
1171  positions_p = pointInterpolate(positions_inner[0].first,
1172  positions_inner[0].second,
1173  d_positions_outer[0].first,
1174  d_positions_outer[0].second,
1175  positions_inner[1].first,
1176  positions_inner[1].second,
1177  d_positions_outer[1].first,
1178  d_positions_outer[1].second,
1179  i,
1180  j,
1181  num_sectors_per_side,
1182  peripheral_invervals);
1183  mesh->add_point(Point(positions_p.first, positions_p.second, 0.0));
1184  }
1185  for (unsigned int j = 1; j <= num_sectors_per_side / 2; j++)
1186  {
1187  positions_p = pointInterpolate(positions_inner[1].first,
1188  positions_inner[1].second,
1189  d_positions_outer[1].first,
1190  d_positions_outer[1].second,
1191  positions_inner[2].first,
1192  positions_inner[2].second,
1193  d_positions_outer[2].first,
1194  d_positions_outer[2].second,
1195  i,
1196  j,
1197  num_sectors_per_side,
1198  peripheral_invervals);
1199  mesh->add_point(Point(positions_p.first, positions_p.second, 0.0));
1200  }
1201  }
1202 
1203  // element definition
1204  BoundaryInfo & boundary_info = mesh->get_boundary_info();
1205 
1206  for (unsigned int i = 0; i < peripheral_invervals; i++)
1207  {
1208  for (unsigned int j = 0; j < num_sectors_per_side; j++)
1209  {
1210  std::unique_ptr<Elem> new_elem;
1211 
1212  new_elem = std::make_unique<Quad4>();
1213  new_elem->set_node(0, mesh->node_ptr(j + (num_sectors_per_side + 1) * (i)));
1214  new_elem->set_node(1, mesh->node_ptr(j + 1 + (num_sectors_per_side + 1) * (i)));
1215  new_elem->set_node(2, mesh->node_ptr(j + 1 + (num_sectors_per_side + 1) * (i + 1)));
1216  new_elem->set_node(3, mesh->node_ptr(j + (num_sectors_per_side + 1) * (i + 1)));
1217 
1218  Elem * elem = mesh->add_elem(std::move(new_elem));
1219 
1220  // add subdoamin and boundary IDs
1221  elem->subdomain_id() = PERIPHERAL_ID_SHIFT + id_shift;
1222  if (i == 0)
1223  {
1224  boundary_info.add_side(elem, 0, OUTER_SIDESET_ID);
1225  if (create_inward_interface_boundaries)
1226  boundary_info.add_side(elem, 0, SLICE_ALT + id_shift * 2);
1227  }
1228  if (i == peripheral_invervals - 1)
1229  {
1230  boundary_info.add_side(elem, 2, OUTER_SIDESET_ID);
1231  if (create_outward_interface_boundaries)
1232  boundary_info.add_side(elem, 2, SLICE_ALT + id_shift * 2 + 1);
1233  }
1234  if (j == 0)
1235  boundary_info.add_side(elem, 3, OUTER_SIDESET_ID);
1236  if (j == num_sectors_per_side - 1)
1237  boundary_info.add_side(elem, 1, OUTER_SIDESET_ID);
1238  }
1239  }
1240 
1241  // convert element to second order if needed
1242  if (quad_elem_type != QUAD_ELEM_TYPE::QUAD4)
1243  {
1244  // full_ordered 2nd order element --> QUAD9, otherwise QUAD8
1245  const bool full_ordered = (quad_elem_type == QUAD_ELEM_TYPE::QUAD9);
1246  mesh->all_second_order(full_ordered);
1247  }
1248 
1249  return mesh;
1250 }
std::unique_ptr< ReplicatedMesh > buildReplicatedMesh(unsigned int dim=libMesh::invalid_uint)
MeshBase & mesh
const BoundaryInfo & get_boundary_info() const
virtual Node * add_point(const Point &p, const dof_id_type id=DofObject::invalid_id, const processor_id_type proc_id=DofObject::invalid_processor_id)=0
virtual Elem * add_elem(Elem *e)=0
std::pair< Real, Real > pointInterpolate(const Real pi_1_x, const Real pi_1_y, const Real po_1_x, const Real po_1_y, const Real pi_2_x, const Real pi_2_y, const Real po_2_x, const Real po_2_y, const unsigned int i, const unsigned int j, const unsigned int num_sectors_per_side, const unsigned int peripheral_intervals) const
Calculates the point coordinates of within a parallelogram region using linear interpolation.
subdomain_id_type subdomain_id() const
void add_side(const dof_id_type elem, const unsigned short int side, const boundary_id_type id)
void all_second_order(const bool full_ordered=true)
static const std::complex< double > j(0, 1)
Complex number "j" (also known as "i")
virtual const Node * node_ptr(const dof_id_type i) const=0

◆ buildSimpleSlice()

std::unique_ptr< ReplicatedMesh > PolygonMeshGeneratorBase::buildSimpleSlice ( std::vector< Real ring_radii,
const std::vector< unsigned int ring_layers,
const std::vector< Real ring_radial_biases,
const multiBdryLayerParams ring_inner_boundary_layer_params,
const multiBdryLayerParams ring_outer_boundary_layer_params,
std::vector< Real ducts_center_dist,
const std::vector< unsigned int ducts_layers,
const std::vector< Real duct_radial_biases,
const multiBdryLayerParams duct_inner_boundary_layer_params,
const multiBdryLayerParams duct_outer_boundary_layer_params,
const Real  pitch,
const unsigned int  num_sectors_per_side,
const unsigned int  background_intervals,
const Real  background_radial_bias,
const singleBdryLayerParams background_inner_boundary_layer_params,
const singleBdryLayerParams background_outer_boundary_layer_params,
dof_id_type node_id_background_meta,
const unsigned int  side_number,
const unsigned int  side_index,
const std::vector< Real azimuthal_tangent = std::vector<Real>(),
const subdomain_id_type  block_id_shift = 0,
const bool  quad_center_elements = false,
const Real  center_quad_factor = 0.0,
const bool  create_inward_interface_boundaries = false,
const bool  create_outward_interface_boundaries = true,
const boundary_id_type  boundary_id_shift = 0,
const bool  generate_side_specific_boundaries = true,
const TRI_ELEM_TYPE  tri_elem_type = TRI_ELEM_TYPE::TRI3,
const QUAD_ELEM_TYPE  quad_elem_type = QUAD_ELEM_TYPE::QUAD4 
)
protectedinherited

Creates a mesh of a slice that corresponds to a single side of the polygon to be generated.

Parameters
ring_radiiradii of the ring regions
ring_layersnumbers of radial intervals of the ring regions
ring_radial_biasesvalues used for radial meshing biasing in ring regions
ring_inner_boundary_layer_paramswidths, radial fractions, radial sectors, and growth factors of the inner boundary layer of the ring regions
ring_outer_boundary_layer_paramswidths, radial fractions, radial sectors, and growth factors of the outer boundary layer of the ring regions
ducts_center_distdistance parameters of the duct regions
ducts_layersnumbers of radial intervals of the duct regions
duct_radial_biasesvalues used for radial meshing biasing in duct regions
duct_inner_boundary_layer_paramswidths, radial fractions, radial sectors, and growth factors of the inner boundary layer of the duct regions
duct_outer_boundary_layer_paramswidths, radial fractions, radial sectors, and growth factors of the outer boundary layer of the duct regions
pitchtwice the distance from the ring center vertex to the side defined by the other vertices
num_sectors_per_sidenumber of azimuthal intervals
background_intervalsnumber of radial intervals of the background region
background_radial_biasvalue used for radial meshing biasing in background region
background_inner_boundary_layer_paramswidth, radial sectors, and growth factor of the inner boundary layer of the background region
background_outer_boundary_layer_paramswidth, radial sectors, and growth factor of the outer boundary layer of the background region
node_id_background_metapointer to the first node's id of the background region
side_numbernumber of sides of the polygon
side_indexindex of the polygon side
azimuthal_tangentvector of tangent values of the azimuthal angles as reference for adaptive boundary matching
block_id_shiftshift of the subdomain ids generated by this function
quad_center_elementswhether the central region contrains quad elements or not
center_quad_factorA fractional radius factor used to determine the radial positions of transition nodes in the center region meshed by quad elements (default is 1.0 - 1.0/div_num)
create_inward_interface_boundarieswhether inward interface boundary sidesets are created
create_outward_interface_boundarieswhether outward interface boundary sidesets are created
boundary_id_shiftshift of the interface boundary ids
generate_side_specific_boundarieswhether the side-specific external boundaries are generated or not
tri_elem_typetype of the triangular elements to be generated
quad_elem_typetype of the quadrilateral elements to be generated
Returns
a mesh of a polygon slice

Definition at line 106 of file PolygonMeshGeneratorBase.C.

Referenced by PolygonConcentricCircleMeshGeneratorBase::generate().

136 {
137  return buildSlice(ring_radii,
138  ring_layers,
139  ring_radial_biases,
140  ring_inner_boundary_layer_params,
141  ring_outer_boundary_layer_params,
142  ducts_center_dist,
143  ducts_layers,
144  duct_radial_biases,
145  duct_inner_boundary_layer_params,
146  duct_outer_boundary_layer_params,
147  pitch,
148  num_sectors_per_side,
149  background_intervals,
150  background_radial_bias,
151  background_inner_boundary_layer_params,
152  background_outer_boundary_layer_params,
153  node_id_background_meta,
154  side_number,
155  side_index,
156  azimuthal_tangent,
157  block_id_shift,
158  quad_center_elements,
159  center_quad_factor,
160  create_inward_interface_boundaries,
161  create_outward_interface_boundaries,
162  boundary_id_shift,
163  1.0,
164  generate_side_specific_boundaries,
165  tri_elem_type,
166  quad_elem_type);
167 }
std::unique_ptr< ReplicatedMesh > buildSlice(std::vector< Real > ring_radii, const std::vector< unsigned int > ring_layers, const std::vector< Real > ring_radial_biases, const multiBdryLayerParams &ring_inner_boundary_layer_params, const multiBdryLayerParams &ring_outer_boundary_layer_params, std::vector< Real > ducts_center_dist, const std::vector< unsigned int > ducts_layers, const std::vector< Real > duct_radial_biases, const multiBdryLayerParams &duct_inner_boundary_layer_params, const multiBdryLayerParams &duct_outer_boundary_layer_params, const Real pitch, const unsigned int num_sectors_per_side, const unsigned int background_intervals, const Real background_radial_bias, const singleBdryLayerParams &background_inner_boundary_layer_params, const singleBdryLayerParams &background_outer_boundary_layer_params, dof_id_type &node_id_background_meta, const Real virtual_side_number, const unsigned int side_index, const std::vector< Real > azimuthal_tangent=std::vector< Real >(), const subdomain_id_type block_id_shift=0, const bool quad_center_elements=false, const Real center_quad_factor=0.0, const bool create_inward_interface_boundaries=false, const bool create_outward_interface_boundaries=true, const boundary_id_type boundary_id_shift=0, const Real pitch_scale_factor=1.0, const bool generate_side_specific_boundaries=true, const TRI_ELEM_TYPE tri_elem_type=TRI_ELEM_TYPE::TRI3, const QUAD_ELEM_TYPE quad_elem_type=QUAD_ELEM_TYPE::QUAD4)
Generates a mesh of a polygon slice, which is the foundation of both buildGeneralSlice and buildSimpl...
static const std::string pitch
static const std::string ring_radii

◆ buildSlice()

std::unique_ptr< ReplicatedMesh > PolygonMeshGeneratorBase::buildSlice ( std::vector< Real ring_radii,
const std::vector< unsigned int ring_layers,
const std::vector< Real ring_radial_biases,
const multiBdryLayerParams ring_inner_boundary_layer_params,
const multiBdryLayerParams ring_outer_boundary_layer_params,
std::vector< Real ducts_center_dist,
const std::vector< unsigned int ducts_layers,
const std::vector< Real duct_radial_biases,
const multiBdryLayerParams duct_inner_boundary_layer_params,
const multiBdryLayerParams duct_outer_boundary_layer_params,
const Real  pitch,
const unsigned int  num_sectors_per_side,
const unsigned int  background_intervals,
const Real  background_radial_bias,
const singleBdryLayerParams background_inner_boundary_layer_params,
const singleBdryLayerParams background_outer_boundary_layer_params,
dof_id_type node_id_background_meta,
const Real  virtual_side_number,
const unsigned int  side_index,
const std::vector< Real azimuthal_tangent = std::vector<Real>(),
const subdomain_id_type  block_id_shift = 0,
const bool  quad_center_elements = false,
const Real  center_quad_factor = 0.0,
const bool  create_inward_interface_boundaries = false,
const bool  create_outward_interface_boundaries = true,
const boundary_id_type  boundary_id_shift = 0,
const Real  pitch_scale_factor = 1.0,
const bool  generate_side_specific_boundaries = true,
const TRI_ELEM_TYPE  tri_elem_type = TRI_ELEM_TYPE::TRI3,
const QUAD_ELEM_TYPE  quad_elem_type = QUAD_ELEM_TYPE::QUAD4 
)
protectedinherited

Generates a mesh of a polygon slice, which is the foundation of both buildGeneralSlice and buildSimpleSlice.

Parameters
ring_radiiradii of the ring regions
ring_layersnumbers of radial intervals of the ring regions
ring_radial_biasesvalues used for radial meshing biasing in ring regions
ring_inner_boundary_layer_paramswidths, radial fractions, radial sectors, and growth factors of the inner boundary layer of the ring regions
ring_outer_boundary_layer_paramswidths, radial fractions, radial sectors, and growth factors of the outer boundary layer of the ring regions
ducts_center_distdistance parameters of the duct regions
ducts_layersnumbers of radial intervals of the duct regions
duct_radial_biasesvalues used for radial meshing biasing in duct regions
duct_inner_boundary_layer_paramswidths, radial fractions, radial sectors, and growth factors of the inner boundary layer of the duct regions
duct_outer_boundary_layer_paramswidths, radial fractions, radial sectors, and growth factors of the outer boundary layer of the duct regions
pitchtwice of the length of the first side times cosine of the azimuthal angle
num_sectors_per_sidenumber of azimuthal intervals
background_intervalsnumber of radial intervals of the background region
background_radial_biasvalue used for radial meshing biasing in background region
background_inner_boundary_layer_paramswidth, radial sectors, and growth factor of the inner boundary layer of the background region
background_outer_boundary_layer_paramswidth, radial sectors, and growth factor of the outer boundary layer of the background region
node_id_background_metapointer to the first node's id of the background region
virtual_side_number360.0 over the azimuthal angle of the slice (happens to be number of sides of the polygon if a regular polygon is to be generated)
side_indexindex of the polygon side
azimuthal_tangentvector of tangent values of the azimuthal angles as reference for adaptive boundary matching
block_id_shiftshift of the subdomain ids generated by this function
quad_center_elementswhether the central region contrains quad elements or not
center_quad_factorA fractional radius factor used to determine the radial positions of transition nodes in the center region meshed by quad elements (default is 1.0 - 1.0/div_num)
create_inward_interface_boundarieswhether inward interface boundary sidesets are created
create_outward_interface_boundarieswhether outward interface boundary sidesets are created
boundary_id_shiftshift of the interface boundary ids
pitch_scale_factorthe ratio between the secondary side length to the primary side length.
generate_side_specific_boundarieswhether the side-specific external boundaries are generated or not
tri_elem_typetype of the triangular elements to be generated
quad_elem_typetype of the quadrilateral elements to be generated
Returns
a mesh of a slice

Definition at line 170 of file PolygonMeshGeneratorBase.C.

Referenced by PolygonMeshGeneratorBase::buildGeneralSlice(), PolygonMeshGeneratorBase::buildSimpleSlice(), and AdvancedConcentricCircleGenerator::generate().

201 {
202  const unsigned short order = quad_elem_type == QUAD_ELEM_TYPE::QUAD4 ? 1 : 2;
203  if (order != (tri_elem_type == TRI_ELEM_TYPE::TRI3 ? 1 : 2))
204  mooseError("In mesh generator ",
205  this->name(),
206  ", an incompatible elements type combination is used when calling "
207  "PolygonMeshGeneratorBase::buildSlice().");
208  // In order to create quadratic elements (i.e., order = 2), we creates nodes with double mesh
209  // density. Thus, the related parameters need to be modified accordingly. A prefix "mod_" is used
210  // to indicate the modified parameters.
211 
212  // For ring_layers, modification is to double the number of layers for order = 2
213  std::vector<unsigned int> mod_ring_layers(ring_layers);
214  std::for_each(
215  mod_ring_layers.begin(), mod_ring_layers.end(), [&order](unsigned int & n) { n *= order; });
216  // For ring_radial_biases, modification is to take the square root of the original biases for
217  // order = 2
218  std::vector<Real> mod_ring_radial_biases(ring_radial_biases);
219  std::for_each(mod_ring_radial_biases.begin(),
220  mod_ring_radial_biases.end(),
221  [&order](Real & n) { n = std::pow(n, 1.0 / order); });
222  // ducts_layers is similar to ring_layers
223  std::vector<unsigned int> mod_ducts_layers(ducts_layers);
224  std::for_each(
225  mod_ducts_layers.begin(), mod_ducts_layers.end(), [&order](unsigned int & n) { n *= order; });
226  // duct_radial_biases is similar to ring_radial_biases
227  std::vector<Real> mod_duct_radial_biases(duct_radial_biases);
228  std::for_each(mod_duct_radial_biases.begin(),
229  mod_duct_radial_biases.end(),
230  [&order](Real & n) { n = std::pow(n, 1.0 / order); });
231  // Azimuthal mesh density is also doubled for order = 2
232  const unsigned int mod_num_sectors_per_side = num_sectors_per_side * order;
233  const unsigned int mod_background_intervals = background_intervals * order;
234  // background_radial_bias is similar to ring_radial_biases
235  const Real mod_background_radial_bias = std::pow(background_radial_bias, 1.0 / order);
236  // Perform similar modifications for boundary layer parameters
237  const auto mod_ring_inner_boundary_layer_params =
238  modifiedMultiBdryLayerParamsCreator(ring_inner_boundary_layer_params, order);
239  const auto mod_ring_outer_boundary_layer_params =
240  modifiedMultiBdryLayerParamsCreator(ring_outer_boundary_layer_params, order);
241  const auto mod_duct_inner_boundary_layer_params =
242  modifiedMultiBdryLayerParamsCreator(duct_inner_boundary_layer_params, order);
243  const auto mod_duct_outer_boundary_layer_params =
244  modifiedMultiBdryLayerParamsCreator(duct_outer_boundary_layer_params, order);
245 
246  const auto mod_background_inner_boundary_layer_params =
247  modifiedSingleBdryLayerParamsCreator(background_inner_boundary_layer_params, order);
248  const auto mod_background_outer_boundary_layer_params =
249  modifiedSingleBdryLayerParamsCreator(background_outer_boundary_layer_params, order);
250 
251  // The distance parameters of the rings and duct need to be modified too as they may be involved
252  // in the boundary layer cases.
253  std::vector<Real> mod_ducts_center_dist(ducts_center_dist);
254  std::vector<Real> mod_ring_radii(ring_radii);
255  bool has_rings(ring_radii.size());
256  bool has_ducts(ducts_center_dist.size());
257  bool has_background(background_intervals);
258  auto mesh = buildReplicatedMesh(2);
259 
260  // Calculate biasing terms
261  // background region needs to be split into three parts
262  const auto main_background_bias_terms =
263  biasTermsCalculator(background_radial_bias, background_intervals);
264  const auto inner_background_bias_terms =
265  biasTermsCalculator(background_inner_boundary_layer_params.bias,
266  background_inner_boundary_layer_params.intervals);
267  const auto outer_background_bias_terms =
268  biasTermsCalculator(background_outer_boundary_layer_params.bias,
269  background_outer_boundary_layer_params.intervals);
270  auto rings_bias_terms = biasTermsCalculator(ring_radial_biases,
271  ring_layers,
272  ring_inner_boundary_layer_params,
273  ring_outer_boundary_layer_params);
274  auto duct_bias_terms = biasTermsCalculator(duct_radial_biases,
275  ducts_layers,
276  duct_inner_boundary_layer_params,
277  duct_outer_boundary_layer_params);
278  // Equivalent "mod_" parts
279  const auto mod_main_background_bias_terms =
280  biasTermsCalculator(mod_background_radial_bias, mod_background_intervals);
281  const auto mod_inner_background_bias_terms =
282  biasTermsCalculator(mod_background_inner_boundary_layer_params.bias,
283  mod_background_inner_boundary_layer_params.intervals);
284  const auto mod_outer_background_bias_terms =
285  biasTermsCalculator(mod_background_outer_boundary_layer_params.bias,
286  mod_background_outer_boundary_layer_params.intervals);
287  auto mod_rings_bias_terms = biasTermsCalculator(mod_ring_radial_biases,
288  mod_ring_layers,
289  mod_ring_inner_boundary_layer_params,
290  mod_ring_outer_boundary_layer_params);
291  auto mod_duct_bias_terms = biasTermsCalculator(mod_duct_radial_biases,
292  mod_ducts_layers,
293  mod_duct_inner_boundary_layer_params,
294  mod_duct_outer_boundary_layer_params);
295 
296  std::vector<unsigned int> total_ring_layers;
297  for (unsigned int i = 0; i < ring_layers.size(); i++)
298  total_ring_layers.push_back(ring_layers[i] + ring_inner_boundary_layer_params.intervals[i] +
299  ring_outer_boundary_layer_params.intervals[i]);
300 
301  if (background_inner_boundary_layer_params.intervals)
302  {
303  total_ring_layers.push_back(background_inner_boundary_layer_params.intervals);
304  rings_bias_terms.push_back(inner_background_bias_terms);
305  ring_radii.push_back((ring_radii.empty() ? 0.0 : ring_radii.back()) +
306  background_inner_boundary_layer_params.width);
307  has_rings = true;
308  }
309  std::vector<unsigned int> mod_total_ring_layers;
310  for (unsigned int i = 0; i < mod_ring_layers.size(); i++)
311  mod_total_ring_layers.push_back(mod_ring_layers[i] +
312  mod_ring_inner_boundary_layer_params.intervals[i] +
313  mod_ring_outer_boundary_layer_params.intervals[i]);
314 
315  if (mod_background_inner_boundary_layer_params.intervals)
316  {
317  mod_total_ring_layers.push_back(mod_background_inner_boundary_layer_params.intervals);
318  mod_rings_bias_terms.push_back(mod_inner_background_bias_terms);
319  mod_ring_radii.push_back((mod_ring_radii.empty() ? 0.0 : mod_ring_radii.back()) +
320  mod_background_inner_boundary_layer_params.width);
321  // has_rings should be modified before in the none "mod_" part
322  }
323 
324  std::vector<unsigned int> total_ducts_layers;
325  if (background_outer_boundary_layer_params.intervals)
326  {
327  total_ducts_layers.push_back(background_outer_boundary_layer_params.intervals);
328  duct_bias_terms.insert(duct_bias_terms.begin(), outer_background_bias_terms);
329  ducts_center_dist.insert(ducts_center_dist.begin(),
330  (ducts_center_dist.empty()
331  ? pitch / 2.0 / std::cos(M_PI / virtual_side_number)
332  : ducts_center_dist.front()) -
333  background_outer_boundary_layer_params.width);
334  has_ducts = true;
335  }
336  for (unsigned int i = 0; i < ducts_layers.size(); i++)
337  total_ducts_layers.push_back(ducts_layers[i] + duct_inner_boundary_layer_params.intervals[i] +
338  duct_outer_boundary_layer_params.intervals[i]);
339 
340  std::vector<unsigned int> mod_total_ducts_layers;
341  if (mod_background_outer_boundary_layer_params.intervals)
342  {
343  mod_total_ducts_layers.push_back(mod_background_outer_boundary_layer_params.intervals);
344  mod_duct_bias_terms.insert(mod_duct_bias_terms.begin(), mod_outer_background_bias_terms);
345  mod_ducts_center_dist.insert(mod_ducts_center_dist.begin(),
346  (mod_ducts_center_dist.empty()
347  ? pitch / 2.0 / std::cos(M_PI / virtual_side_number)
348  : mod_ducts_center_dist.front()) -
349  mod_background_outer_boundary_layer_params.width);
350  // has_ducts should be modified before in the none "mod_" part
351  }
352  for (unsigned int i = 0; i < mod_ducts_layers.size(); i++)
353  mod_total_ducts_layers.push_back(mod_ducts_layers[i] +
354  mod_duct_inner_boundary_layer_params.intervals[i] +
355  mod_duct_outer_boundary_layer_params.intervals[i]);
356 
357  unsigned int angle_number = azimuthal_tangent.size() == 0
358  ? num_sectors_per_side
359  : ((azimuthal_tangent.size() - 1) / order);
360  unsigned int mod_angle_number =
361  azimuthal_tangent.size() == 0 ? mod_num_sectors_per_side : (azimuthal_tangent.size() - 1);
362 
363  // Geometries
364  const Real corner_to_corner =
365  pitch / std::cos(M_PI / virtual_side_number); // distance of bin center to cell corner
366  const Real corner_p[2][2] = {
367  {0.0, 0.5 * corner_to_corner},
368  {0.5 * corner_to_corner * pitch_scale_factor * std::sin(2.0 * M_PI / virtual_side_number),
369  0.5 * corner_to_corner * pitch_scale_factor * std::cos(2.0 * M_PI / virtual_side_number)}};
370  const unsigned int div_num = angle_number / 2 + 1;
371  const unsigned int mod_div_num = mod_angle_number / 2 + 1;
372 
373  // From now on, we work on the nodes, which need the "mod_" parameters
374  std::vector<std::vector<Node *>> nodes(mod_div_num, std::vector<Node *>(mod_div_num));
375  if (quad_center_elements)
376  {
377  Real ring_radii_0;
378 
379  if (has_rings)
380  ring_radii_0 = ring_radii.front() * mod_rings_bias_terms.front()[order - 1];
381  else if (has_ducts)
382  ring_radii_0 = mod_ducts_center_dist.front() * std::cos(M_PI / virtual_side_number) *
383  mod_main_background_bias_terms[order - 1];
384  else
385  ring_radii_0 = pitch / 2.0 * mod_main_background_bias_terms[order - 1];
386  // If center_quad_factor is zero, default value (div_num - 1)/div_num is used.
387  // We use div_num instead of mod_div_num because we are dealing wth elements here
388  // This approach ensures that the order = 2 mesh elements are consistent with the order = 1
389  ring_radii_0 *=
390  center_quad_factor == 0.0 ? (((Real)div_num - 1.0) / (Real)div_num) : center_quad_factor;
391 
392  centerNodes(*mesh, virtual_side_number, mod_div_num, ring_radii_0, nodes);
393  }
394  else // pin-cell center
395  mesh->add_point(Point(0.0, 0.0, 0.0));
396 
397  // create nodes for the ring regions
398  if (has_rings)
399  ringNodes(*mesh,
400  ring_radii,
401  mod_total_ring_layers,
402  mod_rings_bias_terms,
403  mod_num_sectors_per_side,
404  corner_p,
405  corner_to_corner,
406  azimuthal_tangent);
407 
408  if (has_background)
409  {
410  // add nodes in background region; the background region is defined as the area between the
411  // outermost pin (if there is a pin; if no pin, the center) and the innermost hex/duct; if
412  // _has_ducts is false, the background region is the area between the pin and enclosing hexagon
413  Real background_corner_radial_interval_length;
414  Real background_corner_distance;
415  Real background_in;
416  Real background_out; // background outer frontier
417  if (has_rings)
418  background_in = ring_radii.back();
419  else
420  background_in = 0;
421 
422  if (has_ducts)
423  {
424  background_out = mod_ducts_center_dist.front();
425  background_corner_distance =
426  mod_ducts_center_dist
427  .front(); // it is the center to duct (innermost duct) corner distance
428  }
429  else
430  {
431  background_out = 0.5 * corner_to_corner;
432  background_corner_distance =
433  0.5 * corner_to_corner; // it is the center to hex corner distance
434  }
435 
436  background_corner_radial_interval_length =
437  (background_out - background_in) / mod_background_intervals;
438 
439  node_id_background_meta = mesh->n_nodes();
440 
441  // create nodes for background region
442  backgroundNodes(*mesh,
443  mod_num_sectors_per_side,
444  mod_background_intervals,
445  mod_main_background_bias_terms,
446  background_corner_distance,
447  background_corner_radial_interval_length,
448  corner_p,
449  corner_to_corner,
450  background_in,
451  azimuthal_tangent);
452  }
453 
454  // create nodes for duct regions
455  if (has_ducts)
456  ductNodes(*mesh,
457  &mod_ducts_center_dist,
458  mod_total_ducts_layers,
459  mod_duct_bias_terms,
460  mod_num_sectors_per_side,
461  corner_p,
462  corner_to_corner,
463  azimuthal_tangent);
464 
465  // See if the central region is the only part of the innermost part
466  // The central region of the slice is special.
467  // Unlike the outer regions, which are layered quad elements,
468  // the central region is either a layer of tri elements or a specially-patterned quad elements.
469  // If there is at least one `ring` defined in the slice,
470  // the central region must belong to the innermost (first) ring.
471  // Otherwise the central region belongs to the `background`
472  // In either case, if the innermost ring or background has only one radial interval,
473  // the central region is an independent ring or background
474  // Otherwise, the central region and one or several quad element layers together form the
475  // innermost ring or background
476  bool is_central_region_independent;
477  if (ring_layers.empty())
478  is_central_region_independent = mod_background_inner_boundary_layer_params.intervals +
479  mod_background_intervals +
480  mod_background_outer_boundary_layer_params.intervals ==
481  1;
482  else
483  is_central_region_independent = mod_ring_layers[0] +
484  mod_ring_inner_boundary_layer_params.intervals[0] +
485  mod_ring_outer_boundary_layer_params.intervals[0] ==
486  1;
487 
488  // From now on, we work on the elements, which need the none "mod_" parameters
489  // Assign elements, boundaries, and subdomains;
490  // Add Tri3/Tri6/Tri7 or Quad4/Quad8/Quad9 mesh into innermost (central) region
491  if (quad_center_elements)
492  cenQuadElemDef(*mesh,
493  div_num,
494  block_id_shift,
495  create_outward_interface_boundaries && is_central_region_independent,
496  boundary_id_shift,
497  nodes,
498  (!has_rings) && (!has_ducts) && (background_intervals == 1),
499  // Note here, has_ring means either there are ring regions or background inner
500  // boundary layer; has_ducts means either there are duct regions or background
501  // outer boundary layer. Same in cenTriElemDef()
502  side_index,
503  generate_side_specific_boundaries,
504  quad_elem_type);
505  else
507  *mesh,
508  num_sectors_per_side,
509  azimuthal_tangent,
510  block_id_shift,
511  create_outward_interface_boundaries && is_central_region_independent,
512  boundary_id_shift,
513  ((!has_rings) && (!has_ducts) && (background_intervals == 1)) ||
514  ((!has_background) &&
515  (std::accumulate(total_ring_layers.begin(), total_ring_layers.end(), 0) == 1)),
516  // Only for ACCG, it is possible that the entire mesh is a single-layer ring.
517  // cenQuadElemDef() does not need this as it does not work for ACCG.
518  side_index,
519  generate_side_specific_boundaries,
520  tri_elem_type);
521 
522  // Add Quad4 mesh into outer circle
523  // total number of mesh should be all the rings for pin regions + background regions;
524  // total number of quad mesh should be total number of mesh -1 (-1 is because the inner circle for
525  // tri/quad mesh has been added above)
526 
527  std::vector<unsigned int> subdomain_rings;
528  if (has_rings) // define the rings in each subdomain
529  {
530  subdomain_rings = total_ring_layers;
531  subdomain_rings.front() -= 1; // remove the inner TRI mesh subdomain
532  if (background_inner_boundary_layer_params.intervals)
533  {
534  subdomain_rings.back() =
535  background_inner_boundary_layer_params.intervals + background_intervals +
536  background_outer_boundary_layer_params.intervals; // add the background region
537  if (ring_radii.size() == 1)
538  subdomain_rings.back() -= 1; // remove the inner TRI mesh subdomain
539  }
540  else if (has_background)
541  subdomain_rings.push_back(background_inner_boundary_layer_params.intervals +
542  background_intervals +
543  background_outer_boundary_layer_params.intervals);
544  }
545  else
546  {
547  subdomain_rings.push_back(
548  background_inner_boundary_layer_params.intervals + background_intervals +
549  background_outer_boundary_layer_params.intervals); // add the background region
550  subdomain_rings[0] -= 1; // remove the inner TRI mesh subdomain
551  }
552 
553  if (has_ducts)
554  for (unsigned int i = (background_outer_boundary_layer_params.intervals > 0);
555  i < total_ducts_layers.size();
556  i++)
557  subdomain_rings.push_back(total_ducts_layers[i]);
558 
559  quadElemDef(*mesh,
560  num_sectors_per_side,
561  subdomain_rings,
562  side_index,
563  azimuthal_tangent,
564  block_id_shift,
565  quad_center_elements ? (mod_div_num * mod_div_num - 1) : 0,
566  create_inward_interface_boundaries,
567  create_outward_interface_boundaries,
568  boundary_id_shift,
569  generate_side_specific_boundaries,
570  quad_elem_type);
571  if (tri_elem_type == TRI_ELEM_TYPE::TRI6 || quad_elem_type == QUAD_ELEM_TYPE::QUAD8)
573  return mesh;
574 }
std::unique_ptr< ReplicatedMesh > buildReplicatedMesh(unsigned int dim=libMesh::invalid_uint)
void remove_orphaned_nodes()
void cenTriElemDef(ReplicatedMesh &mesh, const unsigned int num_sectors_per_side, const std::vector< Real > azimuthal_tangent=std::vector< Real >(), const subdomain_id_type block_id_shift=0, const bool create_outward_interface_boundaries=true, const boundary_id_type boundary_id_shift=0, const bool assign_external_boundary=false, const unsigned int side_index=0, const bool generate_side_specific_boundaries=true, const TRI_ELEM_TYPE tri_elem_type=TRI_ELEM_TYPE::TRI3) const
Defines triangular elements in the very central region of the polygon.
if(subdm)
MeshBase & mesh
multiBdryLayerParams modifiedMultiBdryLayerParamsCreator(const multiBdryLayerParams &original_multi_bdry_layer_params, const unsigned int order) const
Modifies the input multi boundary layer parameters for node generation, especially for the quadratic ...
virtual const std::string & name() const
virtual Node * add_point(const Point &p, const dof_id_type id=DofObject::invalid_id, const processor_id_type proc_id=DofObject::invalid_processor_id)=0
std::vector< std::vector< Real > > biasTermsCalculator(const std::vector< Real > radial_biases, const std::vector< unsigned int > intervals, const multiBdryLayerParams inner_boundary_layer_params, const multiBdryLayerParams outer_boundary_layer_params) const
Creates bias terms for multiple blocks.
void cenQuadElemDef(ReplicatedMesh &mesh, const unsigned int div_num, const subdomain_id_type block_id_shift, const bool create_outward_interface_boundaries, const boundary_id_type boundary_id_shift, std::vector< std::vector< Node *>> &nodes, const bool assign_external_boundary=false, const unsigned int side_index=0, const bool generate_side_specific_boundaries=true, const QUAD_ELEM_TYPE quad_elem_type=QUAD_ELEM_TYPE::QUAD4) const
Defines quad elements in the very central region of the polygon.
static const std::string pitch
void backgroundNodes(ReplicatedMesh &mesh, const unsigned int num_sectors_per_side, const unsigned int background_intervals, const std::vector< Real > biased_terms, const Real background_corner_distance, const Real background_corner_radial_interval_length, const Real corner_p[2][2], const Real corner_to_corner, const Real background_in, const std::vector< Real > azimuthal_tangent=std::vector< Real >()) const
Creates nodes for the ring-to-polygon transition region (i.e., background) of a single slice...
void ringNodes(ReplicatedMesh &mesh, const std::vector< Real > ring_radii, const std::vector< unsigned int > ring_layers, const std::vector< std::vector< Real >> biased_terms, const unsigned int num_sectors_per_side, const Real corner_p[2][2], const Real corner_to_corner, const std::vector< Real > azimuthal_tangent=std::vector< Real >()) const
Creates nodes for the ring-geometry region of a single slice.
void centerNodes(ReplicatedMesh &mesh, const Real virtual_side_number, const unsigned int div_num, const Real ring_radii_0, std::vector< std::vector< Node *>> &nodes) const
Creates nodes of the very central mesh layer of the polygon for quad central elements.
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
static const std::string ring_radii
void ductNodes(ReplicatedMesh &mesh, std::vector< Real > *const ducts_center_dist, const std::vector< unsigned int > ducts_layers, const std::vector< std::vector< Real >> biased_terms, const unsigned int num_sectors_per_side, const Real corner_p[2][2], const Real corner_to_corner, const std::vector< Real > azimuthal_tangent=std::vector< Real >()) const
Creates nodes for the duct-geometry region of a single slice.
void mooseError(Args &&... args) const
singleBdryLayerParams modifiedSingleBdryLayerParamsCreator(const singleBdryLayerParams &original_single_bdry_layer_params, const unsigned int order) const
Modifies the input single boundary layer parameters for node generation, especially for the quadratic...
MooseUnits pow(const MooseUnits &, int)
virtual dof_id_type n_nodes() const=0
void quadElemDef(ReplicatedMesh &mesh, const unsigned int num_sectors_per_side, const std::vector< unsigned int > subdomain_rings, const unsigned int side_index, const std::vector< Real > azimuthal_tangent=std::vector< Real >(), const subdomain_id_type block_id_shift=0, const dof_id_type nodeid_shift=0, const bool create_inward_interface_boundaries=false, const bool create_outward_interface_boundaries=true, const boundary_id_type boundary_id_shift=0, const bool generate_side_specific_boundaries=true, const QUAD_ELEM_TYPE quad_elem_type=QUAD_ELEM_TYPE::QUAD4) const
Defines general quad elements for the polygon.

◆ cenQuadElemDef()

void PolygonMeshGeneratorBase::cenQuadElemDef ( ReplicatedMesh mesh,
const unsigned int  div_num,
const subdomain_id_type  block_id_shift,
const bool  create_outward_interface_boundaries,
const boundary_id_type  boundary_id_shift,
std::vector< std::vector< Node *>> &  nodes,
const bool  assign_external_boundary = false,
const unsigned int  side_index = 0,
const bool  generate_side_specific_boundaries = true,
const QUAD_ELEM_TYPE  quad_elem_type = QUAD_ELEM_TYPE::QUAD4 
) const
protectedinherited

Defines quad elements in the very central region of the polygon.

Parameters
meshinput mesh to create the elements onto
div_numdivision number of the central mesh layer
block_id_shiftshift of the subdomain ids generated by this function
create_outward_interface_boundarieswhether outward interface boundary sidesets are created
boundary_id_shiftshift of the interface boundary ids
id_arraypointer to a vector that contains the node_ids with basic geometry information
assign_external_boundarywhether the external boundary ids are assigned
side_indexindex of the polygon side (only used if external boundary ids are assigned)
generate_side_specific_boundarieswhether the side-specific external boundaries are generated or not
quad_elem_typetype of the quadrilateral elements to be generated

Definition at line 853 of file PolygonMeshGeneratorBase.C.

Referenced by PolygonMeshGeneratorBase::buildSlice().

863 {
864 
865  BoundaryInfo & boundary_info = mesh.get_boundary_info();
866 
867  // This loop defines quad elements for the central regions except for the outermost layer
868  for (unsigned int i = 0; i < div_num - 1; i++)
869  {
870  unsigned int id_x = 0;
871  unsigned int id_y = i;
872  for (unsigned int j = 0; j < 2 * i + 1; j++)
873  {
874  std::unique_ptr<Elem> new_elem;
875  if (quad_elem_type == QUAD_ELEM_TYPE::QUAD4)
876  {
877  new_elem = std::make_unique<Quad4>();
878  new_elem->set_node(0, nodes[id_x][id_y]);
879  new_elem->set_node(3, nodes[id_x][id_y + 1]);
880  new_elem->set_node(2, nodes[id_x + 1][id_y + 1]);
881  new_elem->set_node(1, nodes[id_x + 1][id_y]);
882  new_elem->subdomain_id() = 1 + block_id_shift;
883  }
884  else // QUAD8/QUAD9
885  {
886  new_elem = std::make_unique<Quad8>();
887  if (quad_elem_type == QUAD_ELEM_TYPE::QUAD9)
888  {
889  new_elem = std::make_unique<Quad9>();
890  new_elem->set_node(8, nodes[id_x * 2 + 1][id_y * 2 + 1]);
891  }
892  new_elem->set_node(0, nodes[id_x * 2][id_y * 2]);
893  new_elem->set_node(3, nodes[id_x * 2][id_y * 2 + 2]);
894  new_elem->set_node(2, nodes[id_x * 2 + 2][id_y * 2 + 2]);
895  new_elem->set_node(1, nodes[id_x * 2 + 2][id_y * 2]);
896  new_elem->set_node(4, nodes[id_x * 2 + 1][id_y * 2]);
897  new_elem->set_node(5, nodes[id_x * 2 + 2][id_y * 2 + 1]);
898  new_elem->set_node(6, nodes[id_x * 2 + 1][id_y * 2 + 2]);
899  new_elem->set_node(7, nodes[id_x * 2][id_y * 2 + 1]);
900  new_elem->subdomain_id() = 1 + block_id_shift;
901  }
902  Elem * elem_Quad = mesh.add_elem(std::move(new_elem));
903 
904  if (id_x == 0)
905  boundary_info.add_side(elem_Quad, 3, SLICE_BEGIN);
906  if (id_y == 0)
907  boundary_info.add_side(elem_Quad, 0, SLICE_END);
908  if (j < i)
909  id_x++;
910  if (j >= i)
911  id_y--;
912  }
913  }
914  // This loop defines the outermost layer quad elements of the central region
915  for (unsigned int i = (div_num - 1) * (div_num - 1); i < div_num * div_num - 1; i++)
916  {
917  std::unique_ptr<Elem> new_elem;
918  if (quad_elem_type == QUAD_ELEM_TYPE::QUAD4)
919  {
920  new_elem = std::make_unique<Quad4>();
921  new_elem->set_node(0, mesh.node_ptr(i));
922  new_elem->set_node(3, mesh.node_ptr(i + 2 * div_num - 1));
923  new_elem->set_node(2, mesh.node_ptr(i + 2 * div_num));
924  new_elem->set_node(1, mesh.node_ptr(i + 1));
925  }
926  else // QUAD8/QUAD9
927  {
928  new_elem = std::make_unique<Quad8>();
929  if (quad_elem_type == QUAD_ELEM_TYPE::QUAD9)
930  {
931  new_elem = std::make_unique<Quad9>();
932  new_elem->set_node(8,
933  mesh.node_ptr((div_num - 1) * (div_num - 1) * 4 +
934  (i - (div_num - 1) * (div_num - 1)) * 2 + 1 +
935  ((div_num - 1) * 4 + 1)));
936  }
937  new_elem->set_node(0,
938  mesh.node_ptr((div_num - 1) * (div_num - 1) * 4 +
939  (i - (div_num - 1) * (div_num - 1)) * 2));
940  new_elem->set_node(3,
941  mesh.node_ptr((div_num - 1) * (div_num - 1) * 4 +
942  (i - (div_num - 1) * (div_num - 1)) * 2 +
943  ((div_num - 1) * 4 + 1) * 2));
944  new_elem->set_node(2,
945  mesh.node_ptr((div_num - 1) * (div_num - 1) * 4 +
946  (i - (div_num - 1) * (div_num - 1)) * 2 + 2 +
947  ((div_num - 1) * 4 + 1) * 2));
948  new_elem->set_node(1,
949  mesh.node_ptr((div_num - 1) * (div_num - 1) * 4 +
950  (i - (div_num - 1) * (div_num - 1)) * 2 + 2));
951  new_elem->set_node(4,
952  mesh.node_ptr((div_num - 1) * (div_num - 1) * 4 +
953  (i - (div_num - 1) * (div_num - 1)) * 2 + 1));
954  new_elem->set_node(5,
955  mesh.node_ptr((div_num - 1) * (div_num - 1) * 4 +
956  (i - (div_num - 1) * (div_num - 1)) * 2 + 2 +
957  ((div_num - 1) * 4 + 1)));
958  new_elem->set_node(6,
959  mesh.node_ptr((div_num - 1) * (div_num - 1) * 4 +
960  (i - (div_num - 1) * (div_num - 1)) * 2 + 1 +
961  ((div_num - 1) * 4 + 1) * 2));
962  new_elem->set_node(7,
963  mesh.node_ptr((div_num - 1) * (div_num - 1) * 4 +
964  (i - (div_num - 1) * (div_num - 1)) * 2 +
965  ((div_num - 1) * 4 + 1)));
966  }
967 
968  Elem * elem_Quad = mesh.add_elem(std::move(new_elem));
969  elem_Quad->subdomain_id() = 1 + block_id_shift;
970  if (create_outward_interface_boundaries)
971  boundary_info.add_side(elem_Quad, 2, 1 + boundary_id_shift);
972  if (i == (div_num - 1) * (div_num - 1))
973  boundary_info.add_side(elem_Quad, 3, SLICE_BEGIN);
974  if (i == div_num * div_num - 2)
975  boundary_info.add_side(elem_Quad, 1, SLICE_END);
976  if (assign_external_boundary)
977  {
978  boundary_info.add_side(elem_Quad, 2, OUTER_SIDESET_ID);
979  if (generate_side_specific_boundaries)
980  boundary_info.add_side(
981  elem_Quad,
982  2,
983  (i < div_num * (div_num - 1) ? OUTER_SIDESET_ID : OUTER_SIDESET_ID_ALT) + side_index);
984  }
985  }
986 }
MeshBase & mesh
const BoundaryInfo & get_boundary_info() const
virtual Elem * add_elem(Elem *e)=0
subdomain_id_type subdomain_id() const
void add_side(const dof_id_type elem, const unsigned short int side, const boundary_id_type id)
static const std::complex< double > j(0, 1)
Complex number "j" (also known as "i")
virtual const Node * node_ptr(const dof_id_type i) const=0

◆ centerNodes()

void PolygonMeshGeneratorBase::centerNodes ( ReplicatedMesh mesh,
const Real  virtual_side_number,
const unsigned int  div_num,
const Real  ring_radii_0,
std::vector< std::vector< Node *>> &  nodes 
) const
protectedinherited

Creates nodes of the very central mesh layer of the polygon for quad central elements.

Parameters
meshinput mesh to add the nodes onto
virtual_side_numbervirtual number of sides of the polygon (360/slice_azimuthal)
div_numdivision number of the central mesh layer
ring_radii_0radius of the central mesh layer
nodespointer to the mesh's nodes
nodesvector that contains the nodes with basic geometry information

Definition at line 577 of file PolygonMeshGeneratorBase.C.

Referenced by PolygonMeshGeneratorBase::buildSlice().

582 {
583  const std::pair<Real, Real> p_origin = std::make_pair(0.0, 0.0);
584  const std::pair<Real, Real> p_bottom =
585  std::make_pair(0.0, ring_radii_0 * std::cos(M_PI / virtual_side_number));
586  const std::pair<Real, Real> p_top =
587  std::make_pair(p_bottom.second * std::sin(2.0 * M_PI / virtual_side_number),
588  p_bottom.second * std::cos(2.0 * M_PI / virtual_side_number));
589  const std::pair<Real, Real> p_diag =
590  std::make_pair(ring_radii_0 * std::sin(M_PI / virtual_side_number),
591  ring_radii_0 * std::cos(M_PI / virtual_side_number));
592 
593  // The four vertices of the central quad region are defined above.
594  // The following loops transverse all the nodes within this central quad region by moving p1 thru
595  // p4 and calculate the four-point intercept (pc).
596  // p_top------o-------p4--------o-----p_diag
597  // | | | | |
598  // | | | | |
599  // o--------o--------o--------o--------o
600  // | | | | |
601  // | | | | |
602  // p1--------o-------pc--------o-------p2
603  // | | | | |
604  // | | | | |
605  // o--------o--------o--------o--------o
606  // | | | | |
607  // | | | | |
608  // p_origin-----o-------p3--------o----p_bottom
609  //
610  // The loops are designed to transverse the nodes as shown below to facilitate elements
611  // and sides creation.
612  //
613  // 25-------24-------23-------22-------21
614  // | | | | |
615  // | | | | |
616  // 16-------15-------14-------13-------20
617  // | | | | |
618  // | | | | |
619  // 9--------8------- 7-------12-------19
620  // | | | | |
621  // | | | | |
622  // 4--------3--------6-------11-------18
623  // | | | | |
624  // | | | | |
625  // 1--------2--------5-------10-------17
626 
627  for (unsigned int i = 0; i < div_num; i++)
628  {
629  unsigned int id_x = 0;
630  unsigned int id_y = i;
631  for (unsigned int j = 0; j < 2 * i + 1; j++)
632  {
633  std::pair<Real, Real> p1 = std::make_pair(
634  (p_origin.first * (div_num - 1 - id_x) + p_top.first * id_x) / (div_num - 1),
635  (p_origin.second * (div_num - 1 - id_x) + p_top.second * id_x) / (div_num - 1));
636  std::pair<Real, Real> p2 = std::make_pair(
637  (p_bottom.first * (div_num - 1 - id_x) + p_diag.first * id_x) / (div_num - 1),
638  (p_bottom.second * (div_num - 1 - id_x) + p_diag.second * id_x) / (div_num - 1));
639  std::pair<Real, Real> p3 = std::make_pair(
640  (p_origin.first * (div_num - 1 - id_y) + p_bottom.first * id_y) / (div_num - 1),
641  (p_origin.second * (div_num - 1 - id_y) + p_bottom.second * id_y) / (div_num - 1));
642  std::pair<Real, Real> p4 = std::make_pair(
643  (p_top.first * (div_num - 1 - id_y) + p_diag.first * id_y) / (div_num - 1),
644  (p_top.second * (div_num - 1 - id_y) + p_diag.second * id_y) / (div_num - 1));
645  std::pair<Real, Real> pc = fourPointIntercept(p1, p2, p3, p4);
646  nodes[id_x][id_y] = mesh.add_point(Point(pc.first, pc.second, 0.0));
647  if (j < i)
648  id_x++;
649  if (j >= i)
650  id_y--;
651  }
652  }
653 }
std::pair< Real, Real > fourPointIntercept(const std::pair< Real, Real > &p1, const std::pair< Real, Real > &p2, const std::pair< Real, Real > &p3, const std::pair< Real, Real > &p4) const
Finds the center of a quadrilateral based on four vertices.
MeshBase & mesh
virtual Node * add_point(const Point &p, const dof_id_type id=DofObject::invalid_id, const processor_id_type proc_id=DofObject::invalid_processor_id)=0
static const std::complex< double > j(0, 1)
Complex number "j" (also known as "i")

◆ cenTriElemDef()

void PolygonMeshGeneratorBase::cenTriElemDef ( ReplicatedMesh mesh,
const unsigned int  num_sectors_per_side,
const std::vector< Real azimuthal_tangent = std::vector<Real>(),
const subdomain_id_type  block_id_shift = 0,
const bool  create_outward_interface_boundaries = true,
const boundary_id_type  boundary_id_shift = 0,
const bool  assign_external_boundary = false,
const unsigned int  side_index = 0,
const bool  generate_side_specific_boundaries = true,
const TRI_ELEM_TYPE  tri_elem_type = TRI_ELEM_TYPE::TRI3 
) const
protectedinherited

Defines triangular elements in the very central region of the polygon.

Parameters
meshinput mesh to create the elements onto
num_sectors_per_sidenumber of azimuthal intervals
azimuthal_tangentvector of tangent values of the azimuthal angles as reference for adaptive boundary matching
block_id_shiftshift of the subdomain ids generated by this function
create_outward_interface_boundarieswhether outward interface boundary sidesets are created
boundary_id_shiftshift of the interface boundary ids
assign_external_boundarywhether the external boundary ids are assigned
side_indexindex of the polygon side (only used if external boundary ids are assigned)
generate_side_specific_boundarieswhether the side-specific external boundaries are generated or not
tri_elem_typetype of the triangular elements to be generated

Definition at line 989 of file PolygonMeshGeneratorBase.C.

Referenced by PolygonMeshGeneratorBase::buildSlice().

999 {
1000  const unsigned short order = tri_elem_type == TRI_ELEM_TYPE::TRI3 ? 1 : 2;
1001  unsigned int angle_number = azimuthal_tangent.size() == 0
1002  ? num_sectors_per_side
1003  : ((azimuthal_tangent.size() - 1) / order);
1004 
1005  BoundaryInfo & boundary_info = mesh.get_boundary_info();
1006  for (unsigned int i = 1; i <= angle_number; i++)
1007  {
1008  std::unique_ptr<Elem> new_elem;
1009  if (tri_elem_type == TRI_ELEM_TYPE::TRI3)
1010  {
1011  new_elem = std::make_unique<Tri3>();
1012  new_elem->set_node(0, mesh.node_ptr(0));
1013  new_elem->set_node(2, mesh.node_ptr(i));
1014  new_elem->set_node(1, mesh.node_ptr(i + 1));
1015  }
1016  else // TRI6/TRI7
1017  {
1018  new_elem = std::make_unique<Tri6>();
1019  if (tri_elem_type == TRI_ELEM_TYPE::TRI7)
1020  {
1021  new_elem = std::make_unique<Tri7>();
1022  new_elem->set_node(6, mesh.node_ptr(i * 2));
1023  }
1024  new_elem->set_node(0, mesh.node_ptr(0));
1025  new_elem->set_node(2, mesh.node_ptr(i * 2 + angle_number * order));
1026  new_elem->set_node(1, mesh.node_ptr((i + 1) * 2 + angle_number * order));
1027  new_elem->set_node(3, mesh.node_ptr(i * 2 + 1));
1028  new_elem->set_node(5, mesh.node_ptr(i * 2 - 1));
1029  new_elem->set_node(4, mesh.node_ptr(i * 2 + 1 + angle_number * order));
1030  }
1031 
1032  Elem * elem = mesh.add_elem(std::move(new_elem));
1033  if (create_outward_interface_boundaries)
1034  boundary_info.add_side(elem, 1, 1 + boundary_id_shift);
1035  elem->subdomain_id() = 1 + block_id_shift;
1036  if (i == 1)
1037  boundary_info.add_side(elem, 2, SLICE_BEGIN);
1038  if (i == angle_number)
1039  boundary_info.add_side(elem, 0, SLICE_END);
1040  if (assign_external_boundary)
1041  {
1042  boundary_info.add_side(elem, 1, OUTER_SIDESET_ID);
1043  if (generate_side_specific_boundaries)
1044  boundary_info.add_side(elem,
1045  1,
1046  (i <= angle_number / 2 ? OUTER_SIDESET_ID : OUTER_SIDESET_ID_ALT) +
1047  side_index);
1048  }
1049  }
1050 }
MeshBase & mesh
const BoundaryInfo & get_boundary_info() const
virtual Elem * add_elem(Elem *e)=0
subdomain_id_type subdomain_id() const
void add_side(const dof_id_type elem, const unsigned short int side, const boundary_id_type id)
virtual const Node * node_ptr(const dof_id_type i) const=0

◆ cutOffPolyDeform()

void PolygonMeshGeneratorBase::cutOffPolyDeform ( MeshBase mesh,
const Real  orientation,
const Real  y_max_0,
const Real  y_max_n,
const Real  y_min,
const unsigned int  mesh_type,
const Real  unit_angle = 60.0,
const Real  tols = 1E-5 
) const
protectedinherited

Deforms peripheral region when the external side of a polygon assembly of stitched meshes cuts off the stitched meshes.

Parameters
meshinput mesh to be deformed
orientationorientation angle of the input mesh (move the deformation direction to y)
y_max_0original maximum y position
y_max_nmaximum y position after deformation
y_minminimum y position that is affected by the deformation
mesh_typewhether the peripheral region is for a corner or a side hexagon mesh.
tolstolerance used to determine the boundary of deformation region
unit_angleunit angle of the geometry, which is 60.0 for hexagonal and 90.0 for square
Returns
n/a (input mesh is directly altered)

Definition at line 1329 of file PolygonMeshGeneratorBase.C.

Referenced by generate(), and PatternedCartesianMeshGenerator::generate().

1337 {
1338  for (auto & node_ptr : as_range(mesh.nodes_begin(), mesh.nodes_end()))
1339  {
1340  // This function can definitely be optimized in future for better efficiency.
1341  Real & x = (*node_ptr)(0);
1342  Real & y = (*node_ptr)(1);
1343  if (mesh_type == CORNER_MESH)
1344  {
1345  nodeCoordRotate(x, y, orientation);
1346  if (x >= 0.0 && y > y_max_0)
1347  y = y - y_max_0 + y_max_n;
1348  else if (x >= 0.0 && y >= y_min)
1349  y = (y - y_min) / (y_max_0 - y_min) * (y_max_n - y_min) + y_min;
1350  else if (y > -x / std::tan(unit_angle / 360.0 * M_PI) + tols && y > y_max_0)
1351  {
1352  x /= y;
1353  y = y - y_max_0 + y_max_n;
1354  x *= y;
1355  }
1356  else if (y > -x / std::tan(unit_angle / 360.0 * M_PI) + tols && y >= y_min)
1357  {
1358  x /= y;
1359  y = (y - y_min) / (y_max_0 - y_min) * (y_max_n - y_min) + y_min;
1360  x *= y;
1361  }
1362  nodeCoordRotate(x, y, -orientation);
1363 
1364  nodeCoordRotate(x, y, orientation - unit_angle);
1365  if (x <= 0 && y > y_max_0)
1366  y = y - y_max_0 + y_max_n;
1367  else if (x <= 0 && y >= y_min)
1368  y = (y - y_min) / (y_max_0 - y_min) * (y_max_n - y_min) + y_min;
1369  else if (y >= x / std::tan(unit_angle / 360.0 * M_PI) - tols && y > y_max_0)
1370  {
1371  x /= y;
1372  y = y - y_max_0 + y_max_n;
1373  x *= y;
1374  }
1375  else if (y >= x / std::tan(unit_angle / 360.0 * M_PI) - tols && y >= y_min)
1376  {
1377  x /= y;
1378  y = (y - y_min) / (y_max_0 - y_min) * (y_max_n - y_min) + y_min;
1379  x *= y;
1380  }
1381  nodeCoordRotate(x, y, unit_angle - orientation);
1382  }
1383  else
1384  {
1385  nodeCoordRotate(x, y, orientation);
1386  if (y > y_max_0)
1387  y = y - y_max_0 + y_max_n;
1388  else if (y >= y_min)
1389  y = (y - y_min) / (y_max_0 - y_min) * (y_max_n - y_min) + y_min;
1390  nodeCoordRotate(x, y, -orientation);
1391  }
1392  }
1393 }
MeshBase & mesh
const std::vector< double > y
void nodeCoordRotate(Real &x, Real &y, const Real theta) const
Calculates x and y coordinates after rotating by theta angle.
const std::vector< double > x
SimpleRange< IndexType > as_range(const std::pair< IndexType, IndexType > &p)
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real

◆ ductNodes()

void PolygonMeshGeneratorBase::ductNodes ( ReplicatedMesh mesh,
std::vector< Real > *const  ducts_center_dist,
const std::vector< unsigned int ducts_layers,
const std::vector< std::vector< Real >>  biased_terms,
const unsigned int  num_sectors_per_side,
const Real  corner_p[2][2],
const Real  corner_to_corner,
const std::vector< Real azimuthal_tangent = std::vector<Real>() 
) const
protectedinherited

Creates nodes for the duct-geometry region of a single slice.

Parameters
meshinput mesh to add the nodes onto
ducts_center_distdistance parameters of the duct regions
ducts_layersnumbers of radial intervals of the duct regions
biased_termsnormalized spacing values used for radial meshing biasing in duct region
num_sectors_per_sidenumber of azimuthal intervals
corner_p[2][2]array contains the coordinates of the corner positions
corner_to_cornerdiameter of the circumscribed circle of the polygon
azimuthal_tangentvector of tangent values of the azimuthal angles as reference for adaptive boundary matching

Definition at line 792 of file PolygonMeshGeneratorBase.C.

Referenced by PolygonMeshGeneratorBase::buildSlice().

800 {
801  unsigned int angle_number =
802  azimuthal_tangent.size() == 0 ? num_sectors_per_side : (azimuthal_tangent.size() - 1);
803  // Add nodes in ducts regions
804  (*ducts_center_dist)
805  .push_back(0.5 * corner_to_corner); // add hex boundary as the last element in this vector
806  std::vector<Real> duct_radius_interval_length(ducts_layers.size());
807 
808  Real bin_radial_distance;
809  for (unsigned int l = 0; l < ducts_layers.size(); l++)
810  {
811  duct_radius_interval_length[l] =
812  ((*ducts_center_dist)[l + 1] - (*ducts_center_dist)[l]) /
813  ducts_layers[l]; // the pin radius interval for each ring_radii/subdomain
814 
815  // add rings in each pin subdomain
816  for (unsigned int k = 0; k < ducts_layers[l]; k++)
817  {
818  bin_radial_distance = ((*ducts_center_dist)[l] +
819  biased_terms[l][k] * ducts_layers[l] * duct_radius_interval_length[l]);
820  const Real pin_corner_p_x = corner_p[0][0] * bin_radial_distance / (0.5 * corner_to_corner);
821  const Real pin_corner_p_y = corner_p[0][1] * bin_radial_distance / (0.5 * corner_to_corner);
822 
823  // pin_corner_p(s) are the points in the pin region, on the bins towards the six corners,
824  // at different intervals
825  mesh.add_point(Point(pin_corner_p_x, pin_corner_p_y, 0.0));
826 
827  for (unsigned int j = 1; j <= angle_number; j++)
828  {
829  const Real cell_boundary_p_x =
830  corner_p[0][0] + (corner_p[1][0] - corner_p[0][0]) *
831  (azimuthal_tangent.size() == 0 ? ((Real)j / (Real)angle_number)
832  : (azimuthal_tangent[j] / 2.0));
833  const Real cell_boundary_p_y =
834  corner_p[0][1] + (corner_p[1][1] - corner_p[0][1]) *
835  (azimuthal_tangent.size() == 0 ? ((Real)j / (Real)angle_number)
836  : (azimuthal_tangent[j] / 2.0));
837  // cell_boundary_p(s) are the points on the cell's six boundaries (flat sides) at
838  // different azimuthal angles
839  const Real pin_azimuthal_p_x =
840  cell_boundary_p_x * bin_radial_distance / (0.5 * corner_to_corner);
841  const Real pin_azimuthal_p_y =
842  cell_boundary_p_y * bin_radial_distance / (0.5 * corner_to_corner);
843 
844  // pin_azimuthal_p are the points on the bins towards different azimuthal angles, at
845  // different intervals; excluding the ones produced by pin_corner_p
846  mesh.add_point(Point(pin_azimuthal_p_x, pin_azimuthal_p_y, 0.0));
847  }
848  }
849  }
850 }
MeshBase & mesh
virtual Node * add_point(const Point &p, const dof_id_type id=DofObject::invalid_id, const processor_id_type proc_id=DofObject::invalid_processor_id)=0
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
static const std::complex< double > j(0, 1)
Complex number "j" (also known as "i")
static const std::string k
Definition: NS.h:130

◆ fourPointIntercept()

std::pair< Real, Real > PolygonMeshGeneratorBase::fourPointIntercept ( const std::pair< Real, Real > &  p1,
const std::pair< Real, Real > &  p2,
const std::pair< Real, Real > &  p3,
const std::pair< Real, Real > &  p4 
) const
protectedinherited

Finds the center of a quadrilateral based on four vertices.

Parameters
p1vertex 1
p2vertex 2
p3vertex 3
p4vertex 4
Returns
the intecept point coordinate x and y

Definition at line 1396 of file PolygonMeshGeneratorBase.C.

Referenced by PolygonMeshGeneratorBase::centerNodes(), and AzimuthalBlockSplitGenerator::nodeModifier().

1400 {
1401  const Real x1 = p1.first;
1402  const Real y1 = p1.second;
1403  const Real x2 = p2.first;
1404  const Real y2 = p2.second;
1405  const Real x3 = p3.first;
1406  const Real y3 = p3.second;
1407  const Real x4 = p4.first;
1408  const Real y4 = p4.second;
1409 
1410  Real x = -((x1 - x2) * (y3 * x4 - x3 * y4) - (x3 - x4) * (y1 * x2 - x1 * y2)) /
1411  ((y1 - y2) * (x3 - x4) - (y3 - y4) * (x1 - x2));
1412  Real y = -((y1 - y2) * (y3 * x4 - x3 * y4) - (y3 - y4) * (y1 * x2 - x1 * y2)) /
1413  ((y1 - y2) * (x3 - x4) - (y3 - y4) * (x1 - x2));
1414 
1415  return std::make_pair(x, y);
1416 }
const std::vector< double > y
const std::vector< double > x
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real

◆ generate()

std::unique_ptr< MeshBase > PatternedHexMeshGenerator::generate ( )
overridevirtual

Reimplemented from PolygonMeshGeneratorBase.

Definition at line 351 of file PatternedHexMeshGenerator.C.

Referenced by HexIDPatternedMeshGenerator::generate().

352 {
353  std::vector<std::unique_ptr<ReplicatedMesh>> meshes(_input_names.size());
354  for (const auto i : index_range(_input_names))
355  {
356  meshes[i] = dynamic_pointer_cast<ReplicatedMesh>(std::move(*_mesh_ptrs[i]));
357  if (!meshes[i])
358  paramError("inputs",
359  "Mesh '",
360  _input_names[i],
361  "' is not a replicated mesh. Only replicated meshes are supported");
362 
363  // throw an error message if the input mesh has a flat side up
364  if (hasMeshProperty<bool>("flat_side_up", _input_names[i]))
365  if (getMeshProperty<bool>("flat_side_up", _input_names[i]))
366  paramError("inputs",
367  "Mesh '",
368  _input_names[i],
369  "' has a flat side facing up, which is not supported.");
370  }
371 
372  std::vector<Real> pitch_array;
373  std::vector<unsigned int> num_sectors_per_side_array;
374  std::vector<unsigned int> num_sectors_per_side_array_tmp;
375  std::vector<std::vector<Real>> control_drum_azimuthal_array;
376  std::vector<unsigned int> background_intervals_array;
377  std::vector<dof_id_type> node_id_background_array;
378  std::vector<Real> max_radius_array;
379  std::vector<bool> is_control_drum_array;
380  Real max_radius_global(0.0);
381  std::vector<Real> pattern_pitch_array;
382 
384  {
385  for (MooseIndex(_input_names) i = 0; i < _input_names.size(); ++i)
386  {
387  // throw an error message if the input mesh does not contain the required meta data
388  if (!hasMeshProperty<Real>("pattern_pitch_meta", _input_names[i]))
389  mooseError(
390  "In PatternedHexMeshGenerator ",
391  _name,
392  ": the unit hexagonal input mesh does not contain appropriate meta data "
393  "required for generating a core mesh. Involved input mesh: ",
394  _input_names[i],
395  "; metadata issue: 'pattern_pitch_meta' is missing. Note that "
396  "'generate_core_metadata' is set to true, which"
397  "means that the mesh generator is producing a core mesh by stitching the input "
398  "assembly meshes together. Therefore,"
399  "the input meshes must contain the metadata of assembly meshes, which can "
400  "usually be either automatically assigned "
401  "by using another PatternedHexMeshGenerator with 'generate_core_metadata' set as "
402  "false and 'pattern_boundary' set as hexagon, or manually assigned by "
403  "AddMetaDataGenerator.");
404  pattern_pitch_array.push_back(getMeshProperty<Real>("pattern_pitch_meta", _input_names[i]));
405  // throw an error message if the input mesh contains non-sense meta data
406  if (pattern_pitch_array.back() == 0.0)
407  mooseError(
408  "In PatternedHexMeshGenerator ",
409  _name,
410  ": the unit hexagonal input mesh does not contain appropriate meta data "
411  "required for generating a core mesh. Involved input mesh: ",
412  _input_names[i],
413  "; metadata issue: 'pattern_pitch_meta' is zero. Note that "
414  "'generate_core_metadata' is set to true, which"
415  "means that the mesh generator is producing a core mesh by stitching the input "
416  "assembly meshes together. Therefore,"
417  "the input meshes must contain the metadata of assembly meshes, which can "
418  "usually be either automatically assigned "
419  "by using another PatternedHexMeshGenerator with 'generate_core_metadata' set as "
420  "false and 'pattern_boundary' set as hexagon, or manually assigned by "
421  "AddMetaDataGenerator.");
422  is_control_drum_array.push_back(
423  getMeshProperty<bool>("is_control_drum_meta", _input_names[i]));
424  control_drum_azimuthal_array.push_back(
425  getMeshProperty<bool>("is_control_drum_meta", _input_names[i])
426  ? getMeshProperty<std::vector<Real>>("azimuthal_angle_meta", _input_names[i])
427  : std::vector<Real>());
428  }
430  *std::max_element(pattern_pitch_array.begin(), pattern_pitch_array.end()),
431  *std::min_element(pattern_pitch_array.begin(), pattern_pitch_array.end())))
432  mooseError(
433  "In PatternedHexMeshGenerator ",
434  _name,
435  ": pattern_pitch metadata values of all input mesh generators must be identical "
436  "when pattern_boundary is 'none' and generate_core_metadata is true. Please check the "
437  "parameters of the mesh generators that produce the input meshes."
438  "Note that some of these mesh generators, such as "
439  "HexagonConcentricCircleAdaptiveBoundaryMeshGenerator and FlexiblePatternGenerator,"
440  "may have different definitions of hexagon size in their input parameters. Please refer "
441  "to the documentation of these mesh generators.",
442  pitchMetaDataErrorGenerator(_input_names, pattern_pitch_array, "pattern_pitch_meta"));
443  else
444  {
445  _pattern_pitch = pattern_pitch_array.front();
446  setMeshProperty("input_pitch_meta", _pattern_pitch);
447  }
448  }
449  else
450  {
451  if (_pattern_boundary == "hexagon")
452  {
453  if (!isParamValid("hexagon_size"))
454  paramError("hexagon_size",
455  "This parameter must be provided when pattern_boundary is hexagon.");
456  else
458  ? getParam<Real>("hexagon_size")
459  : getParam<Real>("hexagon_size") * std::cos(M_PI / 6.0));
460  }
461  for (MooseIndex(_input_names) i = 0; i < _input_names.size(); ++i)
462  {
463  // throw an error message if the input mesh does not contain the required meta data
464  if (!hasMeshProperty<Real>("pitch_meta", _input_names[i]))
465  mooseError("In PatternedHexMeshGenerator ",
466  _name,
467  ": the unit hexagonal input mesh does not contain appropriate meta data "
468  "required for generating an assembly. Involved input mesh: ",
469  _input_names[i],
470  "; metadata issue: 'pitch_meta' is missing");
471  pitch_array.push_back(getMeshProperty<Real>("pitch_meta", _input_names[i]));
472 
473  num_sectors_per_side_array_tmp =
474  getMeshProperty<std::vector<unsigned int>>("num_sectors_per_side_meta", _input_names[i]);
475  if (*std::max_element(num_sectors_per_side_array_tmp.begin(),
476  num_sectors_per_side_array_tmp.end()) !=
477  *std::min_element(num_sectors_per_side_array_tmp.begin(),
478  num_sectors_per_side_array_tmp.end()))
479  mooseError("In PatternedHexMeshGenerator ",
480  _name,
481  ": num_sectors_per_side metadata values of all six sides of each input mesh "
482  "generator must be identical.");
483  if (num_sectors_per_side_array_tmp.front() == 1 && _pattern_boundary == "hexagon")
484  paramError(
485  "inputs",
486  "for each input mesh, the number of sectors on each side must be greater than unity.");
487  num_sectors_per_side_array.push_back(*num_sectors_per_side_array_tmp.begin());
488  background_intervals_array.push_back(
489  getMeshProperty<unsigned int>("background_intervals_meta", _input_names[i]));
490  node_id_background_array.push_back(
491  getMeshProperty<dof_id_type>("node_id_background_meta", _input_names[i]));
492  max_radius_array.push_back(getMeshProperty<Real>("max_radius_meta", _input_names[i]));
493  }
494  max_radius_global = *max_element(max_radius_array.begin(), max_radius_array.end());
495  if (!MooseUtils::absoluteFuzzyEqual(*std::max_element(pitch_array.begin(), pitch_array.end()),
496  *std::min_element(pitch_array.begin(), pitch_array.end())))
497  mooseError("In PatternedHexMeshGenerator ",
498  _name,
499  ": pitch metadata values of all input mesh generators must be identical. Please "
500  "check the "
501  "parameters of the mesh generators that produce the input meshes.",
502  pitchMetaDataErrorGenerator(_input_names, pitch_array, "pitch_meta"));
503  setMeshProperty("input_pitch_meta", pitch_array.front());
504  if (*std::max_element(num_sectors_per_side_array.begin(), num_sectors_per_side_array.end()) !=
505  *std::min_element(num_sectors_per_side_array.begin(), num_sectors_per_side_array.end()))
506  mooseError(
507  "In PatternedHexMeshGenerator ",
508  _name,
509  ": num_sectors_per_side metadata values of all input mesh generators must be identical.");
510  }
511 
512  std::vector<Real> extra_dist;
513  Real extra_dist_shift(0.0);
514  Real y_min(0.0);
515  Real y_max_0(0.0);
516  Real y_max_n(0.0);
517  const Real extra_dist_tol = _pattern_boundary == "hexagon" ? pitch_array.front() / 10.0 : 0.0;
518  const Real extra_dist_shift_0 = _pattern_boundary == "hexagon" ? pitch_array.front() / 5.0 : 0.0;
519  std::vector<unsigned int> peripheral_duct_intervals;
520  if (_pattern_boundary == "hexagon")
521  {
522  if (_has_assembly_duct)
523  {
524  for (unsigned int i = 0; i < _duct_sizes.size(); i++)
525  {
527  _duct_sizes[i] /= std::cos(M_PI / 6.0);
528  extra_dist.push_back(0.5 *
529  (_duct_sizes[i] * 2.0 - pitch_array.front() / std::sqrt(3.0) *
530  (Real)((_pattern.size() / 2) * 3 + 2)));
531  peripheral_duct_intervals.push_back(_duct_intervals[i]);
532  }
533  if (_duct_sizes.back() >= _pattern_pitch / 2.0)
534  paramError("duct_sizes",
535  "The duct sizes should not exceed the size of the hexagonal boundary.");
536  }
537  // calculate the distance between the larger hexagon boundary and the boundary of stitched unit
538  // hexagons this is used to decide whether deformation is needed when cut-off happens or when
539  // the distance is small.
540  extra_dist.push_back(0.5 * (_pattern_pitch - pitch_array.front() / std::sqrt(3.0) *
541  (Real)((_pattern.size() / 2) * 3 + 2)));
542  peripheral_duct_intervals.insert(peripheral_duct_intervals.begin(), _background_intervals);
543 
544  // In same cases, when the external hexagon size is small enough, the external hexagon boundary
545  // may either be very close to the input hexagon meshes that are near the boundary or even cut
546  // off the these hexagons. As long as the ring regions are not cut off, the input hexagons can
547  // be deformed to accommodate the external hexagon shape. This block sets up the range of mesh
548  // region that needs to be deformed.
549  if (extra_dist.front() <= extra_dist_tol)
550  {
551  extra_dist_shift = extra_dist_shift_0 - extra_dist.front();
552  for (Real & d : extra_dist)
553  d += extra_dist_shift;
555  ? max_radius_global // Currently use this, ideally this should be the max of the
556  // outer layer radii
557  : (pitch_array.front() / std::sqrt(3.0));
558  y_max_0 = pitch_array.front() / std::sqrt(3.0) + extra_dist.front();
559  y_max_n = y_max_0 - extra_dist_shift;
560  if (y_max_n <= y_min)
561  mooseError("In PatternedHexMeshGenerator ",
562  _name,
563  ": the assembly is cut off so much that the internal structure that should not "
564  "be altered is compromised.");
565  }
566  }
567 
568  setMeshProperty("pattern_pitch_meta", _pattern_pitch);
569 
570  // create a list of interface boundary ids for each input mesh
571  // NOTE: list of interface boundary ids is stored in mesh metadata
572  std::vector<std::set<boundary_id_type>> input_interface_boundary_ids;
573  input_interface_boundary_ids.resize(_input_names.size());
575  {
576  for (const auto i : make_range(_input_names.size()))
577  {
578  if (!hasMeshProperty<bool>("interface_boundaries", _input_names[i]))
579  mooseError("Metadata 'interface_boundaries' could not be found on the input mesh: ",
580  _input_names[i]);
581  if (!getMeshProperty<bool>("interface_boundaries", _input_names[i]))
582  mooseError("Interface boundary ids were not constructed in the input mesh",
583  _input_names[i]);
584  if (!hasMeshProperty<std::set<boundary_id_type>>("interface_boundary_ids", _input_names[i]))
585  mooseError("Metadata 'interface_boundary_ids' could not be found on the input mesh: ",
586  _input_names[i]);
587  }
588  }
589  for (const auto i : make_range(_input_names.size()))
591  hasMeshProperty<std::set<boundary_id_type>>("interface_boundary_ids", _input_names[i]))
592  input_interface_boundary_ids[i] =
593  getMeshProperty<std::set<boundary_id_type>>("interface_boundary_ids", _input_names[i]);
594 
595  int x_mov = 0;
596 
597  const Real input_pitch((_pattern_boundary == "hexagon" || !_generate_core_metadata)
598  ? pitch_array.front()
599  : _pattern_pitch);
600  std::vector<Real> control_drum_positions_x;
601  std::vector<Real> control_drum_positions_y;
602  std::vector<std::vector<Real>> control_drum_azimuthals;
603 
604  std::unique_ptr<ReplicatedMesh> out_mesh;
605 
606  for (unsigned i = 0; i < _pattern.size(); i++)
607  {
608  Real deltax = -x_mov * input_pitch / 2;
609  if (i == _pattern.size() - 1)
610  x_mov--;
611  else if (_pattern[i].size() < _pattern[i + 1].size())
612  x_mov++;
613  else
614  x_mov--;
615  Real deltay = -(Real)(i)*input_pitch * std::sin(M_PI / 3);
616 
617  for (unsigned int j = 0; j < _pattern[i].size(); j++)
618  {
619  const auto pattern = _pattern[i][j];
620  ReplicatedMesh & pattern_mesh = *meshes[pattern];
621 
622  // No pattern boundary, so no need to wrap with a peripheral mesh
623  // Use the inputs as they stand and translate accordingly later
624  if (_pattern_boundary == "none")
625  {
626  if (_generate_core_metadata && is_control_drum_array[pattern] == 1)
627  {
628  control_drum_positions_x.push_back(deltax + j * input_pitch);
629  control_drum_positions_y.push_back(deltay);
630  control_drum_azimuthals.push_back(control_drum_azimuthal_array[pattern]);
631  }
632 
633  if (j == 0 && i == 0)
634  {
635  out_mesh = dynamic_pointer_cast<ReplicatedMesh>(pattern_mesh.clone());
637  out_mesh->add_elem_integer(
638  "control_drum_id",
639  true,
640  is_control_drum_array[pattern] ? control_drum_azimuthals.size() : 0);
641  // Reassign interface boundary ids
643  reassignBoundaryIDs(*out_mesh,
645  input_interface_boundary_ids[pattern]);
646  continue;
647  }
648  }
649  // Has a pattern boundary so we need to wrap with a peripheral mesh
650  else // has a pattern boundary
651  {
652  Real rotation_angle = std::numeric_limits<Real>::max();
653  Real orientation = std::numeric_limits<Real>::max();
654  unsigned int mesh_type = std::numeric_limits<unsigned int>::max();
655  bool on_periphery = true;
656 
657  if (j == 0 && i == 0)
658  {
659  rotation_angle = 60.;
660  mesh_type = CORNER_MESH;
661  orientation = 0.;
662  }
663  else if (j == 0 && i == _pattern.size() - 1)
664  {
665  rotation_angle = 180.;
666  mesh_type = CORNER_MESH;
667  orientation = -120.;
668  }
669  else if (j == 0 && i == (_pattern.size() - 1) / 2)
670  {
671  rotation_angle = 120.;
672  mesh_type = CORNER_MESH;
673  orientation = -60.;
674  }
675  else if (j == _pattern[i].size() - 1 && i == 0)
676  {
677  rotation_angle = 0.;
678  mesh_type = CORNER_MESH;
679  orientation = 60.;
680  }
681  else if (j == _pattern[i].size() - 1 && i == _pattern.size() - 1)
682  {
683  rotation_angle = -120.;
684  mesh_type = CORNER_MESH;
685  orientation = 180.;
686  }
687  else if (j == _pattern[i].size() - 1 && i == (_pattern.size() - 1) / 2)
688  {
689  rotation_angle = -60.;
690  mesh_type = CORNER_MESH;
691  orientation = 120.;
692  }
693  else if (i == 0)
694  {
695  rotation_angle = 0.;
696  mesh_type = BOUNDARY_MESH;
697  orientation = 0.;
698  }
699  else if (i == _pattern.size() - 1)
700  {
701  rotation_angle = 180.;
702  mesh_type = BOUNDARY_MESH;
703  orientation = -180.;
704  }
705  else if (j == 0 && i < (_pattern.size() - 1) / 2)
706  {
707  rotation_angle = 60.;
708  mesh_type = BOUNDARY_MESH;
709  orientation = -60.;
710  }
711  else if (j == 0 && i > (_pattern.size() - 1) / 2)
712  {
713  rotation_angle = 120.;
714  mesh_type = BOUNDARY_MESH;
715  orientation = -120.;
716  }
717  else if (j == _pattern[i].size() - 1 && i < (_pattern.size() - 1) / 2)
718  {
719  rotation_angle = -60.;
720  mesh_type = BOUNDARY_MESH;
721  orientation = 60.;
722  }
723  else if (j == _pattern[i].size() - 1 && i > (_pattern.size() - 1) / 2)
724  {
725  rotation_angle = -120.;
726  mesh_type = BOUNDARY_MESH;
727  orientation = 120;
728  }
729  else
730  on_periphery = false;
731 
732  if (on_periphery)
733  {
734  auto tmp_peripheral_mesh = dynamic_pointer_cast<ReplicatedMesh>(pattern_mesh.clone());
735  addPeripheralMesh(*tmp_peripheral_mesh,
736  pattern,
737  pitch_array.front(),
738  extra_dist,
739  num_sectors_per_side_array,
740  peripheral_duct_intervals,
741  rotation_angle,
742  mesh_type);
743 
744  if (extra_dist_shift != 0)
745  cutOffPolyDeform(*tmp_peripheral_mesh, orientation, y_max_0, y_max_n, y_min, mesh_type);
746 
747  // Reassign interface boundary ids
749  reassignBoundaryIDs(*tmp_peripheral_mesh,
751  input_interface_boundary_ids[pattern]);
752 
753  if (i == 0 && j == 0)
754  out_mesh = std::move(tmp_peripheral_mesh);
755  else
756  {
757  // Retrieve subdomain name map from the mesh to be stitched and insert it to the main
758  // subdomain map
759  const auto & increment_subdomain_map = tmp_peripheral_mesh->get_subdomain_name_map();
760  out_mesh->set_subdomain_name_map().insert(increment_subdomain_map.begin(),
761  increment_subdomain_map.end());
762 
763  MeshTools::Modification::translate(
764  *tmp_peripheral_mesh, deltax + j * input_pitch, deltay, 0);
765  out_mesh->stitch_meshes(*tmp_peripheral_mesh,
768  TOLERANCE,
769  /*clear_stitched_boundary_ids=*/true,
770  /*verbose=*/false);
771  }
772 
773  continue;
774  }
775  }
776 
778  pattern_mesh.add_elem_integer(
779  "control_drum_id",
780  true,
781  is_control_drum_array[pattern] ? control_drum_azimuthals.size() : 0);
782 
783  // Translate to correct position
784  MeshTools::Modification::translate(pattern_mesh, deltax + j * input_pitch, deltay, 0);
785 
786  // Define a reference map variable for subdomain map
787  auto & main_subdomain_map = out_mesh->set_subdomain_name_map();
788  // Retrieve subdomain name map from the mesh to be stitched and insert it to the main
789  // subdomain map
790  const auto & increment_subdomain_map = pattern_mesh.get_subdomain_name_map();
791  main_subdomain_map.insert(increment_subdomain_map.begin(), increment_subdomain_map.end());
792  // Check if one SubdomainName is shared by more than one subdomain ids
793  std::set<SubdomainName> main_subdomain_map_name_list;
794  for (auto const & id_name_pair : main_subdomain_map)
795  main_subdomain_map_name_list.emplace(id_name_pair.second);
796  if (main_subdomain_map.size() != main_subdomain_map_name_list.size())
797  paramError("inputs", "The input meshes contain subdomain name maps with conflicts.");
798  // Shift interface boundary ids
800  reassignBoundaryIDs(pattern_mesh,
802  input_interface_boundary_ids[pattern]);
803 
804  out_mesh->stitch_meshes(pattern_mesh,
807  TOLERANCE,
808  /*clear_stitched_boundary_ids=*/false,
809  /*verbose=*/false);
810 
811  // Translate back now that we've stitched so that anyone else that uses this mesh has it at
812  // the origin
813  MeshTools::Modification::translate(pattern_mesh, -(deltax + j * input_pitch), -deltay, 0);
814  // Roll back the changes in interface boundary ids for the same reason
816  reassignBoundaryIDs(pattern_mesh,
818  input_interface_boundary_ids[pattern],
819  true);
820  }
821  }
822 
823  // Check if OUTER_SIDESET_ID is really the external boundary. Correct if needed.
824  auto side_list = out_mesh->get_boundary_info().build_side_list();
825  for (auto & sl : side_list)
826  {
827  if (std::get<2>(sl) == OUTER_SIDESET_ID)
828  if (out_mesh->elem_ptr(std::get<0>(sl))->neighbor_ptr(std::get<1>(sl)) != nullptr)
829  out_mesh->get_boundary_info().remove_side(
830  out_mesh->elem_ptr(std::get<0>(sl)), std::get<1>(sl), std::get<2>(sl));
831  }
832  out_mesh->get_boundary_info().clear_boundary_node_ids();
833 
834  out_mesh->get_boundary_info().build_node_list_from_side_list();
835  const auto node_list = out_mesh->get_boundary_info().build_node_list();
836 
837  std::vector<Real> bd_x_list;
838  std::vector<Real> bd_y_list;
839  std::vector<std::pair<Real, dof_id_type>> node_azi_list;
840  const Point origin_pt = MooseMeshUtils::meshCentroidCalculator(*out_mesh);
841  const Real origin_x = origin_pt(0);
842  const Real origin_y = origin_pt(1);
843 
844  MeshTools::Modification::translate(*out_mesh, -origin_x, -origin_y, 0);
845 
847  {
848  const Real azi_tol = 1E-8;
849  for (unsigned int i = 0; i < node_list.size(); ++i)
850  {
851  if (std::get<1>(node_list[i]) == OUTER_SIDESET_ID)
852  {
853  node_azi_list.push_back(
854  std::make_pair(atan2(out_mesh->node_ref(std::get<0>(node_list[i]))(1),
855  out_mesh->node_ref(std::get<0>(node_list[i]))(0)) *
856  180.0 / M_PI,
857  std::get<0>(node_list[i])));
858  // correct the last node's angle value (180.0) if it becomes a negative value.
859  if (node_azi_list.back().first + 180.0 <= azi_tol)
860  node_azi_list.back().first = 180;
861  }
862  }
863  std::sort(node_azi_list.begin(), node_azi_list.end());
864  const unsigned int side_intervals = node_azi_list.size() / HEXAGON_NUM_SIDES;
865  for (unsigned int i = 0; i < HEXAGON_NUM_SIDES; i++)
866  {
867  for (unsigned int j = 1; j <= side_intervals; j++)
868  {
869  Real azi_corr_tmp = atan2((Real)j * 2.0 / (Real)side_intervals - 1.0, std::sqrt(3.0));
870  Real x_tmp = _pattern_pitch / 2.0;
871  Real y_tmp = x_tmp * std::tan(azi_corr_tmp);
872  nodeCoordRotate(x_tmp, y_tmp, (Real)i * 60.0 - 150.0);
873  Point p_tmp = Point(x_tmp, y_tmp, 0.0);
874  out_mesh->add_point(p_tmp, node_azi_list[i * side_intervals + j - 1].second);
875  }
876  }
877 
878  // if quadratic elements are used, additional nodes need to be adjusted based on the new
879  // boundary node locations. adjust side mid-edge nodes to the midpoints of the corner
880  // points, and if QUAD9, adjust center point to new centroid.
883  }
884 
885  MeshTools::Modification::rotate(*out_mesh, _rotate_angle, 0.0, 0.0);
886 
887  // This combination of input parameters is usually used for core mesh generation by stitching
888  // assembly meshes together.
890  {
891  const Real azi_tol = 1E-8;
892  std::vector<std::tuple<Real, Point, std::vector<Real>, dof_id_type>> control_drum_tmp;
893  std::vector<dof_id_type> control_drum_id_sorted;
894  for (unsigned int i = 0; i < control_drum_positions_x.size(); ++i)
895  {
896  control_drum_positions_x[i] -= origin_x;
897  control_drum_positions_y[i] -= origin_y;
898  nodeCoordRotate(control_drum_positions_x[i], control_drum_positions_y[i], _rotate_angle);
899  Real cd_angle = atan2(control_drum_positions_y[i], control_drum_positions_x[i]);
900 
901  for (unsigned int j = 0; j < control_drum_azimuthals[i].size(); j++)
902  {
903  control_drum_azimuthals[i][j] += _rotate_angle;
904  control_drum_azimuthals[i][j] =
905  atan2(std::sin(control_drum_azimuthals[i][j] / 180.0 * M_PI),
906  std::cos(control_drum_azimuthals[i][j] / 180.0 * M_PI)) /
907  M_PI * 180.0; // quick way to move to -M_PI to M_PI
908  }
909  std::sort(control_drum_azimuthals[i].begin(), control_drum_azimuthals[i].end());
910 
911  if (std::abs(cd_angle) < azi_tol)
912  cd_angle = 0;
913  else if (cd_angle < 0.0)
914  cd_angle += 2 * M_PI;
915  control_drum_tmp.push_back(
916  std::make_tuple(cd_angle,
917  Point(control_drum_positions_x[i], control_drum_positions_y[i], 0.0),
918  control_drum_azimuthals[i],
919  i + 1)); // control drum index to help sort control_drum_id
920  }
921  std::sort(control_drum_tmp.begin(), control_drum_tmp.end());
922  std::vector<Point> control_drum_positions;
923  std::vector<Real> control_drum_angles;
924  std::vector<std::vector<Real>> control_drums_azimuthal_meta;
925  for (unsigned int i = 0; i < control_drum_tmp.size(); ++i)
926  {
927  control_drum_positions.push_back(std::get<1>(control_drum_tmp[i]));
928  control_drum_angles.push_back(std::get<0>(control_drum_tmp[i]));
929  control_drums_azimuthal_meta.push_back(std::get<2>(control_drum_tmp[i]));
930  control_drum_id_sorted.push_back(std::get<3>(control_drum_tmp[i]));
931  }
932  setMeshProperty("control_drum_positions", control_drum_positions);
933  setMeshProperty("control_drum_angles", control_drum_angles);
934  setMeshProperty("control_drums_azimuthal_meta", control_drums_azimuthal_meta);
935 
937  {
938  unsigned int id = out_mesh->get_elem_integer_index("control_drum_id");
939  for (const auto & elem : out_mesh->element_ptr_range())
940  {
941  dof_id_type unsorted_control_drum_id = elem->get_extra_integer(id);
942  if (unsorted_control_drum_id != 0)
943  {
944  auto sorted_iter = std::find(control_drum_id_sorted.begin(),
945  control_drum_id_sorted.end(),
946  unsorted_control_drum_id);
947  elem->set_extra_integer(id,
948  std::distance(control_drum_id_sorted.begin(), sorted_iter) + 1);
949  }
950  }
951  }
952 
954  {
955  std::string position_file_name = getMeshProperty<std::string>("position_file_name", name());
956  std::ofstream pos_file(position_file_name);
957  for (unsigned int i = 0; i < control_drum_positions.size(); ++i)
958  pos_file << control_drum_positions[i](0) << " " << control_drum_positions[i](1) << " 0.0\n";
959  pos_file.close();
960  }
961  }
962 
963  // before return, add reporting IDs if _use_reporting_id is set true
964  if (_use_reporting_id)
965  addReportingIDs(*out_mesh, meshes);
966 
967  // Assign customized peripheral block ids and names
968  if (!_peripheral_block_ids.empty())
969  for (const auto & elem : out_mesh->active_element_ptr_range())
971  i++)
972  if (elem->subdomain_id() == i)
973  {
974  elem->subdomain_id() = _peripheral_block_ids[i - PERIPHERAL_ID_SHIFT];
975  break;
976  }
977  if (!_peripheral_block_names.empty())
978  {
979  for (unsigned i = 0; i < _peripheral_block_names.size(); i++)
980  out_mesh->subdomain_name(_peripheral_block_ids.empty() ? (PERIPHERAL_ID_SHIFT + i)
981  : _peripheral_block_ids[i]) =
983  }
984  // Assign customized outer surface boundary id and name
985  if (_external_boundary_id > 0)
987  if (!_external_boundary_name.empty())
988  {
989  out_mesh->get_boundary_info().sideset_name(
992  out_mesh->get_boundary_info().nodeset_name(
995  }
996  // Merge the boundary name maps of all the input meshed to generate the output mesh's boundary
997  // name maps
998  auto & new_sideset_map = out_mesh->get_boundary_info().set_sideset_name_map();
999  auto & new_nodeset_map = out_mesh->get_boundary_info().set_nodeset_name_map();
1000  for (unsigned int i = 0; i < meshes.size(); i++)
1001  {
1002  const auto input_sideset_map = meshes[i]->get_boundary_info().get_sideset_name_map();
1003  new_sideset_map.insert(input_sideset_map.begin(), input_sideset_map.end());
1004  const auto input_nodeset_map = meshes[i]->get_boundary_info().get_nodeset_name_map();
1005  new_nodeset_map.insert(input_nodeset_map.begin(), input_nodeset_map.end());
1006  }
1007 
1008  // set mesh metadata related with interface boundary ids
1009  const std::set<boundary_id_type> boundary_ids = out_mesh->get_boundary_info().get_boundary_ids();
1010  const std::set<boundary_id_type> interface_boundary_ids = getInterfaceBoundaryIDs(
1011  _pattern,
1013  boundary_ids,
1014  input_interface_boundary_ids,
1017  extra_dist.size());
1018  if (interface_boundary_ids.size() > 0)
1019  {
1020  setMeshProperty("interface_boundaries", true);
1021  setMeshProperty("interface_boundary_ids", interface_boundary_ids);
1022  }
1023 
1024  out_mesh->set_isnt_prepared();
1025  auto mesh = dynamic_pointer_cast<MeshBase>(out_mesh);
1026  return mesh;
1027 }
const T & getMeshProperty(const std::string &data_name, const std::string &prefix)
const bool _use_reporting_id
Whether reporting ID is added to mesh.
const PolygonSizeStyle _duct_sizes_style
Style of the duct size parameter(s)
const std::vector< unsigned int > _duct_intervals
Number(s) of radial intervals of duct layer(s)
T & setMeshProperty(const std::string &data_name, Args &&... args)
bool absoluteFuzzyEqual(const T &var1, const T2 &var2, const T3 &tol=libMesh::TOLERANCE *libMesh::TOLERANCE)
const MooseEnum _pattern_boundary
Type of the external boundary shape.
const bool _has_assembly_duct
Whether the hexagonal pattern has external duct(s)
const unsigned int _background_intervals
Number of radial intervals in the background region.
std::vector< SubdomainName > _peripheral_block_names
Subdomain Names of the peripheral regions.
const bool _assign_control_drum_id
Wheter control drum IDs are assigned as an extra element integer.
const std::vector< std::vector< unsigned int > > & _pattern
2D vector of the hexagonal pattern
MeshBase & mesh
const PolygonSizeStyle _hexagon_size_style
Style of the polygon size parameter.
std::unique_ptr< T_DEST, T_DELETER > dynamic_pointer_cast(std::unique_ptr< T_SRC, T_DELETER > &src)
const bool _create_inward_interface_boundaries
Whether inward interface boundaries are created.
const bool _create_outward_interface_boundaries
Whether outward interface boundaries are created.
void changeBoundaryId(const boundary_id_type old_id, const boundary_id_type new_id, bool delete_prev)
virtual const std::string & name() const
void nodeCoordRotate(Real &x, Real &y, const Real theta) const
Calculates x and y coordinates after rotating by theta angle.
std::vector< std::vector< boundary_id_type > > _interface_boundary_id_shift_pattern
hold user-defined shift values for each pattern cell
const std::vector< MeshGeneratorName > & _input_names
Names of input meshes.
bool isParamValid(const std::string &name) const
const Real _rotate_angle
The mesh rotation angle after mesh generation.
void adjustPeripheralQuadraticElements(MeshBase &out_mesh, const QUAD_ELEM_TYPE boundary_quad_elem_type) const
Adjusts the mid-edge node locations in boundary regions when using quadratic elements with uniform bo...
int8_t boundary_id_type
std::string pitchMetaDataErrorGenerator(const std::vector< MeshGeneratorName > &input_names, const std::vector< Real > &metadata_vals, const std::string &metadata_name) const
Generate a string that contains the detailed metadata information for inconsistent input mesh metadat...
const bool _uniform_mesh_on_sides
Whether the nodes on the external boundary are uniformly distributed.
QUAD_ELEM_TYPE _boundary_quad_elem_type
Type of quadrilateral elements to be generated in the periphery region.
std::vector< Real > _duct_sizes
Size parameter(s) of duct(s)
const std::vector< std::unique_ptr< MeshBase > * > _mesh_ptrs
The input meshes.
const boundary_id_type _external_boundary_id
Boundary ID of mesh&#39;s external boundary.
const bool _deform_non_circular_region
Whether the non-circular region (outside the rings) can be deformed.
const bool _generate_control_drum_positions_file
Whether a text file containing control drum positions is generated.
void paramError(const std::string &param, Args... args) const
std::vector< subdomain_id_type > _peripheral_block_ids
Subdomain IDs of the peripheral regions.
const std::string _name
const bool _use_interface_boundary_id_shift
whether the interface boundary ids from input meshes are shifted, using a user-defined pattern of val...
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
void addPeripheralMesh(ReplicatedMesh &mesh, const unsigned int pattern, const Real pitch, const std::vector< Real > &extra_dist, const std::vector< unsigned int > &num_sectors_per_side_array, const std::vector< unsigned int > &peripheral_duct_intervals, const Real rotation_angle, const unsigned int mesh_type)
Adds background and duct region mesh to stitched hexagon meshes.
void addReportingIDs(MeshBase &mesh, const std::vector< std::unique_ptr< ReplicatedMesh >> &from_meshes) const
Adds the reporting IDs onto the input mesh.
Real _pattern_pitch
Pitch size of the input assembly mesh.
IntRange< T > make_range(T beg, T end)
void mooseError(Args &&... args) const
static const std::complex< double > j(0, 1)
Complex number "j" (also known as "i")
const BoundaryName _external_boundary_name
Boundary name of mesh&#39;s external boundary.
Point meshCentroidCalculator(const MeshBase &mesh)
void reassignBoundaryIDs(MeshBase &mesh, const boundary_id_type id_shift, const std::set< boundary_id_type > &boundary_ids, const bool reverse=false)
reassign interface boundary IDs on the input mesh by applying the boundary ID shift ...
bool hasMeshProperty(const std::string &data_name, const std::string &prefix) const
auto index_range(const T &sizable)
assign the same reporting IDs for all tiles in the pattern with same input
uint8_t dof_id_type
const bool _generate_core_metadata
Whether a reactor core mesh with core metadata is generated.
std::set< boundary_id_type > getInterfaceBoundaryIDs(const std::vector< std::vector< unsigned int >> &pattern, const std::vector< std::vector< boundary_id_type >> &interface_boundary_id_shift_pattern, const std::set< boundary_id_type > &boundary_ids, const std::vector< std::set< boundary_id_type >> &input_interface_boundary_ids, const bool use_interface_boundary_id_shift, const bool create_interface_boundary_id, const unsigned int num_extra_layers) const
returns a list of interface boundary IDs on the mesh generated by this mesh generator ...
void cutOffPolyDeform(MeshBase &mesh, const Real orientation, const Real y_max_0, const Real y_max_n, const Real y_min, const unsigned int mesh_type, const Real unit_angle=60.0, const Real tols=1E-5) const
Deforms peripheral region when the external side of a polygon assembly of stitched meshes cuts off th...

◆ getInterfaceBoundaryIDs()

std::set< boundary_id_type > PolygonMeshGeneratorBase::getInterfaceBoundaryIDs ( const std::vector< std::vector< unsigned int >> &  pattern,
const std::vector< std::vector< boundary_id_type >> &  interface_boundary_id_shift_pattern,
const std::set< boundary_id_type > &  boundary_ids,
const std::vector< std::set< boundary_id_type >> &  input_interface_boundary_ids,
const bool  use_interface_boundary_id_shift,
const bool  create_interface_boundary_id,
const unsigned int  num_extra_layers 
) const
protectedinherited

returns a list of interface boundary IDs on the mesh generated by this mesh generator

Parameters
patternpattern of cells used in this mesh generator
interface_boundary_id_shift_pattern2D pattern of shift values applied to the boundary IDs inside each pattern cells
boundary_idslist of boundary IDs on the mesh generated by this mesh generator
input_interface_boundary_idslist of interface boundary IDs of the pattern cells
use_interface_boundary_id_shiftwhether ID shifts are applied to interface boundary IDs of the pattern cells
create_interface_boundary_idwhether interface boundary IDs are generated by this mesh generator
num_extra_layersnumber of extra layers to define background and duct regions on the patterned mesh generated by this mesh generator

Definition at line 1722 of file PolygonMeshGeneratorBase.C.

Referenced by generate(), and PatternedCartesianMeshGenerator::generate().

1730 {
1731  std::set<boundary_id_type> interface_boundary_ids;
1732  // add existing interface boundary ids from input meshes
1733  if (use_interface_boundary_id_shift)
1734  {
1735  for (const auto i : make_range(pattern.size()))
1736  for (const auto j : make_range(pattern[i].size()))
1737  {
1738  const auto & ids = input_interface_boundary_ids[pattern[i][j]];
1739  for (const auto & id : ids)
1740  {
1741  const boundary_id_type new_id = id + interface_boundary_id_shift_pattern[i][j];
1742  auto it = boundary_ids.find(new_id);
1743  if (it != boundary_ids.end())
1744  interface_boundary_ids.insert(new_id);
1745  }
1746  }
1747  }
1748  else
1749  {
1750  for (const auto & ids : input_interface_boundary_ids)
1751  for (const auto & id : ids)
1752  {
1753  auto it = boundary_ids.find(id);
1754  if (it != boundary_ids.end())
1755  interface_boundary_ids.insert(id);
1756  }
1757  }
1758  // add unshifted interface boundary ids for the duct & background regions
1759  if (create_interface_boundary_id)
1760  for (const auto i : make_range(num_extra_layers))
1761  {
1762  boundary_id_type id = SLICE_ALT + i * 2 + 1;
1763  auto it = boundary_ids.find(id);
1764  if (it != boundary_ids.end())
1765  interface_boundary_ids.insert(id);
1766  id = SLICE_ALT + i * 2;
1767  it = boundary_ids.find(id);
1768  if (it != boundary_ids.end())
1769  interface_boundary_ids.insert(id);
1770  }
1771  return interface_boundary_ids;
1772 }
int8_t boundary_id_type
IntRange< T > make_range(T beg, T end)
static const std::complex< double > j(0, 1)
Complex number "j" (also known as "i")
assign the same reporting IDs for all tiles in the pattern with same input

◆ modifiedMultiBdryLayerParamsCreator()

PolygonMeshGeneratorBase::multiBdryLayerParams PolygonMeshGeneratorBase::modifiedMultiBdryLayerParamsCreator ( const multiBdryLayerParams original_multi_bdry_layer_params,
const unsigned int  order 
) const
protectedinherited

Modifies the input multi boundary layer parameters for node generation, especially for the quadratic elements.

Parameters
original_multi_bdry_layer_paramsoriginal multi boundary layer parameters
orderorder of the elements
Returns
modified multi boundary layer parameters

Definition at line 1775 of file PolygonMeshGeneratorBase.C.

Referenced by PolygonMeshGeneratorBase::buildSlice().

1777 {
1778  multiBdryLayerParams mod_multi_bdry_layer_params(original_multi_bdry_layer_params);
1779  std::for_each(mod_multi_bdry_layer_params.intervals.begin(),
1780  mod_multi_bdry_layer_params.intervals.end(),
1781  [&order](unsigned int & n) { n *= order; });
1782  std::for_each(mod_multi_bdry_layer_params.biases.begin(),
1783  mod_multi_bdry_layer_params.biases.end(),
1784  [&order](Real & n) { n = std::pow(n, 1.0 / order); });
1785  return mod_multi_bdry_layer_params;
1786 }
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
MooseUnits pow(const MooseUnits &, int)

◆ modifiedSingleBdryLayerParamsCreator()

PolygonMeshGeneratorBase::singleBdryLayerParams PolygonMeshGeneratorBase::modifiedSingleBdryLayerParamsCreator ( const singleBdryLayerParams original_single_bdry_layer_params,
const unsigned int  order 
) const
protectedinherited

Modifies the input single boundary layer parameters for node generation, especially for the quadratic elements.

Parameters
original_single_bdry_layer_paramsoriginal single boundary layer parameters
orderorder of the elements
Returns
modified single boundary layer parameters

Definition at line 1789 of file PolygonMeshGeneratorBase.C.

Referenced by PolygonMeshGeneratorBase::buildSlice().

1791 {
1792  singleBdryLayerParams mod_single_bdry_layer_params(original_single_bdry_layer_params);
1793  mod_single_bdry_layer_params.intervals *= order;
1794  mod_single_bdry_layer_params.bias = std::pow(mod_single_bdry_layer_params.bias, 1.0 / order);
1795  return mod_single_bdry_layer_params;
1796 }
MooseUnits pow(const MooseUnits &, int)

◆ nodeCoordRotate()

void PolygonMeshGeneratorBase::nodeCoordRotate ( Real x,
Real y,
const Real  theta 
) const
protectedinherited

Calculates x and y coordinates after rotating by theta angle.

Parameters
xx coordinate of the node to be rotated
yy coordinate of the node to be rotated
thetarotation angle
Returns
n/a

Definition at line 1320 of file PolygonMeshGeneratorBase.C.

Referenced by PolygonMeshGeneratorBase::cutOffPolyDeform(), FlexiblePatternGenerator::FlexiblePatternGenerator(), PolygonConcentricCircleMeshGeneratorBase::generate(), generate(), and PatternedCartesianMeshGenerator::generate().

1321 {
1322  const Real x_tmp = x;
1323  const Real y_tmp = y;
1324  x = x_tmp * std::cos(theta * M_PI / 180.0) - y_tmp * std::sin(theta * M_PI / 180.0);
1325  y = x_tmp * std::sin(theta * M_PI / 180.0) + y_tmp * std::cos(theta * M_PI / 180.0);
1326 }
const std::vector< double > y
const std::vector< double > x
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real

◆ pitchMetaDataErrorGenerator()

std::string PolygonMeshGeneratorBase::pitchMetaDataErrorGenerator ( const std::vector< MeshGeneratorName > &  input_names,
const std::vector< Real > &  metadata_vals,
const std::string &  metadata_name 
) const
protectedinherited

Generate a string that contains the detailed metadata information for inconsistent input mesh metadata error messages.

Parameters
input_nameslist of input mesh generator names
metadata_valslist of input mesh metadata values
metadata_namename of the input mesh metadata
Returns
a string that contains the detailed metadata information

Definition at line 1799 of file PolygonMeshGeneratorBase.C.

Referenced by generate(), and PatternedCartesianMeshGenerator::generate().

1803 {
1804  FormattedTable table;
1805  for (unsigned int i = 0; i < input_names.size(); i++)
1806  {
1807  table.addRow(i);
1808  table.addData<std::string>("input name", (std::string)input_names[i]);
1809  table.addData<Real>(metadata_name, metadata_vals[i]);
1810  }
1811  table.outputTimeColumn(false);
1812  std::stringstream detailed_error;
1813  table.printTable(detailed_error);
1814  return "\n" + detailed_error.str();
1815 }
void addData(const std::string &name, const T &value)
void outputTimeColumn(bool output_time)
void printTable(std::ostream &out, unsigned int last_n_entries=0)
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
void addRow(Real time)

◆ pointInterpolate()

std::pair< Real, Real > PolygonMeshGeneratorBase::pointInterpolate ( const Real  pi_1_x,
const Real  pi_1_y,
const Real  po_1_x,
const Real  po_1_y,
const Real  pi_2_x,
const Real  pi_2_y,
const Real  po_2_x,
const Real  po_2_y,
const unsigned int  i,
const unsigned int  j,
const unsigned int  num_sectors_per_side,
const unsigned int  peripheral_intervals 
) const
protectedinherited

Calculates the point coordinates of within a parallelogram region using linear interpolation.

Parameters
pi_1_xx coordinate of the first inner side point (parallelogram vertex)
pi_1_yy coordinate of the first inner side point (parallelogram vertex)
po_1_xx coordinate of the first outer side point (parallelogram vertex)
po_1_yy coordinate of the first outer side point (parallelogram vertex)
pi_2_xx coordinate of the second inner side point (parallelogram vertex)
pi_2_yy coordinate of the second inner side point (parallelogram vertex)
po_2_xx coordinate of the second outer side point (parallelogram vertex)
po_2_yy coordinate of the second outer side point (parallelogram vertex)
ipassed loop index 1
jpassed loop index 2
num_sectors_per_sidenumber of azimuthal intervals
peripheral_invervalsnumber of radial intervals of the peripheral region
Returns
an interpolated position within a parallelogram

Definition at line 1293 of file PolygonMeshGeneratorBase.C.

Referenced by PolygonMeshGeneratorBase::buildSimplePeripheral().

1305 {
1306  auto position_px_inner =
1307  (pi_1_x * (num_sectors_per_side / 2.0 - j) + pi_2_x * j) / (num_sectors_per_side / 2.0);
1308  auto position_py_inner =
1309  (pi_1_y * (num_sectors_per_side / 2.0 - j) + pi_2_y * j) / (num_sectors_per_side / 2.0);
1310  auto position_px_outer =
1311  (d_po_1_x * (num_sectors_per_side / 2.0 - j) + d_po_2_x * j) / (num_sectors_per_side / 2.0);
1312  auto position_py_outer =
1313  (d_po_1_y * (num_sectors_per_side / 2.0 - j) + d_po_2_y * j) / (num_sectors_per_side / 2.0);
1314  auto position_px = position_px_inner + position_px_outer * i / peripheral_intervals;
1315  auto position_py = position_py_inner + position_py_outer * i / peripheral_intervals;
1316  return std::make_pair(position_px, position_py);
1317 }
static const std::complex< double > j(0, 1)
Complex number "j" (also known as "i")

◆ positionSetup()

void PatternedHexMeshGenerator::positionSetup ( std::vector< std::pair< Real, Real >> &  positions_inner,
std::vector< std::pair< Real, Real >> &  d_positions_outer,
const Real  extra_dist_in,
const Real  extra_dist_out,
const Real  pitch,
const unsigned int  radial_index 
) const
protected

Computes the inner and outer node positions of the peripheral region for a single layer.

Parameters
positions_innerkey positions (i.e., vertices and mid-points) of the inner side of the peripheral region
d_positions_outerkey incremental positions (i.e., vertices and mid-points) of the outer side of the peripheral region
extra_dist_inextra distance applied to the inner side
extra_dist_outextra distance applied to the outer side
pitchpitch size of the involved hexagon mesh
radial_indexradial layer index

Definition at line 1102 of file PatternedHexMeshGenerator.C.

Referenced by addPeripheralMesh().

1108 {
1109  positions_inner.resize(0);
1110  d_positions_outer.resize(0);
1111 
1112  // Nine sets of positions are generated here, as shown below.
1113  // CORNER MESH Peripheral {0 1 2}, {2 3 4} and {4 5 6}
1114  // 3 2 1 0
1115  // \ : : :
1116  // \ : : :
1117  // 4. . : :
1118  // ` . :
1119  // 5. | |
1120  // ` | |
1121  // 6. | |
1122  // ` | |
1123  // . .
1124  // .
1125  //
1126  // EDGE MESH Peripheral {0 1 2} and {2 7 8}
1127  // 8 7 2 1 0
1128  // : : : : :
1129  // : : : : :
1130  // : : : :
1131  // : :
1132  // | |
1133  // | |
1134  // | |
1135  // | |
1136  // . .
1137  // .
1138 
1139  positions_inner.push_back(
1140  std::make_pair(-pitch / 2.0,
1141  std::sqrt(3.0) * pitch / 6.0 +
1142  (radial_index != 0 ? std::sqrt(3.0) * pitch / 6.0 + extra_dist_in : 0.0)));
1143  positions_inner.push_back(std::make_pair(
1144  -pitch / 4.0,
1145  std::sqrt(3.0) * pitch / 4.0 +
1146  (radial_index != 0 ? std::sqrt(3.0) * pitch / 12.0 + extra_dist_in : 0.0)));
1147  positions_inner.push_back(std::make_pair(
1148  0.0, std::sqrt(3.0) * pitch / 3.0 + (radial_index != 0 ? extra_dist_in : 0.0)));
1149  positions_inner.push_back(std::make_pair(
1150  pitch / 4.0 + (radial_index != 0 ? pitch / 12.0 + std::sqrt(3.0) * extra_dist_in / 3.0 : 0.0),
1151  std::sqrt(3.0) * pitch / 4.0 +
1152  (radial_index != 0 ? pitch * std::sqrt(3.0) / 12.0 + extra_dist_in : 0.0)));
1153  positions_inner.push_back(std::make_pair(
1154  pitch / 2.0 + (radial_index != 0 ? std::sqrt(3.0) * extra_dist_in / 2.0 : 0.0),
1155  std::sqrt(3.0) * pitch / 6.0 + (radial_index != 0 ? extra_dist_in / 2.0 : 0.0)));
1156  positions_inner.push_back(std::make_pair(
1157  pitch / 2.0 + (radial_index != 0 ? pitch / 8.0 + std::sqrt(3.0) * extra_dist_in / 2.0 : 0.0),
1158  0.0 + (radial_index != 0 ? std::sqrt(3.0) * pitch / 24.0 + extra_dist_in / 2.0 : 0.0)));
1159  positions_inner.push_back(std::make_pair(
1160  pitch / 2.0 + (radial_index != 0 ? pitch / 4.0 + std::sqrt(3.0) * extra_dist_in / 2.0 : 0.0),
1161  -std::sqrt(3.0) * pitch / 6.0 +
1162  (radial_index != 0 ? std::sqrt(3.0) * pitch / 12.0 + extra_dist_in / 2.0 : 0.0)));
1163  positions_inner.push_back(std::make_pair(
1164  pitch / 4.0,
1165  std::sqrt(3.0) * pitch / 4.0 +
1166  (radial_index != 0 ? std::sqrt(3.0) * pitch / 12.0 + extra_dist_in : 0.0)));
1167  positions_inner.push_back(
1168  std::make_pair(pitch / 2.0,
1169  std::sqrt(3.0) * pitch / 6.0 +
1170  (radial_index != 0 ? std::sqrt(3.0) * pitch / 6.0 + extra_dist_in : 0.0)));
1171 
1172  d_positions_outer.push_back(
1173  std::make_pair(0.0,
1174  std::sqrt(3.0) * pitch / 6.0 + extra_dist_out -
1175  (radial_index != 0 ? std::sqrt(3.0) * pitch / 6.0 + extra_dist_in : 0.0)));
1176  d_positions_outer.push_back(std::make_pair(
1177  0.0,
1178  std::sqrt(3.0) * pitch / 12.0 + extra_dist_out -
1179  (radial_index != 0 ? std::sqrt(3.0) * pitch / 12.0 + extra_dist_in : 0.0)));
1180  d_positions_outer.push_back(
1181  std::make_pair(0.0, extra_dist_out - (radial_index != 0 ? extra_dist_in : 0.0)));
1182  d_positions_outer.push_back(std::make_pair(
1183  pitch / 12.0 + std::sqrt(3.0) * extra_dist_out / 3.0 -
1184  (radial_index != 0 ? pitch / 12.0 + std::sqrt(3.0) * extra_dist_in / 3.0 : 0.0),
1185  pitch * std::sqrt(3.0) / 12.0 + extra_dist_out -
1186  (radial_index != 0 ? pitch * std::sqrt(3.0) / 12.0 + extra_dist_in : 0.0)));
1187  d_positions_outer.push_back(
1188  std::make_pair(std::sqrt(3.0) * extra_dist_out / 2.0 -
1189  (radial_index != 0 ? std::sqrt(3.0) * extra_dist_in / 2.0 : 0.0),
1190  extra_dist_out / 2.0 - (radial_index != 0 ? extra_dist_in / 2.0 : 0.0)));
1191  d_positions_outer.push_back(std::make_pair(
1192  pitch / 8.0 + std::sqrt(3.0) * extra_dist_out / 2.0 -
1193  (radial_index != 0 ? pitch / 8.0 + std::sqrt(3.0) * extra_dist_in / 2.0 : 0.0),
1194  std::sqrt(3.0) * pitch / 24.0 + extra_dist_out / 2.0 -
1195  (radial_index != 0 ? std::sqrt(3.0) * pitch / 24.0 + extra_dist_in / 2.0 : 0.0)));
1196  d_positions_outer.push_back(std::make_pair(
1197  pitch / 4.0 + std::sqrt(3.0) * extra_dist_out / 2.0 -
1198  (radial_index != 0 ? pitch / 4.0 + std::sqrt(3.0) * extra_dist_in / 2.0 : 0.0),
1199  std::sqrt(3.0) * pitch / 12.0 + extra_dist_out / 2.0 -
1200  (radial_index != 0 ? std::sqrt(3.0) * pitch / 12.0 + extra_dist_in / 2.0 : 0.0)));
1201  d_positions_outer.push_back(std::make_pair(
1202  0.0,
1203  std::sqrt(3.0) * pitch / 12.0 + extra_dist_out -
1204  (radial_index != 0 ? std::sqrt(3.0) * pitch / 12.0 + extra_dist_in : 0.0)));
1205  d_positions_outer.push_back(
1206  std::make_pair(0.0,
1207  std::sqrt(3.0) * pitch / 6.0 + extra_dist_out -
1208  (radial_index != 0 ? std::sqrt(3.0) * pitch / 6.0 + extra_dist_in : 0.0)));
1209 }
static const std::string pitch

◆ quadElemDef()

void PolygonMeshGeneratorBase::quadElemDef ( ReplicatedMesh mesh,
const unsigned int  num_sectors_per_side,
const std::vector< unsigned int subdomain_rings,
const unsigned int  side_index,
const std::vector< Real azimuthal_tangent = std::vector<Real>(),
const subdomain_id_type  block_id_shift = 0,
const dof_id_type  nodeid_shift = 0,
const bool  create_inward_interface_boundaries = false,
const bool  create_outward_interface_boundaries = true,
const boundary_id_type  boundary_id_shift = 0,
const bool  generate_side_specific_boundaries = true,
const QUAD_ELEM_TYPE  quad_elem_type = QUAD_ELEM_TYPE::QUAD4 
) const
protectedinherited

Defines general quad elements for the polygon.

Parameters
meshinput mesh to create the elements onto
num_sectors_per_sidenumber of azimuthal intervals
subdomain_ringsnumbers of radial intervals of all involved subdomain layers
side_indexindex of the polygon side
azimuthal_tangentvector of tangent values of the azimuthal angles as reference for adaptive boundary matching
block_id_shiftshift of the subdomain ids generated by this function
nodeid_shiftshift of the node_ids of these elements
create_inward_interface_boundarieswhether inward interface boundary sidesets are created
create_outward_interface_boundarieswhether outward interface boundary sidesets are created
boundary_id_shiftshift of the interface boundary ids
generate_side_specific_boundarieswhether the side-specific external boundaries are generated or not
quad_elem_typetype of the quadrilateral elements to be generated

Definition at line 1053 of file PolygonMeshGeneratorBase.C.

Referenced by PolygonMeshGeneratorBase::buildSlice().

1065 {
1066  const unsigned short order = quad_elem_type == QUAD_ELEM_TYPE::QUAD4 ? 1 : 2;
1067  unsigned int angle_number = azimuthal_tangent.size() == 0
1068  ? num_sectors_per_side
1069  : ((azimuthal_tangent.size() - 1) / order);
1070 
1071  BoundaryInfo & boundary_info = mesh.get_boundary_info();
1072  unsigned int j = 0;
1073  for (unsigned int k = 0; k < (subdomain_rings.size()); k++)
1074  {
1075  for (unsigned int m = 0; m < subdomain_rings[k]; m++)
1076  {
1077  for (unsigned int i = 1; i <= angle_number; i++)
1078  {
1079  std::unique_ptr<Elem> new_elem;
1080  if (quad_elem_type == QUAD_ELEM_TYPE::QUAD4)
1081  {
1082  new_elem = std::make_unique<Quad4>();
1083  new_elem->set_node(0, mesh.node_ptr(nodeid_shift + i + (angle_number + 1) * j));
1084  new_elem->set_node(1, mesh.node_ptr(nodeid_shift + i + 1 + (angle_number + 1) * j));
1085  new_elem->set_node(2, mesh.node_ptr(nodeid_shift + i + (angle_number + 1) * (j + 1) + 1));
1086  new_elem->set_node(3, mesh.node_ptr(nodeid_shift + i + (angle_number + 1) * (j + 1)));
1087  }
1088  else // QUAD8/QUAD9
1089  {
1090  new_elem = std::make_unique<Quad8>();
1091  if (quad_elem_type == QUAD_ELEM_TYPE::QUAD9)
1092  {
1093  new_elem = std::make_unique<Quad9>();
1094  new_elem->set_node(
1095  8, mesh.node_ptr(nodeid_shift + i * 2 + (angle_number * 2 + 1) * (j * 2 + 2)));
1096  }
1097  new_elem->set_node(
1098  0,
1099  mesh.node_ptr(nodeid_shift + (i - 1) * 2 + 1 + (angle_number * 2 + 1) * (j * 2 + 1)));
1100  new_elem->set_node(
1101  1, mesh.node_ptr(nodeid_shift + i * 2 + 1 + (angle_number * 2 + 1) * (j * 2 + 1)));
1102  new_elem->set_node(
1103  2, mesh.node_ptr(nodeid_shift + i * 2 + 1 + (angle_number * 2 + 1) * (j * 2 + 3)));
1104  new_elem->set_node(
1105  3,
1106  mesh.node_ptr(nodeid_shift + (i - 1) * 2 + 1 + (angle_number * 2 + 1) * (j * 2 + 3)));
1107  new_elem->set_node(
1108  4, mesh.node_ptr(nodeid_shift + i * 2 + (angle_number * 2 + 1) * (j * 2 + 1)));
1109  new_elem->set_node(
1110  5, mesh.node_ptr(nodeid_shift + i * 2 + 1 + (angle_number * 2 + 1) * (j * 2 + 2)));
1111  new_elem->set_node(
1112  6, mesh.node_ptr(nodeid_shift + i * 2 + (angle_number * 2 + 1) * (j * 2 + 3)));
1113  new_elem->set_node(
1114  7,
1115  mesh.node_ptr(nodeid_shift + (i - 1) * 2 + 1 + (angle_number * 2 + 1) * (j * 2 + 2)));
1116  }
1117  Elem * elem = mesh.add_elem(std::move(new_elem));
1118  if (i == 1)
1119  boundary_info.add_side(elem, 3, SLICE_BEGIN);
1120  if (i == angle_number)
1121  boundary_info.add_side(elem, 1, SLICE_END);
1122 
1123  if (subdomain_rings[0] == 0)
1124  elem->subdomain_id() = k + 1 + block_id_shift;
1125  else
1126  elem->subdomain_id() = k + 2 + block_id_shift;
1127 
1128  if (m == 0 && create_inward_interface_boundaries && k > 0)
1129  boundary_info.add_side(elem, 0, k * 2 + boundary_id_shift);
1130  if (m == (subdomain_rings[k] - 1))
1131  {
1132  if (k == (subdomain_rings.size() - 1))
1133  {
1134  boundary_info.add_side(elem, 2, OUTER_SIDESET_ID);
1135  if (generate_side_specific_boundaries)
1136  {
1137  if (i <= angle_number / 2)
1138  boundary_info.add_side(elem, 2, OUTER_SIDESET_ID + side_index);
1139  else
1140  boundary_info.add_side(elem, 2, OUTER_SIDESET_ID_ALT + side_index);
1141  }
1142  }
1143  else if (create_outward_interface_boundaries)
1144  boundary_info.add_side(elem, 2, k * 2 + 1 + boundary_id_shift);
1145  }
1146  }
1147  j++;
1148  }
1149  }
1150 }
MeshBase & mesh
const BoundaryInfo & get_boundary_info() const
virtual Elem * add_elem(Elem *e)=0
subdomain_id_type subdomain_id() const
void add_side(const dof_id_type elem, const unsigned short int side, const boundary_id_type id)
static const std::complex< double > j(0, 1)
Complex number "j" (also known as "i")
virtual const Node * node_ptr(const dof_id_type i) const=0
static const std::string k
Definition: NS.h:130

◆ reassignBoundaryIDs()

void PolygonMeshGeneratorBase::reassignBoundaryIDs ( MeshBase mesh,
const boundary_id_type  id_shift,
const std::set< boundary_id_type > &  boundary_ids,
const bool  reverse = false 
)
protectedinherited

reassign interface boundary IDs on the input mesh by applying the boundary ID shift

Parameters
meshinput mesh
id_shiftID shift value to be applied
boundary_idslist of boundary IDs to be reassigned
reverseremove boundary ID shift

Definition at line 1703 of file PolygonMeshGeneratorBase.C.

Referenced by generate(), and PatternedCartesianMeshGenerator::generate().

1707 {
1708  const std::set<boundary_id_type> existing_boundary_ids =
1710  for (const auto id : boundary_ids)
1711  {
1712 
1713  const boundary_id_type old_id = (!reverse) ? id : id + id_shift;
1714  const boundary_id_type new_id = (!reverse) ? id + id_shift : id;
1715  auto it = existing_boundary_ids.find(old_id);
1716  if (it != existing_boundary_ids.end())
1717  MooseMesh::changeBoundaryId(mesh, old_id, new_id, true);
1718  }
1719 }
MeshBase & mesh
void changeBoundaryId(const boundary_id_type old_id, const boundary_id_type new_id, bool delete_prev)
const BoundaryInfo & get_boundary_info() const
int8_t boundary_id_type
const std::set< boundary_id_type > & get_boundary_ids() const

◆ ringNodes()

void PolygonMeshGeneratorBase::ringNodes ( ReplicatedMesh mesh,
const std::vector< Real ring_radii,
const std::vector< unsigned int ring_layers,
const std::vector< std::vector< Real >>  biased_terms,
const unsigned int  num_sectors_per_side,
const Real  corner_p[2][2],
const Real  corner_to_corner,
const std::vector< Real azimuthal_tangent = std::vector<Real>() 
) const
protectedinherited

Creates nodes for the ring-geometry region of a single slice.

Parameters
meshinput mesh to add the nodes onto
ring_radiiradii of the ring regions
ring_layersnumbers of radial intervals of the ring regions
biased_termsnormalized spacing values used for radial meshing biasing in ring regions
num_sectors_per_sidenumber of azimuthal intervals
corner_p[2][2]array contains the coordinates of the corner positions
corner_to_cornerdiameter of the circumscribed circle of the polygon
azimuthal_tangentvector of tangent values of the azimuthal angles as reference for adaptive boundary matching

Definition at line 656 of file PolygonMeshGeneratorBase.C.

Referenced by PolygonMeshGeneratorBase::buildSlice().

664 {
665  const unsigned int angle_number =
666  azimuthal_tangent.size() == 0 ? num_sectors_per_side : (azimuthal_tangent.size() - 1);
667 
668  // Add nodes in pins regions
669  for (unsigned int l = 0; l < ring_layers.size(); l++)
670  {
671  // the pin radius interval for each ring_radii/subdomain
672  const Real pin_radius_interval_length =
673  l == 0 ? ring_radii[l] / ring_layers[l]
674  : (ring_radii[l] - ring_radii[l - 1]) / ring_layers[l];
675 
676  // add rings in each pin subdomain
677  for (unsigned int k = 0; k < ring_layers[l]; k++)
678  {
679  const Real bin_radial_distance =
680  l == 0 ? (biased_terms[l][k] * ring_layers[l] *
681  pin_radius_interval_length) // this is from the cell/pin center to
682  // the first circle
683  : (ring_radii[l - 1] +
684  biased_terms[l][k] * ring_layers[l] * pin_radius_interval_length);
685  const Real pin_corner_p_x = corner_p[0][0] * bin_radial_distance / (0.5 * corner_to_corner);
686  const Real pin_corner_p_y = corner_p[0][1] * bin_radial_distance / (0.5 * corner_to_corner);
687 
688  // pin_corner_p(s) are the points in the pin region, on the bins towards the six corners,
689  // at different intervals
690  mesh.add_point(Point(pin_corner_p_x, pin_corner_p_y, 0.0));
691 
692  for (unsigned int j = 1; j <= angle_number; j++)
693  {
694  const Real cell_boundary_p_x =
695  corner_p[0][0] + (corner_p[1][0] - corner_p[0][0]) *
696  (azimuthal_tangent.size() == 0 ? ((Real)j / (Real)angle_number)
697  : (azimuthal_tangent[j] / 2.0));
698  const Real cell_boundary_p_y =
699  corner_p[0][1] + (corner_p[1][1] - corner_p[0][1]) *
700  (azimuthal_tangent.size() == 0 ? ((Real)j / (Real)angle_number)
701  : (azimuthal_tangent[j] / 2.0));
702  // cell_boundary_p(s) are the points on the cell's six boundaries (flat sides) at
703  // different azimuthal angles
704  const Real pin_azimuthal_p_x =
705  cell_boundary_p_x * bin_radial_distance /
706  std::sqrt(Utility::pow<2>(cell_boundary_p_x) + Utility::pow<2>(cell_boundary_p_y));
707  const Real pin_azimuthal_p_y =
708  cell_boundary_p_y * bin_radial_distance /
709  std::sqrt(Utility::pow<2>(cell_boundary_p_x) + Utility::pow<2>(cell_boundary_p_y));
710 
711  // pin_azimuthal_p are the points on the bins towards different azimuthal angles, at
712  // different intervals; excluding the ones produced by pin_corner_p
713  mesh.add_point(Point(pin_azimuthal_p_x, pin_azimuthal_p_y, 0.0));
714  }
715  }
716  }
717 }
MeshBase & mesh
virtual Node * add_point(const Point &p, const dof_id_type id=DofObject::invalid_id, const processor_id_type proc_id=DofObject::invalid_processor_id)=0
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
static const std::string ring_radii
static const std::complex< double > j(0, 1)
Complex number "j" (also known as "i")
static const std::string k
Definition: NS.h:130

◆ setRingExtraIDs()

void PolygonMeshGeneratorBase::setRingExtraIDs ( MeshBase mesh,
const std::string  id_name,
const unsigned int  num_sides,
const std::vector< unsigned int num_sectors_per_side,
const std::vector< unsigned int ring_intervals,
const bool  ring_wise_id,
const bool  quad_center_elements 
)
protectedinherited

assign ring extra ids to polygon mesh

Parameters
meshinput mesh where ring extra ids are assigned
id_namering extra id name
num_sidesnumber of polygon sides
num_sectors_per_sidenumber of sectors of each side of the polygon
ring_intervalsnumber of rings in each circle
ring_wise_idwhether ring ids are assigned to each ring or to each block
quad_center_elementswhether center elements are quad or triangular

Definition at line 1638 of file PolygonMeshGeneratorBase.C.

Referenced by PolygonConcentricCircleMeshGeneratorBase::generate(), and TriPinHexAssemblyGenerator::generate().

1645 {
1646  // this function assumes that elements are ordered by rings (inner) then by sectors (outer
1647  // ordering)
1648  const auto extra_id_index = mesh.add_elem_integer(id_name);
1649  auto elem_it = mesh.elements_begin();
1650  for (unsigned int is = 0; is < num_sides; ++is)
1651  {
1652  // number of elements in the current sector
1653  unsigned int nelem = mesh.n_elem() * num_sectors_per_side[is] /
1654  (accumulate(num_sectors_per_side.begin(), num_sectors_per_side.end(), 0));
1655  if (!ring_wise_id)
1656  {
1657  for (unsigned int ir : index_range(ring_intervals))
1658  {
1659  // number of elements in the current ring and sector
1660  unsigned int nelem_annular_ring = num_sectors_per_side[is] * ring_intervals[ir];
1661  // if _quad_center_elements is true, the number of elements in center ring are
1662  // _num_sectors_per_side[is] * _num_sectors_per_side[is] / 4
1663  if (quad_center_elements && ir == 0)
1664  nelem_annular_ring = num_sectors_per_side[is] * (ring_intervals[ir] - 1) +
1665  num_sectors_per_side[is] * num_sectors_per_side[is] / 4;
1666  // assign ring id
1667  for (unsigned i = 0; i < nelem_annular_ring; ++i, ++elem_it)
1668  (*elem_it)->set_extra_integer(extra_id_index, ir + 1);
1669  // update number of elements in background region of current side.
1670  nelem -= nelem_annular_ring;
1671  }
1672  }
1673  else
1674  {
1675  unsigned int ir = 0;
1676  for (unsigned int ir0 : index_range(ring_intervals))
1677  {
1678  for (unsigned int ir1 = 0; ir1 < ring_intervals[ir0]; ++ir1)
1679  {
1680  // number of elements in the current ring and sector
1681  unsigned int nelem_annular_ring = num_sectors_per_side[is];
1682  // if _quad_center_elements is true, the number of elements in center ring are
1683  // _num_sectors_per_side[is] * _num_sectors_per_side[is] / 4
1684  if (quad_center_elements && ir == 0)
1685  nelem_annular_ring = num_sectors_per_side[is] * num_sectors_per_side[is] / 4;
1686  // assign ring id
1687  for (unsigned i = 0; i < nelem_annular_ring; ++i, ++elem_it)
1688  (*elem_it)->set_extra_integer(extra_id_index, ir + 1);
1689  // update ring id
1690  ++ir;
1691  // update number of elements in background region of current side.
1692  nelem -= nelem_annular_ring;
1693  }
1694  }
1695  }
1696  // assign ring id of 0 to the background region
1697  for (unsigned i = 0; i < nelem; ++i, ++elem_it)
1698  (*elem_it)->set_extra_integer(extra_id_index, 0);
1699  }
1700 }
unsigned int add_elem_integer(std::string name, bool allocate_data=true, dof_id_type default_value=DofObject::invalid_id)
MeshBase & mesh
PetscErrorCode PetscInt const PetscInt IS * is
virtual dof_id_type n_elem() const=0
auto index_range(const T &sizable)

◆ setSectorExtraIDs()

void PolygonMeshGeneratorBase::setSectorExtraIDs ( MeshBase mesh,
const std::string  id_name,
const unsigned int  num_sides,
const std::vector< unsigned int num_sectors_per_side 
)
protectedinherited

assign sector extra ids to polygon mesh

Parameters
meshinput mesh where sector extra ids are assigned
id_namesector extra ID name
num_sidenumber of polygon sides
num_sectors_per_sidenumber of sections of each side of the polygon

Definition at line 1613 of file PolygonMeshGeneratorBase.C.

Referenced by PolygonConcentricCircleMeshGeneratorBase::generate(), and TriPinHexAssemblyGenerator::generate().

1617 {
1618  const auto extra_id_index = mesh.add_elem_integer(id_name);
1619  // vector to store sector ids for each element
1620  auto elem_it = mesh.elements_begin();
1621  unsigned int id = 1;
1622  // starting element id of the current sector
1623  for (unsigned int is = 0; is < num_sides; ++is)
1624  {
1625  // number of elements in the current sector
1626  unsigned int nelem_sector =
1627  mesh.n_elem() * num_sectors_per_side[is] /
1628  (accumulate(num_sectors_per_side.begin(), num_sectors_per_side.end(), 0));
1629  // assign sector ids to mesh
1630  for (unsigned i = 0; i < nelem_sector; ++i, ++elem_it)
1631  (*elem_it)->set_extra_integer(extra_id_index, id);
1632  // update sector id
1633  ++id;
1634  }
1635 }
unsigned int add_elem_integer(std::string name, bool allocate_data=true, dof_id_type default_value=DofObject::invalid_id)
MeshBase & mesh
PetscErrorCode PetscInt const PetscInt IS * is
virtual dof_id_type n_elem() const=0

◆ validParams()

InputParameters PatternedHexMeshGenerator::validParams ( )
static

Definition at line 22 of file PatternedHexMeshGenerator.C.

Referenced by HexIDPatternedMeshGenerator::validParams().

23 {
25  params.addRequiredParam<std::vector<MeshGeneratorName>>("inputs", "The input MeshGenerators.");
26  params.addRequiredRangeCheckedParam<std::vector<std::vector<unsigned int>>>(
27  "pattern",
28  "pattern>=0",
29  "A double-indexed hexagonal-shaped array starting with the upper-left corner.");
30  MooseEnum pattern_boundary("none hexagon", "hexagon");
31  params.addParam<MooseEnum>(
32  "pattern_boundary", pattern_boundary, "The boundary shape of the patterned mesh.");
33  params.addParam<bool>(
34  "generate_core_metadata",
35  false,
36  "A Boolean parameter that controls whether the core related metadata "
37  "is generated for other MOOSE objects such as 'MultiControlDrumFunction' or not.");
38  params.addRangeCheckedParam<unsigned int>("background_intervals",
39  3,
40  "background_intervals>0",
41  "Radial intervals in the assembly peripheral region.");
42  params.addRangeCheckedParam<Real>("hexagon_size",
43  "hexagon_size>0.0",
44  "Size of the outmost hexagon boundary to be generated; this is "
45  "required only when pattern type is 'hexagon'.");
46  MooseEnum hexagon_size_style("apothem radius", "apothem");
47  params.addParam<MooseEnum>(
48  "hexagon_size_style",
49  hexagon_size_style,
50  "Style in which the hexagon size is given (default: apothem i.e. half-pitch).");
51  params.addRangeCheckedParam<std::vector<Real>>(
52  "duct_sizes", "duct_sizes>0.0", "Distance(s) from center to duct(s) inner boundaries.");
53  MooseEnum duct_sizes_style("apothem radius", "apothem");
54  params.addParam<MooseEnum>("duct_sizes_style",
55  duct_sizes_style,
56  "Style in which hexagon center to duct distance(s) is given (apothem "
57  "= center-to-face, radius = center-to-vertex).");
58  params.addRangeCheckedParam<std::vector<unsigned int>>(
59  "duct_intervals", "duct_intervals>0", "Number of meshing intervals in each enclosing duct.");
60  params.addParam<bool>("uniform_mesh_on_sides",
61  false,
62  "Whether the side elements are reorganized to have a uniform size.");
63  params.addParam<bool>("generate_control_drum_positions_file",
64  false,
65  "Whether a positions file is generated in the core mesh mode.");
66  params.addParam<bool>("assign_control_drum_id",
67  false,
68  "Whether control drum id is assigned to the mesh as an extra integer.");
69  std::string position_file_default = "positions_meta.data";
70  params.addParam<std::string>(
71  "position_file", position_file_default, "Data file name to store control drum positions.");
72  // A hexagon pattern_boundary mesh can be used in "inputs" of `PatternedHexMeshGenerator` after a
73  // 90-degree rotation.
74  params.addParam<Real>(
75  "rotate_angle",
76  90.0,
77  "Rotate the entire patterned mesh by a certain degrees that is defined here.");
79  "background_block_id",
80  "Optional customized block id for the background block in 'assembly' mode; must be provided "
81  "along with 'duct_block_ids' if 'duct_sizes' is provided.");
82  params.addParam<SubdomainName>(
83  "background_block_name",
84  "Optional customized block name for the background block in 'assembly' mode; must be "
85  "provided along with 'duct_block_names' if 'duct_sizes' is provided.");
86  params.addParam<std::vector<subdomain_id_type>>(
87  "duct_block_ids",
88  "Optional customized block ids for each duct geometry block in 'assembly' mode; must be "
89  "provided along with 'background_block_id'.");
90  params.addParam<std::vector<SubdomainName>>(
91  "duct_block_names",
92  std::vector<SubdomainName>(),
93  "Optional customized block names for each duct geometry block in 'assembly' mode; must be "
94  "provided along with 'background_block_name'.");
95  params.addRangeCheckedParam<boundary_id_type>("external_boundary_id",
96  "external_boundary_id>0",
97  "Optional customized external boundary id.");
98  params.addParam<bool>("create_inward_interface_boundaries",
99  false,
100  "Whether the inward interface boundary sidesets are created.");
101  params.addParam<bool>("create_outward_interface_boundaries",
102  true,
103  "Whether the outward interface boundary sidesets are created.");
104  params.addParam<BoundaryName>(
105  "external_boundary_name", BoundaryName(), "Optional customized external boundary name.");
106  params.addParam<bool>("deform_non_circular_region",
107  true,
108  "Whether the non-circular region (outside the rings) can be deformed.");
109  params.addParam<std::vector<std::string>>("id_name", "List of extra integer ID set names");
110  params.addParam<std::vector<MeshGeneratorName>>(
111  "exclude_id", "Name of input meshes to be excluded in ID generation");
112  std::vector<MooseEnum> option = {MooseEnum("cell pattern manual", "cell")};
113  params.addParam<std::vector<MooseEnum>>(
114  "assign_type", option, "List of integer ID assignment types");
115  params.addParam<std::vector<std::vector<std::vector<dof_id_type>>>>(
116  "id_pattern",
117  "User-defined element IDs. A double-indexed array starting with the upper-left corner. When "
118  "providing multiple patterns, each pattern should be separated using '|'");
119  params.addParam<std::vector<std::vector<boundary_id_type>>>(
120  "interface_boundary_id_shift_pattern",
121  "User-defined shift values for each pattern cell. A double-indexed array starting with the "
122  "upper-left corner.");
123  MooseEnum quad_elem_type("QUAD4 QUAD8 QUAD9", "QUAD4");
124  params.addParam<MooseEnum>(
125  "boundary_region_element_type",
126  quad_elem_type,
127  "Type of the quadrilateral elements to be generated in the boundary region.");
128  params.addParam<bool>(
129  "allow_unused_inputs",
130  false,
131  "Whether additional input assemblies can be part of inputs without being used in lattice");
132  params.addParamNamesToGroup(
133  "background_block_id background_block_name duct_block_ids boundary_region_element_type "
134  "duct_block_names external_boundary_id external_boundary_name "
135  "create_inward_interface_boundaries create_outward_interface_boundaries",
136  "Customized Subdomain/Boundary");
137  params.addParamNamesToGroup(
138  "generate_control_drum_positions_file assign_control_drum_id position_file", "Control Drum");
139  params.addParamNamesToGroup(
140  "background_intervals duct_intervals uniform_mesh_on_sides deform_non_circular_region",
141  "Mesh Density");
142  params.addParamNamesToGroup("id_name exclude_id assign_type id_pattern", "Reporting ID");
143  params.addClassDescription(
144  "This PatternedHexMeshGenerator source code assembles hexagonal meshes into a hexagonal grid "
145  "and optionally forces the outer boundary to be hexagonal and/or adds a duct.");
146 
147  return params;
148 }
void addRequiredRangeCheckedParam(const std::string &name, const std::string &parsed_function, const std::string &doc_string)
void addParam(const std::string &name, const std::initializer_list< typename T::value_type > &value, const std::string &doc_string)
void addRequiredParam(const std::string &name, const std::string &doc_string)
static InputParameters validParams()
int8_t boundary_id_type
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
void addRangeCheckedParam(const std::string &name, const T &value, const std::string &parsed_function, const std::string &doc_string)

Member Data Documentation

◆ _allow_unused_inputs

const bool PatternedHexMeshGenerator::_allow_unused_inputs
protected

Whether to allow additional assembly types to be passed to "inputs" parameter without being used in lattice.

Definition at line 100 of file PatternedHexMeshGenerator.h.

Referenced by PatternedHexMeshGenerator().

◆ _assign_control_drum_id

const bool PatternedHexMeshGenerator::_assign_control_drum_id
protected

Wheter control drum IDs are assigned as an extra element integer.

Definition at line 56 of file PatternedHexMeshGenerator.h.

Referenced by generate().

◆ _assign_types

std::vector<ReportingIDGeneratorUtils::AssignType> PatternedHexMeshGenerator::_assign_types
protected

reporting ID assignment type

Definition at line 86 of file PatternedHexMeshGenerator.h.

Referenced by addReportingIDs(), and PatternedHexMeshGenerator().

◆ _background_intervals

const unsigned int PatternedHexMeshGenerator::_background_intervals
protected

Number of radial intervals in the background region.

Definition at line 42 of file PatternedHexMeshGenerator.h.

Referenced by generate().

◆ _boundary_quad_elem_type

QUAD_ELEM_TYPE PatternedHexMeshGenerator::_boundary_quad_elem_type
protected

Type of quadrilateral elements to be generated in the periphery region.

Definition at line 98 of file PatternedHexMeshGenerator.h.

Referenced by addPeripheralMesh(), and generate().

◆ _create_inward_interface_boundaries

const bool PatternedHexMeshGenerator::_create_inward_interface_boundaries
protected

Whether inward interface boundaries are created.

Definition at line 68 of file PatternedHexMeshGenerator.h.

Referenced by addPeripheralMesh(), and generate().

◆ _create_outward_interface_boundaries

const bool PatternedHexMeshGenerator::_create_outward_interface_boundaries
protected

Whether outward interface boundaries are created.

Definition at line 70 of file PatternedHexMeshGenerator.h.

Referenced by addPeripheralMesh(), and generate().

◆ _deform_non_circular_region

const bool PatternedHexMeshGenerator::_deform_non_circular_region
protected

Whether the non-circular region (outside the rings) can be deformed.

Definition at line 74 of file PatternedHexMeshGenerator.h.

Referenced by generate().

◆ _duct_block_ids

const std::vector<subdomain_id_type> PatternedHexMeshGenerator::_duct_block_ids
protected

Subdomain IDs of the duct layers.

Definition at line 60 of file PatternedHexMeshGenerator.h.

Referenced by PatternedHexMeshGenerator().

◆ _duct_block_names

const std::vector<SubdomainName> PatternedHexMeshGenerator::_duct_block_names
protected

Subdomain Names of the duct layers.

Definition at line 62 of file PatternedHexMeshGenerator.h.

Referenced by PatternedHexMeshGenerator().

◆ _duct_intervals

const std::vector<unsigned int> PatternedHexMeshGenerator::_duct_intervals
protected

Number(s) of radial intervals of duct layer(s)

Definition at line 50 of file PatternedHexMeshGenerator.h.

Referenced by generate().

◆ _duct_sizes

std::vector<Real> PatternedHexMeshGenerator::_duct_sizes
protected

Size parameter(s) of duct(s)

Definition at line 46 of file PatternedHexMeshGenerator.h.

Referenced by generate(), and PatternedHexMeshGenerator().

◆ _duct_sizes_style

const PolygonSizeStyle PatternedHexMeshGenerator::_duct_sizes_style
protected

Style of the duct size parameter(s)

Definition at line 48 of file PatternedHexMeshGenerator.h.

Referenced by generate().

◆ _exclude_ids

std::vector<bool> PatternedHexMeshGenerator::_exclude_ids
protected

vector indicating which ids in the pattern to exclude (true at pattern positions to exclude)

Definition at line 90 of file PatternedHexMeshGenerator.h.

Referenced by addReportingIDs(), and PatternedHexMeshGenerator().

◆ _external_boundary_id

const boundary_id_type PatternedHexMeshGenerator::_external_boundary_id
protected

Boundary ID of mesh's external boundary.

Definition at line 64 of file PatternedHexMeshGenerator.h.

Referenced by generate().

◆ _external_boundary_name

const BoundaryName PatternedHexMeshGenerator::_external_boundary_name
protected

Boundary name of mesh's external boundary.

Definition at line 66 of file PatternedHexMeshGenerator.h.

Referenced by generate().

◆ _generate_control_drum_positions_file

const bool PatternedHexMeshGenerator::_generate_control_drum_positions_file
protected

Whether a text file containing control drum positions is generated.

Definition at line 54 of file PatternedHexMeshGenerator.h.

Referenced by generate().

◆ _generate_core_metadata

const bool PatternedHexMeshGenerator::_generate_core_metadata
protected

Whether a reactor core mesh with core metadata is generated.

Definition at line 40 of file PatternedHexMeshGenerator.h.

Referenced by generate(), and PatternedHexMeshGenerator().

◆ _has_assembly_duct

const bool PatternedHexMeshGenerator::_has_assembly_duct
protected

Whether the hexagonal pattern has external duct(s)

Definition at line 44 of file PatternedHexMeshGenerator.h.

Referenced by generate().

◆ _hexagon_size_style

const PolygonSizeStyle PatternedHexMeshGenerator::_hexagon_size_style
protected

Style of the polygon size parameter.

Definition at line 72 of file PatternedHexMeshGenerator.h.

Referenced by generate().

◆ _id_patterns

std::map<std::string, std::vector<std::vector<dof_id_type> > > PatternedHexMeshGenerator::_id_patterns
protected

hold ID patterns for each manual reporting ID. Individual ID pattern contains ID values for each pattern cell.

Definition at line 92 of file PatternedHexMeshGenerator.h.

Referenced by addReportingIDs(), and PatternedHexMeshGenerator().

◆ _input_names

const std::vector<MeshGeneratorName>& PatternedHexMeshGenerator::_input_names
protected

Names of input meshes.

Definition at line 34 of file PatternedHexMeshGenerator.h.

Referenced by generate(), and PatternedHexMeshGenerator().

◆ _interface_boundary_id_shift_pattern

std::vector<std::vector<boundary_id_type> > PatternedHexMeshGenerator::_interface_boundary_id_shift_pattern
protected

hold user-defined shift values for each pattern cell

Definition at line 96 of file PatternedHexMeshGenerator.h.

Referenced by generate(), and PatternedHexMeshGenerator().

◆ _mesh_ptrs

const std::vector<std::unique_ptr<MeshBase> *> PatternedHexMeshGenerator::_mesh_ptrs
protected

The input meshes.

Definition at line 31 of file PatternedHexMeshGenerator.h.

Referenced by generate().

◆ _pattern

const std::vector<std::vector<unsigned int> >& PatternedHexMeshGenerator::_pattern
protected

2D vector of the hexagonal pattern

Definition at line 36 of file PatternedHexMeshGenerator.h.

Referenced by addReportingIDs(), generate(), and PatternedHexMeshGenerator().

◆ _pattern_boundary

const MooseEnum PatternedHexMeshGenerator::_pattern_boundary
protected

Type of the external boundary shape.

Definition at line 38 of file PatternedHexMeshGenerator.h.

Referenced by addReportingIDs(), generate(), and PatternedHexMeshGenerator().

◆ _pattern_pitch

Real PatternedHexMeshGenerator::_pattern_pitch
protected

Pitch size of the input assembly mesh.

Definition at line 76 of file PatternedHexMeshGenerator.h.

Referenced by generate().

◆ _peripheral_block_ids

std::vector<subdomain_id_type> PatternedHexMeshGenerator::_peripheral_block_ids
protected

Subdomain IDs of the peripheral regions.

Definition at line 78 of file PatternedHexMeshGenerator.h.

Referenced by generate(), and PatternedHexMeshGenerator().

◆ _peripheral_block_names

std::vector<SubdomainName> PatternedHexMeshGenerator::_peripheral_block_names
protected

Subdomain Names of the peripheral regions.

Definition at line 80 of file PatternedHexMeshGenerator.h.

Referenced by generate(), and PatternedHexMeshGenerator().

◆ _reporting_id_names

std::vector<std::string> PatternedHexMeshGenerator::_reporting_id_names
protected

names of reporting ID

Definition at line 84 of file PatternedHexMeshGenerator.h.

Referenced by addReportingIDs(), and PatternedHexMeshGenerator().

◆ _rotate_angle

const Real PatternedHexMeshGenerator::_rotate_angle
protected

The mesh rotation angle after mesh generation.

Definition at line 58 of file PatternedHexMeshGenerator.h.

Referenced by generate().

◆ _uniform_mesh_on_sides

const bool PatternedHexMeshGenerator::_uniform_mesh_on_sides
protected

Whether the nodes on the external boundary are uniformly distributed.

Definition at line 52 of file PatternedHexMeshGenerator.h.

Referenced by generate().

◆ _use_exclude_id

const bool PatternedHexMeshGenerator::_use_exclude_id
protected

flag to indicate if exclude_id is defined

Definition at line 88 of file PatternedHexMeshGenerator.h.

Referenced by addReportingIDs(), and PatternedHexMeshGenerator().

◆ _use_interface_boundary_id_shift

const bool PatternedHexMeshGenerator::_use_interface_boundary_id_shift
protected

whether the interface boundary ids from input meshes are shifted, using a user-defined pattern of values for each pattern cell

Definition at line 94 of file PatternedHexMeshGenerator.h.

Referenced by generate(), and PatternedHexMeshGenerator().

◆ _use_reporting_id

const bool PatternedHexMeshGenerator::_use_reporting_id
protected

Whether reporting ID is added to mesh.

Definition at line 82 of file PatternedHexMeshGenerator.h.

Referenced by generate(), and PatternedHexMeshGenerator().


The documentation for this class was generated from the following files: