The following code generates a finite element mesh.

order = 2;
mesh = ToElementMesh[ImplicitRegion[300 < Sqrt[x x + y y], {x, y}], {{0, 1000}, {0, 1000}}, MaxCellMeasure -> 2000, "MaxBoundaryCellMeasure" -> 10,"MeshOrder" -> order, "NodeReordering" -> True]
topol = mesh["MeshElements"][[1, 1]];
nnodes = mesh["Coordinates"];

I need to get the the ids of the nodes that are located in the corners. How can i do that?

enter image description here

  • $\begingroup$ What do you need the ids for? $\endgroup$ – user21 Feb 6 '17 at 6:48

There is Position which almost does what you need out of the box, unfortunately it checks for exact equality while you need only numerical equality. On the other hand the mesh generation doesn't guarantee that the mesh nodes will be close enough to the given coordinates to make Equal consider them equal, so on my computer your solution will fail because:

Nearest[nnodes, {300, 0}]=={300,0}
(* False *)

What I would suggest is a combination of Nearest and Position:

findIds[nodes_, coords_] := Flatten[
  Map[Position[nodes, First@#] &, Nearest[nodes, coords]]

which I think should be somewhat more robust and also a bit faster. Depending on what you are using that for, you might add some error checking...

Here is a slightly changed version that seems to be somewhat faster, at least if the numbers of nodes to find is not too large:

findIds[nodes_, coords_] := Module[{
    nodestofind = Nearest[nodes, coords][[All, 1]]
  Flatten[Position[nodes, Alternatives @@ nodestofind]]

As kglr has mentioned in a comment, since version 11 there is also the possibility to get the index directly from Nearest like this:


Actually using Automatic instead of "Index" would also work, but I think "Index" is a bit clearer and unlike Automatic is documented. Unsurprisingly this is then also by far the fastet of the given alternatives. Defining a function for it would be trivial but almost seems superfluous...

| improve this answer | |
  • $\begingroup$ @ Albert Retey thank you. I have a similar problem in which i want to find all the ids in a specific line, how would you do that? $\endgroup$ – Diogo Feb 4 '17 at 17:35
  • $\begingroup$ i have posted another question in the following link, please take a look: mathematica.stackexchange.com/questions/136961/… $\endgroup$ – Diogo Feb 4 '17 at 17:56
  • 1
    $\begingroup$ (+1) Note that Nearest[nodes -> Automatic, coords, 1] returns the position of the nearest element, without the need for Position. $\endgroup$ – kglr Feb 5 '17 at 13:47
  • $\begingroup$ @kglr: thanks for mentioning that new functionality of Nearest. It is always worth to go back to the documentation of newer versions, I was looking for exactly that functionality a while ago when it was not available yet :-) $\endgroup$ – Albert Retey Feb 5 '17 at 19:46

I found a solution.

  FindIds[nnodes_, coords_] := Block[{idvec, nodetofind},
       idvec = {};
       nodetofind = coords;
          If[nnodes[[i]] == nodetofind[[j]],
            AppendTo[idvec, i];
          , {i, 1, Length[nnodes]}];
        , {j, 1, Length[nodetofind]}];
    nodetofind = {{300, 0}, {0, 300}};
    {hole1, hole2} = FindIds[nnodes, nodetofind]
    nodetofind = {{300, 0}, {1000, 0}};
    {inferiorline1, inferiorline2} = FindIds[nnodes, nodetofind]
    nodetofind = {{0, 300}, {0, 1000}};
    {leftline1, leftline2} = FindIds[nnodes, nodetofind]
| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.