I'm writing a routine using FEMAP API and I've needed to create an array containing pairs of nodes IDs, being the first node from node-set1 and the second from the node-set2. The criterion of choice is that the node of node-set2 must be the closest of the node from node-set1. I've written a For... Next loop inside another For.. Next loop where a "i" node of set1 had the distance calculated to all "j" nodes of set2. The pair i-j that had the minimum distance between them was transferred to an array and this process was repeated until the For... Next loop walks through all "i" nodes.
This routine works properly and does exactly what is expected but when there are many nodes in the set1 and set2 I've realized that the it demands lots of time to run. I'd like to know if there are some function in FEMAP API that does what I needed faster. I looked up in the API Reference Manual and the method GetClosest almost does what I needed. The problem is that it get the closest node among all the model's nodes and I need that it get the closest node among the nodes of a specific set.
Could somebody help me?
Use feCheckCoincidentNode3, it'll automatically find the pairs you mention and replace your entire For...Next loop.
A more advanced and generalised method would be if we had access in the API to an internal KDTree to be able to find, for any location, the N nearest neighbours nodes. This would open huge possibilities. Or add math libraries with KDTree/nearest neighbour search routines.
Thank you for your answer!
I've already had read about the feCheckCoincidentNode. Unfortunately it doesn't satisfy completely my needs because it demands a tolerance as input. The tolerance should be unimportant once I need to find just the closest node. If I input a small value for tolerance, it is possible that none coincident node would be found; if I input a great value, it is possible that a node in set1 would find more than one node in set2. Is there some alternative to overcome the tolerance issue?
You're truly dealing with nearest neighbour considerations. If the coincident node tool doesn't work for you, I would say the best way is to add a math library and use KDTree methods. If you're looking for execution speed this will be the best.
I've been using ALGLIB v2.6 VB6 version for quite a while now for small macros (v3.8 otherwise, but that's a little more complicated).
It's not hard to use:
1) download the free version 2.6, store the .bas files somewhere
2) The file you're intereseted in is "nearestneighbour.bas". At the top of the file, add the following lines:
(replace with your file path of course). The idea is that nearest neighbour needs methods located in the files ap.bas and tsort.bas
3) at the top of your FEMAP macro (in the API window) add:
and voila! checkout the ALGLIB VB6 ref manual to understand how to implement your search. It is well documented and easy to understand, much like the FEMAP API doc.
It can seem tedious at first, but combining FEMAP's API with strong math tools like ALGLIB opens a whole other level of FEA coding.
I obviously haven't seen your code, but one of the things that can cause performance issues is simply the number of calls to API functions/properties. This is not because of FEMAP, but just because of the rather significant overhead of any OLE/COM call. When you mention that you have a large number of nodes that you are then comparing against another large set of nodes, I can envision lots of calls to "Get" and checking coordinates. One thing that might help you significantly is to make a call to "GetCoordArray" on the Node object for each of the sets of nodes. This will give you back arrays of the nodal IDs and coordinates which you can then use to do all of your comparisons without doing any further API calls. Depending on your original code, you might find this makes orders of magnitudes improvements.
I implemented the KDTree routine but it wasn't so fast as I expect. Maybe because its query seeks the nearest neighbor for a point at a time. Thus i had to put the query inside a For... Next... loop and this process spends nearly so much time as measure the distance between each point combination. It was probably because when the API calls a Function the time for walk through a certain number of lines is greater than if this lines were written inside the routine. I think that's the reason... Anyway, i thank you because it gave me the opportunity of learn something new.