7 #ifndef FACETED_SETUP_H 8 #define FACETED_SETUP_H 14 #include "wonton/mesh/AuxMeshTopology.h" 15 #include "wonton/support/Point.h" 19 namespace Portage {
namespace Meshfree {
namespace Weight {
37 template<
int dim,
class Mesh>
38 void faceted_setup_cell(Mesh
const& mesh,
41 double smoothing_factor,
double boundary_factor) {
43 if (smoothing_factor < 0.) {
44 throw std::runtime_error(
"smoothing_factor must be non-negative");
45 }
else if (boundary_factor < 0.) {
46 throw std::runtime_error(
"boundary_factor must be non-negative");
49 int ncells = mesh.num_owned_cells();
50 smoothing_lengths.resize(ncells);
51 extents.resize(ncells);
54 for (
int i = 0; i < ncells; i++) {
55 std::vector<int> faces, fdirs;
56 mesh.cell_get_faces_and_dirs(i, &faces, &fdirs);
58 int nfaces = faces.size();
59 std::vector<std::vector<double>> h = smoothing_lengths[i];
62 Wonton::Point<dim> fcent, ccent, normal, distance;
63 std::vector<int> fnodes;
64 std::vector<Wonton::Point<dim>> fncoord;
65 for (
int j = 0; j < nfaces; j++) {
67 mesh.face_centroid(faces[j], &fcent);
68 mesh.cell_centroid(i, &ccent);
69 mesh.face_get_nodes(faces[j], &fnodes);
70 int const num_face_nodes = fnodes.size();
71 fncoord.resize(num_face_nodes + 1);
72 for (
int k = 0; k < num_face_nodes; k++) {
73 mesh.node_get_coordinates(fnodes[k], &(fncoord[k]));
75 fncoord[num_face_nodes] = fncoord[0];
79 std::vector<double> delta(2);
80 for (
int k = 0; k < 2; k++) delta[k] = fncoord[1][k] - fncoord[0][k];
82 normal[1] = -delta[0];
83 if (fdirs[j] < 0) normal *= -1.0;
84 double norm = sqrt(normal[0] * normal[0] + normal[1] * normal[1]);
89 }
else if (dim == 3) {
92 std::vector<std::vector<double>> bivec(2, std::vector<double>(3, 0.));
93 for (
int k = 0; k < 3; k++) {
94 bivec[0][k] = fncoord[0][k] - fcent[k];
99 for (
int k = 1; k <= num_face_nodes; k++) {
100 for (
int m = 0; m < 3; m++) bivec[1][m] = fncoord[k][m] - fcent[m];
101 std::vector<double> cross(3, 0.);
102 cross[0] = bivec[1][2] * bivec[0][1] - bivec[1][1] * bivec[0][2];
103 cross[1] = -bivec[1][2] * bivec[0][0] + bivec[1][0] * bivec[0][2];
104 cross[2] = bivec[1][1] * bivec[0][0] - bivec[1][0] * bivec[0][1];
105 double norm = sqrt(cross[0] * cross[0] + cross[1] * cross[1] + cross[2] * cross[2]);
106 for (
int m = 0; m < 3; m++) {
112 if (fdirs[j] < 0) normal *= -1.0;
114 for (
int k = 0; k < 3; k++) norm += normal[k] * normal[k];
118 for (
int k = 0; k < 3; k++) h[j][k] = normal[k];
121 distance = Wonton::Point<dim>(fcent - ccent);
122 double smoothing = 0.0;
123 for (
int k = 0; k < dim; k++) smoothing += 2 * distance[k] * normal[k];
124 if (smoothing < 0.0) {
126 smoothing = -smoothing;
128 if (mesh.on_exterior_boundary(Wonton::FACE, faces[j]) and boundary_factor > 0.) {
129 h[j][dim] = boundary_factor * smoothing;
131 h[j][dim] = smoothing_factor * smoothing;
134 smoothing_lengths[i] = h;
138 for (
int i = 0; i < ncells; i++) {
140 std::vector<int> node_indices;
141 mesh.cell_get_nodes(i, &node_indices);
142 Wonton::Point<dim> cmin, cmax, first_coords;
143 mesh.node_get_coordinates(node_indices[0], &first_coords);
145 for (
int k = 0; k < dim; k++) {
146 cmin[k] = first_coords[k];
147 cmax[k] = first_coords[k];
150 int const num_node_indices = node_indices.size();
151 for (
int j = 1; j < num_node_indices; j++) {
152 Wonton::Point<dim> node_coords;
153 mesh.node_get_coordinates(node_indices[j], &node_coords);
154 for (
int k = 0; k < dim; k++) {
155 cmin[k] = std::min(node_coords[k], cmin[k]);
156 cmax[k] = std::max(node_coords[k], cmax[k]);
161 Wonton::Point<dim> dx;
162 for (
int k = 0; k < dim; k++) { dx[k] = cmax[k] - cmin[k]; }
165 for (
int k = 0; k < dim; k++) { dx[k] *= 2. * smoothing_factor; }
189 template<
int dim,
class Mesh>
190 void faceted_setup_cell(std::vector<Mesh*> meshes,
193 double smoothing_factor,
double boundary_factor) {
198 for (
auto&& mesh : meshes)
199 total_cells += mesh->num_owned_cells();
201 smoothing_lengths.resize(total_cells);
202 extents.resize(total_cells);
204 for (
auto&& mesh : meshes) {
205 int ncells = mesh->num_owned_cells();
208 faceted_setup_cell<dim, Mesh>(*mesh, sl, ex, smoothing_factor, boundary_factor);
209 for (
int i = 0; i < ncells; i++) {
210 smoothing_lengths[offset + i] = sl[i];
211 extents[offset + i] = ex[i];
251 template<
int dim,
class Mesh,
class State>
252 void faceted_setup_cell(
const Mesh& mesh,
const State& state,
253 std::string field,
double tolerance,
256 double smoothing_factor,
double boundary_factor) {
258 faceted_setup_cell(mesh, smoothing_lengths, extents,
259 smoothing_factor, smoothing_factor);
262 const_cast<State&
>(state).mesh_get_data(Wonton::CELL, field, &fval);
264 for (
int i = 0; i < mesh.num_owned_cells(); i++) {
265 std::vector<int> faces, dirs, fcells;
266 mesh.cell_get_faces_and_dirs(i, &faces, &dirs);
267 std::vector<std::vector<double>> h = smoothing_lengths[i];
268 int const num_faces = faces.size();
269 for (
int j = 0; j < num_faces; j++) {
270 mesh.face_get_cells(faces[j], Wonton::PARALLEL_OWNED, &fcells);
271 for (
int k : fcells) {
272 if (k == i)
continue;
273 if (std::fabs(fval[i] - fval[k]) > tolerance) {
274 h[j][dim] *= (boundary_factor / smoothing_factor);
278 smoothing_lengths[i] = h;
std::vector< T > vector
Definition: portage.h:238
Definition: coredriver.h:42