SCOREC / core

parallel finite element unstructured meshes
Other
179 stars 63 forks source link

how are matches defined for entities on the part boundary? #211

Open cwsmith opened 5 years ago

cwsmith commented 5 years ago

Is the attached figure for matched vertices on the part boundary correct? (inkscape source matches.svg.gz )

matches

KennethEJansen commented 5 years ago

I have created a small Simmetrix case to infer what Simmetrix does regarding matching in hopes that, since PUMI is able to convert Simmetrix serial matched mesh to MDS, we can do the same with these small meshes and then see how PUMI handles them as it parts them (remembering now that PUMI cannot read parallel matched meshes from Simmetrix so a slight change from what we discussed on Slack). Here is the path on the viz nodes:

kjansen@viz003: /projects/tools/Models/Box $ ls box-2D5x5.sms box-3D_FaceMatch.sms box_nat.x_t box.smd box.x_t

cwsmith commented 5 years ago

Thank you @KennethEJansen .

For what it is worth, the SimModSuite documentation of EN_matches(...) describes the following in the API for getting a list of matched mesh entities to a given mesh entity ('ent'): "In case of a matched part boundary entity, only the "owned" copy will exist in the list, however the list itself is stored on all copies. Thus if ent is a matched non-original part boundary entity, ent will not exist in the returned list, but its EN_original() will. In all other cases where ent is matched, ent will exist in the returned list."

So, from what I understand, I think EN_matches(...) returns the following for case 1: <ent matchedEnt[,matchedEnt,...]> A A,B B A.B A' A,B B' A,B And for case 2, ent=A returns A,B, and ent=B returns A,B. I'm including 'ent' in the list based on the last sentence of the documentation.

We can confirm this and how pumi processes them with your test cases.

cwsmith commented 5 years ago

The apfSim getMatches(...) call https://github.com/SCOREC/core/blob/51d8d1d1115dacc00573bab88421d5c0f32ebd10/apf_sim/apfSIM.cc#L909-L937 calls EN_matches(...) and removes 'ent', if it exists, from the returned list of matches. Note, 'ent' is assumed to be a pointer to a entity that exists on the calling process/part.

cwsmith commented 5 years ago

Attached is a 2d plate with the top and bottom edges matched, 16 quads, and split to two parts:

plate.tar.gz

The per-part vertex numbering is shown below. Part 0 is on the left and part 1 is on the right.

splitplatevtxids_2p

Running the following grep commands on the debug*.txt files from the tarball lists the matched pairs (see the included debug source code for implementation details).

$ grep 'ent    14' debug0.txt                                                                                                                           
self   0 ent    14 ent_isOwned  1 peer  0 match     4
self   0 ent    14 ent_isOwned  1 peer  1 match     5
self   0 ent    14 ent_isOwned  1 peer  1 match    14
$ grep 'ent     4' debug0.txt                                                                                                                
self   0 ent     4 ent_isOwned  1 peer  0 match    14
self   0 ent     4 ent_isOwned  1 peer  1 match     5
self   0 ent     4 ent_isOwned  1 peer  1 match    14
$ grep 'ent     5' debug1.txt 
self   1 ent     5 ent_isOwned  0 peer  0 match     4
self   1 ent     5 ent_isOwned  0 peer  0 match    14
self   1 ent     5 ent_isOwned  0 peer  1 match    14
$ grep 'ent    14' debug1.txt 
self   1 ent    14 ent_isOwned  0 peer  0 match     4
self   1 ent    14 ent_isOwned  0 peer  0 match    14
self   1 ent    14 ent_isOwned  0 peer  1 match     5

This shows that we have the following matching construction for case 1:

matchescase1

KennethEJansen commented 5 years ago

Riccardo confirms that he is numbering elements in z first so, for the smallest case we gave you to debug, which has 50x50x50 elements, using my formula on the other ticket, as long as you choose n_parts=2500/k
where k is an integer that results in an integer value for n_parts, you will be guaranteed to have part boundaries like the case you have proven your code to handle (e.g., no staircase part boundaries). We tested this with n_parts =5 and got the expected 5 slab partitions that do equal inertial cuts of the x axis (e.g., 12,500 elements per slab with are nodes from the first six yz planes stepped in x). I think that is the only case we have given you but we can make the others work. I suppose we do need to be mindful of the fact that BG is power of 2 based machines so, in this case we would prefer cutting it into 4 slabs instead (2500 is still divisible by 4). In general we can live with the constraint that

NumElx NumEly=16 SomeInteger

so that our initial partition can be a 16 for cases that are around 1B or replace 16 by 8 for meshes half that size (this is because we earlier proved we could part the 1B case on 16 but not 8 Cooley nodes (see other ticket)).

rickybalin commented 5 years ago

Here are the files for the bump. One set of files is for a mesh with 1 element only in the spanwise direction, the other set is for a mesh with 4 elements in that direction.

(rename to *.tgz) Bump4elmZ.zip Bump1elmZ.zip

cwsmith commented 5 years ago

The attached tarballs have headers added to the connectivity files for mesh dimension and topology.

Bump4elmZ.tar.gz Bump1elmZ.tar.gz

@rickybalin It looks like the .match files only encode one side of the match pair. For example,

$ head -n 2 2DGaussHill_test.match 
1 2
2 -1
$ head -n5 2DGaussHill_test_4elm.match 
1 5
2 -1
3 -1
4 -1
5 -1

Would you please upload .match files that have each vertex in the matched pair listing the id of the other vertex?

rickybalin commented 5 years ago

Sorry about that, I used an old script to make those. These have the right .match files.

correctedMatches.tar.gz

cwsmith commented 5 years ago

Looks good. Thank you.

cwsmith commented 5 years ago

So far so good. The image below shows each mesh (left 1 elm, right 4 elms) created with four parts. bumps