Skip to content

Commit

Permalink
refactor!(core): make dimension an argument of sew/link methods (#253)
Browse files Browse the repository at this point in the history
* add new link methods

* add new sew methods

* remove old link and sew methods from public API

* fox core crate usages

* update other crates & doctest

* fix docs
  • Loading branch information
imrn99 authored Dec 13, 2024
1 parent 2b7e7fc commit f40f105
Show file tree
Hide file tree
Showing 20 changed files with 705 additions and 557 deletions.
16 changes: 8 additions & 8 deletions benches/benches/core/cmap2/link_and_sew.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ fn get_sew_map(n_square: usize) -> CMap2<FloatType> {
#[bench::medium(&mut get_link_map(64))]
#[bench::large(&mut get_link_map(256))]
fn one_link(map: &mut CMap2<FloatType>) -> &mut CMap2<FloatType> {
map.force_one_link(4, 6);
map.force_link::<1>(4, 6);
black_box(map)
}

Expand All @@ -60,7 +60,7 @@ fn one_link(map: &mut CMap2<FloatType>) -> &mut CMap2<FloatType> {
#[bench::medium(&mut get_link_map(64))]
#[bench::large(&mut get_link_map(256))]
fn two_link(map: &mut CMap2<FloatType>) -> &mut CMap2<FloatType> {
map.force_two_link(4, 6);
map.force_link::<2>(4, 6);
black_box(map)
}

Expand All @@ -69,7 +69,7 @@ fn two_link(map: &mut CMap2<FloatType>) -> &mut CMap2<FloatType> {
#[bench::medium(&mut get_map(64))]
#[bench::large(&mut get_map(256))]
fn one_unlink(map: &mut CMap2<FloatType>) -> &mut CMap2<FloatType> {
map.force_one_unlink(4);
map.force_unlink::<1>(4);
black_box(map)
}

Expand All @@ -78,7 +78,7 @@ fn one_unlink(map: &mut CMap2<FloatType>) -> &mut CMap2<FloatType> {
#[bench::medium(&mut get_map(64))]
#[bench::large(&mut get_map(256))]
fn two_unlink(map: &mut CMap2<FloatType>) -> &mut CMap2<FloatType> {
map.force_two_unlink(4);
map.force_unlink::<2>(4);
black_box(map)
}

Expand All @@ -98,7 +98,7 @@ library_benchmark_group!(
#[bench::medium(&mut get_sew_map(64))]
#[bench::large(&mut get_sew_map(256))]
fn one_sew(map: &mut CMap2<FloatType>) -> &mut CMap2<FloatType> {
map.force_one_sew(4, 6);
map.force_sew::<1>(4, 6);
black_box(map)
}

Expand All @@ -107,7 +107,7 @@ fn one_sew(map: &mut CMap2<FloatType>) -> &mut CMap2<FloatType> {
#[bench::medium(&mut get_sew_map(64))]
#[bench::large(&mut get_sew_map(256))]
fn two_sew(map: &mut CMap2<FloatType>) -> &mut CMap2<FloatType> {
map.force_two_sew(4, 6);
map.force_sew::<2>(4, 6);
black_box(map)
}

Expand All @@ -116,7 +116,7 @@ fn two_sew(map: &mut CMap2<FloatType>) -> &mut CMap2<FloatType> {
#[bench::medium(&mut get_map(64))]
#[bench::large(&mut get_map(256))]
fn one_unsew(map: &mut CMap2<FloatType>) -> &mut CMap2<FloatType> {
map.force_one_unsew(4);
map.force_unsew::<1>(4);
black_box(map)
}

Expand All @@ -125,7 +125,7 @@ fn one_unsew(map: &mut CMap2<FloatType>) -> &mut CMap2<FloatType> {
#[bench::medium(&mut get_map(64))]
#[bench::large(&mut get_map(256))]
fn two_unsew(map: &mut CMap2<FloatType>) -> &mut CMap2<FloatType> {
map.force_two_unsew(4);
map.force_unsew::<2>(4);
black_box(map)
}

Expand Down
14 changes: 7 additions & 7 deletions examples/examples/io/write.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,17 +39,17 @@ fn main() {
// unsew the square & duplicate vertices to avoid data loss
// this duplication effectively means that there are two existing vertices
// for a short time, before being merged back by the sewing ops
map.force_one_unsew(d1);
map.force_one_unsew(d3);
map.force_unsew::<1>(d1);
map.force_unsew::<1>(d3);
// link the two new dart in order to
map.force_two_link(dsplit1, dsplit2);
map.force_link::<2>(dsplit1, dsplit2);
// define beta1 of the new darts, i.e. tell them where they point to
map.force_one_sew(dsplit1, d4);
map.force_one_sew(dsplit2, d2);
map.force_sew::<1>(dsplit1, d4);
map.force_sew::<1>(dsplit2, d2);

// sew the original darts to the new darts
map.force_one_sew(d1, dsplit1);
map.force_one_sew(d3, dsplit2);
map.force_sew::<1>(d1, dsplit1);
map.force_sew::<1>(d3, dsplit2);
// fuse the edges; this is where duplicated vertices are merged back together
});
let elapsed = now.elapsed();
Expand Down
12 changes: 6 additions & 6 deletions honeycomb-core/src/attributes/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -136,10 +136,10 @@ fn temperature_map() {
.add_attribute::<Temperature>();
let map: CMap2<f64> = builder.build().unwrap();

map.force_two_link(1, 2);
map.force_two_link(3, 4);
map.force_two_link(5, 6);
map.force_one_link(1, 3);
map.force_link::<2>(1, 2);
map.force_link::<2>(3, 4);
map.force_link::<2>(5, 6);
map.force_link::<1>(1, 3);
map.force_write_vertex(1, (0.0, 0.0));
map.force_write_vertex(2, (1.0, 0.0));
map.force_write_vertex(4, (1.5, 0.0));
Expand All @@ -161,7 +161,7 @@ fn temperature_map() {
Some(Temperature::from(273.))
);
// sew one segment
map.force_one_sew(3, 5);
map.force_sew::<1>(3, 5);
assert_eq!(map.vertex_id(4), map.vertex_id(5));
assert_eq!(
map.force_read_attribute::<Temperature>(map.vertex_id(4)),
Expand All @@ -172,7 +172,7 @@ fn temperature_map() {
Some(Vertex2::from((2., 0.)))
);
// unsew another
map.force_one_unsew(1);
map.force_unsew::<1>(1);
assert_ne!(map.vertex_id(2), map.vertex_id(3));
assert_eq!(
map.force_read_attribute::<Temperature>(map.vertex_id(2)),
Expand Down
22 changes: 11 additions & 11 deletions honeycomb-core/src/cmap/builder/io.rs
Original file line number Diff line number Diff line change
Expand Up @@ -205,10 +205,10 @@ pub fn build_2d_from_vtk<T: CoordsFloat>(
d2 as VertexIdType,
vertices[vids[2]],
);
cmap.force_one_link(d0, d1); // edge d0 links vertices vids[0] & vids[1]
cmap.force_one_link(d1, d2); // edge d1 links vertices vids[1] & vids[2]
cmap.force_one_link(d2, d0); // edge d2 links vertices vids[2] & vids[0]
// record a trace of the built cell for future 2-sew
cmap.force_link::<1>(d0, d1); // edge d0 links vertices vids[0] & vids[1]
cmap.force_link::<1>(d1, d2); // edge d1 links vertices vids[1] & vids[2]
cmap.force_link::<1>(d2, d0); // edge d2 links vertices vids[2] & vids[0]
// record a trace of the built cell for future 2-sew
sew_buffer.insert((vids[0], vids[1]), d0);
sew_buffer.insert((vids[1], vids[2]), d1);
sew_buffer.insert((vids[2], vids[0]), d2);
Expand All @@ -230,7 +230,7 @@ pub fn build_2d_from_vtk<T: CoordsFloat>(
di as VertexIdType,
vertices[vids[i]],
);
cmap.force_one_link(di, dip1);
cmap.force_link::<1>(di, dip1);
sew_buffer
.insert((vids[i], vids[(i + 1) % n_vertices]), di);
});
Expand Down Expand Up @@ -265,11 +265,11 @@ pub fn build_2d_from_vtk<T: CoordsFloat>(
d3 as VertexIdType,
vertices[vids[3]],
);
cmap.force_one_link(d0, d1); // edge d0 links vertices vids[0] & vids[1]
cmap.force_one_link(d1, d2); // edge d1 links vertices vids[1] & vids[2]
cmap.force_one_link(d2, d3); // edge d2 links vertices vids[2] & vids[3]
cmap.force_one_link(d3, d0); // edge d3 links vertices vids[3] & vids[0]
// record a trace of the built cell for future 2-sew
cmap.force_link::<1>(d0, d1); // edge d0 links vertices vids[0] & vids[1]
cmap.force_link::<1>(d1, d2); // edge d1 links vertices vids[1] & vids[2]
cmap.force_link::<1>(d2, d3); // edge d2 links vertices vids[2] & vids[3]
cmap.force_link::<1>(d3, d0); // edge d3 links vertices vids[3] & vids[0]
// record a trace of the built cell for future 2-sew
sew_buffer.insert((vids[0], vids[1]), d0);
sew_buffer.insert((vids[1], vids[2]), d1);
sew_buffer.insert((vids[2], vids[3]), d2);
Expand Down Expand Up @@ -298,7 +298,7 @@ pub fn build_2d_from_vtk<T: CoordsFloat>(
}
while let Some(((id0, id1), dart_id0)) = sew_buffer.pop_first() {
if let Some(dart_id1) = sew_buffer.remove(&(id1, id0)) {
cmap.force_two_sew(dart_id0, dart_id1);
cmap.force_sew::<2>(dart_id0, dart_id1);
}
}
Ok(cmap)
Expand Down
149 changes: 149 additions & 0 deletions honeycomb-core/src/cmap/dim2/links/mod.rs
Original file line number Diff line number Diff line change
@@ -1,2 +1,151 @@
mod one;
mod two;

use stm::{StmResult, Transaction};

use crate::{
cmap::{CMap2, DartIdType},
prelude::CoordsFloat,
};

/// # **Link operations**
impl<T: CoordsFloat> CMap2<T> {
/// # `I`-link operator.
///
/// This operation corresponds to coherently linking two darts via their *β* images. Unlike
/// sewing, this does not affect associated attributes.
///
/// For a thorough explanation of this operation, its hypothesis & consequences, refer
/// to the [user guide][UG].
///
/// [UG]: https://lihpc-computational-geometry.github.io/honeycomb/user-guide/definitions/sew.html
///
/// # Arguments
///
/// - `const I: u8` -- Sew dimension.
/// - `trans: &mut Transaction` -- Transaction associated to the operation.
/// - `ld: DartIdType` -- First dart ID.
/// - `rd: DartIdType` -- Second dart ID.
///
/// # Errors
///
/// This method should be called in a transactional context. The `Result` is then used to
/// validate the transaction; It should not be processed manually. The policy in case of
/// failure can be defined when creating the transaction, using `Transaction::with_control`.
///
/// # Panics
///
/// The method may panic if:
/// - `I >= 3` or `I == 0`,
/// - the two darts are not I-linkable.
pub fn link<const I: u8>(
&self,
trans: &mut Transaction,
ld: DartIdType,
rd: DartIdType,
) -> StmResult<()> {
// these assertions + match on a const are optimized away
assert!(I < 3);
assert_ne!(I, 0);
match I {
1 => self.one_link(trans, ld, rd),
2 => self.two_link(trans, ld, rd),
_ => unreachable!(),
}
}

/// # `I`-unlink operator.
///
/// This operation corresponds to unlinking two darts by resetting their *β* images. Unlike
/// linking, this does not affect associated attributes.
///
/// For a thorough explanation of this operation, its hypothesis & consequences, refer
/// to the [user guide][UG].
///
/// [UG]: https://lihpc-computational-geometry.github.io/honeycomb/user-guide/definitions/sew.html
///
/// # Arguments
///
/// - `const I: u8` -- Unsew dimension.
/// - `trans: &mut Transaction` -- Transaction associated to the operation.
/// - `ld: DartIdType` -- First dart ID.
///
/// The second dart ID is fetched using `I` and `ld`.
///
/// # Errors
///
/// This method should be called in a transactional context. The `Result` is then used to
/// validate the transaction; It should not be processed manually. The policy in case of
/// failure can be defined when creating the transaction, using `Transaction::with_control`.
///
/// # Panics
///
/// The method may panic if:
/// - `I >= 3` or `I == 0`
/// - `ld` is already `I`-free,
pub fn unlink<const I: u8>(&self, trans: &mut Transaction, ld: DartIdType) -> StmResult<()> {
// these assertions + match on a const are optimized away
assert!(I < 3);
assert_ne!(I, 0);
match I {
1 => self.one_unlink(trans, ld),
2 => self.two_unlink(trans, ld),
_ => unreachable!(),
}
}

/// # `I`-link operator.
///
/// This variant is equivalent to `sew`, but internally uses a transaction that will
/// be retried until validated.
///
/// # Arguments
///
/// - `const I: u8` -- Sew dimension.
/// - `ld: DartIdType` -- First dart ID.
/// - `rd: DartIdType` -- Second dart ID.
///
/// # Panics
///
/// The method may panic if:
/// - `I >= 3` or `I == 0`,
/// - the two darts are not I-linkable.
pub fn force_link<const I: u8>(&self, ld: DartIdType, rd: DartIdType) {
// these assertions + match on a const are optimized away
assert!(I < 3);
assert_ne!(I, 0);
match I {
1 => self.force_one_link(ld, rd),
2 => self.force_two_link(ld, rd),
_ => unreachable!(),
}
}

/// # `I`-unlink operator.
///
/// This variant is equivalent to `sew`, but internally uses a transaction that will
/// be retried until validated.
///
/// # Arguments
///
/// - `const I: u8` -- Unsew dimension.
/// - `ld: DartIdType` -- First dart ID.
///
/// The second dart ID is fetched using `I` and `ld`.
///
/// # Panics
///
/// The method may panic if:
/// - `I >= 3` or `I == 0`
/// - `ld` is already `I`-free,
pub fn force_unlink<const I: u8>(&self, ld: DartIdType) {
// these assertions + match on a const are optimized away
assert!(I < 3);
assert_ne!(I, 0);
match I {
1 => self.force_one_unlink(ld),
2 => self.force_two_unlink(ld),
_ => unreachable!(),
}
}
}
Loading

0 comments on commit f40f105

Please sign in to comment.