NimbleSM
NimbleSM is a solid mechanics simulation code for dynamic systems
Loading...
Searching...
No Matches
nimble_contact_manager.h
Go to the documentation of this file.
1/*
2//@HEADER
3// ************************************************************************
4//
5// NimbleSM
6// Copyright 2018
7// National Technology & Engineering Solutions of Sandia, LLC (NTESS)
8//
9// Under the terms of Contract DE-NA0003525 with NTESS, the U.S. Government
10// retains certain rights in this software.
11//
12// Redistribution and use in source and binary forms, with or without
13// modification, are permitted provided that the following conditions are
14// met:
15//
16// 1. Redistributions of source code must retain the above copyright
17// notice, this list of conditions and the following disclaimer.
18//
19// 2. Redistributions in binary form must reproduce the above copyright
20// notice, this list of conditions and the following disclaimer in the
21// documentation and/or other materials provided with the distribution.
22//
23// 3. Neither the name of the Corporation nor the names of the
24// contributors may be used to endorse or promote products derived from
25// this software without specific prior written permission.
26//
27// THIS SOFTWARE IS PROVIDED BY NTESS "AS IS" AND ANY EXPRESS OR IMPLIED
28// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
29// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
30// NO EVENT SHALL NTESS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
31// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
32// TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
33// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
34// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
35// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
36// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37//
38// Questions? Contact David Littlewood (djlittl@sandia.gov)
39//
40// ************************************************************************
41//@HEADER
42*/
43
44#ifndef NIMBLE_CONTACT_H
45#define NIMBLE_CONTACT_H
46
47#include <cfloat>
48#include <cmath>
49#include <map>
50#include <memory>
51#include <unordered_map>
52#include <stdexcept>
53#include <vector>
54
57#include "nimble_defs.h"
59#include "nimble_genesis_mesh.h"
60#include "nimble_view.h"
61
62#ifdef NIMBLE_HAVE_KOKKOS
64#endif
65
66#include "nimble_timer.h"
67
68namespace nimble_kokkos {
69
70class ModelData;
71
72}
73
74namespace nimble {
75
76class DataManager;
77class VectorCommunicator;
78
79namespace details {
80
81inline void
82getContactForce(const double penalty, const double gap, const double normal[3], double contact_force[3])
83{
84 const double scale = penalty * gap;
85 for (int i = 0; i < 3; ++i) contact_force[i] = scale * normal[i];
86}
87
88} // namespace details
89
91{
93
94 template <typename VecType>
97 const ContactEntity& node,
98 ContactEntity& face,
99 const double gap,
100 const double normal[3],
101 const double barycentric_coordinates[3],
102 VecType& full_contact_force) const
103 {
104 constexpr int dim_vec = 3;
105 double contact_force[dim_vec]{};
106 details::getContactForce(penalty, gap, normal, contact_force);
107 //
108 //--- Create a local dummy copy of 'face' to avoid "critical" section
109 //
110 ContactEntity tmp_face;
111 tmp_face.entity_type_ = face.entity_type_;
118 tmp_face.SetNodalContactForces(contact_force, barycentric_coordinates);
119 tmp_face.ScatterForceToContactManagerForceVector<VecType>(full_contact_force);
120 //
121 //--- Create a local dummy copy of 'node' to avoid "critical" section
122 //
123 ContactEntity tmp_node;
125 tmp_node.node_id_for_node_1_ = node.node_id_for_node_1_;
126 tmp_node.SetNodalContactForces(contact_force);
127 tmp_node.ScatterForceToContactManagerForceVector<VecType>(full_contact_force);
128 }
129
130 double penalty;
131};
132
134{
135 public:
142
143 /// \brief Constructor
144 ContactManager(std::shared_ptr<ContactInterface> interface, nimble::DataManager& data_manager);
145
146 /// \brief Default destructor
147 virtual ~ContactManager() = default;
148
149 //
150 // Interface functions
151 //
152
153 /// \brief Indicates whether contact is enabled or not
154 ///
155 /// \return Boolean for contact
156 bool
158 {
159 return contact_enabled_;
160 }
161
162 /// \brief Set the penalty parameter for enforcing contact
163 ///
164 /// \param penalty_parameter Penalty value
165 void
166 SetPenaltyParameter(double penalty_parameter)
167 {
168 penalty_parameter_ = penalty_parameter;
170 contact_interface->SetUpPenaltyEnforcement(penalty_parameter_);
171 }
172
173 /// \brief Create contact entities between different blocks
174 ///
175 /// \param mesh
176 /// \param mpi_container
177 /// \param primary_block_ids
178 /// \param secondary_block_ids
179 void
181 GenesisMesh const& mesh,
182 nimble::VectorCommunicator& mpi_container,
183 std::vector<int> const& primary_block_ids,
184 std::vector<int> const& secondary_block_ids);
185
186 /// \brief Initialize contact visualization output
187 ///
188 /// \param contact_visualization_exodus_file_name Filename for output
189 virtual void
190 InitializeContactVisualization(std::string const& contact_visualization_exodus_file_name);
191
192 /// \brief Write information about contact
193 ///
194 /// \param time_current Current time
195 virtual void
196 ContactVisualizationWriteStep(double time_current);
197
198 /// \brief Compute the contact force
199 ///
200 /// \param data_manager
201 /// \param step
202 /// \param debug_output
203 /// \param contact_force
204 virtual void
205 ComputeContactForce(int step, bool debug_output, nimble::Viewify<2> contact_force);
206
207 /// \brief Returns the number of contact faces
208 ///
209 /// \return Number of contact faces
210 ///
211 /// \note When using Kokkos, the data is extracted from the "host".
212 size_t
213 numContactFaces() const;
214
215 /// \brief Returns the number of contact nodes
216 ///
217 /// \return Number of contact nodes
218 ///
219 /// \note When using Kokkos, the data is extracted from the "host".
220 size_t
221 numContactNodes() const;
222
223 /// \brief Returns the number of contact faces "actively" in collision
224 ///
225 /// \return Number of active contact faces
226 ///
227 /// \note When using Kokkos, the data is extracted from the "host".
228 size_t
229 numActiveContactFaces() const;
230
231 /// \brief Returns the number of contact nodes "actively" in collision
232 ///
233 /// \return Number of active contact nodes
234 ///
235 /// \note When using Kokkos, the data is extracted from the "host".
236 size_t
237 numActiveContactNodes() const;
238
239 /// \brief Return timing information
240 /// \return Reference to map of strings to time value
241 const std::unordered_map<std::string, double>&
242 getTimers();
243
244 //
245 // Static functions
246 //
247
248 static void
250 GenesisMesh const& mesh,
251 std::vector<int> const& block_ids,
252 int entity_id_offset,
253 std::vector<std::vector<int>>& skin_faces,
254 std::vector<int>& entity_ids);
255
256 static void
257 RemoveInternalSkinFaces(GenesisMesh const& mesh, std::vector<std::vector<int>>& faces, std::vector<int>& entity_ids);
258
259 // DEPRECATED
260 /// \brief Compute the projection of a point onto a triangular face
261 ///
262 /// \param[in] node Node to project
263 /// \param[in] tri Face to project onto
264 /// \param[out] projection_type Result of projection (FACE: success,
265 /// UNKNOWN: point projects outside the face)
266 /// \param[out] closest_point Projection
267 /// \param[out] gap Normal distance when the point projects onto the face
268 /// \param[out] normal Unit normal vector outside of face
269 /// \param[in] tolerance Tolerance to fit into the face (defaut value = 1e-08)
270 static void
272 const ContactEntity& node,
273 const ContactEntity& tri,
274 PROJECTION_TYPE* projection_type,
275 ContactEntity::vertex* closest_point,
276 double& gap,
277 double* normal,
278 double tolerance = 1.e-8);
279
280 /// \brief Compute the projection of a point onto a triangular face
281 ///
282 /// \param[in] node Node to project
283 /// \param[in] tri Face to project onto
284 /// \param[out] in True if node is inside the facet
285 /// \param[out] gap Normal distance when the point projects onto the face
286 /// \param[out] normal Unit normal vector outside of face
287 /// \param[out] barycentric_coordinates Projection of node on facet
288 /// \param[in] tolerance Tolerance to fit into the face (defaut value = 1e-08)
289 static void
291 const ContactEntity& node,
292 const ContactEntity& tri,
293 bool& in,
294 double& gap,
295 double* normal,
296 double* barycentric_coordinates,
297 double tolerance = 1.e-8);
298
299 /// \brief Return the penalty coefficient for enforcing contact force
300 ///
301 /// \return Penalty value
302 double
303 GetPenaltyForceParam() const noexcept
304 {
305 return enforcement.penalty;
306 }
307
308 protected:
309 //
310 // Specific functions
311 //
312
313 /// \brief Write visualization data to Exodus file at time t
314 ///
315 /// \param t Current time
316 ///
317 /// \note When using Kokkos, the data is extracted from the "host".
318 void
319 WriteVisualizationData(double t);
320
321 template <typename ArgT>
322 void
324 std::vector<std::vector<int>> const& primary_skin_faces,
325 std::vector<int> const& primary_skin_entity_ids,
326 std::vector<int> const& secondary_node_ids,
327 std::vector<int> const& secondary_node_entity_ids,
328 std::map<int, double> const& secondary_node_char_lens,
329 ArgT& contact_nodes,
330 ArgT& contact_faces) const;
331
332 void
333 BoundingBox(double& x_min, double& x_max, double& y_min, double& y_max, double& z_min, double& z_max) const;
334
335 double
337
338 void
339 ComputeContactForce(int step, bool debug_output)
340 {
341 if (penalty_parameter_ <= 0.0) {
342 throw std::invalid_argument("\nError in ComputeContactForce(), invalid penalty_parameter.\n");
343 }
344 double background_grid_cell_size = BoundingBoxAverageCharacteristicLengthOverAllRanks();
345#ifdef NIMBLE_HAVE_KOKKOS
347#endif
348 }
349
350 void
352 void
353 GetForces(nimble_kokkos::DeviceVectorNodeView contact_force_d) const;
354
355 void
356 BruteForceBoxIntersectionSearch(std::vector<ContactEntity> const& nodes, std::vector<ContactEntity> const& triangles);
357
358 void
360 const ContactEntity* nodes,
361 const ContactEntity* triangles,
362 ContactEntity::vertex* closest_points,
363 PROJECTION_TYPE* projection_types,
364 std::size_t num_elements);
365
366 void
368 const ContactEntity& node,
369 const ContactEntity& tri,
370 ContactEntity::vertex* closest_point,
371 PROJECTION_TYPE* projection_type,
372 double tolerance);
373
374 /// \brief Returns a read-only reference to contact face entity
375 ///
376 /// \param i_face Index of the contact face
377 /// \return Read-only reference to contact face entity
378 ///
379 /// \note When using Kokkos, the data is extracted from the "host".
380 const ContactEntity&
381 getContactFace(size_t i_face) const;
382
383 /// \brief Returns a read-only reference to contact node entity
384 ///
385 /// \param i_node Index of the contact node
386 /// \return Read-only reference to contact node entity
387 ///
388 /// \note When using Kokkos, the data is extracted from the "host".
389 const ContactEntity&
390 getContactNode(size_t i_node) const;
391
392 /// \brief Reset the contact status for all entities
393 void
395
396 /// \brief Zero the contact forces
397 void
399
400 template <typename VecType>
401 void
403 ContactEntity& node,
404 ContactEntity& face,
405 const double gap,
406 const double direction[3],
407 const double facet_coordinates[3],
408 VecType& full_contact_force) const
409 {
410 enforcement.EnforceContact<VecType>(node, face, gap, direction, facet_coordinates, full_contact_force);
411 }
412
414 void
415 startTimer(const std::string& str_val)
416 {
417#ifdef NIMBLE_TIME_CONTACT
418 watch_.Start(str_val);
419#endif
420 }
421
423 void
424 stopTimer(const std::string& str_val)
425 {
426#ifdef NIMBLE_TIME_CONTACT
427 watch_.Stop(str_val);
428#endif
429 }
430 //--- Variables
431
433
436 std::size_t total_num_contacts = 0;
437
439
440 bool contact_enabled_ = false;
442
443 std::vector<int> node_ids_;
444 std::vector<double> model_coord_;
445 std::vector<double> coord_;
446 std::vector<double> force_;
447
448 double contact_visualization_model_coord_bounding_box_[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
451
456
461
462 // TODO remove this once enforcement is on device
464 nimble_kokkos::HostContactEntityArrayView("contact_faces_h", 1);
466 nimble_kokkos::HostContactEntityArrayView("contact_nodes_h", 1);
467
469
470 std::unordered_map<std::string, double> timers_;
471#ifdef NIMBLE_TIME_CONTACT
472 nimble::Timer watch_;
473#endif
474
475 std::shared_ptr<ContactInterface> contact_interface;
476};
477
478std::shared_ptr<nimble::ContactManager>
479GetContactManager(std::shared_ptr<ContactInterface> interface, nimble::DataManager& data_manager);
480
481} // namespace nimble
482
483#endif // NIMBLE_MATERIAL_H
Definition nimble_contact_entity.h:126
Definition nimble_contact_entity.h:116
int node_id_4_for_fictitious_node_
Definition nimble_contact_entity.h:578
int node_id_for_node_1_
Definition nimble_contact_entity.h:572
int node_id_for_node_2_
Definition nimble_contact_entity.h:573
NIMBLE_INLINE_FUNCTION void SetNodalContactForces(const double *const contact_force, const double *const N=nullptr)
Distribute input force among node(s) of the entity.
Definition nimble_contact_entity.h:429
@ NODE
Definition nimble_contact_entity.h:121
int node_id_2_for_fictitious_node_
Definition nimble_contact_entity.h:576
CONTACT_ENTITY_TYPE entity_type_
Definition nimble_contact_entity.h:531
int node_id_1_for_fictitious_node_
Definition nimble_contact_entity.h:575
int node_id_3_for_fictitious_node_
Definition nimble_contact_entity.h:577
NIMBLE_INLINE_FUNCTION void ScatterForceToContactManagerForceVector(ArgT &force) const
Definition nimble_contact_entity.h:261
PenaltyContactEnforcement enforcement
Definition nimble_contact_manager.h:438
nimble_kokkos::DeviceContactEntityArrayView contact_nodes_d_
Definition nimble_contact_manager.h:459
static void SimpleClosestPointProjectionSingle(const ContactEntity &node, const ContactEntity &tri, PROJECTION_TYPE *projection_type, ContactEntity::vertex *closest_point, double &gap, double *normal, double tolerance=1.e-8)
Compute the projection of a point onto a triangular face.
Definition nimble_contact_manager.cc:1467
void ResetContactStatus()
Reset the contact status for all entities.
Definition nimble_contact_manager.cc:1623
std::vector< double > coord_
Definition nimble_contact_manager.h:445
nimble_kokkos::DeviceIntegerArrayView node_ids_d_
Definition nimble_contact_manager.h:452
nimble_kokkos::DeviceContactEntityArrayView contact_faces_d_
Definition nimble_contact_manager.h:457
void EnforceNodeFaceInteraction(ContactEntity &node, ContactEntity &face, const double gap, const double direction[3], const double facet_coordinates[3], VecType &full_contact_force) const
Definition nimble_contact_manager.h:402
nimble_kokkos::HostContactEntityArrayView contact_nodes_h_
Definition nimble_contact_manager.h:465
const ContactEntity & getContactNode(size_t i_node) const
Returns a read-only reference to contact node entity.
Definition nimble_contact_manager.cc:722
std::size_t total_num_contacts
Definition nimble_contact_manager.h:436
void GetForces(nimble_kokkos::DeviceVectorNodeView contact_force_d) const
Definition nimble_contact_manager.cc:733
bool ContactEnabled() const
Indicates whether contact is enabled or not.
Definition nimble_contact_manager.h:157
std::vector< double > model_coord_
Definition nimble_contact_manager.h:444
std::shared_ptr< ContactInterface > contact_interface
Definition nimble_contact_manager.h:475
size_t numActiveContactNodes() const
Returns the number of contact nodes "actively" in collision.
Definition nimble_contact_manager.cc:704
nimble::TimeKeeper total_search_time
Definition nimble_contact_manager.h:434
std::unordered_map< std::string, double > timers_
Definition nimble_contact_manager.h:470
ProjectionType
Definition nimble_contact_manager.h:137
@ NODE_OR_EDGE
Definition nimble_contact_manager.h:139
@ UNKNOWN
Definition nimble_contact_manager.h:138
@ FACE
Definition nimble_contact_manager.h:140
nimble_kokkos::ModelData * model_data_
Definition nimble_contact_manager.h:468
void ZeroContactForce()
Zero the contact forces.
Definition nimble_contact_manager.cc:1631
virtual ~ContactManager()=default
Default destructor.
size_t numContactFaces() const
Returns the number of contact faces.
Definition nimble_contact_manager.cc:680
double penalty_parameter_
Definition nimble_contact_manager.h:441
nimble_kokkos::DeviceScalarNodeView coord_d_
Definition nimble_contact_manager.h:454
static void Projection(const ContactEntity &node, const ContactEntity &tri, bool &in, double &gap, double *normal, double *barycentric_coordinates, double tolerance=1.e-8)
Compute the projection of a point onto a triangular face.
Definition nimble_contact_manager.cc:1550
void ApplyDisplacements(nimble_kokkos::DeviceVectorNodeView displacement_d)
Definition nimble_contact_manager.cc:751
static void SkinBlocks(GenesisMesh const &mesh, std::vector< int > const &block_ids, int entity_id_offset, std::vector< std::vector< int > > &skin_faces, std::vector< int > &entity_ids)
Definition nimble_contact_manager.cc:789
nimble_kokkos::DeviceScalarNodeView force_d_
Definition nimble_contact_manager.h:455
void SetPenaltyParameter(double penalty_parameter)
Set the penalty parameter for enforcing contact.
Definition nimble_contact_manager.h:166
void BoundingBox(double &x_min, double &x_max, double &y_min, double &y_max, double &z_min, double &z_max) const
Definition nimble_contact_manager.cc:1208
nimble_kokkos::DeviceScalarNodeView model_coord_d_
Definition nimble_contact_manager.h:453
double contact_visualization_model_coord_bounding_box_[6]
Definition nimble_contact_manager.h:448
std::vector< int > node_ids_
Definition nimble_contact_manager.h:443
NIMBLE_INLINE_FUNCTION void startTimer(const std::string &str_val)
Definition nimble_contact_manager.h:415
void BruteForceBoxIntersectionSearch(std::vector< ContactEntity > const &nodes, std::vector< ContactEntity > const &triangles)
Definition nimble_contact_manager.cc:1267
void ComputeContactForce(int step, bool debug_output)
Definition nimble_contact_manager.h:339
void ClosestPointProjectionSingle(const ContactEntity &node, const ContactEntity &tri, ContactEntity::vertex *closest_point, PROJECTION_TYPE *projection_type, double tolerance)
Definition nimble_contact_manager.cc:1300
void ClosestPointProjection(const ContactEntity *nodes, const ContactEntity *triangles, ContactEntity::vertex *closest_points, PROJECTION_TYPE *projection_types, std::size_t num_elements)
Definition nimble_contact_manager.cc:1279
const ContactEntity & getContactFace(size_t i_face) const
Returns a read-only reference to contact face entity.
Definition nimble_contact_manager.cc:716
void CreateContactNodesAndFaces(std::vector< std::vector< int > > const &primary_skin_faces, std::vector< int > const &primary_skin_entity_ids, std::vector< int > const &secondary_node_ids, std::vector< int > const &secondary_node_entity_ids, std::map< int, double > const &secondary_node_char_lens, ArgT &contact_nodes, ArgT &contact_faces) const
Definition nimble_contact_manager.cc:1045
const std::unordered_map< std::string, double > & getTimers()
Return timing information.
Definition nimble_contact_manager.cc:1665
void WriteVisualizationData(double t)
Write visualization data to Exodus file at time t.
Definition nimble_contact_manager.cc:605
nimble::DataManager & data_manager_
Definition nimble_contact_manager.h:432
nimble_kokkos::HostContactEntityArrayView contact_faces_h_
Definition nimble_contact_manager.h:463
nimble::GenesisMesh genesis_mesh_for_contact_visualization_
Definition nimble_contact_manager.h:449
virtual void ComputeContactForce(int step, bool debug_output, nimble::Viewify< 2 > contact_force)
Compute the contact force.
Definition nimble_contact_manager.cc:396
nimble::TimeKeeper total_enforcement_time
Definition nimble_contact_manager.h:435
virtual void ContactVisualizationWriteStep(double time_current)
Write information about contact.
Definition nimble_contact_manager.cc:596
virtual void InitializeContactVisualization(std::string const &contact_visualization_exodus_file_name)
Initialize contact visualization output.
Definition nimble_contact_manager.cc:432
bool contact_enabled_
Definition nimble_contact_manager.h:440
enum nimble::ContactManager::ProjectionType PROJECTION_TYPE
static void RemoveInternalSkinFaces(GenesisMesh const &mesh, std::vector< std::vector< int > > &faces, std::vector< int > &entity_ids)
Definition nimble_contact_manager.cc:938
void CreateContactEntities(GenesisMesh const &mesh, nimble::VectorCommunicator &mpi_container, std::vector< int > const &primary_block_ids, std::vector< int > const &secondary_block_ids)
Create contact entities between different blocks.
Definition nimble_contact_manager.cc:185
NIMBLE_INLINE_FUNCTION void stopTimer(const std::string &str_val)
Definition nimble_contact_manager.h:424
size_t numActiveContactFaces() const
Returns the number of contact faces "actively" in collision.
Definition nimble_contact_manager.cc:692
double BoundingBoxAverageCharacteristicLengthOverAllRanks() const
Definition nimble_contact_manager.cc:1249
double GetPenaltyForceParam() const noexcept
Return the penalty coefficient for enforcing contact force.
Definition nimble_contact_manager.h:303
nimble::ExodusOutput exodus_output_for_contact_visualization_
Definition nimble_contact_manager.h:450
size_t numContactNodes() const
Returns the number of contact nodes.
Definition nimble_contact_manager.cc:686
ContactManager(std::shared_ptr< ContactInterface > interface, nimble::DataManager &data_manager)
Constructor.
Definition nimble_contact_manager.cc:179
std::vector< double > force_
Definition nimble_contact_manager.h:446
Definition nimble_data_manager.h:70
Definition nimble_exodus_output.h:59
Definition nimble_genesis_mesh.h:59
Definition nimble_timer.h:54
Definition nimble_timer.h:97
Definition nimble_vector_communicator.h:74
Definition nimble_view.h:72
Definition nimble_kokkos_model_data.h:72
void getContactForce(const double penalty, const double gap, const double normal[3], double contact_force[3])
Definition nimble_contact_manager.h:82
Definition nimble_contact_manager.h:68
Field< FieldType::DeviceVectorNode >::View DeviceVectorNodeView
Definition nimble_kokkos_defs.h:585
Kokkos::View< nimble::ContactEntity *, nimble_kokkos::kokkos_layout, nimble_kokkos::kokkos_host > HostContactEntityArrayView
Definition nimble_kokkos_contact_defs.h:17
Kokkos::View< nimble::ContactEntity *, nimble_kokkos::kokkos_layout, nimble_kokkos::kokkos_device > DeviceContactEntityArrayView
Definition nimble_kokkos_contact_defs.h:15
Field< FieldType::DeviceScalarNode >::View DeviceScalarNodeView
Definition nimble_kokkos_defs.h:582
Kokkos::View< int *, kokkos_device > DeviceIntegerArrayView
Definition nimble_kokkos_defs.h:606
Definition kokkos_contact_manager.h:49
std::shared_ptr< nimble::ContactManager > GetContactManager(std::shared_ptr< ContactInterface > interface, nimble::DataManager &data_manager)
Definition nimble_contact_manager.cc:152
#define NIMBLE_INLINE_FUNCTION
Definition nimble_defs.h:50
Definition nimble_contact_manager.h:91
double penalty
Definition nimble_contact_manager.h:130
NIMBLE_INLINE_FUNCTION void EnforceContact(const ContactEntity &node, ContactEntity &face, const double gap, const double normal[3], const double barycentric_coordinates[3], VecType &full_contact_force) const
Definition nimble_contact_manager.h:96
PenaltyContactEnforcement()
Definition nimble_contact_manager.h:92