Skip to content

Commit 6551e16

Browse files
committed
git subrepo pull src/vgrid
subrepo: subdir: "src/vgrid" merged: "aff34f4" upstream: origin: "[email protected]:jreniel/schismrs-vgrid.git" branch: "main" commit: "aff34f4" git-subrepo: version: "0.4.5" origin: "https://github.com/ingydotnet/git-subrepo" commit: "dbb99be"
1 parent a2c13d1 commit 6551e16

File tree

6 files changed

+126
-38
lines changed

6 files changed

+126
-38
lines changed

src/vgrid/.gitrepo

+2-2
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
[subrepo]
77
remote = [email protected]:jreniel/schismrs-vgrid.git
88
branch = main
9-
commit = 6c8ef6b58fb355fb8e7b6b4ab070be57e4adf18b
10-
parent = 2969634fb366a60e1c695458be74af57634dceb1
9+
commit = aff34f42690ee15e2e1770a89fce82743bbf0e2b
10+
parent = a2c13d1087c0e22b7a6d63bacefc68b5f53aa259
1111
method = merge
1212
cmdver = 0.4.5

src/vgrid/build.rs

-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
21
use std::error::Error;
32
use vergen::EmitBuilder;
43

src/vgrid/src/bin/gen_sz.rs

+50-10
Original file line numberDiff line numberDiff line change
@@ -11,34 +11,72 @@ const VERSION: &'static str = concat! {
1111
env! {"VERGEN_GIT_DESCRIBE"}
1212
};
1313

14+
fn greater_than_two(s: &str) -> Result<usize, String> {
15+
let value: usize = s
16+
.parse()
17+
.map_err(|_| format!("`{}` isn't a valid positive integer", s))?;
18+
19+
if value >= 2 {
20+
Ok(value)
21+
} else {
22+
Err(format!(
23+
"The value must be greater or equal than 2, got {}",
24+
value
25+
))
26+
}
27+
}
28+
1429
#[derive(Parser, Debug)]
1530
#[command(author, about, long_about = None)]
1631
#[command(version = VERSION)]
1732
struct Cli {
1833
hgrid_path: PathBuf,
1934
#[clap(short, long)]
2035
output_filepath: Option<PathBuf>,
21-
#[clap(long)]
22-
slevels: usize,
23-
#[clap(long, value_delimiter = ' ', num_args = 1..)]
36+
#[clap(
37+
long,
38+
help = "Number of sigma-levels. Must be an integer greater or equal than 0.",
39+
value_parser=clap::builder::ValueParser::new(greater_than_two),
40+
default_value = "2",
41+
)
42+
]
43+
slevels: Option<usize>,
44+
#[clap(long, value_delimiter = ' ', num_args = 1..,
45+
help = "Space delimited list of depths for each z-level. \
46+
Optional. Defaults to pure sigma grid."
47+
)]
2448
zlevels: Option<Vec<f64>>,
49+
2550
#[clap(
2651
long,
52+
default_value = "0.1",
2753
help = "Range is (0., 20.]. Values closer to 0. make the transformation \
2854
more similar to traditional sigma. Larger values will increase \
2955
resolution at the top and bottom."
3056
)]
31-
theta_f: f64,
57+
theta_f: Option<f64>,
58+
3259
#[clap(
3360
long,
61+
default_value = "0.",
3462
help = "Range is [0., 1.]. For values closer to 0. the surface is \
3563
resolved. For values closer to 1., both the surface and bottom \
3664
are resolved."
3765
)]
38-
theta_b: f64,
39-
#[clap(long, help = "Critical layer depth. Value must be > 5.", alias = "hc")]
66+
theta_b: Option<f64>,
67+
#[clap(
68+
long,
69+
help = "Critical layer depth. Value must be > 5.",
70+
alias = "hc",
71+
default_value = "5."
72+
)]
4073
critical_depth: f64,
41-
#[clap(short, long, default_value = "0.")]
74+
#[clap(
75+
short,
76+
long,
77+
default_value = "0.",
78+
help = "Water level offset. Not typically needed."
79+
)]
4280
etal: Option<f64>,
4381
#[clap(long, action)]
4482
show_plot: bool,
@@ -52,9 +90,9 @@ fn entrypoint() -> Result<(), Box<dyn Error>> {
5290
let hgrid = Hgrid::try_from(&cli.hgrid_path)?;
5391
let mut builder = SZBuilder::default();
5492
builder.hgrid(&hgrid);
55-
builder.slevels(&cli.slevels);
56-
builder.theta_f(&cli.theta_f);
57-
builder.theta_b(&cli.theta_b);
93+
builder.slevels(&cli.slevels.as_ref().unwrap());
94+
builder.theta_f(&cli.theta_f.as_ref().unwrap());
95+
builder.theta_b(&cli.theta_b.as_ref().unwrap());
5896
builder.critical_depth(&cli.critical_depth);
5997
builder.etal(&cli.etal.as_ref().unwrap());
6098
if cli.zlevels.is_some() {
@@ -63,6 +101,8 @@ fn entrypoint() -> Result<(), Box<dyn Error>> {
63101
let sz = builder.build()?;
64102
if cli.output_filepath.is_some() {
65103
sz.write_to_file(&cli.output_filepath.as_ref().unwrap())?;
104+
} else {
105+
println!("{}", sz)
66106
};
67107

68108
if cli.show_plot || cli.save_plot.is_some() {

src/vgrid/src/bin/gen_vqs.rs

+32-10
Original file line numberDiff line numberDiff line change
@@ -78,12 +78,21 @@ enum Modes {
7878

7979
#[derive(Args, Debug)]
8080
struct KmeansCliOpts {
81-
#[clap(short, long)]
81+
#[clap(short, long, help = "Number of clusters. Must be an interger >= 1")]
8282
clusters: usize,
83-
#[clap(short, long, default_value = "2")]
83+
#[clap(
84+
short,
85+
long,
86+
default_value = "2",
87+
help = "Controls the initial number of layers. Must be an integer >= 2."
88+
)]
8489
shallow_levels: Option<usize>,
85-
#[clap(long)]
86-
max_levels: usize,
90+
#[clap(
91+
long,
92+
help = "Controls the maximum number of layers in the clustering hierarchy. \
93+
Defaults to shallow_levels + clusters - 1"
94+
)]
95+
max_levels: Option<usize>,
8796
}
8897

8998
#[derive(Args, Debug)]
@@ -96,18 +105,27 @@ struct HsmCliOpts {
96105

97106
#[derive(Args, Debug)]
98107
struct AutoCliOpts {
99-
#[clap(long)]
108+
#[clap(long, help = "Number of master grids to generate. Must be an int >= 1")]
100109
ngrids: usize,
101110
#[clap(
102111
long,
103112
default_value = "1.",
104113
help = "This is the first depth below etal. This input is positive down."
105114
)]
106115
initial_depth: Option<f64>,
107-
#[clap(long, default_value = "2")]
116+
#[clap(
117+
short,
118+
long,
119+
default_value = "2",
120+
help = "Controls the initial number of layers. Must be an integer >= 2."
121+
)]
108122
shallow_levels: Option<usize>,
109-
#[clap(long)]
110-
max_levels: usize,
123+
#[clap(
124+
long,
125+
help = "Controls the maximum number of layers in the clustering hierarchy. \
126+
Defaults to shallow_levels + clusters - 1"
127+
)]
128+
max_levels: Option<usize>,
111129
}
112130

113131
fn entrypoint() -> Result<(), Box<dyn Error>> {
@@ -151,7 +169,9 @@ fn entrypoint() -> Result<(), Box<dyn Error>> {
151169
if let Some(shallow_levels) = &opts.shallow_levels {
152170
builder.shallow_levels(shallow_levels);
153171
}
154-
builder.max_levels(&opts.max_levels);
172+
if let Some(max_levels) = &opts.max_levels {
173+
builder.max_levels(max_levels);
174+
}
155175
builder.build()?
156176
}
157177
Modes::Auto(opts) => {
@@ -162,7 +182,9 @@ fn entrypoint() -> Result<(), Box<dyn Error>> {
162182
builder.dz_bottom_min(&cli.dz_bottom_min);
163183
builder.initial_depth(&opts.initial_depth.as_ref().unwrap());
164184
builder.shallow_levels(&opts.shallow_levels.as_ref().unwrap());
165-
builder.max_levels(&opts.max_levels);
185+
if let Some(max_levels) = &opts.max_levels {
186+
builder.max_levels(max_levels);
187+
}
166188
builder.build()?
167189
}
168190
};

src/vgrid/src/sz.rs

+12-3
Original file line numberDiff line numberDiff line change
@@ -100,13 +100,11 @@ pub struct SZBuilder<'a> {
100100

101101
impl<'a> SZBuilder<'a> {
102102
pub fn build(&self) -> Result<SZ, SZBuilderError> {
103-
let hgrid = self
104-
.hgrid
105-
.ok_or_else(|| SZBuilderError::UninitializedFieldError("hgrid".to_string()))?;
106103
let slevels = self
107104
.slevels
108105
.as_ref()
109106
.ok_or_else(|| SZBuilderError::UninitializedFieldError("slevels".to_string()))?;
107+
Self::validate_s_levels(slevels)?;
110108
let theta_f = self
111109
.theta_f
112110
.as_ref()
@@ -126,6 +124,9 @@ impl<'a> SZBuilder<'a> {
126124
.etal
127125
.as_ref()
128126
.ok_or_else(|| SZBuilderError::UninitializedFieldError("etal".to_string()))?;
127+
let hgrid = self
128+
.hgrid
129+
.ok_or_else(|| SZBuilderError::UninitializedFieldError("hgrid".to_string()))?;
129130
let depths = hgrid.depths();
130131
let deepest_point = depths.min()?;
131132
let z_array: Array1<f64> = match &self.zlevels {
@@ -164,6 +165,12 @@ impl<'a> SZBuilder<'a> {
164165
};
165166
Ok(())
166167
}
168+
fn validate_s_levels(s_levels: &usize) -> Result<(), SZBuilderError> {
169+
if *s_levels < 2 {
170+
return Err(SZBuilderError::InvalidSLevels);
171+
};
172+
Ok(())
173+
}
167174
fn validate_z_levels(deepest_point: &f64, zlevels: &Vec<f64>) -> Result<(), SZBuilderError> {
168175
if !zlevels.iter().all(|&val| val <= 0.0) {
169176
return Err(SZBuilderError::InvalidZLevels);
@@ -225,6 +232,8 @@ pub enum SZBuilderError {
225232
MinMaxError(#[from] ndarray_stats::errors::MinMaxError),
226233
#[error("zlevels must be all negative and increasing")]
227234
InvalidZLevels,
235+
#[error("slevels must be >= 2")]
236+
InvalidSLevels,
228237
#[error("The first point of zlevels must be smaller or equal to the deepest point in the mesh ({0}) but got {1}")]
229238
InvalidZLevelsValues(f64, f64),
230239
#[error("theta_b must be in [0., 1.], but got {0}")]

src/vgrid/src/vqs.rs

+30-12
Original file line numberDiff line numberDiff line change
@@ -360,17 +360,22 @@ impl<'a> VQSKMeansBuilder<'a> {
360360
VQSKMeansBuilderError::UninitializedFieldError("shallow_levels".to_string())
361361
})?;
362362
Self::validate_shallow_levels(shallow_levels)?;
363-
let max_levels = self.max_levels.ok_or_else(|| {
364-
VQSKMeansBuilderError::UninitializedFieldError("max_levels".to_string())
365-
})?;
366-
Self::validate_max_levels(shallow_levels, max_levels)?;
363+
// let max_levels = self.max_levels.ok_or_else(|| {
364+
// VQSKMeansBuilderError::UninitializedFieldError("max_levels".to_string())
365+
// })?;
366+
let max_levels = match self.max_levels {
367+
Some(max_levels) => *max_levels,
368+
None => Self::calculate_max_levels(shallow_levels, nclusters),
369+
};
370+
Self::validate_max_levels(shallow_levels, &max_levels)?;
371+
367372
let dz_bottom_min = self.dz_bottom_min.ok_or_else(|| {
368373
VQSKMeansBuilderError::UninitializedFieldError("dz_bottom_min".to_string())
369374
})?;
370375
let mut hsm = kmeans_hsm(hgrid, nclusters, etal)?;
371376
hsm.iter_mut().for_each(|depth| *depth = depth.abs());
372377
let mut nlevels = Vec::<usize>::with_capacity(*nclusters);
373-
let levels = Array::linspace(*shallow_levels as f64, *max_levels as f64, *nclusters);
378+
let levels = Array::linspace(*shallow_levels as f64, max_levels as f64, *nclusters);
374379
for level in levels.iter() {
375380
let mut level = level.round() as usize;
376381
if level < *shallow_levels {
@@ -421,9 +426,13 @@ impl<'a> VQSKMeansBuilder<'a> {
421426
}
422427
Ok(())
423428
}
429+
430+
fn calculate_max_levels(shallow_levels: &usize, clusters: &usize) -> usize {
431+
shallow_levels + clusters - 1
432+
}
424433
fn validate_max_levels(
425-
shallow_levels: &'a usize,
426-
max_levels: &'a usize,
434+
shallow_levels: &usize,
435+
max_levels: &usize,
427436
) -> Result<(), VQSKMeansBuilderError> {
428437
if *shallow_levels > *max_levels {
429438
return Err(VQSKMeansBuilderError::InvalidMaxLevels(
@@ -484,12 +493,17 @@ impl<'a> VQSAutoBuilder<'a> {
484493
VQSAutoBuilderError::UninitializedFieldError("shallow_levels".to_string())
485494
})?;
486495
Self::validate_shallow_levels(shallow_levels)?;
487-
let max_levels = self.max_levels.ok_or_else(|| {
488-
VQSAutoBuilderError::UninitializedFieldError("max_levels".to_string())
489-
})?;
490-
Self::validate_max_levels(shallow_levels, max_levels)?;
496+
let max_levels = match self.max_levels {
497+
Some(max_levels) => *max_levels,
498+
None => Self::calculate_max_levels(shallow_levels, ngrids),
499+
};
500+
Self::validate_max_levels(shallow_levels, &max_levels)?;
501+
// let max_levels = self.max_levels.ok_or_else(|| {
502+
// VQSAutoBuilderError::UninitializedFieldError("max_levels".to_string())
503+
// })?;
504+
// Self::validate_max_levels(shallow_levels, max_levels)?;
491505
let (hsm, nlevels) =
492-
Self::build_hsm_and_nlevels(hgrid, ngrids, initial_depth, shallow_levels, max_levels)?;
506+
Self::build_hsm_and_nlevels(hgrid, ngrids, initial_depth, shallow_levels, &max_levels)?;
493507
Ok(VQSBuilder::default()
494508
.hgrid(&hgrid)
495509
.depths(&hsm)
@@ -525,6 +539,10 @@ impl<'a> VQSAutoBuilder<'a> {
525539
Ok(())
526540
}
527541

542+
fn calculate_max_levels(shallow_levels: &usize, clusters: &usize) -> usize {
543+
shallow_levels + clusters - 1
544+
}
545+
528546
fn exponential_samples(start: f64, end: f64, steps: usize) -> Vec<f64> {
529547
let mut samples = Vec::with_capacity(steps);
530548
let scale = (end / start).powf(1.0 / (steps as f64 - 1.0));

0 commit comments

Comments
 (0)