@@ -86,6 +86,7 @@ void SolidMechanicsMortarContact::implicitStepSetup( real64 const & time_n,
8686 MeshLevel & mesh,
8787 string_array const & )
8888 {
89+ // naive way to assign master and slave mesh levels
8990 if (meshName == " meshMaster" ){
9091 this ->m_meshMaster = &mesh;
9192 }
@@ -94,25 +95,14 @@ void SolidMechanicsMortarContact::implicitStepSetup( real64 const & time_n,
9495 this ->m_meshSlave = &mesh;
9596 }
9697
97- // FaceManager const & faceManager = mesh.getFaceManager();
9898 ElementRegionManager const & elemManager = mesh.getElemManager ();
9999
100- // Get the topology of all faces in the grid
101- // ArrayOfArraysView< localIndex const > const faceToNodeMap = faceManager.nodeList().toViewConst();
102- // arrayView2d< double const > const surfaceCentroid = faceManager.faceCenter().toViewConst();
103-
104- // Get mortar surface region
105- // FaceElementSubRegion const & subRegion = region.getUniqueSubRegion< FaceElementSubRegion >();
106- // arrayView2d< localIndex const > const elemsToFaces = subRegion.faceList().toViewConst();
107-
108- std::cout << " Processing interface: " << meshName << std::endl;
109100 elemManager.forElementSubRegions < FaceElementSubRegion >([&](const FaceElementSubRegion & subRegion )
110101 {
111-
112- // assign surface to master or slave depending on object path
102+ // assign surface to master or slave depending on object path (again, naive)
113103 string surfacePath = subRegion.getPath ();
114104 if (surfacePath.find (" surfaceSlave" ) != std::string::npos){
115- GEOS_ERROR_IF (m_surfaceSlave != nullptr ," Slve surface has already been assigned." );
105+ GEOS_ERROR_IF (m_surfaceSlave != nullptr ," Slave surface has already been assigned." );
116106 this ->m_surfaceSlave = &subRegion;
117107 }
118108
@@ -122,83 +112,12 @@ void SolidMechanicsMortarContact::implicitStepSetup( real64 const & time_n,
122112 }
123113 });
124114
125-
126- // loop in the subRegions (only one for now)
127- // get map from surface in surfaceRegion to face in FaceManager
128- // arrayView2d< localIndex const > const elemsToFaces = subRegion.faceList().toViewConst();
129-
130- // loop over each surface in the mortar interface
131- // forAll< parallelHostPolicy >( subRegion.size(), [=] ( localIndex const ksurf )
132- // {
133- // inspect the surfaces and avalilable informations:
134- // print node indices, coordinates, centroid
135- // localIndex const kface = elemsToFaces[ksurf][0];
136- // localIndex const numNodesPerFace = faceToNodeMap.sizeOfArray( kface );
137-
138- // std::cout << "SURFACE " << ksurf << std::endl;
139- /*
140- std::cout << "Surface centroid: ";
141- for (int i = 0; i < 3; ++i) {
142- std::cout << surfaceCentroid[kface][i] << " ";
143- }
144- std::cout << "Nodes list: ";
145- for (int jn = 0; jn < numNodesPerFace; ++jn) {
146- std::cout << faceToNodeMap[kface][jn] << " ";
147- }
148- std::cout << std::endl;
149- */
150- // });
151115 } );
152116
153117
154-
155-
156-
157118 std::cout << " Processing master/slave connectivity" << std::endl;
158119
159- std::unique_ptr<TreeNodeMortar> treeMaster = std::make_unique<TreeNodeMortar>();
160- std::unique_ptr<TreeNodeMortar> treeSlave = std::make_unique<TreeNodeMortar>();
161-
162- // list of surfaces of master root
163- array1d<localIndex> surfRootMaster (m_surfaceMaster->size ()) ;
164- array1d<localIndex> surfRootSlave (m_surfaceSlave->size ()) ;
165-
166- for (localIndex i=0 ; i < m_surfaceMaster->size (); ++i)
167- {
168- surfRootMaster (i) = i;
169- }
170-
171- for (localIndex i=0 ; i < m_surfaceSlave->size (); ++i)
172- {
173- surfRootSlave (i) = i;
174- }
175-
176- // create binary trees recursively
177- std::cout << " Populating master tree" << std::endl;
178- treeMaster->createNode (*m_meshMaster,*m_surfaceMaster,surfRootMaster);
179- std::cout << " Populating slave tree" << std::endl;
180- treeSlave->createNode (*m_meshSlave,*m_surfaceSlave,surfRootSlave);
181-
182- // prepare connectivitiy map slave -> master
183- localIndex nSurfSlave = m_surfaceSlave->size ();
184- m_connectivityMap.resize (nSurfSlave);
185-
186- // populate connectivity map
187- contactSearch (treeSlave,treeMaster);
188-
189- for (localIndex i=0 ; i<nSurfSlave; ++i)
190- {
191- localIndex N = m_connectivityMap.sizeOfArray (i);
192- std::cout << " SLAVE ELEMENT: " << i << std::endl;
193- std::cout << " N = " << N << " MASTER ELEMENT:" ;
194- for (localIndex j=0 ; j<N; ++j)
195- {
196- std::cout << " " << m_connectivityMap[i][j];
197- }
198- std::cout << std::endl;
199- std::cout << " __________________________________________" << std::endl;
200- }
201-
120+ this ->getConnectivityMap ();
202121
203122 // ////////////////////////////////////////////////////////////////////////////////
204123 GEOS_ERROR (" Mortar solver is not implemented yet. " );
@@ -273,13 +192,60 @@ void SolidMechanicsMortarContact::updateState( DomainPartition & domain )
273192 GEOS_UNUSED_VAR ( domain );
274193}
275194
195+ void SolidMechanicsMortarContact::getConnectivityMap ()
196+ {
197+ // using smart pointers for the trees
198+ std::unique_ptr<TreeNodeMortar> treeMaster = std::make_unique<TreeNodeMortar>();
199+ std::unique_ptr<TreeNodeMortar> treeSlave = std::make_unique<TreeNodeMortar>();
200+
201+ // progressive list of surfaces to create tree roots
202+ array1d<localIndex> surfRootMaster (m_surfaceMaster->size ()) ;
203+ array1d<localIndex> surfRootSlave (m_surfaceSlave->size ()) ;
204+
205+ for (localIndex i=0 ; i < m_surfaceMaster->size (); ++i)
206+ {
207+ surfRootMaster (i) = i;
208+ }
209+
210+ for (localIndex i=0 ; i < m_surfaceSlave->size (); ++i)
211+ {
212+ surfRootSlave (i) = i;
213+ }
214+
215+ // create binary trees recursively
216+ std::cout << " Populating master tree" << std::endl;
217+ treeMaster->createNode (*m_meshMaster,*m_surfaceMaster,surfRootMaster);
218+ std::cout << " Populating slave tree" << std::endl;
219+ treeSlave->createNode (*m_meshSlave,*m_surfaceSlave,surfRootSlave);
220+
221+ // initialize connectivity map
222+ localIndex nSurfSlave = m_surfaceSlave->size ();
223+ m_connectivityMap.resize (nSurfSlave);
224+
225+ // perform contact search and populate connectivity map
226+ contactSearch (treeSlave,treeMaster);
227+
228+ for (localIndex i=0 ; i<nSurfSlave; ++i)
229+ {
230+ localIndex N = m_connectivityMap.sizeOfArray (i);
231+ std::cout << " SLAVE ELEMENT: " << i << std::endl;
232+ std::cout << " MASTER ELEMENT:" ;
233+ for (localIndex j=0 ; j<N; ++j)
234+ {
235+ std::cout << " " << m_connectivityMap[i][j];
236+ }
237+ std::cout << std::endl;
238+ std::cout << " __________________________________________" << std::endl;
239+ }
240+ }
241+
276242void SolidMechanicsMortarContact::contactSearch (std::unique_ptr<TreeNodeMortar> const & nodeSlave, std::unique_ptr<TreeNodeMortar> const & nodeMaster)
277243{
278244 if (!checkIntersection (nodeSlave,nodeMaster)) return ;
279245
280246 if ((nodeSlave->isLeaf ) && (nodeMaster->isLeaf ))
281247 {
282- std::cout << " found intersection between slave " << nodeSlave->leafId << " and master " << nodeMaster->leafId << std::endl;
248+ // std::cout << "found intersection between slave " << nodeSlave->leafId << " and master " << nodeMaster->leafId << std::endl;
283249 m_connectivityMap.emplaceBack (nodeSlave->leafId ,nodeMaster->leafId );
284250 return ;
285251 }
@@ -325,7 +291,6 @@ void TreeNodeMortar::createNode(MeshLevel const & mesh,
325291 ArrayOfArraysView< localIndex const > const & faceToNodeMap = faceManager.nodeList ().toViewConst ();
326292 arrayView2d< double const > const surfCenter = faceManager.faceCenter ().toViewConst ();
327293 localIndex nSurf = surfList.size ();
328- std::cout << " NSurfaces = " << nSurf << std::endl;
329294 arrayView2d<double const > const coords = nodeManager.referencePosition ();
330295
331296 double const pP[3 ][9 ] = POLYTOP_PRIMITIVES;
@@ -339,55 +304,58 @@ void TreeNodeMortar::createNode(MeshLevel const & mesh,
339304 for (localIndex j=0 ; j<nNodes; ++j)
340305 {
341306 localIndex id = faceToNodeMap[kface][j];
342- // std::cout << coords[id][0] << " " << coords[id][1] << " " << coords[id][2] << std::endl;
307+
343308 for (localIndex k = 0 ; k<9 ; ++k)
344309 {
345310 real64 P = coords[id][0 ]*pP[0 ][k] +
346- coords[id][1 ]*pP[1 ][k] +
347- coords[id][2 ]*pP[2 ][k];
348- if (P < this ->polytop [2 *k]) this ->polytop [2 *k] = P; // store minimum primitive
349- if (P > this ->polytop [2 *k+1 ]) this ->polytop [2 *k+1 ] = P; // store maximum primitive
311+ coords[id][1 ]*pP[1 ][k] +
312+ coords[id][2 ]*pP[2 ][k];
313+ // store minimum polytop primitive
314+ if (P < this ->polytop [2 *k]) this ->polytop [2 *k] = P;
315+ // store maximum polytop primitive
316+ if (P > this ->polytop [2 *k+1 ]) this ->polytop [2 *k+1 ] = P;
350317 }
351318 }
352319 }
353320
354- // get maximum polytop direction
321+ // get direction of polytop maximum size
355322 localIndex dir = 0 ;
356323 real64 diff = -1 ;
357324 for (localIndex k = 0 ; k<9 ; ++k)
358325 {
326+ // add a small tolerance to avoid degenerate boxes
359327 real64 d = polytop[2 *k+1 ] - polytop[2 *k] + 1e-3 ;
360- // expand the polytop
328+
329+ // expand the polytop for safety
361330 polytop[2 *k] -= BOUNDING_BOX_EXPANSION*d;
362331 polytop[2 *k+1 ] += BOUNDING_BOX_EXPANSION*d;
332+
363333 if (d > diff)
364334 {
365335 dir = k;
366336 diff = d;
367337 }
368- std::cout << this ->polytop [2 *k] << " " << this ->polytop [2 *k+1 ] << std::endl;
369338 }
370339
371340 if (surfList.size () == 1 ) // leaf node
372341 {
373342 this -> isLeaf = true ;
374343 this -> leafId = surfList[0 ];
375- std::cout << " LEAF FOUND - surface: " << leafId << std::endl;
376344 return ;
377345 }
378346
379-
380347 // split the surface list into left and right child
381348 std::vector<real64> surfacePrimitive (nSurf);
382349 for (localIndex i=0 ; i<nSurf; ++i)
383350 {
384- localIndex kface = elemsToFaces[surfList[i]][0 ];
385- surfacePrimitive[i] = surfCenter[kface][0 ]*pP[0 ][dir] +
351+ // compute the polytopal primitives of the surface centroids
352+ localIndex kface = elemsToFaces[surfList[i]][0 ];
353+ surfacePrimitive[i] = surfCenter[kface][0 ]*pP[0 ][dir] +
386354 surfCenter[kface][1 ]*pP[1 ][dir] +
387355 surfCenter[kface][2 ]*pP[2 ][dir];
388356 }
389357
390- // get median of surface centroid primitives
358+ // get median m of surface centroid primitives
391359 std::vector<real64> surfSort = surfacePrimitive;
392360 std::sort (surfSort.begin (), surfSort.end ());
393361 real64 m = (nSurf % 2 == 1 ) ? surfSort[nSurf / 2 ] : (surfSort[nSurf / 2 - 1 ] + surfSort[nSurf / 2 ]) / 2.0 ;
@@ -401,6 +369,7 @@ void TreeNodeMortar::createNode(MeshLevel const & mesh,
401369 (surfacePrimitive[i] <= m) ? surfLeft.emplace_back (surfList[i]) : surfRight.emplace_back (surfList[i]);
402370 }
403371
372+ /*
404373 for (localIndex i = 0; i < surfLeft.size(); ++i)
405374 {
406375 std::cout << "Left child" << std::endl;
@@ -412,10 +381,10 @@ void TreeNodeMortar::createNode(MeshLevel const & mesh,
412381 std::cout << "Right child" << std::endl;
413382 std::cout << surfRight[i] << std::endl;
414383 }
415-
416384 std::cout << "_____________________________________________" << std::endl;
385+ */
417386
418- // create child recursively
387+ // create left and right child recursively
419388 this ->left = std::make_unique<TreeNodeMortar>();
420389 this ->left ->createNode (mesh,surf,surfLeft);
421390 this ->right = std::make_unique<TreeNodeMortar>();
0 commit comments