Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor!(core): make dimension an argument of sew/link methods #253

Merged
merged 7 commits into from
Dec 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading