Skip to content

Commit 3b4aadd

Browse files
committed
add: Additional test cases, method to choose level set spacing
1 parent d354156 commit 3b4aadd

8 files changed

Lines changed: 42839 additions & 0 deletions

File tree

scripts/clevis_quad.jou

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
reset
2+
import step "/Users/caleb/Downloads/bracket(1).step" noheal color
3+
surf all copy
4+
delete vol 1
5+
webcut body 3 4 with plane yplane offset -0.0127
6+
webcut body 18 19 with plane zplane offset 0.0254
7+
create volume surface all heal
8+
9+
surf 37 38 39 40 scheme polyhedron
10+
composite create surface 17 25 24 23 20 keep angle 15
11+
12+
surf all size 0.005
13+
14+
#curve 101 71 70 97 72 81 interval 1
15+
#curve 101 71 70 97 72 81 scheme equal
16+
#mesh curve 101 71 70 97 72 81
17+
18+
mesh surface 37 33 38 26 27 28 39 40 35
19+
20+
delete mesh surface 37 propagate
21+
copy mesh surface 38 onto surface 37 source curve 146 source vertex 85 target curve 145 target vertex 58
22+
23+
delete mesh surface 40 propagate
24+
copy mesh surface 39 onto surface 40 source curve 151 source vertex 49 target curve 150 target vertex 69
25+
26+
#vol 21 scheme sweep source surf 37 33 38 26 27 28 39 40 35 target surf 41
27+
#mesh vol all

scripts/clevis_tet.jou

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
reset
2+
import step "/Users/caleb/Downloads/bracket(1).step" noheal color
3+
surf all copy
4+
delete vol 1
5+
webcut body 3 4 with plane yplane offset -0.0127
6+
webcut body 2 3 4 5 14 15 16 17 18 19 with plane zplane offset 0.0254
7+
create volume surface all heal
8+
9+
vol all scheme tet
10+
mesh vol all
11+
12+
nodeset 1 add surface 26 27 28 39 40 41 42 53 54 55 56
13+
nodeset 1 name "start"
14+
nodeset 2 add surface 23 24 25 37 38 43 44
15+
nodeset 2 name "end"
16+
17+
export abaqus "/Users/caleb/sweeps/attempt-sweep/test/data/clevis.inp" mesh_only overwrite everything

scripts/flange_imprinted.jou

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
reset
2+
import step "/Users/caleb/Downloads/flange(1).step" noheal color
3+
create surface rectangle width 8 height 9 xplane
4+
move body 2 y 4 z 3.5
5+
imprint body all
6+
7+
create surface rectangle width 9 height 2 xplane
8+
move body 3 y -7 z 3.5
9+
imprint body 3 1
10+
rotate Surface 25 angle 45 about Z include_merged
11+
imprint body 3 1
12+
rotate Surface 25 angle 45 about Z include_merged
13+
imprint body 3 1
14+
rotate Surface 25 angle 45 about Z include_merged
15+
imprint body 3 1
16+
rotate Surface 25 angle 90 about Z include_merged
17+
imprint body 3 1
18+
rotate Surface 25 angle 45 about Z include_merged
19+
imprint body 3 1
20+
rotate Surface 25 angle 45 about Z include_merged
21+
imprint body 3 1
22+
23+
delete body all except 1
24+
25+
vol 1 scheme tet
26+
mesh vol 1
27+
28+
nodeset 1 add surface 5 4 3 2 1
29+
nodeset 1 name "end"
30+
31+
nodeset 2 add surface 7
32+
nodeset 2 name "start"
33+
34+
export abaqus "/Users/caleb/sweeps/attempt-sweep/test/data/flange_imprinted.inp" mesh_only overwrite everything

src/main.cpp

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,83 @@ std::vector<int> verifyDelaunayTetrahedralization( const SimplicialComplex& mesh
157157
return failed_tetrahedra;
158158
}
159159

160+
std::vector<double> computeEquallySpacedLevelSetValues( const topology::TetMeshCombinatorialMap& mesh,
161+
const Eigen::VectorXd& vertex_values,
162+
const double max_spacing )
163+
{
164+
// 1. Compute gradient magnitude for each triangle (constant per triangle)
165+
std::vector<double> gradient_magnitudes;
166+
std::vector<std::pair<double, double>> triangle_value_ranges;
167+
168+
const topology::CombinatorialMapBoundary bdry( mesh );
169+
170+
const auto vert_ids = indexingOrError( bdry, 0 );
171+
172+
iterateCellsWhile( bdry, 2, [&]( const topology::Face& face ) {
173+
const auto tri = triangleOfFace( mesh, face );
174+
175+
const double f0 = vertex_values( vert_ids( topology::Vertex( face.dart() ) ) );
176+
const double f1 = vertex_values( vert_ids( topology::Vertex( phi( bdry, 1, face.dart() ).value() ) ) );
177+
const double f2 = vertex_values( vert_ids( topology::Vertex( phi( bdry, -1, face.dart() ).value() ) ) );
178+
179+
const Eigen::Vector3d field_vals( f0, f1, f2 );
180+
const Eigen::Vector3d grad = gradient( tri, field_vals );
181+
const double grad_magnitude = grad.norm();
182+
183+
if( grad_magnitude < 1e-12 ) return true; // Skip degenerate/flat triangles
184+
185+
gradient_magnitudes.push_back( grad_magnitude );
186+
187+
const double f_min = std::min( { f0, f1, f2 } );
188+
const double f_max = std::max( { f0, f1, f2 } );
189+
triangle_value_ranges.push_back( { f_min, f_max } );
190+
return true;
191+
} );
192+
193+
// 2. Step through [0,1], at each step finding the minimum gradient
194+
// in the "active" triangles (those intersected by current level set)
195+
std::vector<double> levels = { 0.0 };
196+
double current_value = 0.0;
197+
198+
while( current_value < 1.0 - 1e-10 )
199+
{
200+
// Find min gradient among triangles that contain current_value
201+
double min_grad = std::numeric_limits<double>::infinity();
202+
for( size_t i = 0; i < gradient_magnitudes.size(); ++i )
203+
{
204+
if( triangle_value_ranges.at( i ).first <= current_value &&
205+
current_value <= triangle_value_ranges.at( i ).second )
206+
{
207+
min_grad = std::min( min_grad, gradient_magnitudes.at( i ) );
208+
}
209+
}
210+
211+
if( std::isinf( min_grad ) || min_grad < 1e-12 )
212+
{
213+
// No active triangles or flat region
214+
current_value = 1.0;
215+
}
216+
else
217+
{
218+
// To achieve max spacing d: dv = d * ||∇f||_min
219+
const double dv = max_spacing * min_grad;
220+
current_value += dv;
221+
}
222+
223+
if( current_value < 1.0 )
224+
{
225+
levels.push_back( std::min( current_value, 1.0 ) );
226+
}
227+
}
228+
229+
if( levels.back() < 1.0 - 1e-10 )
230+
{
231+
levels.push_back( 1.0 );
232+
}
233+
234+
return levels;
235+
}
236+
160237
int main( int argc, char* argv[] )
161238
{
162239
const std::vector<std::string> input_args(argv + 1, argv + argc);
@@ -172,6 +249,10 @@ int main( int argc, char* argv[] )
172249
return SweepInputTestCases::ventricle();
173250
else if( std::find( input_args.begin(), input_args.end(), "flange" ) != input_args.end() )
174251
return SweepInputTestCases::flange();
252+
else if( std::find( input_args.begin(), input_args.end(), "flange_imprinted" ) != input_args.end() )
253+
return SweepInputTestCases::flange_imprinted();
254+
else if( std::find( input_args.begin(), input_args.end(), "clevis" ) != input_args.end() )
255+
return SweepInputTestCases::clevis();
175256
else if( std::find( input_args.begin(), input_args.end(), "cube" ) != input_args.end() )
176257
return SweepInputTestCases::twelveTetCube();
177258
else if( std::find( input_args.begin(), input_args.end(), "bunny" ) != input_args.end() )
@@ -356,6 +437,9 @@ int main( int argc, char* argv[] )
356437
sweepEmbedding( map, sweep_input.zero_bcs, sweep_input.one_bcs, normals );
357438
std::cout << "Laplace time 2: " << t.stop( 4 ) << std::endl;
358439

440+
std::cout << "Level set values: " << computeEquallySpacedLevelSetValues( map, ans, 0.7 ) << std::endl;
441+
442+
359443
const Eigen::Matrix3Xd grad = gradientsWithBoundaryCorrection( map, sides, ans, normals );
360444

361445
if( std::find( input_args.begin(), input_args.end(), "output-laplace" ) != input_args.end() )

test/SimplicialComplexTestCases.hpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,16 @@ class SweepInputTestCases
229229
return sweep_input;
230230
}
231231

232+
static SweepInput flange_imprinted()
233+
{
234+
return io::loadINPFile( SRC_HOME "/test/data/flange_imprinted.inp", "start", "end" );
235+
}
236+
237+
static SweepInput clevis()
238+
{
239+
return io::loadINPFile( SRC_HOME "/test/data/clevis.inp", "start", "end" );
240+
}
241+
232242
static SweepInput bunny()
233243
{
234244
SweepInput sweep_input = io::loadINPFile( SRC_HOME "/test/data/stanford_bunny.inp", "SS1_S3", "SS2_S3" );

0 commit comments

Comments
 (0)