diff --git a/src/mesh/ImplicitMeshSmoother.cpp b/src/mesh/ImplicitMeshSmoother.cpp index 43538914a2069268254c8d76d765bdf0ce39d7bc..b73d6ec3d425caaf7c0bd327e6f6b554fa74df0d 100644 --- a/src/mesh/ImplicitMeshSmoother.cpp +++ b/src/mesh/ImplicitMeshSmoother.cpp @@ -79,46 +79,49 @@ class ImplicitMeshSmootherHandler::ImplicitMeshSmoother } void - _browseBC(NodeValue<bool>& is_fixed) const + _browseBC(NodeValue<bool>& is_fixed, NodeValue<int>& is_symmetric) const { + int n_sym = 1; for (auto&& boundary_condition : m_boundary_condition_list) { std::visit( [&](auto&& bc) { using BCType = std::decay_t<decltype(bc)>; - // if constexpr (std::is_same_v<BCType, SymmetryBoundaryCondition>) { - // const Rd& n = bc.outgoingNormal(); + if constexpr (std::is_same_v<BCType, SymmetryBoundaryCondition>) { + // const Rd& n = bc.outgoingNormal(); - // const Rdxd I = identity; - // const Rdxd nxn = tensorProduct(n, n); - // const Rdxd P = I - nxn; + // const Rdxd I = identity; + // const Rdxd nxn = tensorProduct(n, n); + // const Rdxd P = I - nxn; - // const Array<const NodeId>& node_list = bc.nodeList(); - // parallel_for( - // node_list.size(), PUGS_LAMBDA(const size_t i_node) { - // const NodeId node_id = node_list[i_node]; - - // shift[node_id] = P * shift[node_id]; - // }); - - // } else if constexpr (std::is_same_v<BCType, AxisBoundaryCondition>) { - // if constexpr (Dimension > 1) { - // const Rd& t = bc.direction(); + const Array<const NodeId>& node_list = bc.nodeList(); + parallel_for( + node_list.size(), PUGS_LAMBDA(const size_t i_node) { + const NodeId node_id = node_list[i_node]; + if (is_symmetric[node_id] != 0) { + is_fixed[node_id] = true; + } else if (!is_fixed[node_id]) { + is_symmetric[node_id] = n_sym; + } + }); + n_sym += 1; + // } else if constexpr (std::is_same_v<BCType, AxisBoundaryCondition>) { + // if constexpr (Dimension > 1) { + // const Rd& t = bc.direction(); - // const Rdxd txt = tensorProduct(t, t); + // const Rdxd txt = tensorProduct(t, t); - // const Array<const NodeId>& node_list = bc.nodeList(); - // parallel_for( - // node_list.size(), PUGS_LAMBDA(const size_t i_node) { - // const NodeId node_id = node_list[i_node]; + // const Array<const NodeId>& node_list = bc.nodeList(); + // parallel_for( + // node_list.size(), PUGS_LAMBDA(const size_t i_node) { + // const NodeId node_id = node_list[i_node]; - // shift[node_id] = txt * shift[node_id]; - // }); - // } else { - // throw UnexpectedError("AxisBoundaryCondition make no sense in dimension 1"); - // } + // shift[node_id] = txt * shift[node_id]; + // }); + // } else { + // throw UnexpectedError("AxisBoundaryCondition make no sense in dimension 1"); + // } - // } else - if constexpr (std::is_same_v<BCType, FixedBoundaryCondition>) { + } else if constexpr (std::is_same_v<BCType, FixedBoundaryCondition>) { const Array<const NodeId>& node_list = bc.nodeList(); parallel_for( node_list.size(), PUGS_LAMBDA(const size_t i_node) { @@ -167,22 +170,23 @@ class ImplicitMeshSmootherHandler::ImplicitMeshSmoother int local_free_id = 0; int local_fixed_id = 0; non_zeros_free.fill(1); + // Warning this is not correct non_zeros_fixed.fill(0); for (NodeId n_id = 0; n_id < m_given_mesh.numberOfNodes(); n_id++) { - // std::cout << " n_id " << n_id << "\n"; if (is_fixed[n_id]) { gid_node_fixed[local_fixed_id] = n_id; - for (size_t i_face = 0; i_face < node_to_face_matrix[n_id].size(); ++i_face) { - FaceId face_id = node_to_face_matrix[n_id][i_face]; - for (size_t i_node = 0; i_node < face_to_node_matrix[face_id].size(); ++i_node) { - NodeId node_id = face_to_node_matrix[face_id][i_node]; - if ((node_id == n_id) or (is_fixed[node_id])) { - continue; - } else { - non_zeros_fixed[local_fixed_id] += 1; - } - } - } + // for (size_t i_face = 0; i_face < node_to_face_matrix[n_id].size(); ++i_face) { + // FaceId face_id = node_to_face_matrix[n_id][i_face]; + + // for (size_t i_node = 0; i_node < face_to_node_matrix[face_id].size(); ++i_node) { + // NodeId node_id = face_to_node_matrix[face_id][i_node]; + // if ((node_id == n_id) or (is_fixed[node_id])) { + // continue; + // } else { + // non_zeros_fixed[local_fixed_id] += 1; + // } + // } + // } local_fixed_id++; } else { gid_node_free[local_free_id] = n_id; @@ -190,8 +194,10 @@ class ImplicitMeshSmootherHandler::ImplicitMeshSmoother FaceId face_id = node_to_face_matrix[n_id][i_face]; for (size_t i_node = 0; i_node < face_to_node_matrix[face_id].size(); ++i_node) { NodeId node_id = face_to_node_matrix[face_id][i_node]; - if ((node_id == n_id) or (is_fixed[node_id])) { + if ((node_id == n_id)) { continue; + } else if ((is_fixed[node_id])) { + non_zeros_fixed[local_free_id] += 1; } else { non_zeros_free[local_free_id] += 1; } @@ -205,6 +211,7 @@ class ImplicitMeshSmootherHandler::ImplicitMeshSmoother _fillMatrix(CRSMatrixDescriptor<double>& Afree, CRSMatrixDescriptor<double>& Afixed, const NodeValue<bool>& is_fixed, + const NodeValue<int>& is_symmetric, const NodeValue<int>& id_free, const NodeValue<int>& id_fixed) const // , @@ -219,18 +226,37 @@ class ImplicitMeshSmootherHandler::ImplicitMeshSmoother continue; } else { Assert(id_free[n_id] == local_free_id, "bad matrix definition"); - for (size_t i_face = 0; i_face < node_to_face_matrix[n_id].size(); ++i_face) { - FaceId face_id = node_to_face_matrix[n_id][i_face]; - for (size_t i_node = 0; i_node < face_to_node_matrix[face_id].size(); ++i_node) { - NodeId node_id = face_to_node_matrix[face_id][i_node]; - if (node_id == n_id) { - continue; - } else if ((is_fixed[node_id])) { - Afree(local_free_id, local_free_id) += 1; - Afixed(local_free_id, id_fixed[node_id]) -= 1; - } else { - Afree(local_free_id, local_free_id) += 1; - Afree(local_free_id, id_free[node_id]) -= 1; + if (is_symmetric[n_id]) { + for (size_t i_face = 0; i_face < node_to_face_matrix[n_id].size(); ++i_face) { + FaceId face_id = node_to_face_matrix[n_id][i_face]; + for (size_t i_node = 0; i_node < face_to_node_matrix[face_id].size(); ++i_node) { + NodeId node_id = face_to_node_matrix[face_id][i_node]; + if (node_id == n_id) { + continue; + } else if ((is_fixed[node_id])) { + Afree(local_free_id, local_free_id) += 1; + Afixed(local_free_id, id_fixed[node_id]) -= 1; + } else if (is_symmetric[node_id] == is_symmetric[n_id]) { + Afree(local_free_id, local_free_id) += 1; + Afree(local_free_id, id_free[node_id]) -= 1; + } + } + } + + } else { + for (size_t i_face = 0; i_face < node_to_face_matrix[n_id].size(); ++i_face) { + FaceId face_id = node_to_face_matrix[n_id][i_face]; + for (size_t i_node = 0; i_node < face_to_node_matrix[face_id].size(); ++i_node) { + NodeId node_id = face_to_node_matrix[face_id][i_node]; + if (node_id == n_id) { + continue; + } else if ((is_fixed[node_id])) { + Afree(local_free_id, local_free_id) += 1; + Afixed(local_free_id, id_fixed[node_id]) -= 1; + } else { + Afree(local_free_id, local_free_id) += 1; + Afree(local_free_id, id_free[node_id]) -= 1; + } } } } @@ -239,6 +265,49 @@ class ImplicitMeshSmootherHandler::ImplicitMeshSmoother } } + void + _correct_sym(const NodeValue<const Rd>& old_xr, NodeValue<Rd>& new_xr) const + { + for (auto&& boundary_condition : m_boundary_condition_list) { + std::visit( + [&](auto&& bc) { + using BCType = std::decay_t<decltype(bc)>; + if constexpr (std::is_same_v<BCType, SymmetryBoundaryCondition>) { + const Rd& n = bc.outgoingNormal(); + + const Rdxd I = identity; + const Rdxd nxn = tensorProduct(n, n); + const Rdxd P = I - nxn; + + const Array<const NodeId>& node_list = bc.nodeList(); + parallel_for( + node_list.size(), PUGS_LAMBDA(const size_t i_node) { + const NodeId node_id = node_list[i_node]; + Rd depl = new_xr[node_id] - old_xr[node_id]; + new_xr[node_id] = old_xr[node_id] + P * depl; + }); + // } else if constexpr (std::is_same_v<BCType, AxisBoundaryCondition>) { + // if constexpr (Dimension > 1) { + // const Rd& t = bc.direction(); + + // const Rdxd txt = tensorProduct(t, t); + + // const Array<const NodeId>& node_list = bc.nodeList(); + // parallel_for( + // node_list.size(), PUGS_LAMBDA(const size_t i_node) { + // const NodeId node_id = node_list[i_node]; + + // shift[node_id] = txt * shift[node_id]; + // }); + // } else { + // throw UnexpectedError("AxisBoundaryCondition make no sense in dimension 1"); + // } + } + }, + boundary_condition); + } + } + NodeValue<Rd> _getPosition(NodeValue<const bool> is_displaced) const { @@ -247,7 +316,9 @@ class ImplicitMeshSmootherHandler::ImplicitMeshSmoother NodeValue<Rd> pos_r{connectivity}; NodeValue<bool> is_fixed{connectivity}; + NodeValue<int> is_symmetric{connectivity}; is_fixed.fill(false); + is_symmetric.fill(0); parallel_for( m_given_mesh.numberOfNodes(), PUGS_LAMBDA(NodeId node_id) { pos_r[node_id] = given_xr[node_id]; @@ -255,24 +326,26 @@ class ImplicitMeshSmootherHandler::ImplicitMeshSmoother is_fixed[node_id] = true; } }); - _browseBC(is_fixed); + _browseBC(is_fixed, is_symmetric); + // std::cout << "is_fixed " << is_fixed << "\n"; + // std::cout << "is_symmetric " << is_symmetric << "\n"; NodeValue<int> node_dof_id{connectivity}; size_t nb_free, nb_fixed; NodeValue<int> id_free{connectivity}; NodeValue<int> id_fixed{connectivity}; _computeMatrixSize(is_fixed, id_fixed, id_free, nb_free, nb_fixed); + std::cout << " nb_free " << nb_free << " nb_fixed " << nb_fixed << "\n"; Array<int> non_zeros_free{nb_free}; Array<int> non_zeros_fixed{nb_free}; Array<NodeId> gid_node_free{nb_free}; Array<NodeId> gid_node_fixed{nb_fixed}; _findLocalIds(is_fixed, gid_node_free, gid_node_fixed, non_zeros_free, non_zeros_fixed); - std::cout << " nb_free " << nb_free << " nb_fixed " << nb_fixed << "\n"; CRSMatrixDescriptor<double> Afree(nb_free, nb_free, non_zeros_free); CRSMatrixDescriptor<double> Afixed(nb_free, nb_fixed, non_zeros_fixed); LinearSolver solver; - _fillMatrix(Afree, Afixed, is_fixed, id_free, id_fixed); + _fillMatrix(Afree, Afixed, is_fixed, is_symmetric, id_free, id_fixed); Vector<double> F{nb_fixed}; CRSMatrix Mfree{Afree.getCRSMatrix()}; CRSMatrix Mfixed{Afixed.getCRSMatrix()}; @@ -283,6 +356,10 @@ class ImplicitMeshSmootherHandler::ImplicitMeshSmoother Vector<double> X{nb_free}; Vector<double> b{nb_free}; b = Mfixed * F; + // std::cout << " Mfixed " << Mfixed << "\n"; + // std::cout << " F " << F << "\n"; + // std::cout << " b " << b << "\n"; + // std::cout << " Mfree " << Mfree << "\n"; solver.solveLocalSystem(Mfree, X, b); parallel_for( m_given_mesh.numberOfNodes(), PUGS_LAMBDA(NodeId node_id) { @@ -291,6 +368,7 @@ class ImplicitMeshSmootherHandler::ImplicitMeshSmoother } }); } + _correct_sym(m_given_mesh.xr(), pos_r); // synchronize(pos_r); return pos_r; }