diff --git a/src/scheme/ScalarHybridScheme.cpp b/src/scheme/ScalarHybridScheme.cpp index b650caa5440c0a2fa9768c9d3534dc8a9366cb22..84ec83e474941185aa06420b4e536f70c2c4f539 100644 --- a/src/scheme/ScalarHybridScheme.cpp +++ b/src/scheme/ScalarHybridScheme.cpp @@ -807,6 +807,153 @@ class ScalarHybridSchemeHandler::ScalarHybridScheme : public ScalarHybridSchemeH return compute_w; }(); + const NodeValue<const TinyVector<2>> normal_edge_index = [&] { + NodeValue<TinyVector<2>> compute_normal_edge_index{mesh->connectivity()}; + compute_normal_edge_index.fill(zero); + parallel_for( + mesh->numberOfNodes(), PUGS_LAMBDA(NodeId node_id) { + bool l1_OK = false; + + if (node_is_edge[node_id]) { + const auto& node_to_cell = node_to_cell_matrix[node_id]; + CellId cell_id = node_to_cell[0]; + const auto& cell_to_node = cell_to_node_matrix[cell_id]; + for (size_t i_node = 0; i_node < cell_to_node.size(); ++i_node) { + const NodeId node_id_in_cell = cell_to_node[i_node]; + if (node_is_corner[node_id_in_cell] && not node_is_edge[node_id_in_cell]) { + cell_id = node_to_cell[1]; + } + } + + const auto& cell_to_face = cell_to_face_matrix[cell_id]; + for (size_t i_face = 0; i_face < cell_to_face.size(); ++i_face) { + const FaceId face_id = cell_to_face[i_face]; + if (is_boundary_face[face_id]) { + if (not l1_OK) { + compute_normal_edge_index[node_id][0] = face_id; + l1_OK = true; + } else { + compute_normal_edge_index[node_id][1] = face_id; + } + } + } + } + }); + return compute_normal_edge_index; + }(); + + const NodeValue<const TinyVector<Dimension>> normal1_edge = [&] { + NodeValue<TinyVector<Dimension>> compute_normal1_edge{mesh->connectivity()}; + compute_normal1_edge.fill(zero); + parallel_for( + mesh->numberOfNodes(), PUGS_LAMBDA(NodeId node_id) { + if (node_is_edge[node_id]) { + const FaceId l1 = normal_edge_index[node_id][0]; + + const auto& node_to_cell = node_to_cell_matrix[node_id]; + CellId cell_id = node_to_cell[0]; + const auto& cell_to_node = cell_to_node_matrix[cell_id]; + for (size_t i_node = 0; i_node < cell_to_node.size(); ++i_node) { + const NodeId node_id_in_cell = cell_to_node[i_node]; + if (node_is_corner[node_id_in_cell] && not node_is_edge[node_id_in_cell]) { + cell_id = node_to_cell[1]; + } + } + + if (dot(nl[l1], xl[l1] - xj[cell_id]) <= 0) { + compute_normal1_edge[node_id] = -nl[l1]; + } else { + compute_normal1_edge[node_id] = nl[l1]; + } + } + }); + return compute_normal1_edge; + }(); + + const NodeValue<const TinyVector<Dimension>> normal2_edge = [&] { + NodeValue<TinyVector<Dimension>> compute_normal2_edge{mesh->connectivity()}; + compute_normal2_edge.fill(zero); + parallel_for( + mesh->numberOfNodes(), PUGS_LAMBDA(NodeId node_id) { + if (node_is_edge[node_id]) { + const FaceId l2 = normal_edge_index[node_id][1]; + + const auto& node_to_cell = node_to_cell_matrix[node_id]; + CellId cell_id = node_to_cell[0]; + const auto& cell_to_node = cell_to_node_matrix[cell_id]; + for (size_t i_node = 0; i_node < cell_to_node.size(); ++i_node) { + const NodeId node_id_in_cell = cell_to_node[i_node]; + if (node_is_corner[node_id_in_cell] && not node_is_edge[node_id_in_cell]) { + cell_id = node_to_cell[1]; + } + } + if (dot(nl[l2], xl[l2] - xj[cell_id]) <= 0) { + compute_normal2_edge[node_id] = -nl[l2]; + } else { + compute_normal2_edge[node_id] = nl[l2]; + } + } + }); + return compute_normal2_edge; + }(); + + const NodeValue<const TinyVector<Dimension>> normal_orth_edge = [&] { + NodeValue<TinyVector<Dimension>> compute_normal_orth_edge{mesh->connectivity()}; + compute_normal_orth_edge.fill(zero); + parallel_for( + mesh->numberOfNodes(), PUGS_LAMBDA(NodeId node_id) { + // bool l1_OK = false; + // FaceId l1 = 0; + // FaceId l2 = 0; + // TinyVector<Dimension> n1 = zero; + // TinyVector<Dimension> n2 = zero; + + if (node_is_edge[node_id]) { + // const auto& node_to_cell = node_to_cell_matrix[node_id]; + // CellId cell_id = node_to_cell[0]; + // const auto& cell_to_node = cell_to_node_matrix[cell_id]; + // for (size_t i_node = 0; i_node < cell_to_node.size(); ++i_node) { + // const NodeId node_id_in_cell = cell_to_node[i_node]; + // if (node_is_corner[node_id_in_cell] && not node_is_edge[node_id_in_cell]) { + // cell_id = node_to_cell[1]; + // } + // } + + // const auto& cell_to_face = cell_to_face_matrix[cell_id]; + // for (size_t i_face = 0; i_face < cell_to_face.size(); ++i_face) { + // const FaceId face_id = cell_to_face[i_face]; + // if (is_boundary_face[face_id]) { + // if (not l1_OK) { + // l1 = face_id; + // if (dot(nl[l1], xl[l1] - xj[cell_id]) <= 0) { + // n1 = -nl[l1]; + // } else { + // n1 = nl[l1]; + // } + // l1_OK = true; + + // } else { + // l2 = face_id; + // if (dot(nl[l2], xl[l2] - xj[cell_id]) <= 0) { + // n2 = -nl[l2]; + // } else { + // n2 = nl[l2]; + // } + // } + // } + // } + + compute_normal_orth_edge[node_id][0] = + normal1_edge[node_id][1] * normal2_edge[node_id][2] - normal1_edge[node_id][2] * normal2_edge[node_id][1]; + compute_normal_orth_edge[node_id][1] = + normal1_edge[node_id][2] * normal2_edge[node_id][0] - normal1_edge[node_id][0] * normal2_edge[node_id][2]; + compute_normal_orth_edge[node_id][2] = + normal1_edge[node_id][0] * normal2_edge[node_id][1] - normal1_edge[node_id][1] * normal2_edge[node_id][0]; + } + }); + return compute_normal_orth_edge; + }(); + const FaceValue<const double> face_boundary_values = [&] { FaceValue<double> compute_face_boundary_values{mesh->connectivity()}; FaceValue<double> sum_mes_l{mesh->connectivity()}; @@ -1273,9 +1420,11 @@ class ScalarHybridSchemeHandler::ScalarHybridScheme : public ScalarHybridSchemeH } else if (node_is_edge[node_id]) { for (size_t i_cell_j = 0; i_cell_j < node_to_cell.size(); ++i_cell_j) { const CellId cell_id_j = node_to_cell[i_cell_j]; + const size_t i_node_j = node_local_number_in_its_cells[i_cell_j]; for (size_t i_cell_k = 0; i_cell_k < node_to_cell.size(); ++i_cell_k) { - const CellId cell_id_k = node_to_cell[i_cell_k]; + const CellId cell_id_k = node_to_cell[i_cell_k]; + const auto& cell_to_face = cell_to_face_matrix[cell_id_j]; for (size_t i_face = 0; i_face < cell_to_face.size(); ++i_face) { @@ -1283,59 +1432,27 @@ class ScalarHybridSchemeHandler::ScalarHybridScheme : public ScalarHybridSchemeH const auto& face_to_node = face_to_node_matrix[face_id]; const size_t numberOfNodesPerFace = face_to_node.size(); if (not is_boundary_face[face_id]) { - bool l1_OK = false; - bool l2_OK = false; - FaceId l1 = 0; - FaceId l2 = 0; - TinyVector<Dimension> n1 = zero; - TinyVector<Dimension> n2 = zero; - TinyVector<Dimension> t = zero; - // std::cout << "Test 1.3.01 \n"; - for (size_t j_face = 0; j_face < cell_to_face.size(); ++j_face) { - const FaceId face_id_j = cell_to_face[j_face]; - if (is_boundary_face[face_id_j]) { - // const auto& face_to_node_j = face_to_node_matrix[face_id_j]; - // std::cout << "Test 1.3.02 \n"; - - // std::cout << "Test 1.3.03 \n"; - if (not l1_OK) { - l1 = face_id_j; - l1_OK = true; - } else { - l2 = face_id_j; - l2_OK = true; - } - } - } - if (dot(nl[l1], xl[l1] - xj[cell_id_j]) <= 0 and l1_OK) { - n1 = -nl[l1]; - } else { - n1 = nl[l1]; - } - // std::cout << "Test 1.3.04 \n"; - if (dot(nl[l2], xl[l2] - xj[cell_id_j]) <= 0 and l2_OK) { - n2 = -nl[l2]; - } else { - n2 = nl[l2]; - } - // std::cout << "Test 1.3.05 \n"; - if (l1_OK && l2_OK) { - t[0] = n1[1] * n2[2] - n1[2] * n2[1]; - t[1] = n1[2] * n2[0] - n1[0] * n2[2]; - t[2] = n1[0] * n2[1] - n1[1] * n2[0]; - } - // std::cout << "Test 1.3.06 \n"; + TinyVector<Dimension> t = normal_orth_edge[node_id]; - // std::cout << "Test 1.3.1 \n"; for (size_t i_face_to_node = 0; i_face_to_node < face_to_node.size(); ++i_face_to_node) { if (face_to_node[i_face_to_node] == node_id) { - // std::cout << "Test 1.3.1.1 \n"; const auto& face_to_cell = face_to_cell_matrix[face_id]; for (size_t i_cell = 0; i_cell < face_to_cell.size(); ++i_cell) { - // std::cout << "Test 1.3.1.2 \n"; CellId cell_id = face_to_cell[i_cell]; if (cell_id_k == cell_id_j) { - // std::cout << "Test 1.3.1.3 \n"; + S1(cell_id_j, cell_id_k) += (1. - lambda) * dt * (1. - cn_coeff / 2.) * + dot(1. / + (dot(xj1_xj2(cell_id_j, i_face), node_kappar[node_id] * t) * + pow(l2Norm(node_kappar[node_id] * t), 2)) * + node_kappar[node_id] * t, + node_kappar[node_id] * Cjr(cell_id_j, i_node_j)); + S2(cell_id_j, cell_id_k) -= (1. - lambda) * dt * (cn_coeff / 2.) * + dot(1. / + (dot(xj1_xj2(cell_id_j, i_face), node_kappar[node_id] * t) * + pow(l2Norm(node_kappar[node_id] * t), 2)) * + node_kappar[node_id] * t, + node_kappar[node_id] * Cjr(cell_id_j, i_node_j)); + S1(cell_id_j, cell_id_k) += lambda * dt * (1. - cn_coeff / 2.) * mes_l[face_id] / numberOfNodesPerFace * dot(1. / @@ -1350,8 +1467,20 @@ class ScalarHybridSchemeHandler::ScalarHybridScheme : public ScalarHybridSchemeH pow(l2Norm(node_kappar[node_id] * t), 2)) * node_kappar[node_id] * t, base_xj1_xj2_orth(cell_id_j, i_face)); - // std::cout << "Test 1.3.2 \n"; } else { + S1(cell_id_j, cell_id_k) -= (1. - lambda) * dt * (1. - cn_coeff / 2.) * + dot(1. / + (dot(xj1_xj2(cell_id_j, i_face), node_kappar[node_id] * t) * + pow(l2Norm(node_kappar[node_id] * t), 2)) * + node_kappar[node_id] * t, + node_kappar[node_id] * Cjr(cell_id_j, i_node_j)); + S2(cell_id_j, cell_id_k) += (1. - lambda) * dt * (cn_coeff / 2.) * + dot(1. / + (dot(xj1_xj2(cell_id_j, i_face), node_kappar[node_id] * t) * + pow(l2Norm(node_kappar[node_id] * t), 2)) * + node_kappar[node_id] * t, + node_kappar[node_id] * Cjr(cell_id_j, i_node_j)); + S1(cell_id_j, cell_id_k) -= lambda * dt * (1. - cn_coeff / 2.) * mes_l[face_id] / numberOfNodesPerFace * dot(1. / @@ -1574,7 +1703,8 @@ class ScalarHybridSchemeHandler::ScalarHybridScheme : public ScalarHybridSchemeH } else if (node_is_corner[node_id] && not node_is_edge[node_id]) { const auto& node_to_face = node_to_face_matrix[node_id]; - const CellId cell_id = node_to_cell[0]; + // const CellId cell_id = node_to_cell[0]; + const CellId cell_id = node_to_cell[0]; for (size_t i_face = 0; i_face < node_to_face.size(); ++i_face) { FaceId face_id = node_to_face[i_face]; const auto& face_to_node = face_to_node_matrix[face_id]; @@ -1583,11 +1713,15 @@ class ScalarHybridSchemeHandler::ScalarHybridScheme : public ScalarHybridSchemeH b_prev[cell_id] += (1 - lambda) / numberOfNodesPerFace * face_boundary_prev_values[face_id] * mes_l[face_id]; } + } else if (node_is_edge[node_id]) { - const auto& node_to_cell = node_to_cell_matrix[node_id]; + const auto& node_local_number_in_its_cell = node_local_numbers_in_their_cells.itemArray(node_id); + // const auto& node_to_cell = node_to_cell_matrix[node_id]; for (size_t i_cell = 0; i_cell < node_to_cell.size(); ++i_cell) { const CellId cell_id = node_to_cell[i_cell]; + const size_t i_node = node_local_number_in_its_cell[i_cell]; + const auto& cell_to_face = cell_to_face_matrix[cell_id]; for (size_t i_face = 0; i_face < cell_to_face.size(); ++i_face) { @@ -1595,66 +1729,74 @@ class ScalarHybridSchemeHandler::ScalarHybridScheme : public ScalarHybridSchemeH const auto& face_to_node = face_to_node_matrix[face_id]; const size_t numberOfNodesPerFace = face_to_node.size(); if (not is_boundary_face[face_id]) { - bool l1_OK = false; - FaceId l1 = 0; - FaceId l2 = 0; - TinyVector<Dimension> n1 = zero; - TinyVector<Dimension> n2 = zero; - TinyVector<Dimension> t = zero; - for (size_t j_face = 0; j_face < cell_to_face.size(); ++j_face) { - const FaceId face_id_j = cell_to_face[j_face]; - const auto& face_to_node_j = face_to_node_matrix[face_id_j]; - for (size_t j_face_to_node = 0; j_face_to_node < face_to_node_j.size(); ++j_face_to_node) { - if (is_boundary_face[face_id_j]) { - if (not l1_OK) { - l1 = face_id_j; - l1_OK = true; - } else { - l2 = face_id_j; - } - if (dot(nl[l1], xl[l1] - xj[cell_id]) <= 0) { - n1 = -nl[l1]; - } else { - n1 = nl[l1]; - } - if (dot(nl[l2], xl[l2] - xj[cell_id]) <= 0) { - n2 = -nl[l2]; - } else { - n2 = nl[l2]; - } - t[0] = n1[1] * n2[2] - n1[2] * n2[1]; - t[1] = n1[2] * n2[0] - n1[0] * n2[2]; - t[2] = n1[0] * n2[1] - n1[1] * n2[0]; - } + FaceId l1 = normal_edge_index[node_id][0]; + FaceId l2 = normal_edge_index[node_id][1]; + TinyVector<Dimension> n1 = normal1_edge[node_id]; + TinyVector<Dimension> n2 = normal2_edge[node_id]; + TinyVector<Dimension> t = normal_orth_edge[node_id]; + + // std::cout << "node_id : " << node_id << "; cell_id : " << cell_id + // << "; xj1-xj2 = " << xj1_xj2(cell_id, i_face) << "; t = " << t << "\n"; + + for (size_t i_face_to_node = 0; i_face_to_node < face_to_node.size(); ++i_face_to_node) { + if (face_to_node[i_face_to_node] == node_id) { + b[cell_id] += (1. - lambda) * + dot(face_boundary_values[l1] / pow(l2Norm(node_kappar[node_id] * n1), 2) * + node_kappar[node_id] * n1 + + face_boundary_values[l2] / pow(l2Norm(node_kappar[node_id] * n2), 2) * + node_kappar[node_id] * n2 - + 1. / dot(xj1_xj2(cell_id, i_face), node_kappar[node_id] * t) * + dot(xj1_xj2(cell_id, i_face), + face_boundary_values[l1] / pow(l2Norm(node_kappar[node_id] * n1), 2) * + node_kappar[node_id] * n1 + + face_boundary_values[l2] / pow(l2Norm(node_kappar[node_id] * n2), 2) * + node_kappar[node_id] * n2) / + pow(l2Norm(node_kappar[node_id] * t), 2) * node_kappar[node_id] * t, + node_kappar[node_id] * Cjr(cell_id, i_node)); + b_prev[cell_id] += + (1. - lambda) * + dot(face_boundary_prev_values[l1] / pow(l2Norm(node_kappar[node_id] * n1), 2) * + node_kappar[node_id] * n1 + + face_boundary_prev_values[l2] / pow(l2Norm(node_kappar[node_id] * n2), 2) * + node_kappar[node_id] * n2 - + 1. / dot(xj1_xj2(cell_id, i_face), node_kappar[node_id] * t) * + dot(xj1_xj2(cell_id, i_face), + face_boundary_prev_values[l1] / pow(l2Norm(node_kappar[node_id] * n1), 2) * + node_kappar[node_id] * n1 + + face_boundary_prev_values[l2] / pow(l2Norm(node_kappar[node_id] * n2), 2) * + node_kappar[node_id] * n2) / + pow(l2Norm(node_kappar[node_id] * t), 2) * node_kappar[node_id] * t, + node_kappar[node_id] * Cjr(cell_id, i_node)); + + b[cell_id] += lambda * mes_l[face_id] / numberOfNodesPerFace * + dot(face_boundary_values[l1] / pow(l2Norm(node_kappar[node_id] * n1), 2) * + node_kappar[node_id] * n1 + + face_boundary_values[l2] / pow(l2Norm(node_kappar[node_id] * n2), 2) * + node_kappar[node_id] * n2 - + 1. / dot(xj1_xj2(cell_id, i_face), node_kappar[node_id] * t) * + dot(xj1_xj2(cell_id, i_face), + face_boundary_values[l1] / pow(l2Norm(node_kappar[node_id] * n1), 2) * + node_kappar[node_id] * n1 + + face_boundary_values[l2] / pow(l2Norm(node_kappar[node_id] * n2), 2) * + node_kappar[node_id] * n2) / + pow(l2Norm(node_kappar[node_id] * t), 2) * node_kappar[node_id] * t, + base_xj1_xj2_orth(cell_id, i_face)); + b_prev[cell_id] += + lambda * mes_l[face_id] / numberOfNodesPerFace * + dot(face_boundary_prev_values[l1] / pow(l2Norm(node_kappar[node_id] * n1), 2) * + node_kappar[node_id] * n1 + + face_boundary_prev_values[l2] / pow(l2Norm(node_kappar[node_id] * n2), 2) * + node_kappar[node_id] * n2 - + 1. / dot(xj1_xj2(cell_id, i_face), node_kappar[node_id] * t) * + dot(xj1_xj2(cell_id, i_face), + face_boundary_prev_values[l1] / pow(l2Norm(node_kappar[node_id] * n1), 2) * + node_kappar[node_id] * n1 + + face_boundary_prev_values[l2] / pow(l2Norm(node_kappar[node_id] * n2), 2) * + node_kappar[node_id] * n2) / + pow(l2Norm(node_kappar[node_id] * t), 2) * node_kappar[node_id] * t, + base_xj1_xj2_orth(cell_id, i_face)); } } - b[cell_id] += - lambda * mes_l[face_id] / numberOfNodesPerFace * - dot(face_boundary_values[l1] / pow(l2Norm(node_kappar[node_id] * n1), 2) * node_kappar[node_id] * n1 + - face_boundary_values[l2] / pow(l2Norm(node_kappar[node_id] * n2), 2) * node_kappar[node_id] * - n2 - - 1. / dot(xj1_xj2(cell_id, i_face), node_kappar[node_id] * t) * - dot(xj1_xj2(cell_id, i_face), - face_boundary_values[l1] / pow(l2Norm(node_kappar[node_id] * n1), 2) * - node_kappar[node_id] * n1 + - face_boundary_values[l2] / pow(l2Norm(node_kappar[node_id] * n2), 2) * - node_kappar[node_id] * n2) / - pow(l2Norm(node_kappar[node_id] * t), 2) * node_kappar[node_id] * t, - base_xj1_xj2_orth(cell_id, i_face)); - b_prev[cell_id] += - lambda * mes_l[face_id] / numberOfNodesPerFace * - dot(face_boundary_prev_values[l1] / pow(l2Norm(node_kappar[node_id] * n1), 2) * node_kappar[node_id] * - n1 + - face_boundary_prev_values[l2] / pow(l2Norm(node_kappar[node_id] * n2), 2) * - node_kappar[node_id] * n2 - - 1. / dot(xj1_xj2(cell_id, i_face), node_kappar[node_id] * t) * - dot(xj1_xj2(cell_id, i_face), - face_boundary_prev_values[l1] / pow(l2Norm(node_kappar[node_id] * n1), 2) * - node_kappar[node_id] * n1 + - face_boundary_prev_values[l2] / pow(l2Norm(node_kappar[node_id] * n2), 2) * - node_kappar[node_id] * n2) / - pow(l2Norm(node_kappar[node_id] * t), 2) * node_kappar[node_id] * t, - base_xj1_xj2_orth(cell_id, i_face)); } } }