From a92b7a1b0cda68dc4fa9c9486d4efe924ec52879 Mon Sep 17 00:00:00 2001 From: "Jostein R. Natvig" Date: Wed, 25 Jan 2012 10:49:49 +0100 Subject: [PATCH] Copy modifications to reorder-related codes from MRST repository branches/mrst-reorg/mex/reorder-C, revision 8955. The changes are: (1) addition of documentation of input arguments in tarjan.c and (2) an MIT licence header (codes originated in a PhD project). --- opm/core/transport/reorder/nlsolvers.c | 22 ++++- opm/core/transport/reorder/nlsolvers.h | 22 ++++- opm/core/transport/reorder/tarjan.c | 127 ++++++++++++++++++------- opm/core/transport/reorder/tarjan.h | 27 +++++- 4 files changed, 156 insertions(+), 42 deletions(-) diff --git a/opm/core/transport/reorder/nlsolvers.c b/opm/core/transport/reorder/nlsolvers.c index b521a064..2f958702 100644 --- a/opm/core/transport/reorder/nlsolvers.c +++ b/opm/core/transport/reorder/nlsolvers.c @@ -1,4 +1,24 @@ -/* Copyright 2011 (c) Jostein R. Natvig */ +/* +Copyright (C) 2012 (c) Jostein R. Natvig + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ #include #include diff --git a/opm/core/transport/reorder/nlsolvers.h b/opm/core/transport/reorder/nlsolvers.h index 40de92d1..a21b1333 100644 --- a/opm/core/transport/reorder/nlsolvers.h +++ b/opm/core/transport/reorder/nlsolvers.h @@ -1,4 +1,24 @@ -/* Copyright 2011 (c) Jostein R. Natvig */ +/* +Copyright (C) 2012 (c) Jostein R. Natvig + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ #ifndef NLSOLVERS_H #define NLSOLVERS_H diff --git a/opm/core/transport/reorder/tarjan.c b/opm/core/transport/reorder/tarjan.c index dd4290d3..9150c209 100644 --- a/opm/core/transport/reorder/tarjan.c +++ b/opm/core/transport/reorder/tarjan.c @@ -1,4 +1,24 @@ -/* Copyright 2011 (c) Jostein R. Natvig */ +/* +Copyright (C) 2012 (c) Jostein R. Natvig + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ #include #include @@ -14,49 +34,70 @@ static int min(int a, int b){ return a < b? a : b;} -/* Improved (or obfuscated) version uses less memory - * - * Use end of P and Q as stack: - * push operation is *s--=elm, - * pop operation is elm=*++s, - * peek operation is *(s+1) +/* + Compute the strong components of directed graph G(edges, vertices), + return components in reverse topological sorted sequence. + Complexity O(|vertices|+|edges|). See "http://en.wikipedia.org/wiki/ + Tarjan's_strongly_connected_components_algorithm". + + nv - number of vertices + + ia,ja - adjacency matrix for directed graph in compressed sparse row + format: vertex i has directed edges to vertices ja[ia[i]], + ..., ja[ia[i+1]-1]. + + vert - permutation of vertices into topologically sorted sequence of + strong components (i.e., loops). + + comp - pointers to start of each strongly connected component in + vert, the i'th component has vertices vert[comp[i]], ..., + vert[comp[i+1]-1]. + + ncomp - number of strong components. + + work - block of memory of size 3*nv*sizeof(int). */ + +/*--------------------------------------------------------------------*/ void -tarjan (int size, int *ia, int *ja, int *P, int *Q, int *ncomp, - int *work) +tarjan (int nv, const int *ia, const int *ja, int *vert, int *comp, + int *ncomp, int *work) /*--------------------------------------------------------------------*/ { + /* Hint: end of VERT and COMP are used as stacks. */ + enum {DONE=-2, REMAINING=-1}; - int c,v,seed,child; - int i; + int c, v, seed, child; + int i; - int *stack = Q + size, *bottom = stack; - int *cstack = P + size-1, *cbottom = cstack; + int *stack = comp + nv; + int *bottom = stack; + int *cstack = vert + nv-1; + int *cbottom = cstack; + int t = 0; + int pos = 0; - int t = 0; - int pos = 0; - - int *time = work; - int *link = (int *) time + size; - int *status = (int*) link + size; /* dual usage... */ + int *time = work; + int *link = (int *) time + nv; + int *status = (int *) link + nv; /* dual usage... */ (void) cbottom; - memset(work, 0, 3*size * sizeof *work); - memset(P, 0, size * sizeof *P ); - memset(Q, 0, (size+1) * sizeof *Q ); + memset(work, 0, 3*nv * sizeof *work); + memset(vert, 0, nv * sizeof *vert ); + memset(comp, 0, (nv+1) * sizeof *comp ); - /* Init status all nodes */ - for (i=0; i= -2); if (status[c] == REMAINING) { - status[c] = ia[c+1]-ia[c]; /* number of descendants of c */ + /* number of descendants of c */ + status[c] = ia[c+1]-ia[c]; time[c] = link[c] = t++; - *cstack-- = c; /* push c on strongcomp stack */ + + /* push c on strongcomp stack */ + *cstack-- = c; } @@ -95,17 +141,22 @@ tarjan (int size, int *ia, int *ja, int *P, int *Q, int *ncomp, { assert (cstack != cbottom); - v = *++cstack; /* pop strong component stack */ + /* pop strong component stack */ + v = *++cstack; status[v] = DONE; - P[pos++] = v; /* store vertex in P */ + + /* store vertex in VERT */ + vert[pos++] = v; } while ( v != c ); - *Q++ = pos; /* store end point of component */ + /* store end point of component */ + *comp++ = pos; ++*ncomp; } - ++stack; /* pop c */ + /* pop c */ + ++stack; if (stack != bottom) { @@ -121,11 +172,13 @@ tarjan (int size, int *ia, int *ja, int *P, int *Q, int *ncomp, assert(status[c] > 0); child = ja[ia[c] + status[c]-1]; - --status[c]; /* Decrement descendant count of c*/ + /* decrement descendant count of c*/ + --status[c]; if (status[child] == REMAINING) { - *stack-- = child; /* push child */ + /* push child */ + *stack-- = child; } else if (status[child] >= 0) diff --git a/opm/core/transport/reorder/tarjan.h b/opm/core/transport/reorder/tarjan.h index b46535ee..f331aaed 100644 --- a/opm/core/transport/reorder/tarjan.h +++ b/opm/core/transport/reorder/tarjan.h @@ -1,4 +1,24 @@ -/* Copyright 2011 (c) Jostein R. Natvig */ +/* +Copyright (C) 2012 (c) Jostein R. Natvig + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ #ifndef TARJAN_H_INCLUDED #define TARJAN_H_INCLUDED @@ -6,8 +26,9 @@ extern "C" { #endif - void tarjan (int size, int *ia, int *ja, int *rowP, int *P, - int *ncomp, int *work); + void + tarjan (int nv, const int *ia, const int *ja, int *vert, int *comp, + int *ncomp, int *work); #ifdef __cplusplus }