<commit_before>//* This file is part of the MOOSE framework
//* https://www.mooseframework.org
//*
//* All rights reserved, see COPYRIGHT for full restrictions
//* https://github.com/idaholab/moose/blob/master/COPYRIGHT
//*
//* Licensed under LGPL 2.1, please see LICENSE for details
//* https://www.gnu.org/licenses/lgpl-2.1.html

#include "StackGenerator.h"
#include "CastUniquePointer.h"

#include "libmesh/replicated_mesh.h"
#include "libmesh/distributed_mesh.h"
#include "libmesh/boundary_info.h"
#include "libmesh/mesh_modification.h"
#include "libmesh/bounding_box.h"
#include "libmesh/mesh_tools.h"
#include "libmesh/point.h"

#include <typeinfo>

registerMooseObject("MooseApp", StackGenerator);

template <>
InputParameters
validParams<StackGenerator>()
{
  InputParameters params = validParams<MeshGenerator>();

  MooseEnum dims("2=2 3=3");
  params.addRequiredParam<MooseEnum>("dim", dims, "The dimension of the mesh to be generated");

  params.addRequiredParam<std::vector<MeshGeneratorName>>("inputs",
                                                          "The meshes we want to stitch together");

  params.addParam<Real>("bottom_height", 0, "The height of the bottom of the final mesh");

  // y boundary names (2D case)
  params.addParam<BoundaryName>("top_boundary", "top", "name of the top (y) boundary");
  params.addParam<BoundaryName>("bottom_boundary", "bottom", "name of the bottom (y) boundary");

  // z boundary names (3D case)
  params.addParam<BoundaryName>("front_boundary", "front", "name of the front (z) boundary");
  params.addParam<BoundaryName>("back_boundary", "back", "name of the back (z) boundary");

  params.addClassDescription("Use the supplied meshes and stitch them on top of each other");

  return params;
}

StackGenerator::StackGenerator(const InputParameters & parameters)
  : MeshGenerator(parameters),
    _dim(getParam<MooseEnum>("dim")),
    _input_names(getParam<std::vector<MeshGeneratorName>>("inputs")),
    _bottom_height(getParam<Real>("bottom_height"))
{
  // Grab the input meshes
  _mesh_ptrs.reserve(_input_names.size());
  for (auto i = beginIndex(_input_names); i < _input_names.size(); ++i)
    _mesh_ptrs.push_back(&getMeshByName(_input_names[i]));
}

std::unique_ptr<MeshBase>
StackGenerator::generate()
{
  std::unique_ptr<ReplicatedMesh> mesh = dynamic_pointer_cast<ReplicatedMesh>(*_mesh_ptrs[0]);
  if (mesh == nullptr)
    mooseError("StackGenerator only works with ReplicatedMesh : mesh from Meshgenerator ",
               _input_names[0],
               "is not a ReplicatedMesh.");

  int dim = static_cast<int>(_dim);

  if (dim != int(mesh->mesh_dimension()))
    mooseError("The first mesh's dimension and the dimension provided don't match !");

  // Reserve spaces for the other meshes (no need to store the first one another time)
  _meshes.reserve(_input_names.size() - 1);

  // Read in all of the other meshes
  for (auto i = beginIndex(_input_names, 1); i < _input_names.size(); ++i)
    _meshes.push_back(dynamic_pointer_cast<ReplicatedMesh>(*_mesh_ptrs[i]));

  // Check that the casts didn't fail, and that the dimensions match
  for (auto i = beginIndex(_meshes); i < _meshes.size(); ++i)
  {
    if (_meshes[i] == nullptr)
      mooseError("StackGenerator only works with ReplicatedMesh : mesh from Meshgenerator ",
                 _input_names[i + 1],
                 "is not a ReplicatedMesh.");
    if (int(_meshes[i]->mesh_dimension()) != dim)
      mooseError("Mesh from MeshGenerator : ", _input_names[i + 1], " is not in ", _dim, "D.");
  }

  boundary_id_type first, second;

  switch (_dim)
  {
    case 2:
    {
      first = mesh->get_boundary_info().get_id_by_name(getParam<BoundaryName>("top_boundary"));
      second = mesh->get_boundary_info().get_id_by_name(getParam<BoundaryName>("bottom_boundary"));
      break;
    }
    case 3:
    {
      first = mesh->get_boundary_info().get_id_by_name(getParam<BoundaryName>("front_boundary"));
      second = mesh->get_boundary_info().get_id_by_name(getParam<BoundaryName>("back_boundary"));
      break;
    }
  }

  // Getting the z width of each mesh
  std::vector<Real> heights;
  heights.push_back(computeWidth(*mesh, _dim) + _bottom_height);
  for (auto i = beginIndex(_meshes); i < _meshes.size(); ++i)
    heights.push_back(computeWidth(*_meshes[i], _dim) + *heights.rbegin());

  switch (_dim)
  {
    case 2:
      MeshTools::Modification::translate(*mesh, 0, _bottom_height, 0);
      break;
    case 3:
      MeshTools::Modification::translate(*mesh, 0, 0, _bottom_height);
      break;
  }

  for (auto i = beginIndex(_meshes); i < _meshes.size(); ++i)
  {
    switch (_dim)
    {
      case 2:
        MeshTools::Modification::translate(*_meshes[i], 0, heights[i], 0);
        break;
      case 3:
        MeshTools::Modification::translate(*_meshes[i], 0, 0, heights[i]);
        break;
    }
    mesh->stitch_meshes(
        *_meshes[i], first, second, TOLERANCE, /*clear_stitched_boundary_ids=*/true);
  }

  return dynamic_pointer_cast<MeshBase>(mesh);
}

Real
StackGenerator::computeWidth(const MeshBase & mesh, const int & dim)
{
  std::set<subdomain_id_type> sub_ids;
  mesh.subdomain_ids(sub_ids);<commit_msg>Change the boundary ids initialization.<commit_after>//* This file is part of the MOOSE framework
//* https://www.mooseframework.org
//*
//* All rights reserved, see COPYRIGHT for full restrictions
//* https://github.com/idaholab/moose/blob/master/COPYRIGHT
//*
//* Licensed under LGPL 2.1, please see LICENSE for details
//* https://www.gnu.org/licenses/lgpl-2.1.html

#include "StackGenerator.h"
#include "CastUniquePointer.h"

#include "libmesh/replicated_mesh.h"
#include "libmesh/distributed_mesh.h"
#include "libmesh/boundary_info.h"
#include "libmesh/mesh_modification.h"
#include "libmesh/bounding_box.h"
#include "libmesh/mesh_tools.h"
#include "libmesh/point.h"

#include <typeinfo>

registerMooseObject("MooseApp", StackGenerator);

template <>
InputParameters
validParams<StackGenerator>()
{
  InputParameters params = validParams<MeshGenerator>();

  MooseEnum dims("2=2 3=3");
  params.addRequiredParam<MooseEnum>("dim", dims, "The dimension of the mesh to be generated");

  params.addRequiredParam<std::vector<MeshGeneratorName>>("inputs",
                                                          "The meshes we want to stitch together");

  params.addParam<Real>("bottom_height", 0, "The height of the bottom of the final mesh");

  // y boundary names (2D case)
  params.addParam<BoundaryName>("top_boundary", "top", "name of the top (y) boundary");
  params.addParam<BoundaryName>("bottom_boundary", "bottom", "name of the bottom (y) boundary");

  // z boundary names (3D case)
  params.addParam<BoundaryName>("front_boundary", "front", "name of the front (z) boundary");
  params.addParam<BoundaryName>("back_boundary", "back", "name of the back (z) boundary");

  params.addClassDescription("Use the supplied meshes and stitch them on top of each other");

  return params;
}

StackGenerator::StackGenerator(const InputParameters & parameters)
  : MeshGenerator(parameters),
    _dim(getParam<MooseEnum>("dim")),
    _input_names(getParam<std::vector<MeshGeneratorName>>("inputs")),
    _bottom_height(getParam<Real>("bottom_height"))
{
  // Grab the input meshes
  _mesh_ptrs.reserve(_input_names.size());
  for (auto i = beginIndex(_input_names); i < _input_names.size(); ++i)
    _mesh_ptrs.push_back(&getMeshByName(_input_names[i]));
}

std::unique_ptr<MeshBase>
StackGenerator::generate()
{
  std::unique_ptr<ReplicatedMesh> mesh = dynamic_pointer_cast<ReplicatedMesh>(*_mesh_ptrs[0]);
  if (mesh == nullptr)
    mooseError("StackGenerator only works with ReplicatedMesh : mesh from Meshgenerator ",
               _input_names[0],
               "is not a ReplicatedMesh.");

  int dim = static_cast<int>(_dim);

  if (dim != int(mesh->mesh_dimension()))
    mooseError("The first mesh's dimension and the dimension provided don't match !");

  // Reserve spaces for the other meshes (no need to store the first one another time)
  _meshes.reserve(_input_names.size() - 1);

  // Read in all of the other meshes
  for (auto i = beginIndex(_input_names, 1); i < _input_names.size(); ++i)
    _meshes.push_back(dynamic_pointer_cast<ReplicatedMesh>(*_mesh_ptrs[i]));

  // Check that the casts didn't fail, and that the dimensions match
  for (auto i = beginIndex(_meshes); i < _meshes.size(); ++i)
  {
    if (_meshes[i] == nullptr)
      mooseError("StackGenerator only works with ReplicatedMesh : mesh from Meshgenerator ",
                 _input_names[i + 1],
                 "is not a ReplicatedMesh.");
    if (int(_meshes[i]->mesh_dimension()) != dim)
      mooseError("Mesh from MeshGenerator : ", _input_names[i + 1], " is not in ", _dim, "D.");
  }

  boundary_id_type first =
      mesh->get_boundary_info().get_id_by_name(getParam<BoundaryName>("top_boundary"));
  boundary_id_type second =
      mesh->get_boundary_info().get_id_by_name(getParam<BoundaryName>("bottom_boundary"));

  if (dim == 3)
  {
    first = mesh->get_boundary_info().get_id_by_name(getParam<BoundaryName>("front_boundary"));
    second = mesh->get_boundary_info().get_id_by_name(getParam<BoundaryName>("back_boundary"));
  }

  // Getting the width of each mesh
  std::vector<Real> heights;
  heights.push_back(computeWidth(*mesh, _dim) + _bottom_height);
  for (auto i = beginIndex(_meshes); i < _meshes.size(); ++i)
    heights.push_back(computeWidth(*_meshes[i], _dim) + *heights.rbegin());

  // Move the first mesh at the provided height
  switch (_dim)
  {
    case 2:
      MeshTools::Modification::translate(*mesh, 0, _bottom_height, 0);
      break;
    case 3:
      MeshTools::Modification::translate(*mesh, 0, 0, _bottom_height);
      break;
  }

  // Move all of the other meshes in the right spots then stitch them one by one to the first one
  for (auto i = beginIndex(_meshes); i < _meshes.size(); ++i)
  {
    switch (_dim)
    {
      case 2:
        MeshTools::Modification::translate(*_meshes[i], 0, heights[i], 0);
        break;
      case 3:
        MeshTools::Modification::translate(*_meshes[i], 0, 0, heights[i]);
        break;
    }
    mesh->stitch_meshes(
        *_meshes[i], first, second, TOLERANCE, /*clear_stitched_boundary_ids=*/true);
  }

  return dynamic_pointer_cast<MeshBase>(mesh);
}

Real
StackGenerator::computeWidth(const MeshBase & mesh, const int & dim)
{
  std::set<subdomain_id_type> sub_ids;
  mesh.subdomain_ids(sub_ids);
{'fraction_non_alphanumeric': 0.1388623783164726, 'fraction_numerical': 0.005821721702615003, 'mean_word_length': 4.172260612043435, 'pattern_counts': {'":': 0, '<': 69, '<?xml version=': 0, '>': 73, 'https://': 6, 'lorem ipsum': 0, 'www.': 4, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6637582', 'n_tokens_mistral': 3466, 'n_tokens_neox': 3351, 'n_words': 786}