#pragma once // Contact discretization on a uniform refinement of the combined traces. #include #include #include "Elasticity.h" #include "ContactUniformLambdaPartition.h" namespace contact_uniform_union_partition { constexpr double kContactEps = 1e-12; inline bool almost_equal(double lhs, double rhs) { return std::fabs(lhs - rhs) < kContactEps; } inline std::vector build_mortar_elements( const std::vector& bottom_x, const std::vector& top_x, const std::vector& lambda_nodes, double contact_left, double contact_right) { std::vector partition; partition.reserve(bottom_x.size() + top_x.size() + lambda_nodes.size() + 2); partition.push_back(contact_left); partition.push_back(contact_right); auto append_contact_nodes = [&](const std::vector& nodes) { for (double x : nodes) if (x >= contact_left - kContactEps && x <= contact_right + kContactEps) partition.push_back(x); }; append_contact_nodes(bottom_x); append_contact_nodes(top_x); append_contact_nodes(lambda_nodes); std::sort(partition.begin(), partition.end()); partition.erase(std::unique(partition.begin(), partition.end(), almost_equal), partition.end()); std::vector mortar_elements; mortar_elements.reserve(partition.size() - 1); for (size_t seg = 0; seg + 1 < partition.size(); ++seg) mortar_elements.push_back({ partition[seg], partition[seg + 1] }); return mortar_elements; } inline ContactDiscretization build( const std::vector& bottom_x, const std::vector& top_x, double contact_left, double contact_right, size_t lambda_node_count) { ContactDiscretization discretization = contact_uniform_lambda_partition::build( bottom_x, top_x, contact_left, contact_right, lambda_node_count); discretization.mortar_elements = build_mortar_elements( bottom_x, top_x, discretization.lambda_nodes, contact_left, contact_right); return discretization; } } // namespace contact_uniform_union_partition