Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
SWIFTsim
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Deploy
Releases
Model registry
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
SWIFT
SWIFTsim
Commits
91f57f53
Commit
91f57f53
authored
4 years ago
by
Bert Vandenbroucke
Browse files
Options
Downloads
Patches
Plain Diff
Voronoi grid now stores per cell interaction lists of pairs that share an interface.
parent
c0b0a3b6
No related branches found
No related tags found
No related merge requests found
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
src/shadowfax/voronoi.h
+145
-25
145 additions, 25 deletions
src/shadowfax/voronoi.h
with
145 additions
and
25 deletions
src/shadowfax/voronoi.h
+
145
−
25
View file @
91f57f53
...
@@ -32,6 +32,36 @@
...
@@ -32,6 +32,36 @@
#include
<string.h>
#include
<string.h>
/**
* @brief Voronoi interface.
*
* An interface is a connection between two neighbouring Voronoi cells. It is
* completely defined by the indices of the generators that generate the two
* neighbouring cells, a surface area and a midpoint position.
*/
struct
voronoi_pair
{
/*! Index of the generator on the left of the interface (always a particle
* within the local cell). */
int
left
;
/*! Index of the generator on the right of the interface (can be a local
* particle, but also a particle in a neighbouring cell). */
int
right
;
/*! Surface area of the interface. */
double
surface_area
;
/*! Midpoint of the interface. */
double
midpoint
[
2
];
#ifdef VORONOI_STORE_CONNECTIONS
/*! First vertex of the interface. */
double
a
[
2
];
/*! Second vertex of the interface. */
double
b
[
2
];
#endif
};
/**
/**
* @brief Voronoi grid.
* @brief Voronoi grid.
*
*
...
@@ -85,6 +115,10 @@ struct voronoi {
...
@@ -85,6 +115,10 @@ struct voronoi {
/*! @brief Length of each edge connection. */
/*! @brief Length of each edge connection. */
double
*
face_areas
;
double
*
face_areas
;
struct
voronoi_pair
*
pairs
[
27
];
int
pair_index
[
27
];
int
pair_size
[
27
];
/*! @brief Number of connections. */
/*! @brief Number of connections. */
int
connection_index
;
int
connection_index
;
...
@@ -94,6 +128,69 @@ struct voronoi {
...
@@ -94,6 +128,69 @@ struct voronoi {
int
connection_size
;
int
connection_size
;
};
};
/**
* @brief Compute the midpoint and surface area of the face with the given
* vertices.
*
* @param ax, ay, bx, by Face vertices.
* @param result Midpoint of the face.
* @return Surface area of the face.
*/
static
inline
double
voronoi_compute_midpoint_area_face
(
double
ax
,
double
ay
,
double
bx
,
double
by
,
double
*
result
)
{
result
[
0
]
=
0
.
5
*
(
ax
+
bx
);
result
[
1
]
=
0
.
5
*
(
ay
+
by
);
double
sx
=
bx
-
ax
;
double
sy
=
by
-
ay
;
return
sqrt
(
sx
*
sx
+
sy
*
sy
);
}
/**
* @brief Add a two particle pair to the grid.
*
* The grid connectivity is stored per cell sid: sid=0 corresponds to particle
* pairs encountered during a self task (both particles are within the local
* cell), while sid=1-26 correspond to particle interactions for which the right
* neighbour is part of one of the 26 neighbouring cells.
*
* For each pair, we compute and store all the quantities required to compute
* fluxes between the Voronoi cells: the surface area and midpoint of the
* interface.
*
* @param v Voronoi grid.
* @param sid Index of the cell list in which the pair is stored.
* @param lid Index of the left particle within its cell (the cell linked to
* this grid).
* @param rid Index of the right particle within cell sid.
* @param ax,ay,bx,by Vertices of the interface.
*/
static
inline
void
voronoi_add_pair
(
struct
voronoi
*
restrict
v
,
int
sid
,
int
lid
,
int
rid
,
double
ax
,
double
ay
,
double
bx
,
double
by
)
{
if
(
v
->
pair_index
[
sid
]
==
v
->
pair_size
[
sid
])
{
v
->
pair_size
[
sid
]
<<=
1
;
v
->
pairs
[
sid
]
=
(
struct
voronoi_pair
*
)
realloc
(
v
->
pairs
[
sid
],
v
->
pair_size
[
sid
]
*
sizeof
(
struct
voronoi_pair
));
}
struct
voronoi_pair
*
this_pair
=
&
v
->
pairs
[
sid
][
v
->
pair_index
[
sid
]];
this_pair
->
left
=
lid
;
this_pair
->
right
=
rid
;
this_pair
->
surface_area
=
voronoi_compute_midpoint_area_face
(
ax
,
ay
,
bx
,
by
,
this_pair
->
midpoint
);
#ifdef VORONOI_STORE_CONNECTIONS
this_pair
->
a
[
0
]
=
ax
;
this_pair
->
a
[
1
]
=
ay
;
this_pair
->
b
[
0
]
=
bx
;
this_pair
->
b
[
1
]
=
by
;
#endif
++
v
->
pair_index
[
sid
];
}
/**
/**
* @brief Add a new edge connection to the grid.
* @brief Add a new edge connection to the grid.
*
*
...
@@ -142,27 +239,6 @@ static inline double voronoi_compute_centroid_volume_triangle(
...
@@ -142,27 +239,6 @@ static inline double voronoi_compute_centroid_volume_triangle(
return
0
.
5
*
fabs
(
s10x
*
s20y
-
s20x
*
s10y
);
return
0
.
5
*
fabs
(
s10x
*
s20y
-
s20x
*
s10y
);
}
}
/**
* @brief Compute the midpoint and surface area of the face with the given
* vertices.
*
* @param ax, ay, bx, by Face vertices.
* @param result Midpoint of the face.
* @return Surface area of the face.
*/
static
inline
double
voronoi_compute_midpoint_area_face
(
double
ax
,
double
ay
,
double
bx
,
double
by
,
double
*
result
)
{
result
[
0
]
=
0
.
5
*
(
ax
+
bx
);
result
[
1
]
=
0
.
5
*
(
ay
+
by
);
double
sx
=
bx
-
ax
;
double
sy
=
by
-
ay
;
return
sqrt
(
sx
*
sx
+
sy
*
sy
);
}
/**
/**
* @brief Initialise the Voronoi grid based on the given Delaunay tessellation.
* @brief Initialise the Voronoi grid based on the given Delaunay tessellation.
*
*
...
@@ -241,6 +317,12 @@ static inline void voronoi_init(struct voronoi *restrict v,
...
@@ -241,6 +317,12 @@ static inline void voronoi_init(struct voronoi *restrict v,
v
->
connections
=
(
int
*
)
malloc
(
v
->
number_of_cells
*
sizeof
(
int
));
v
->
connections
=
(
int
*
)
malloc
(
v
->
number_of_cells
*
sizeof
(
int
));
v
->
face_midpoints
=
(
double
*
)
malloc
(
2
*
v
->
number_of_cells
*
sizeof
(
double
));
v
->
face_midpoints
=
(
double
*
)
malloc
(
2
*
v
->
number_of_cells
*
sizeof
(
double
));
v
->
face_areas
=
(
double
*
)
malloc
(
v
->
number_of_cells
*
sizeof
(
double
));
v
->
face_areas
=
(
double
*
)
malloc
(
v
->
number_of_cells
*
sizeof
(
double
));
for
(
int
i
=
0
;
i
<
27
;
++
i
)
{
v
->
pairs
[
i
]
=
(
struct
voronoi_pair
*
)
malloc
(
10
*
sizeof
(
struct
voronoi_pair
));
v
->
pair_index
[
i
]
=
0
;
v
->
pair_size
[
i
]
=
10
;
}
v
->
connection_index
=
0
;
v
->
connection_index
=
0
;
v
->
connection_size
=
v
->
number_of_cells
;
v
->
connection_size
=
v
->
number_of_cells
;
/* loop over all cell generators, and hence over all non-ghost, non-dummy
/* loop over all cell generators, and hence over all non-ghost, non-dummy
...
@@ -253,6 +335,7 @@ static inline void voronoi_init(struct voronoi *restrict v,
...
@@ -253,6 +335,7 @@ static inline void voronoi_init(struct voronoi *restrict v,
v
->
cell_centroid
[
2
*
i
]
=
0
.;
v
->
cell_centroid
[
2
*
i
]
=
0
.;
v
->
cell_centroid
[
2
*
i
+
1
]
=
0
.;
v
->
cell_centroid
[
2
*
i
+
1
]
=
0
.;
double
centroid
[
2
];
double
centroid
[
2
];
double
face_midpoint
[
2
];
/* get the generator position, we use it during centroid/volume
/* get the generator position, we use it during centroid/volume
calculations */
calculations */
...
@@ -278,6 +361,9 @@ static inline void voronoi_init(struct voronoi *restrict v,
...
@@ -278,6 +361,9 @@ static inline void voronoi_init(struct voronoi *restrict v,
next neighbouring triangle that has this generator as vertex, in the
next neighbouring triangle that has this generator as vertex, in the
counterclockwise direction */
counterclockwise direction */
int
vi0p1
=
(
vi0
+
1
)
%
3
;
int
vi0p1
=
(
vi0
+
1
)
%
3
;
int
first_vertex
=
d
->
triangles
[
t0
].
vertices
[
vi0p1
];
int
t1
=
d
->
triangles
[
t0
].
neighbours
[
vi0p1
];
int
t1
=
d
->
triangles
[
t0
].
neighbours
[
vi0p1
];
int
vi1
=
d
->
triangles
[
t0
].
index_in_neighbour
[
vi0p1
];
int
vi1
=
d
->
triangles
[
t0
].
index_in_neighbour
[
vi0p1
];
/* loop around until we arrive back at the original triangle */
/* loop around until we arrive back at the original triangle */
...
@@ -303,10 +389,29 @@ static inline void voronoi_init(struct voronoi *restrict v,
...
@@ -303,10 +389,29 @@ static inline void voronoi_init(struct voronoi *restrict v,
v
->
cell_centroid
[
2
*
i
]
+=
V
*
centroid
[
0
];
v
->
cell_centroid
[
2
*
i
]
+=
V
*
centroid
[
0
];
v
->
cell_centroid
[
2
*
i
+
1
]
+=
V
*
centroid
[
1
];
v
->
cell_centroid
[
2
*
i
+
1
]
+=
V
*
centroid
[
1
];
v
->
face_areas
[
c1
]
=
voronoi_compute_midpoint_area_face
(
double
face_area
=
bx
,
by
,
cx
,
cy
,
v
->
face_midpoints
+
2
*
c1
);
voronoi_compute_midpoint_area_face
(
bx
,
by
,
cx
,
cy
,
face_midpoint
);
v
->
face_areas
[
c1
]
=
face_area
;
v
->
face_midpoints
[
2
*
c1
]
=
face_midpoint
[
0
];
v
->
face_midpoints
[
2
*
c1
+
1
]
=
face_midpoint
[
1
];
int
vi1p2
=
(
vi1
+
2
)
%
3
;
int
vi1p2
=
(
vi1
+
2
)
%
3
;
/* the neighbour corresponding to the face is the same vertex that
determines the next triangle */
int
other_vertex
=
d
->
triangles
[
t0
].
vertices
[
vi1p2
];
if
(
other_vertex
<
d
->
ngb_offset
)
{
if
(
other_vertex
>
i
)
{
/* only store pairs once */
voronoi_add_pair
(
v
,
0
,
i
,
other_vertex
,
bx
,
by
,
cx
,
cy
);
}
}
else
{
/* no check on other_vertex > i required, since this is always true */
int
sid
=
d
->
ngb_cells
[
other_vertex
-
d
->
ngb_offset
];
int
pid
=
d
->
ngb_indices
[
other_vertex
-
d
->
ngb_offset
];
voronoi_add_pair
(
v
,
sid
,
i
,
pid
,
bx
,
by
,
cx
,
cy
);
}
vi1
=
d
->
triangles
[
t1
].
index_in_neighbour
[
vi1p2
];
vi1
=
d
->
triangles
[
t1
].
index_in_neighbour
[
vi1p2
];
t1
=
d
->
triangles
[
t1
].
neighbours
[
vi1p2
];
t1
=
d
->
triangles
[
t1
].
neighbours
[
vi1p2
];
}
}
...
@@ -323,8 +428,23 @@ static inline void voronoi_init(struct voronoi *restrict v,
...
@@ -323,8 +428,23 @@ static inline void voronoi_init(struct voronoi *restrict v,
v
->
cell_centroid
[
2
*
i
]
+=
V
*
centroid
[
0
];
v
->
cell_centroid
[
2
*
i
]
+=
V
*
centroid
[
0
];
v
->
cell_centroid
[
2
*
i
+
1
]
+=
V
*
centroid
[
1
];
v
->
cell_centroid
[
2
*
i
+
1
]
+=
V
*
centroid
[
1
];
v
->
face_areas
[
c0
]
=
voronoi_compute_midpoint_area_face
(
double
face_area
=
bx
,
by
,
cx
,
cy
,
v
->
face_midpoints
+
2
*
c0
);
voronoi_compute_midpoint_area_face
(
bx
,
by
,
cx
,
cy
,
face_midpoint
);
v
->
face_areas
[
c0
]
=
face_area
;
v
->
face_midpoints
[
2
*
c0
]
=
face_midpoint
[
0
];
v
->
face_midpoints
[
2
*
c0
+
1
]
=
face_midpoint
[
1
];
if
(
first_vertex
<
d
->
ngb_offset
)
{
if
(
first_vertex
>
i
)
{
/* only store pairs once */
voronoi_add_pair
(
v
,
0
,
i
,
first_vertex
,
bx
,
by
,
cx
,
cy
);
}
}
else
{
/* no check on other_vertex > i required, since this is always true */
int
sid
=
d
->
ngb_cells
[
first_vertex
-
d
->
ngb_offset
];
int
pid
=
d
->
ngb_indices
[
first_vertex
-
d
->
ngb_offset
];
voronoi_add_pair
(
v
,
sid
,
i
,
pid
,
bx
,
by
,
cx
,
cy
);
}
/* now compute the actual centroid by dividing the volume-weighted
/* now compute the actual centroid by dividing the volume-weighted
accumulators by the cell volume */
accumulators by the cell volume */
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment