← Back to team overview

dolfin team mailing list archive

Re: Rivara bundle (was: Re: new refinement method)

 

On 13/01/09 03:31 PM, Bartosz Sawicki wrote:
On 12/01/09 05:41 PM, Johan Jansson wrote:
Bartosz Sawicki wrote:

On 09/01/09 09:38 AM, Johan Jansson wrote:
Hi!

This looks interesting, could you please post references to the papers you mentioned about the algorithm?
Basic concept is from Rivara, but I'd like to avoid recursive algorithms, which has usually efficiency problems.

I don't think recursive algorithms have efficiency problems, what do you mean by that? Quicksort is a recursive algorithm for example, and it's one of the fastest sorting algorithms.

You are right, recursive can be very fast. I've found idea of iterative Rivara, which seems easy to implement and robust - so I implemented it.
I'm not convinced that iterative is better than recursive, or opposite.

I've found in some papers [1], where they use similar algorithm but with iteration procedure. Propably something like this is also implemented in FEtk.org (GAMer package). I write "probably" because the code is still unpublished, and I can't find any documentation about it.

[1] N. A. Baker, D. Sept, M. J. Holst, J. A. McCammon: The adaptive multilevel finite element solution of the Poisson–Boltzmann equation on massively parallel computers,IBM J. RES. & DEV. VOL. 45 NO. 3/4 MAY/JULY 2001
Thanks for the reference, I'll look this paper up.

On this paper they only mention that they use iterative bisection algorithm. I could find anything more about iterative version of Rivara.

Algorithm with I've implemented. It wasn't directly taken from any paper:

  while( there are any marked cells ):
     forech cell which is marked:
        find the longest edge
        if the edge hasn't been bisected:
           bisect longest edge e
           remember bisected edge and new vertex
        else :
           use vertex which was remembered
        bisect cell
     foreach bisected edge:
        mark all cells which incidence the edge

The weak point of the algorithm is the storing of bisected edges, and serching in them. I use double index STL mapping for that purpose - which works pretty well, but that's the slowest part of the algorithm.

I have some ideas, which can make it faster, but it hasn't been tested yet. Stay tuned ...

The mesh quality is fine, because _only the longest edge_ is bisected.

Ok, good! I see that the algorithm you've implemented is indeed an iterative variant of the Rivara algorithm. I think this could be very useful to know. But as you mention your implementation has some performance issues, could it also be because of the mesh re-initialization (connectivity) in each iteration?

You are deeply right. mesh.init(1) takes a lot of time - I think that it is possible to completely eliminate replace edge MeshFunction with map. It should definitely speed up the algorithm.


Here is a bundle of the Rivara refinement:

http://www.csc.kth.se/~jjan/dolfin-transfer/rivara.bundle

Which exists as:

dolfin/mesh/RivaraRefinement.cpp

together with a performance test in:

sandbox/refinement-perf

You can run the test as:

./demo rivara

for the recursive Rivara refinement and:

./demo iterative-Rivara

for the iterative Rivara refinement.

I realize the iterative version is an early implementation, but these are the times I get on my computer:

recursive Rivara: 2.3s
iterative Rivara: 416s

So the recursive implementation is over 100 times faster...

That's really impressive. But I would rather conclude that my implementation is 100 times slower. As you've mentioned, I haven't used tricky, dynamic mesh structure, so a lot of time is lost in every iteration for new mesh object creation. Computation of mesh connectivity for edges is also time consuming.

I'll try to improve efficiency, but I'm afraid that your time is unbeatable.


Is it really only the map which makes the iterative version so slow, or could it be something simple? Perhaps a re-implementation with a dynamic mesh as in my implementation would speed it up?

I'm sure you are right, but do you think that it is worth to have two implementation of nearly the same algorithm?


I've just checked what is worth my iterative algorithm. I eliminated edge MeshFunction - what decreases required time more that two times.

Was:
>> recursive Rivara: 2.2s
>> iterative Rivara: 406s

Is:
>> recursive Rivara: 2.2s
>> iterative Rivara: 130s


Speed up is visible, but your clever recursive version with dynamic meshes is out of reach. You did really good job. The only advantage of my iterative algorithm is simply implementation, but nothing more.

I strongly suggest is to switch default Mesh::refine() into the new, recursive algorithm.

New DMesh (or DynamicMesh) class can be useful for coarsening, or other local mesh modification. I would move it into separate file.

BArtek








References