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...

  • $\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$ 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]

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.