diff --git a/doc/manual/manual-contact_detector.tex b/doc/manual/manual-contact_detector.tex new file mode 100644 index 000000000..9f5d1b263 --- /dev/null +++ b/doc/manual/manual-contact_detector.tex @@ -0,0 +1,8 @@ +For contact detection, \akantu has a class \code{ContactDetector} + +\begin{cpp} + ... + contact_detector [ + contact_surfaces = [master, slave] + ] +\end{cpp} \ No newline at end of file diff --git a/examples/contact_mechanics/contact_detection_2d.cc b/examples/contact_mechanics/contact_detection_2d.cc index 458e29715..a2672733c 100644 --- a/examples/contact_mechanics/contact_detection_2d.cc +++ b/examples/contact_mechanics/contact_detection_2d.cc @@ -1,58 +1,57 @@ /** * @file test_contact_detection.cc * * @author Mohit Pundir * * @date creation: Mon Oct 22 2018 * @date last modification: Mon Oct 22 2018 * * @brief Test for contact detection * * @section LICENSE * * Copyright (©) 2010-2018 EPFL (Ecole Polytechnique Fédérale de Lausanne) * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides) * * Akantu is free software: you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License as published by the Free * Software Foundation, either version 3 of the License, or (at your option) any * later version. * * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more * details. * * You should have received a copy of the GNU Lesser General Public License * along with Akantu. If not, see . * */ /* -------------------------------------------------------------------------- */ #include #include /* -------------------------------------------------------------------------- */ -#include "contact_detection.hh" +#include "contact_detector.hh" /* -------------------------------------------------------------------------- */ using namespace akantu; int main(int argc, char* argv[]) { initialize("material.dat", argc, argv); const UInt spatial_diemnsion = 2; Mesh mesh(spatial_diemnsion); mesh.read("hertz_2d.msh"); - ContactDetection detect(mesh, "rigid", "contact_surface"); - - //detect.set("master_surface", "rigid"); - //detect.set("master_surface", "elastic"); - - detect.search(); + ContactDetector detector(mesh, "bot_body", "top_body"); + //detector.setMasterSurface("rigid"); + //detector.setSlaveSurface("contact_surface"); + + detector.search(); finalize(); } diff --git a/examples/contact_mechanics/contact_detection_3d.cc b/examples/contact_mechanics/contact_detection_3d.cc index ae9e80a40..03c1fe8e7 100644 --- a/examples/contact_mechanics/contact_detection_3d.cc +++ b/examples/contact_mechanics/contact_detection_3d.cc @@ -1,55 +1,57 @@ /** * @file test_contact_detection.cc * * @author Mohit Pundir * * @date creation: Mon Oct 22 2018 * @date last modification: Mon Oct 22 2018 * * @brief Test for contact detection * * @section LICENSE * * Copyright (©) 2010-2018 EPFL (Ecole Polytechnique Fédérale de Lausanne) * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides) * * Akantu is free software: you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License as published by the Free * Software Foundation, either version 3 of the License, or (at your option) any * later version. * * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more * details. * * You should have received a copy of the GNU Lesser General Public License * along with Akantu. If not, see . * */ /* -------------------------------------------------------------------------- */ #include #include /* -------------------------------------------------------------------------- */ -#include "contact_detection.hh" +#include "contact_detector.hh" /* -------------------------------------------------------------------------- */ using namespace akantu; int main(int argc, char* argv[]) { initialize("material.dat", argc, argv); const UInt spatial_diemnsion = 3; Mesh mesh(spatial_diemnsion); mesh.read("hertz_3d.msh"); - ContactDetection detect(mesh, "rigid_surface", "contact_surface"); - - detect.search(); + ContactDetector detector(mesh, "rigid", "elastic"); + detector.setMasterSurface("rigid_surface"); + detector.setSlaveSurface("contact_surface"); + + detector.search(); finalize(); } diff --git a/examples/contact_mechanics/hertz_2d.geo b/examples/contact_mechanics/hertz_2d.geo index 1af7b5faf..1ebb01542 100644 --- a/examples/contact_mechanics/hertz_2d.geo +++ b/examples/contact_mechanics/hertz_2d.geo @@ -1,29 +1,29 @@ cl1 = 0.01; cl2 = 0.01; cl3 = 0.01; -Dy = 0.1; +Dy = 0.05; Point(1) = {0, 0.1-Dy, 0, cl1}; Point(2) = {0.5, 0.6-Dy, 0, cl2}; Point(3) = {-0.5, 0.6-Dy, 0, cl2}; Point(4) = {0.5, 0.1, 0, cl3}; Point(5) = {-0.5, 0.1, 0, cl3}; Point(6) = {-0.5, -0.25, 0, cl3}; Point(7) = {0.5, -0.25, 0, cl3}; Point(8) = {0, 0.6-Dy, 0, cl2}; Circle(1) = {3, 8, 1}; Circle(2) = {1, 8, 2}; Line(3) = {2, 8}; Line(13) = {8, 3}; Line(4) = {6, 7}; Line(5) = {7, 4}; Line(6) = {4, 5}; Line(7) = {5, 6}; Line Loop(9) = {2, 3, 13, 1}; Plane Surface(9) = {9}; Line Loop(11) = {6, 7, 4, 5}; Plane Surface(11) = {11}; Physical Line("rigid") = {6}; Physical Line("contact_surface") = {1, 2}; Physical Line("top") = {3, 13}; Physical Surface("top_body") = {9}; Physical Surface("bot_body") = {11}; \ No newline at end of file diff --git a/examples/contact_mechanics/material.dat b/examples/contact_mechanics/material.dat index e69de29bb..eaa59aaae 100644 --- a/examples/contact_mechanics/material.dat +++ b/examples/contact_mechanics/material.dat @@ -0,0 +1,4 @@ +contact_detector [ + master_surface = rigid + slave_surface = contact_surface +] \ No newline at end of file diff --git a/packages/contact_mechanics.cmake b/packages/contact_mechanics.cmake index 477a50764..57fac5659 100644 --- a/packages/contact_mechanics.cmake +++ b/packages/contact_mechanics.cmake @@ -1,44 +1,47 @@ #=============================================================================== # @file contact_mechanics.cmake # # @author Mohit Pundir # # @date creation: Sun Oct 21 2018 # @date last modification: Sun Oct 21 2018 # # @brief package description for contact mechanics # # @section LICENSE # # Copyright (©) 2010-2012, 2014, 2015 EPFL (Ecole Polytechnique Fédérale de # Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des # Solides) # # Akantu is free software: you can redistribute it and/or modify it under the # terms of the GNU Lesser General Public License as published by the Free # Software Foundation, either version 3 of the License, or (at your option) any # later version. # # Akantu is distributed in the hope that it will be useful, but WITHOUT ANY # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR # A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more # details. # # You should have received a copy of the GNU Lesser General Public License # along with Akantu. If not, see . # #=============================================================================== package_declare(contact_mechanics DESCRIPTION "Use Contact Mechanics package of Akantu") package_declare_sources(contact_mechanics - model/contact_mechanics/contact_detection.hh - model/contact_mechanics/contact_detection.cc) + model/contact_mechanics/contact_mechanics_model.hh + model/contact_mechanics/contact_mechanics_model.cc + model/contact_mechanics/contact_detector.hh + model/contact_mechanics/contact_detector.cc + model/contact_mechanics/contact_element.hh) package_declare_documentation_files(contact_mechanics - #manual-contactmechanicsmodel.tex + manual-contact_detector.tex ) package_declare_documentation(contact_mechanics - "This package activates the conatct ") + "This package activates the contact ") diff --git a/src/io/parser/parser.hh b/src/io/parser/parser.hh index e888e6b4b..be92244f2 100644 --- a/src/io/parser/parser.hh +++ b/src/io/parser/parser.hh @@ -1,510 +1,510 @@ /** * @file parser.hh * * @author Nicolas Richart * * @date creation: Wed Nov 13 2013 * @date last modification: Fri Dec 08 2017 * * @brief File parser interface * * @section LICENSE * * Copyright (©) 2014-2018 EPFL (Ecole Polytechnique Fédérale de Lausanne) * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides) * * Akantu is free software: you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License as published by the Free * Software Foundation, either version 3 of the License, or (at your option) any * later version. * * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more * details. * * You should have received a copy of the GNU Lesser General Public License * along with Akantu. If not, see . * */ /* -------------------------------------------------------------------------- */ #include "aka_common.hh" #include "aka_random_generator.hh" /* -------------------------------------------------------------------------- */ #include /* -------------------------------------------------------------------------- */ #ifndef __AKANTU_PARSER_HH__ #define __AKANTU_PARSER_HH__ namespace akantu { #ifndef SWIG // clang-format off #define AKANTU_SECTION_TYPES \ (cohesive_inserter) \ (contact) \ (embedded_interface) \ (friction) \ (global) \ (heat) \ (integration_scheme) \ (material) \ (mesh) \ (model) \ (model_solver) \ (neighborhood) \ (neighborhoods) \ (non_linear_solver) \ (non_local) \ (rules) \ (solver) \ (time_step_solver) \ (user) \ (weight_function) \ - (contact_detection) \ + (contact_detector) \ (not_defined) // clang-format on /// Defines the possible section types AKANTU_ENUM_DECLARE(ParserType, AKANTU_SECTION_TYPES) AKANTU_ENUM_OUTPUT_STREAM(ParserType, AKANTU_SECTION_TYPES) AKANTU_ENUM_INPUT_STREAM(ParserType, AKANTU_SECTION_TYPES) /// Defines the possible search contexts/scopes (for parameter search) enum ParserParameterSearchCxt { _ppsc_current_scope = 0x1, _ppsc_parent_scope = 0x2, _ppsc_current_and_parent_scope = 0x3 }; #endif /* ------------------------------------------------------------------------ */ /* Parameters Class */ /* ------------------------------------------------------------------------ */ class ParserSection; /// @brief The ParserParameter objects represent the end of tree branches as /// they /// are the different informations contained in the input file. class ParserParameter { public: ParserParameter() : name(std::string()), value(std::string()), dbg_filename(std::string()) { } ParserParameter(const std::string & name, const std::string & value, const ParserSection & parent_section) : parent_section(&parent_section), name(name), value(value), dbg_filename(std::string()) {} ParserParameter(const ParserParameter & param) = default; virtual ~ParserParameter() = default; /// Get parameter name const std::string & getName() const { return name; } /// Get parameter value const std::string & getValue() const { return value; } /// Set info for debug output void setDebugInfo(const std::string & filename, UInt line, UInt column) { dbg_filename = filename; dbg_line = line; dbg_column = column; } template inline operator T() const; // template inline operator Vector() const; // template inline operator Matrix() const; /// Print parameter info in stream void printself(std::ostream & stream, __attribute__((unused)) unsigned int indent = 0) const { stream << name << ": " << value << " (" << dbg_filename << ":" << dbg_line << ":" << dbg_column << ")"; } private: void setParent(const ParserSection & sect) { parent_section = § } friend class ParserSection; private: /// Pointer to the parent section const ParserSection * parent_section{nullptr}; /// Name of the parameter std::string name; /// Value of the parameter std::string value; /// File for debug output std::string dbg_filename; /// Position of parameter in parsed file UInt dbg_line, dbg_column; }; /* ------------------------------------------------------------------------ */ /* Sections Class */ /* ------------------------------------------------------------------------ */ /// ParserSection represents a branch of the parsing tree. class ParserSection { public: using SubSections = std::multimap; using Parameters = std::map; private: using const_section_iterator_ = SubSections::const_iterator; public: /* ------------------------------------------------------------------------ */ /* SubSection iterator */ /* ------------------------------------------------------------------------ */ /// Iterator on sections class const_section_iterator { public: using iterator_category = std::forward_iterator_tag; using value_type = ParserSection; using pointer = ParserSection *; using reference = ParserSection &; const_section_iterator() = default; const_section_iterator(const const_section_iterator_ & it) : it(it) {} const_section_iterator(const const_section_iterator & other) = default; const_section_iterator & operator=(const const_section_iterator & other) = default; const ParserSection & operator*() const { return it->second; } const ParserSection * operator->() const { return &(it->second); } bool operator==(const const_section_iterator & other) const { return it == other.it; } bool operator!=(const const_section_iterator & other) const { return it != other.it; } const_section_iterator & operator++() { ++it; return *this; } const_section_iterator operator++(int) { const_section_iterator tmp = *this; operator++(); return tmp; } private: const_section_iterator_ it; }; /* ------------------------------------------------------------------------ */ /* Parameters iterator */ /* ------------------------------------------------------------------------ */ /// Iterator on parameters class const_parameter_iterator { public: const_parameter_iterator(const const_parameter_iterator & other) = default; const_parameter_iterator(const Parameters::const_iterator & it) : it(it) {} const_parameter_iterator & operator=(const const_parameter_iterator & other) { if (this != &other) { it = other.it; } return *this; } const ParserParameter & operator*() const { return it->second; } const ParserParameter * operator->() { return &(it->second); }; bool operator==(const const_parameter_iterator & other) const { return it == other.it; } bool operator!=(const const_parameter_iterator & other) const { return it != other.it; } const_parameter_iterator & operator++() { ++it; return *this; } const_parameter_iterator operator++(int) { const_parameter_iterator tmp = *this; operator++(); return tmp; } private: Parameters::const_iterator it; }; /* ---------------------------------------------------------------------- */ ParserSection() : name(std::string()) {} ParserSection(const std::string & name, ParserType type) : parent_section(nullptr), name(name), type(type) {} ParserSection(const std::string & name, ParserType type, const std::string & option, const ParserSection & parent_section) : parent_section(&parent_section), name(name), type(type), option(option) {} ParserSection(const ParserSection & section) : parent_section(section.parent_section), name(section.name), type(section.type), option(section.option), parameters(section.parameters), sub_sections_by_type(section.sub_sections_by_type) { setChldrenPointers(); } ParserSection & operator=(const ParserSection & other) { if (&other != this) { parent_section = other.parent_section; name = other.name; type = other.type; option = other.option; parameters = other.parameters; sub_sections_by_type = other.sub_sections_by_type; setChldrenPointers(); } return *this; } virtual ~ParserSection(); virtual void printself(std::ostream & stream, unsigned int indent = 0) const; /* ---------------------------------------------------------------------- */ /* Creation functions */ /* ---------------------------------------------------------------------- */ public: ParserParameter & addParameter(const ParserParameter & param); ParserSection & addSubSection(const ParserSection & section); protected: /// Clean ParserSection content void clean() { parameters.clear(); sub_sections_by_type.clear(); } private: void setChldrenPointers() { for (auto && param_pair : this->parameters) param_pair.second.setParent(*this); for (auto && sub_sect_pair : this->sub_sections_by_type) sub_sect_pair.second.setParent(*this); } /* ---------------------------------------------------------------------- */ /* Accessors */ /* ---------------------------------------------------------------------- */ public: #ifndef SWIG class SubSectionsRange : public std::pair { public: SubSectionsRange(const const_section_iterator & first, const const_section_iterator & second) : std::pair(first, second) {} auto begin() { return this->first; } auto end() { return this->second; } }; /// Get begin and end iterators on subsections of certain type auto getSubSections(ParserType type = ParserType::_not_defined) const { if (type != ParserType::_not_defined) { auto range = sub_sections_by_type.equal_range(type); return SubSectionsRange(range.first, range.second); } else { return SubSectionsRange(sub_sections_by_type.begin(), sub_sections_by_type.end()); } } /// Get number of subsections of certain type UInt getNbSubSections(ParserType type = ParserType::_not_defined) const { if (type != ParserType::_not_defined) { return this->sub_sections_by_type.count(type); } else { return this->sub_sections_by_type.size(); } } /// Get begin and end iterators on parameters auto getParameters() const { return std::pair( parameters.begin(), parameters.end()); } #endif /* ---------------------------------------------------------------------- */ /// Get parameter within specified context const ParserParameter & getParameter( const std::string & name, ParserParameterSearchCxt search_ctx = _ppsc_current_scope) const { Parameters::const_iterator it; if (search_ctx & _ppsc_current_scope) it = parameters.find(name); if (it == parameters.end()) { if ((search_ctx & _ppsc_parent_scope) && parent_section) return parent_section->getParameter(name, search_ctx); else { AKANTU_SILENT_EXCEPTION( "The parameter " << name << " has not been found in the specified context"); } } return it->second; } /* ------------------------------------------------------------------------ */ /// Get parameter within specified context, with a default value in case the /// parameter does not exists template const T getParameter( const std::string & name, const T & default_value, ParserParameterSearchCxt search_ctx = _ppsc_current_scope) const { try { T tmp = this->getParameter(name, search_ctx); return tmp; } catch (debug::Exception &) { return default_value; } } /* ------------------------------------------------------------------------ */ /// Check if parameter exists within specified context bool hasParameter( const std::string & name, ParserParameterSearchCxt search_ctx = _ppsc_current_scope) const { Parameters::const_iterator it; if (search_ctx & _ppsc_current_scope) it = parameters.find(name); if (it == parameters.end()) { if ((search_ctx & _ppsc_parent_scope) && parent_section) return parent_section->hasParameter(name, search_ctx); else { return false; } } return true; } /* -------------------------------------------------------------------------- */ /// Get value of given parameter in context template T getParameterValue( const std::string & name, ParserParameterSearchCxt search_ctx = _ppsc_current_scope) const { const ParserParameter & tmp_param = getParameter(name, search_ctx); T t = tmp_param; return t; } /* -------------------------------------------------------------------------- */ /// Get section name const std::string getName() const { return name; } /// Get section type ParserType getType() const { return type; } /// Get section option const std::string getOption(const std::string & def = "") const { return option != "" ? option : def; } protected: void setParent(const ParserSection & sect) { parent_section = § } /* ---------------------------------------------------------------------- */ /* Members */ /* ---------------------------------------------------------------------- */ private: /// Pointer to the parent section const ParserSection * parent_section{nullptr}; /// Name of section std::string name; /// Type of section, see AKANTU_SECTION_TYPES ParserType type{ParserType::_not_defined}; /// Section option std::string option; /// Map of parameters in section Parameters parameters; /// Multi-map of subsections SubSections sub_sections_by_type; }; /* ------------------------------------------------------------------------ */ /* Parser Class */ /* ------------------------------------------------------------------------ */ /// Root of parsing tree, represents the global ParserSection class Parser : public ParserSection { public: Parser() : ParserSection("global", ParserType::_global) {} void parse(const std::string & filename); std::string getLastParsedFile() const; static bool isPermissive() { return permissive_parser; } public: /// Parse real scalar static Real parseReal(const std::string & value, const ParserSection & section); /// Parse real vector static Vector parseVector(const std::string & value, const ParserSection & section); /// Parse real matrix static Matrix parseMatrix(const std::string & value, const ParserSection & section); #ifndef SWIG /// Parse real random parameter static RandomParameter parseRandomParameter(const std::string & value, const ParserSection & section); #endif protected: /// General parse function template static T parseType(const std::string & value, Grammar & grammar); protected: // friend class Parsable; static bool permissive_parser; std::string last_parsed_file; }; inline std::ostream & operator<<(std::ostream & stream, const ParserParameter & _this) { _this.printself(stream); return stream; } inline std::ostream & operator<<(std::ostream & stream, const ParserSection & section) { section.printself(stream); return stream; } } // akantu namespace std { template <> struct iterator_traits<::akantu::Parser::const_section_iterator> { using iterator_category = input_iterator_tag; using value_type = ::akantu::ParserParameter; using difference_type = ptrdiff_t; using pointer = const ::akantu::ParserParameter *; using reference = const ::akantu::ParserParameter &; }; } #include "parser_tmpl.hh" #endif /* __AKANTU_PARSER_HH__ */ diff --git a/src/model/contact_mechanics/contact_detection.cc b/src/model/contact_mechanics/contact_detection.cc deleted file mode 100644 index bc5123dfd..000000000 --- a/src/model/contact_mechanics/contact_detection.cc +++ /dev/null @@ -1,232 +0,0 @@ -/** - * @file contact_detection.cc - * - * @author Mohit Pundir - * - * @date creation: Wed Sep 12 2018 - * @date last modification: Fri Sep 21 2018 - * - * @brief Mother class for all detection algorithms - * - * @section LICENSE - * - * Copyright (©) 2010-2018 EPFL (Ecole Polytechnique Fédérale de Lausanne) - * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides) - * - * Akantu is free software: you can redistribute it and/or modify it under the - * terms of the GNU Lesser General Public License as published by the Free - * Software Foundation, either version 3 of the License, or (at your option) any - * later version. - * - * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more - * details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Akantu. If not, see . - * - */ - -/* -------------------------------------------------------------------------- */ -#include "contact_detection.hh" -/* -------------------------------------------------------------------------- */ - -namespace akantu { - - -/* -------------------------------------------------------------------------- */ - ContactDetection::ContactDetection(Mesh & mesh,std::string master, std::string slave, const ID & id, - UInt memory_id) - : Memory(id, memory_id), - Parsable(ParserType::_contact_detection, id), - mesh(mesh) { - - this->spatial_dimension = mesh.getSpatialDimension(); - - this->registerParam("master_surface", master_id, _pat_parsmod, - "Master surface id"); - this->registerParam("slave_surface", slave_id, _pat_parsmod, - "Slave surface id"); - - this->master_id = master; - this->slave_id = slave; - - this->getMaximalDetectionDistance(); - -} - -/* -------------------------------------------------------------------------- */ -void ContactDetection::getMaximalDetectionDistance() { - - AKANTU_DEBUG_IN(); - - Real el_size; - Real max_el_size = std::numeric_limits::min(); - - auto & master_group = - mesh.getElementGroup(master_id); - - for (auto & type: master_group.elementTypes(spatial_dimension - 1, _not_ghost)) { - - UInt nb_nodes_per_element = mesh.getNbNodesPerElement(type); - - Array coord(0, nb_nodes_per_element * spatial_dimension); - FEEngine::extractNodalToElementField(mesh, mesh.getNodes(), coord, type, - _not_ghost); - auto el_coord = coord.begin(spatial_dimension, nb_nodes_per_element); - UInt nb_element = mesh.getNbElement(type); - - for (UInt el =0; el < nb_element; ++el, ++el_coord) { - el_size = FEEngine::getElementInradius(*el_coord, type); - max_el_size = std::max(max_el_size, el_size); - } - - AKANTU_DEBUG_INFO("The maximum element size : " - << max_el_size ); - } - - this->max_dd = max_el_size; - - AKANTU_DEBUG_OUT(); -} - -/* -------------------------------------------------------------------------- */ -void ContactDetection::search() { - this->globalSearch(); - this->localSearch(); -} - - -/* -------------------------------------------------------------------------- */ -void ContactDetection::globalSearch() { - - auto & master_list = - mesh.getElementGroup(master_id).getNodeGroup().getNodes(); - - auto & slave_list = - mesh.getElementGroup(slave_id).getNodeGroup().getNodes(); - - BBox bbox_master(spatial_dimension); - this->constructBoundingBox(bbox_master, master_list); - - BBox bbox_slave(spatial_dimension); - this->constructBoundingBox(bbox_slave, slave_list); - - auto && bbox_intersection = - bbox_master.intersection(bbox_slave); - - Vector center(spatial_dimension); - bbox_intersection.getCenter(center); - - Vector spacing(spatial_dimension); - this->computeCellSpacing(spacing); - - SpatialGrid master_grid(spatial_dimension, spacing, center); - this->constructGrid(master_grid, bbox_intersection, master_list); - - SpatialGrid slave_grid(spatial_dimension, spacing, center); - this->constructGrid(slave_grid, bbox_intersection, slave_list); - - if (AKANTU_DEBUG_TEST(dblDump)) { - Mesh mesh(spatial_dimension, "save"); - master_grid.saveAsMesh(mesh); - mesh.write("grid.msh"); - } - - AKANTU_DEBUG_INFO( "Grid Details " - << master_grid ); - - // (bucket sort - construct the grid in intersected bounding box) - // create 2 array As and Am which contains ith cell j nodes - // need to find nodes int he intersecting box - // based on the position of the node, a cell can be assigned - // given in report - // the arrays are replaced by spatial grids - - // TODO : increase the lower and upper bound for both bbox -} - -/* -------------------------------------------------------------------------- */ -void ContactDetection::localSearch() { - - // local search - // out of these array check each cell for closet node in that cell - // and neighbouring cells find the actual orthogonally closet - // check the projection of slave node on master facets connected to - // the closet master node, if yes update the contact element with - // slave node and master node and master surfaces connected to the - // master node - // these master surfaces will be needed later to update contact elements - - // PART I - // for each cell in slave grid - // for each node in each cell - // check the corresponding and neighboring cell in master grid - // find the closet master mode - - // PART II - // Once closet master node if found , - // find the attached elements to it surface/line - // mesh.getAssociatedElements( function seems to be the key) - - // PART III - // compute the orthogonal distance from each associated element - - // PART IV - // create contact element, - // contact element should have one slave node and master facets - - - - -} - -/* -------------------------------------------------------------------------- */ -void ContactDetection::constructGrid(SpatialGrid & grid, BBox & bbox, - const Array & nodes_list) { - - const auto & positions = mesh.getNodes(); - - auto to_grid = [&](UInt node) { - Vector pos(spatial_dimension); - for (UInt s: arange(spatial_dimension)) { - pos(s) = positions(node, s); - } - - if (bbox.contains(pos)) { - grid.insert(node, pos); - } - }; - - std::for_each(nodes_list.begin(), nodes_list.end(), to_grid); -} - -/* -------------------------------------------------------------------------- */ -void ContactDetection::constructBoundingBox(BBox & bbox, const Array & nodes_list) { - - const auto & positions = mesh.getNodes(); - - auto to_bbox = [&](UInt node) { - Vector pos(spatial_dimension); - for (UInt s: arange(spatial_dimension)) { - pos(s) = positions(node, s); - } - - bbox += pos; - }; - - std::for_each(nodes_list.begin(), nodes_list.end(), to_bbox); -} - -/* -------------------------------------------------------------------------- */ -void ContactDetection::computeCellSpacing(Vector & spacing) { - - for (UInt s: arange(spatial_dimension)) - spacing(s) = std::sqrt(2.0) * max_dd; - -} - - - -} // akantu diff --git a/src/model/contact_mechanics/contact_detector.cc b/src/model/contact_mechanics/contact_detector.cc new file mode 100644 index 000000000..731273d5f --- /dev/null +++ b/src/model/contact_mechanics/contact_detector.cc @@ -0,0 +1,427 @@ +/** + * @file contact_detector.cc + * + * @author Mohit Pundir + * + * @date creation: Wed Sep 12 2018 + * @date last modification: Fri Sep 21 2018 + * + * @brief Mother class for all detection algorithms + * + * @section LICENSE + * + * Copyright (©) 2010-2018 EPFL (Ecole Polytechnique Fédérale de Lausanne) + * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides) + * + * Akantu is free software: you can redistribute it and/or modify it under the + * terms of the GNU Lesser General Public License as published by the Free + * Software Foundation, either version 3 of the License, or (at your option) any + * later version. + * + * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more + * details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Akantu. If not, see . + * + */ + +/* -------------------------------------------------------------------------- */ +#include "contact_detector.hh" +/* -------------------------------------------------------------------------- */ + +namespace akantu { + +/* -------------------------------------------------------------------------- */ + ContactDetector::ContactDetector(Mesh & mesh, std::string master, std::string slave, const ID & id, UInt memory_id) + : ContactDetector(mesh, mesh.getNodes(), master, slave, id, memory_id) { + + } + +/* -------------------------------------------------------------------------- */ + ContactDetector::ContactDetector(Mesh & mesh, Array & positions, std::string master, std::string slave, const ID & id, UInt memory_id) + : Memory(id, memory_id), + Parsable(ParserType::_contact_detector, id), + mesh(mesh), + positions(positions) { + + AKANTU_DEBUG_IN(); + + this->spatial_dimension = mesh.getSpatialDimension(); + + this->registerParam("master_surface", master_surface, _pat_parsmod, + "Master surface id"); + this->registerParam("slave_surface", slave_surface, _pat_parsmod, + "Slave surface id"); + + //auto & ms = this->get("master_surface"); + + //const Parser & parser = getStaticParser(); + //const ParserSection & section_detector = + // *(parser.getSubSections(ParserType::_contact_detector).first); + //this->parseSection(section_detector); + + //auto sub_sections = getStaticParser(); + //this->master_surface = section_detector.getParameter("master_surface", _ppsc_current_scope); + //this->master_surface = section_detector.getParameter("slave_surface", _ppsc_current_scope); + + this->master_id = master; + this->slave_id = slave; + + this->mesh.fillNodesToElements(); + + AKANTU_DEBUG_OUT(); +} + + +/* -------------------------------------------------------------------------- */ +void ContactDetector::getMaximalDetectionDistance() { + + AKANTU_DEBUG_IN(); + + Real el_size; + Real max_el_size = std::numeric_limits::min(); + + auto & master_group = + mesh.getElementGroup(master_surface); + + for (auto & type: master_group.elementTypes(spatial_dimension - 1, _not_ghost)) { + + UInt nb_nodes_per_element = mesh.getNbNodesPerElement(type); + + Array coord(0, nb_nodes_per_element * spatial_dimension); + FEEngine::extractNodalToElementField(mesh, mesh.getNodes(), coord, type, + _not_ghost); + auto el_coord = coord.begin(spatial_dimension, nb_nodes_per_element); + UInt nb_element = mesh.getNbElement(type); + + for (UInt el =0; el < nb_element; ++el, ++el_coord) { + el_size = FEEngine::getElementInradius(*el_coord, type); + max_el_size = std::max(max_el_size, el_size); + } + + AKANTU_DEBUG_INFO("The maximum element size : " + << max_el_size ); + } + + this->max_dd = max_el_size; + + AKANTU_DEBUG_OUT(); +} + +/* -------------------------------------------------------------------------- */ +void ContactDetector::setMasterSurface(std::string master_surface) { + this->master_surface = master_surface; + this->getMaximalDetectionDistance(); +} + + + +/* -------------------------------------------------------------------------- */ +void ContactDetector::setSlaveSurface(std::string slave_surface) { + this->slave_surface = slave_surface; +} + + +/* -------------------------------------------------------------------------- */ +void ContactDetector::search() { + this->globalSearch(); +} + + +/* -------------------------------------------------------------------------- */ +void ContactDetector::globalSearch() { + + auto & master_list = + mesh.getElementGroup(master_id).getNodeGroup().getNodes(); + + auto & slave_list = + mesh.getElementGroup(slave_id).getNodeGroup().getNodes(); + + BBox bbox_master(spatial_dimension); + this->constructBoundingBox(bbox_master, master_list); + + BBox bbox_slave(spatial_dimension); + this->constructBoundingBox(bbox_slave, slave_list); + + auto && bbox_intersection = + bbox_master.intersection(bbox_slave); + + AKANTU_DEBUG_INFO( "Intersection BBox " + << bbox_intersection ); + + Vector center(spatial_dimension); + bbox_intersection.getCenter(center); + + Vector spacing(spatial_dimension); + this->computeCellSpacing(spacing); + + auto & master_surface_list = + mesh.getElementGroup(master_surface).getNodeGroup().getNodes(); + + auto & slave_surface_list = + mesh.getElementGroup(slave_surface).getNodeGroup().getNodes(); + + SpatialGrid master_grid(spatial_dimension, spacing, center); + this->constructGrid(master_grid, bbox_intersection, master_surface_list); + + SpatialGrid slave_grid(spatial_dimension, spacing, center); + this->constructGrid(slave_grid, bbox_intersection, slave_surface_list); + + if (AKANTU_DEBUG_TEST(dblDump)) { + Mesh mesh(spatial_dimension, "save"); + master_grid.saveAsMesh(mesh); + mesh.write("master_grid.msh"); + } + + if (AKANTU_DEBUG_TEST(dblDump)) { + Mesh mesh2(spatial_dimension, "save"); + slave_grid.saveAsMesh(mesh2); + mesh2.write("slave_grid.msh"); + } + + AKANTU_DEBUG_INFO( "Grid Details " << master_grid ); + // search slave grid nodes in contactelement array and if they exits + // and still have orthogonal projection on its associated master + // facetremove it from the spatial grid or do not consider it for + // local search, maybe better option will be to have spatial grid of + // type node info and one of the variable of node info should be + // facet already exits + // so contact eleemnts will be updated based on the above + // consideration , this means only those contact elements will be + // keep whose slave node is still in intersection bbox and still has + // projection in its master facet + // also if slave node is already exists in contact element and + // orthogonal projection does not exits then search the associated + // master facets with the current master facets within a given + // radius , this is subjected to computational cost as searching + // neighbbor cells can be more effective. + this->localSearch(slave_grid, master_grid); +} + +/* -------------------------------------------------------------------------- */ + void ContactDetector::localSearch(SpatialGrid & slave_grid, SpatialGrid & master_grid) { + + // local search + // out of these array check each cell for closet node in that cell + // and neighbouring cells find the actual orthogonally closet + // check the projection of slave node on master facets connected to + // the closet master node, if yes update the contact element with + // slave node and master node and master surfaces connected to the + // master node + // these master surfaces will be needed later to update contact + // elements + + Array slave_nodes; + Array master_nodes; + + // find the closet master node for each slave node + for (auto && cell_id : slave_grid) { + AKANTU_DEBUG_INFO("Looping on next cell"); + + + for (auto && q1: slave_grid.getCell(cell_id)) { + + Vector pos(spatial_dimension); + for (UInt s: arange(spatial_dimension)) { + pos(s) = this->positions(q1, s); + } + + Real closet_distance = std::numeric_limits::max(); + UInt closet_master_node; + + // loop over all the neighboring cells of the current cells + for (auto && neighbor_cell : cell_id.neighbors()) { + //AKANTU_DEBUG_INFO("Looping on neighbor cell"); + // loop over the data of neighboring cells from master grid + + for (auto && q2 : master_grid.getCell(neighbor_cell)) { + + AKANTU_DEBUG_INFO("Looping on neighbor cell in master"); + Vector pos2(spatial_dimension); + for (UInt s: arange(spatial_dimension)) { + pos2(s) = this->positions(q2, s); + } + + Real distance = pos.distance(pos2); + std::cout << distance << " " << closet_distance << std::endl; + + if (distance <= closet_distance) { + closet_master_node = q2; + closet_distance = distance; + } + } + } + + slave_nodes.push_back(q1); + master_nodes.push_back(closet_master_node); + } + + } + + + for (auto & master: master_nodes) { + Array elements; + mesh.getAssociatedElements(master, elements); + + //Array normals(elements.size(), spatial_dimension); + //this->computeNormalOnElements(elements, normals); + + //Array projections(elements.size(), 0); + //this->computeOrthogonalProjections(normals, projections); + + // create a contact element + // elements array + // minimum orthogonal projection + // and the corresponding normal + // UInt slave node + // Element master element + // contact_element = std::make_shared(UInt, Element); + // contact_element->setGap(projection) + // contact_element->setNormal(normal(p)); + // contact_element->setPatch(elements); + // elements.push_back(contact_element); + + } + + // PART III + // compute the orthogonal distance from each associated element + // this->computeOrthogonalDistance(*sit, elements); + // give orthogonal distance + // /// compute normals on facets + // this->computeNormals(); belongs to model class + // put this function in contact model class + // and create the mesh_facets in conatct detection class + // this->getFEEngine("FacetsFEEngine") + //.computeNormalsOnIntegrationPoints(_not_ghost); + // const auto & tangents = model->getTangents(type_facet); + // const auto & normals = model->getFEEngine("FacetsFEEngine") + // .getNormalsOnIntegrationPoints(type_facet); + + + // PART IV + // create contact element, + // contact element should have one slave node and master facets + // ContactElement > e(slave, elements); + // set the orthogonal and orthogonal distance + // + +} + + +/* -------------------------------------------------------------------------- */ +void ContactDetector::constructGrid(SpatialGrid & grid, BBox & bbox, + const Array & nodes_list) { + auto to_grid = [&](UInt node) { + Vector pos(spatial_dimension); + for (UInt s: arange(spatial_dimension)) { + pos(s) = this->positions(node, s); + } + + if (bbox.contains(pos)) { + grid.insert(node, pos); + } + }; + + std::for_each(nodes_list.begin(), nodes_list.end(), to_grid); +} + +/* -------------------------------------------------------------------------- */ +void ContactDetector::constructBoundingBox(BBox & bbox, const Array & nodes_list) { + + auto to_bbox = [&](UInt node) { + Vector pos(spatial_dimension); + for (UInt s: arange(spatial_dimension)) { + pos(s) = this->positions(node, s); + } + + bbox += pos; + }; + + std::for_each(nodes_list.begin(), nodes_list.end(), to_bbox); + + AKANTU_DEBUG_INFO("BBox" << bbox); + + auto & lower_bound = bbox.getLowerBounds(); + auto & upper_bound = bbox.getUpperBounds(); + + for (UInt s: arange(spatial_dimension)) { + lower_bound(s) -= this->max_dd; + upper_bound(s) += this->max_dd; + } + + + AKANTU_DEBUG_INFO("BBox" << bbox); +} + +/* -------------------------------------------------------------------------- */ +void ContactDetector::computeCellSpacing(Vector & spacing) { + + for (UInt s: arange(spatial_dimension)) + spacing(s) = std::sqrt(2.0) * max_dd; + +} + +/* -------------------------------------------------------------------------- */ +void ContactDetector::computeNormalOnElements(Array & elements, Array & normals) { + + // get from connectivity the nodes for each element in Array elements; + + const Matrix & coords; + this->coordinatesOfElement(e, coords); + + Matrix J(this->spatial_dimension, this->spatial_dimension); + this->vectorsAlongElement(coords, J); + + switch (this->spatial_dimension) { + case 2: { + // extract the vectors + Math::normal2(J.storage(), normal.storage()); + break; + } + case 3: { + Math::normal3(J(0).storage(), J(1).storage, normal(p).storage()); + break; + } + default: + break; + } +} + + + +/* -------------------------------------------------------------------------- */ +/* To be put in conatct mechancis model class + +void ContactDetector::computeNormals() { + AKANTU_DEBUG_IN(); + + Mesh & mesh_facets = this->inserter->getMeshFacets(); + this->getFEEngine("FacetsFEEngine") + .computeNormalsOnIntegrationPoints(_not_ghost); + + UInt tangent_components = + Model::spatial_dimension * (Model::spatial_dimension - 1); + + tangents.initialize(mesh_facets, _nb_component = tangent_components, + _spatial_dimension = Model::spatial_dimension - 1); + + for (auto facet_type : + mesh_facets.elementTypes(Model::spatial_dimension - 1)) { + const Array & normals = + this->getFEEngine("FacetsFEEngine") + .getNormalsOnIntegrationPoints(facet_type); + + Array & tangents = this->tangents(facet_type); + + Math::compute_tangents(normals, tangents); + } + + AKANTU_DEBUG_OUT(); +}*/ + + + +} // akantu diff --git a/src/model/contact_mechanics/contact_detection.hh b/src/model/contact_mechanics/contact_detector.hh similarity index 72% copy from src/model/contact_mechanics/contact_detection.hh copy to src/model/contact_mechanics/contact_detector.hh index 267c6ec81..bc0b0fa3e 100644 --- a/src/model/contact_mechanics/contact_detection.hh +++ b/src/model/contact_mechanics/contact_detector.hh @@ -1,113 +1,149 @@ /** * @file contact_detection.hh * * @author Mohit Pundir * * @date creation: Wed Sep 12 2018 * @date last modification: Tue Oct 23 2018 * * @brief Mother class for all detection algorithms * * @section LICENSE * * Copyright (©) 2010-2018 EPFL (Ecole Polytechnique Fédérale de Lausanne) * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides) * * Akantu is free software: you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License as published by the Free * Software Foundation, either version 3 of the License, or (at your option) any * later version. * * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more * details. * * You should have received a copy of the GNU Lesser General Public License * along with Akantu. If not, see . * */ /* -------------------------------------------------------------------------- */ #include "aka_common.hh" #include "aka_memory.hh" #include "aka_grid_dynamic.hh" #include "aka_bbox.hh" #include "mesh.hh" #include "mesh_io.hh" #include "fe_engine.hh" #include "parsable.hh" #include "element_group.hh" +//#include "contact_element.hh" /* -------------------------------------------------------------------------- */ -#ifndef __AKANTU_CONTACT_DETECTION_HH__ -#define __AKANTU_CONTACT_DETECTION_HH__ +#ifndef __AKANTU_CONTACT_DETECTOR_HH__ +#define __AKANTU_CONTACT_DETECTOR_HH__ -namespace akantu { +namespace akantu { + +enum class Surface { + _master, + _slave +}; /* -------------------------------------------------------------------------- */ -class ContactDetection : +class ContactDetector : private Memory, public Parsable { /* ------------------------------------------------------------------------ */ /* Constructor/Destructors */ /* ------------------------------------------------------------------------ */ public: - ContactDetection(Mesh &, std::string , std::string , const ID & id = "contact_detection", - UInt memory_id = 0); + ContactDetector(Mesh &, std::string , std::string , + const ID & id = "contact_detector", + UInt memory_id = 0); - ~ContactDetection() = default; + ContactDetector(Mesh &, Array & positions, std::string, + std::string , const ID & id = "contact_detector", UInt memory_id = 0); + + + ~ContactDetector() = default; /* ------------------------------------------------------------------------ */ /* Members */ /* ------------------------------------------------------------------------ */ public: - /// + /// sets the master surface id + // TODO : needs to be changes , more efficient way + void setMasterSurface(std::string); + + /// sets the slave surface id + // TODO : needs to be changes , more efficient way + void setSlaveSurface(std::string); + + /// void search(); - + +private: /// performs global spatial search void globalSearch(); /// performs local search to create contact element - void localSearch(); + /// TODO: templated function typename + void localSearch(SpatialGrid &, SpatialGrid &); /// constructs a grid containing nodes lying within bounding box + /// TODO : templated fucntion to created tempalte Spatial Grid void constructGrid(SpatialGrid &, BBox &, const Array &); /// constructs the bounding box based on nodes list void constructBoundingBox(BBox &, const Array &); /// computes the optimal cell size for grid void computeCellSpacing(Vector &); /// computes the maximum in radius for a given mesh void getMaximalDetectionDistance(); + /* ------------------------------------------------------------------------ */ /* Class Members */ /* ------------------------------------------------------------------------ */ private: /// maximal detection distance Real max_dd; /// dimension of the model UInt spatial_dimension{0}; /// Mesh Mesh & mesh; /// id for master surface/curve std::string master_id; /// id for slave surface/curve std::string slave_id; + /// + std::string slave_surface; + + /// + std::string master_surface; + + /// contains the updated positions of the nodes + Array & positions; + + using Elements = std::vector>; + /// + Elements elements; + }; } // namespace akantu -#endif /* __AKANTU_CONTACT_DETECTION_HH__ */ +#endif /* __AKANTU_CONTACT_DETECTOR_HH__ */ diff --git a/src/model/contact_mechanics/contact_detection.hh b/src/model/contact_mechanics/contact_element.hh similarity index 55% copy from src/model/contact_mechanics/contact_detection.hh copy to src/model/contact_mechanics/contact_element.hh index 267c6ec81..6a971bebc 100644 --- a/src/model/contact_mechanics/contact_detection.hh +++ b/src/model/contact_mechanics/contact_element.hh @@ -1,113 +1,103 @@ /** - * @file contact_detection.hh + * @file contact_element.hh * * @author Mohit Pundir * * @date creation: Wed Sep 12 2018 * @date last modification: Tue Oct 23 2018 * * @brief Mother class for all detection algorithms * * @section LICENSE * * Copyright (©) 2010-2018 EPFL (Ecole Polytechnique Fédérale de Lausanne) * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides) * * Akantu is free software: you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License as published by the Free * Software Foundation, either version 3 of the License, or (at your option) any * later version. * * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more * details. * * You should have received a copy of the GNU Lesser General Public License * along with Akantu. If not, see . * */ /* -------------------------------------------------------------------------- */ #include "aka_common.hh" -#include "aka_memory.hh" -#include "aka_grid_dynamic.hh" -#include "aka_bbox.hh" -#include "mesh.hh" -#include "mesh_io.hh" -#include "fe_engine.hh" -#include "parsable.hh" -#include "element_group.hh" + + /* -------------------------------------------------------------------------- */ -#ifndef __AKANTU_CONTACT_DETECTION_HH__ -#define __AKANTU_CONTACT_DETECTION_HH__ +#ifndef __AKANTU_CONTACT_ELEMENT_HH__ +#define __AKANTU_CONTACT_ELEMENT_HH__ +/* -------------------------------------------------------------------------- */ -namespace akantu { - -/* -------------------------------------------------------------------------- */ +namespace akantu { -class ContactDetection : - private Memory, public Parsable { +template +class ContactElement { /* ------------------------------------------------------------------------ */ - /* Constructor/Destructors */ + /* Constructor/ Destructors */ /* ------------------------------------------------------------------------ */ public: - - ContactDetection(Mesh &, std::string , std::string , const ID & id = "contact_detection", - UInt memory_id = 0); - ~ContactDetection() = default; + ContactElement(S slave, M master) + : slave(slave), master(master) { + + } + + ~ContactElement() = default; /* ------------------------------------------------------------------------ */ - /* Members */ + /* Accessors */ /* ------------------------------------------------------------------------ */ public: - /// - void search(); - - /// performs global spatial search - void globalSearch(); + // sets the value of normal vector + AKANTU_SET_MACRO(Normal, Vector, normal); - /// performs local search to create contact element - void localSearch(); + // sets the value of tangent vector + AKANTU_SET_MACRO(Tangent, Vector, tangent); - /// constructs a grid containing nodes lying within bounding box - void constructGrid(SpatialGrid &, BBox &, const Array &); + // sets the value of gap + AKANTU_SET_MACRO(Gap, Real, gap); - /// constructs the bounding box based on nodes list - void constructBoundingBox(BBox &, const Array &); - - /// computes the optimal cell size for grid - void computeCellSpacing(Vector &); - - /// computes the maximum in radius for a given mesh - void getMaximalDetectionDistance(); - + // sets the value of normal vector + AKANTU_SET_MACRO(Patch, Array, patch); + /* ------------------------------------------------------------------------ */ /* Class Members */ - /* ------------------------------------------------------------------------ */ -private: - /// maximal detection distance - Real max_dd; + /* ------------------------------------------------------------------------ */ +public: + + /// slave node + S node; - /// dimension of the model - UInt spatial_dimension{0}; + /// master element/node + M master; - /// Mesh - Mesh & mesh; + /// normalized normal direction + Vector normal; - /// id for master surface/curve - std::string master_id; + /// normalized tangent direction + Vector tangent; - /// id for slave surface/curve - std::string slave_id; + /// penetration gap between slave and master + Real gap; + /// an array of master nodes/elements around slave node + Array patch; }; - -} // namespace akantu -#endif /* __AKANTU_CONTACT_DETECTION_HH__ */ + +} // akantu + +#endif /* __AKANTU_CONTACT_ELEMENT_HH__ */ diff --git a/examples/contact_mechanics/contact_detection_2d.cc b/src/model/contact_mechanics/contact_mechanics_model.cc similarity index 60% copy from examples/contact_mechanics/contact_detection_2d.cc copy to src/model/contact_mechanics/contact_mechanics_model.cc index 458e29715..29aaa564d 100644 --- a/examples/contact_mechanics/contact_detection_2d.cc +++ b/src/model/contact_mechanics/contact_mechanics_model.cc @@ -1,58 +1,68 @@ /** - * @file test_contact_detection.cc + * @file coontact_mechanics_model.cc * * @author Mohit Pundir * - * @date creation: Mon Oct 22 2018 - * @date last modification: Mon Oct 22 2018 + * @date creation: Tue May 08 2012 + * @date last modification: Wed Feb 21 2018 * - * @brief Test for contact detection + * @brief Contact mechanics model * * @section LICENSE * * Copyright (©) 2010-2018 EPFL (Ecole Polytechnique Fédérale de Lausanne) * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides) * * Akantu is free software: you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License as published by the Free * Software Foundation, either version 3 of the License, or (at your option) any * later version. * * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more * details. * * You should have received a copy of the GNU Lesser General Public License * along with Akantu. If not, see . * */ /* -------------------------------------------------------------------------- */ - -#include -#include - +#include "fe_engine.hh" +#include "contact_mechanics_model.hh" /* -------------------------------------------------------------------------- */ -#include "contact_detection.hh" +#include /* -------------------------------------------------------------------------- */ -using namespace akantu; -int main(int argc, char* argv[]) { +namespace akantu { + +ContactMechanicsModel::ContactMechanicsModel( Mesh & mesh, UInt dim, const ID & id, + const MemoryID & memory_id, + const ModelType model_type) + : Model(mesh, model_type, dim, id, memory_id) { + + AKANTU_DEBUG_IN(); + + + //this->detector = std::make_unique( + // this->mesh, id + ":contact_detector"); - initialize("material.dat", argc, argv); - const UInt spatial_diemnsion = 2; + AKANTU_DEBUG_OUT(); + +} - Mesh mesh(spatial_diemnsion); - mesh.read("hertz_2d.msh"); - ContactDetection detect(mesh, "rigid", "contact_surface"); +ContactMechanicsModel::~ContactMechanicsModel() { + AKANTU_DEBUG_IN(); - //detect.set("master_surface", "rigid"); - //detect.set("master_surface", "elastic"); + AKANTU_DEBUG_OUT(); +} - detect.search(); +void ContactMechanicsModel::initModel() { - finalize(); +} + + } diff --git a/src/model/contact_mechanics/contact_detection.hh b/src/model/contact_mechanics/contact_mechanics_model.hh similarity index 51% rename from src/model/contact_mechanics/contact_detection.hh rename to src/model/contact_mechanics/contact_mechanics_model.hh index 267c6ec81..589dc2785 100644 --- a/src/model/contact_mechanics/contact_detection.hh +++ b/src/model/contact_mechanics/contact_mechanics_model.hh @@ -1,113 +1,94 @@ /** - * @file contact_detection.hh + * @file contact_mechanics_model.hh * * @author Mohit Pundir * - * @date creation: Wed Sep 12 2018 - * @date last modification: Tue Oct 23 2018 + * @date creation: Tue Jul 27 2010 + * @date last modification: Wed Feb 21 2018 * - * @brief Mother class for all detection algorithms + * @brief Model of Contact Mechanics * * @section LICENSE * * Copyright (©) 2010-2018 EPFL (Ecole Polytechnique Fédérale de Lausanne) * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides) * * Akantu is free software: you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License as published by the Free * Software Foundation, either version 3 of the License, or (at your option) any * later version. * * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more * details. * * You should have received a copy of the GNU Lesser General Public License * along with Akantu. If not, see . * */ /* -------------------------------------------------------------------------- */ -#include "aka_common.hh" -#include "aka_memory.hh" -#include "aka_grid_dynamic.hh" -#include "aka_bbox.hh" -#include "mesh.hh" -#include "mesh_io.hh" -#include "fe_engine.hh" -#include "parsable.hh" -#include "element_group.hh" +#include "model.hh" +#include "contact_detector.hh" /* -------------------------------------------------------------------------- */ -#ifndef __AKANTU_CONTACT_DETECTION_HH__ -#define __AKANTU_CONTACT_DETECTION_HH__ +#ifndef __AKANTU_CONTACT_MECHANICS_MODEL_HH__ +#define __AKANTU_CONTACT_MECHANICS_MODEL_HH__ +namespace akantu { +} // namespace akantu -namespace akantu { - -/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ +namespace akantu { -class ContactDetection : - private Memory, public Parsable { +/* -------------------------------------------------------------------------- */ +class ContactMechanicsModel + : public Model { /* ------------------------------------------------------------------------ */ - /* Constructor/Destructors */ + /* Constructors/Destructors */ /* ------------------------------------------------------------------------ */ -public: - ContactDetection(Mesh &, std::string , std::string , const ID & id = "contact_detection", - UInt memory_id = 0); + +public: + ContactMechanicsModel( + Mesh & mesh, UInt spatial_dimension = _all_dimensions, + const ID & id = "contact_mechanics_model", const MemoryID & memory_id = 0, + const ModelType model_type = ModelType::_contact_mechanics_model); - ~ContactDetection() = default; + ~ContactMechanicsModel() override; /* ------------------------------------------------------------------------ */ - /* Members */ + /* Methods */ /* ------------------------------------------------------------------------ */ -public: - /// - void search(); - - /// performs global spatial search - void globalSearch(); +protected: - /// performs local search to create contact element - void localSearch(); + /// initialize the modelType + void initModel() override; - /// constructs a grid containing nodes lying within bounding box - void constructGrid(SpatialGrid &, BBox &, const Array &); - /// constructs the bounding box based on nodes list - void constructBoundingBox(BBox &, const Array &); + friend class ContactDetector; + +private: - /// computes the optimal cell size for grid - void computeCellSpacing(Vector &); + void computeNormals(); - /// computes the maximum in radius for a given mesh - void getMaximalDetectionDistance(); - /* ------------------------------------------------------------------------ */ /* Class Members */ /* ------------------------------------------------------------------------ */ private: - /// maximal detection distance - Real max_dd; + + /// contact detection + std::unique_ptr detector; - /// dimension of the model - UInt spatial_dimension{0}; +}; - /// Mesh - Mesh & mesh; - /// id for master surface/curve - std::string master_id; - /// id for slave surface/curve - std::string slave_id; -}; - } // namespace akantu -#endif /* __AKANTU_CONTACT_DETECTION_HH__ */ + +#endif