-
Notifications
You must be signed in to change notification settings - Fork 13
Expand file tree
/
Copy pathdam_break.cpp
More file actions
197 lines (156 loc) · 6.29 KB
/
dam_break.cpp
File metadata and controls
197 lines (156 loc) · 6.29 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
#include <ExaMPM_BoundaryConditions.hpp>
#include <ExaMPM_Solver.hpp>
#include <Cabana_Core.hpp>
#include <Cabana_Grid.hpp>
#include <Kokkos_Core.hpp>
#include <mpi.h>
#include <array>
#include <cmath>
//---------------------------------------------------------------------------//
// Create the problem setup. The initial geometry is a static water column
// from [0,0.4] in X, [0,0.6] in Z, with the entire Y domain filled.
struct ParticleInitFunc
{
double _volume;
double _mass;
ParticleInitFunc( const double cell_size, const int ppc,
const double density )
: _volume( cell_size * cell_size * cell_size / ( ppc * ppc * ppc ) )
, _mass( _volume * density )
{
}
template <class ParticleType>
KOKKOS_INLINE_FUNCTION bool operator()( const double x[3],
ParticleType& p ) const
{
if ( 0.0 <= x[0] && x[0] <= 0.4 && 0.0 <= x[1] && x[1] <= 1.0 &&
0.0 <= x[2] && x[2] <= 0.6 )
{
// Affine matrix.
for ( int d0 = 0; d0 < 3; ++d0 )
for ( int d1 = 0; d1 < 3; ++d1 )
Cabana::get<0>( p, d0, d1 ) = 0.0;
// Velocity
for ( int d = 0; d < 3; ++d )
Cabana::get<1>( p, d ) = 0.0;
// Position
for ( int d = 0; d < 3; ++d )
Cabana::get<2>( p, d ) = x[d];
// Mass
Cabana::get<3>( p ) = _mass;
// Volume
Cabana::get<4>( p ) = _volume;
// Deformation gradient determinant.
Cabana::get<5>( p ) = 1.0;
return true;
}
return false;
}
};
//---------------------------------------------------------------------------//
void damBreak( const double cell_size, const int ppc, const int halo_size,
const double delta_t, const double t_final, const int write_freq,
const std::string& device )
{
// The dam break domain is in a box on [0,1] in each dimension.
Kokkos::Array<double, 6> global_box = { 0.0, 0.0, 0.0, 1.0, 1.0, 1.0 };
// Compute the number of cells in each direction. The user input must
// squarely divide the domain.
std::array<int, 3> global_num_cell = {
static_cast<int>( 1.0 / cell_size ),
static_cast<int>( 1.0 / cell_size ),
static_cast<int>( 1.0 / cell_size ) };
// This will look like a 2D problem so make the Y direction periodic.
std::array<bool, 3> periodic = { false, false, false };
// Due to the 2D nature of the problem we will only partition in Y. The
// behavior of the fluid will be to largely just run out in X and Z with
// little movement in Y.
int comm_size;
MPI_Comm_size( MPI_COMM_WORLD, &comm_size );
std::array<int, 3> ranks_per_dim = { 1, comm_size, 1 };
Cabana::Grid::ManualBlockPartitioner<3> partitioner( ranks_per_dim );
// Material properties.
double bulk_modulus = 1.0e5;
double density = 1.0e3;
double gamma = 7.0;
double kappa = 100.0;
// Gravity pulls down in z.
double gravity = 9.81;
// Free slip conditions (alternative: NO_SLIP)
ExaMPM::BoundaryCondition bc;
bc.boundary[0] = ExaMPM::BoundaryType::FREE_SLIP;
bc.boundary[1] = ExaMPM::BoundaryType::FREE_SLIP;
bc.boundary[2] = ExaMPM::BoundaryType::FREE_SLIP;
bc.boundary[3] = ExaMPM::BoundaryType::FREE_SLIP;
bc.boundary[4] = ExaMPM::BoundaryType::FREE_SLIP;
bc.boundary[5] = ExaMPM::BoundaryType::FREE_SLIP;
// Solve the problem.
auto solver = ExaMPM::createSolver(
device, MPI_COMM_WORLD, global_box, global_num_cell, periodic,
partitioner, halo_size, ParticleInitFunc( cell_size, ppc, density ),
ppc, bulk_modulus, density, gamma, kappa, delta_t, gravity, bc );
solver->solve( t_final, write_freq );
}
//---------------------------------------------------------------------------//
int main( int argc, char* argv[] )
{
// enable the use of subfiling by setting enviroment H5FD_SUBFILING
const char* env_val = std::getenv( "H5FD_SUBFILING" );
if ( env_val != NULL )
{
int mpi_thread_required = MPI_THREAD_MULTIPLE;
int mpi_thread_provided = 0;
// HDF5 Subfiling VFD requires MPI_Init_thread with MPI_THREAD_MULTIPLE
MPI_Init_thread( &argc, &argv, mpi_thread_required,
&mpi_thread_provided );
if ( mpi_thread_provided < mpi_thread_required )
{
printf( "MPI_THREAD_MULTIPLE not supported\n" );
MPI_Abort( MPI_COMM_WORLD, -1 );
}
}
else
MPI_Init( &argc, &argv );
Kokkos::initialize( argc, argv );
// check inputs and write usage
if ( argc < 8 )
{
std::cerr << "Usage: ./DamBreak cell_size parts_per_cell_size "
"halo_cells dt t_end write_freq device\n";
std::cerr << "\nwhere cell_size edge length of a computational "
"cell (domain is unit cube)\n";
std::cerr
<< " parts_per_cell particles per cell in each direction\n";
std::cerr << " halo_cells number of halo cells\n";
std::cerr << " dt time step size\n";
std::cerr << " t_end simulation end time\n";
std::cerr
<< " write_freq number of steps between output files\n";
std::cerr << " device compute device: serial, openmp, "
"cuda, hip\n";
std::cerr << "\nfor example: ./DamBreak 0.05 2 0 0.001 1.0 10 serial\n";
Kokkos::finalize();
MPI_Finalize();
return 0;
}
// cell size
double cell_size = std::atof( argv[1] );
// particles per cell in a dimension
int ppc = std::atoi( argv[2] );
// number of halo cells.
int halo_size = std::atoi( argv[3] );
// time step size.
double delta_t = std::atof( argv[4] );
// end time.
double t_final = std::atof( argv[5] );
// write frequency
int write_freq = std::atoi( argv[6] );
// device type
std::string device( argv[7] );
// run the problem.
damBreak( cell_size, ppc, halo_size, delta_t, t_final, write_freq, device );
Kokkos::finalize();
MPI_Finalize();
return 0;
}
//---------------------------------------------------------------------------//