Line data Source code
1 : //* This file is part of the MOOSE framework
2 : //* https://mooseframework.inl.gov
3 : //*
4 : //* All rights reserved, see COPYRIGHT for full restrictions
5 : //* https://github.com/idaholab/moose/blob/master/COPYRIGHT
6 : //*
7 : //* Licensed under LGPL 2.1, please see LICENSE for details
8 : //* https://www.gnu.org/licenses/lgpl-2.1.html
9 :
10 : #include "SphereSurfaceMeshGenerator.h"
11 : #include "CastUniquePointer.h"
12 :
13 : // libMesh includes
14 : #include "libmesh/face_tri3.h"
15 : #include "libmesh/mesh_modification.h"
16 : #include "libmesh/mesh_refinement.h"
17 : #include "libmesh/sphere.h"
18 : #include "libmesh/unstructured_mesh.h"
19 : #include "libmesh/replicated_mesh.h"
20 :
21 : registerMooseObject("PhaseFieldApp", SphereSurfaceMeshGenerator);
22 :
23 : InputParameters
24 0 : SphereSurfaceMeshGenerator::validParams()
25 : {
26 0 : InputParameters params = MeshGenerator::validParams();
27 0 : params.addClassDescription(
28 : "Generated sphere mesh - a two dimensional manifold embedded in three dimensional space");
29 0 : params.addParam<Real>("radius", 1.0, "Sphere radius");
30 0 : params.addParam<Point>("center", Point(0, 0, 0), "Center of the sphere");
31 0 : params.addParam<unsigned int>(
32 0 : "depth", 3, "Iteration steps in the triangle bisection construction");
33 0 : return params;
34 0 : }
35 :
36 0 : SphereSurfaceMeshGenerator::SphereSurfaceMeshGenerator(const InputParameters & parameters)
37 : : MeshGenerator(parameters),
38 0 : _radius(getParam<Real>("radius")),
39 0 : _center(getParam<Point>("center")),
40 0 : _depth(getParam<unsigned int>("depth"))
41 : {
42 0 : }
43 :
44 : std::unique_ptr<MeshBase>
45 0 : SphereSurfaceMeshGenerator::generate()
46 : {
47 : // Have MOOSE construct the correct libMesh::Mesh object using Mesh block and CLI parameters.
48 0 : auto mesh = buildMeshBaseObject();
49 0 : mesh->set_mesh_dimension(2);
50 0 : mesh->set_spatial_dimension(3);
51 :
52 0 : const libMesh::Sphere sphere(_center, _radius);
53 :
54 : // icosahedron points (using golden ratio rectangle construction)
55 : const Real phi = (1.0 + std::sqrt(5.0)) / 2.0;
56 : const Real X = std::sqrt(1.0 / (phi * phi + 1.0));
57 : const Real Z = X * phi;
58 : const Point vdata[12] = {{-X, 0.0, Z},
59 : {X, 0.0, Z},
60 : {-X, 0.0, -Z},
61 : {X, 0.0, -Z},
62 : {0.0, Z, X},
63 : {0.0, Z, -X},
64 : {0.0, -Z, X},
65 : {0.0, -Z, -X},
66 : {Z, X, 0.0},
67 : {-Z, X, 0.0},
68 : {Z, -X, 0.0},
69 : {-Z, -X, 0.0}};
70 0 : for (unsigned int i = 0; i < 12; ++i)
71 0 : mesh->add_point(vdata[i] * _radius + _center, i);
72 :
73 : // icosahedron faces
74 0 : const unsigned int tindices[20][3] = {{0, 4, 1}, {0, 9, 4}, {9, 5, 4}, {4, 5, 8}, {4, 8, 1},
75 : {8, 10, 1}, {8, 3, 10}, {5, 3, 8}, {5, 2, 3}, {2, 7, 3},
76 : {7, 10, 3}, {7, 6, 10}, {7, 11, 6}, {11, 0, 6}, {0, 1, 6},
77 : {6, 1, 10}, {9, 0, 11}, {9, 11, 2}, {9, 2, 5}, {7, 2, 11}};
78 0 : for (unsigned int i = 0; i < 20; ++i)
79 : {
80 0 : Elem * elem = mesh->add_elem(new Tri3);
81 0 : elem->set_node(0, mesh->node_ptr(tindices[i][0]));
82 0 : elem->set_node(1, mesh->node_ptr(tindices[i][1]));
83 0 : elem->set_node(2, mesh->node_ptr(tindices[i][2]));
84 : }
85 :
86 : // we need to prepare distributed meshes before using refinement
87 0 : if (!mesh->is_replicated())
88 0 : mesh->prepare_for_use();
89 :
90 : // Now we have the beginnings of a sphere.
91 : // Add some more elements by doing uniform refinements and
92 : // popping nodes to the boundary.
93 0 : libMesh::MeshRefinement mesh_refinement(*mesh);
94 :
95 : // Loop over the elements, refine, pop nodes to boundary.
96 0 : for (unsigned int r = 0; r < _depth; ++r)
97 : {
98 0 : mesh_refinement.uniformly_refine(1);
99 :
100 0 : auto it = mesh->active_nodes_begin();
101 0 : const auto end = mesh->active_nodes_end();
102 :
103 0 : for (; it != end; ++it)
104 : {
105 0 : Node & node = **it;
106 0 : node = sphere.closest_point(node);
107 : }
108 : }
109 :
110 : // Flatten the AMR mesh to get rid of inactive elements
111 0 : MeshTools::Modification::flatten(*mesh);
112 :
113 0 : return dynamic_pointer_cast<MeshBase>(mesh);
114 0 : }
|