OOFEM 3.0
Loading...
Searching...
No Matches
contactsearch.C
Go to the documentation of this file.
1/*
2 *
3 * ##### ##### ###### ###### ### ###
4 * ## ## ## ## ## ## ## ### ##
5 * ## ## ## ## #### #### ## # ##
6 * ## ## ## ## ## ## ## ##
7 * ## ## ## ## ## ## ## ##
8 * ##### ##### ## ###### ## ##
9 *
10 *
11 * OOFEM : Object Oriented Finite Element Code
12 *
13 * Copyright (C) 1993 - 2025 Borek Patzak
14 *
15 *
16 *
17 * Czech Technical University, Faculty of Civil Engineering,
18 * Department of Structural Mechanics, 166 29 Prague, Czech Republic
19 *
20 * This library is free software; you can redistribute it and/or
21 * modify it under the terms of the GNU Lesser General Public
22 * License as published by the Free Software Foundation; either
23 * version 2.1 of the License, or (at your option) any later version.
24 *
25 * This program is distributed in the hope that it will be useful,
26 * but WITHOUT ANY WARRANTY; without even the implied warranty of
27 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
28 * Lesser General Public License for more details.
29 *
30 * You should have received a copy of the GNU Lesser General Public
31 * License along with this library; if not, write to the Free Software
32 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
33 */
34
35#include "contactsearch.h"
36#include "intarray.h"
37#include "floatarray.h"
38#include "floatarrayf.h"
39#include "floatmatrix.h"
40#include "node.h"
41#include "domain.h"
42#include "fecontactsurface.h"
43#include "contactpoint.h"
44#include "contactpair.h"
45#include <limits>
46
47
48namespace oofem {
49
50
51 ContactSearchAlgorithm_Surface2FESurface :: ContactSearchAlgorithm_Surface2FESurface(FEContactSurface *scs, FEContactSurface *mcs, Domain *d, int sd) : ContactSearchAlgorithm(d)
52{
53 this->slaveContactSurface = scs;
54 this->masterContactSurface = mcs;
55 this->surface_dimension = sd;
56}
57
58
59void
60ContactSearchAlgorithm_Surface2FESurface :: createContactPairs()
61{
62 contactPairs.clear();
63 for ( int slave_ce = 1; slave_ce <= this->slaveContactSurface->giveNumberOfContactElements(); slave_ce++ ) {
64 for ( GaussPoint *gp : * this->slaveContactSurface->giveContactElement_InSet(slave_ce)->giveDefaultIntegrationRulePtr() ) {
65 auto cp_slave = std::make_unique<FEContactPoint_Slave>(this->slaveContactSurface, this->slaveContactSurface->giveContactElement_InSet(slave_ce)->giveNumber(), surface_dimension, gp);
66 auto contactPair = std::make_unique<ContactPair>(std::move(cp_slave));
67 contactPairs.emplace_back(std::move(contactPair));
68 }
69 }
70}
71
72 ContactSearchAlgorithm_Surface2FESurface_3d :: ContactSearchAlgorithm_Surface2FESurface_3d(FEContactSurface *scs, FEContactSurface *mcs, Domain *d) : ContactSearchAlgorithm_Surface2FESurface(scs, mcs, d, 2)
73{
74}
75
76
77void
78ContactSearchAlgorithm_Surface2FESurface_3d :: updateContactPairs(TimeStep *tStep)
79{
80
81 FloatArrayF<3> normalVector, tangentVector1, tangentVector2;
82 for (auto &cp : contactPairs) {
83 auto slavePoint = dynamic_cast<FEContactPoint_Slave*> (cp->giveSlaveContactPoint());
84 //iterate over all contact elements
85 int closestContactElementId = -1;
86 FloatArray contactPointLocalCoordinates;
87 double gap = 0;
88 for ( int i = 1; i <= this->masterContactSurface->giveNumberOfContactElements(); i++ ) {
89 auto contactElement = this->masterContactSurface->giveContactElement_InSet(i);
90 // check if we are not testing the point with its own element
91 if(slavePoint->giveContactElementId() == contactElement->giveNumber()) {
92 break;
93 }
97 /* auto boundingBox = contactElement.giveBoundingBox();
98 if(!boundingBox.contains(node.giveCoordinates())) {
99 continue;
100 } else {*/
101 auto [inElement,localCoords, newGap,normal, t1, t2] = this->masterContactSurface->findContactPointInElement_3d(slavePoint, contactElement, tStep);
102 if(inElement) {
103 //FloatArray globalCoords, nodeCoords;
104 //
105 //contactElement->giveInterpolation()->local2global( globalCoords, localCoords, FEIElementDeformedGeometryWrapper(contactElement, tStep) );
106 //contact when gap is negative !!!
107 if ( closestContactElementId == -1. || newGap < gap ) {
108 //larger gap/penetration found, update it
109 gap = newGap;
110 normalVector = normal;
111 tangentVector1 = -t1;
112 tangentVector2 = -t2;
113 contactPointLocalCoordinates = localCoords;
114 closestContactElementId = contactElement->giveNumber();
115 }
116 }
117 }
118
119 //update contact pairs for each node
120 if(closestContactElementId) {
121 auto master_point = std::make_unique<FEContactPoint_Master>(this->masterContactSurface, closestContactElementId, 2, contactPointLocalCoordinates);
122 cp->setMasterContactPoint(std::move(master_point));
123 cp->setNormalGap(gap);
124 cp->setNormalVector(normalVector);
125 cp->setTangentVector1(tangentVector1);
126 cp->setTangentVector2(tangentVector2);
127
128 }
129 }
130
131}
132
133
134
135 ContactSearchAlgorithm_Surface2FESurface_2d :: ContactSearchAlgorithm_Surface2FESurface_2d(FEContactSurface *scs, FEContactSurface *mcs, Domain *d) : ContactSearchAlgorithm_Surface2FESurface(scs, mcs, d, 1)
136{
137}
138
139
140void
141ContactSearchAlgorithm_Surface2FESurface_2d :: updateContactPairs(TimeStep *tStep)
142{
143
144 FloatArrayF<2> normalVector, tangentVector1;
145 for (auto &cp : contactPairs) {
146 auto slavePoint = dynamic_cast<FEContactPoint_Slave*> (cp->giveSlaveContactPoint());
147 //iterate over all contact elements
148 int closestContactElementId = -1;
149 FloatArray contactPointLocalCoordinates, contactPointGlobalCoordinates;
150 double gap = std::numeric_limits<double>::infinity();
151 for ( int i = 1; i <= this->masterContactSurface->giveNumberOfContactElements(); i++ ) {
152 auto masterContactElement = this->masterContactSurface->giveContactElement_InSet(i);
153 // check if we are not testing the point with its own element
154 if(slavePoint->giveContactElementId() == masterContactElement->giveNumber()) {
155 continue;
156 }
157
161 /* auto boundingBox = contactElement.giveBoundingBox();
162 if(!boundingBox.contains(node.giveCoordinates())) {
163 continue;
164 } else {*/
165 auto [inElement,localCoords, newGap,normal, t1] = this->masterContactSurface->findContactPointInElement_2d(slavePoint, masterContactElement, tStep);
166 if(inElement) {
167 FloatArray globalCoords, nodeCoords;
168 //
169 masterContactElement->giveInterpolation()->local2global( globalCoords, localCoords, FEIElementDeformedGeometryWrapper(masterContactElement, tStep) );
170 //contact when gap is negative!!!
171 if ( closestContactElementId == -1. || newGap < gap ) {
172 //larger gap/penetration found, update it
173 gap = newGap;
174 normalVector = normal;
175 tangentVector1 = t1;
176 contactPointLocalCoordinates = localCoords;
177 contactPointGlobalCoordinates = globalCoords;
178 closestContactElementId = masterContactElement->giveNumber();
179 }
180 }
181 }
182
183 //update contact pairs for each node
184 if(closestContactElementId) {
185 auto masterContactPoint = std::make_unique<FEContactPoint_Master>(this->masterContactSurface, closestContactElementId, 1, contactPointLocalCoordinates);
186 cp->setMasterContactPoint(std::move(masterContactPoint));
187 cp->setNormalGap(gap);
188 cp->setNormalVector(normalVector);
189 cp->setTangentVector1(tangentVector1);
190 }
191 }
192
193}
194
195
196
197} // end namespace oofem
ContactSearchAlgorithm_Surface2FESurface(FEContactSurface *scs, FEContactSurface *mcs, Domain *d, int sd)
std::vector< std::unique_ptr< ContactPair > > contactPairs
Abstract representation of a finite element contact surface.

This page is part of the OOFEM-3.0 documentation. Copyright Copyright (C) 1994-2025 Borek Patzak Bořek Patzák
Project e-mail: oofem@fsv.cvut.cz
Generated at for OOFEM by doxygen 1.15.0 written by Dimitri van Heesch, © 1997-2011