Skip to content

Commit 45a5725

Browse files
authored
Imex time stepping (#775)
* imex2 and vplb example
1 parent fb396f5 commit 45a5725

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+1585
-917
lines changed

CMakeLists.txt

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -504,13 +504,14 @@ if (${ASGARD_USE_PCH})
504504
target_precompile_headers (asgard_exe REUSE_FROM libasgard)
505505
endif ()
506506

507-
set (_asgard_pdes continuity diffusion elliptic sinwav two_stream
507+
set (_asgard_pdes continuity diffusion elliptic sinwav two_stream vplb
508508
mass_internal varcoeff_internal bound_internal relaxation_internal)
509509

510510
foreach (_asgexe ${_asgard_pdes})
511511
add_executable (${_asgexe} "${CMAKE_CURRENT_SOURCE_DIR}/src/pde/${_asgexe}.cpp")
512512
target_link_libraries (${_asgexe} PUBLIC libasgard)
513-
install(TARGETS ${_asgexe} EXPORT "asgard-export" RUNTIME DESTINATION "share/asgard/pde")
513+
install(TARGETS ${_asgexe} RUNTIME DESTINATION "share/asgard/pde")
514+
install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/src/pde/${_asgexe}.cpp" DESTINATION "share/asgard/examples")
514515
endforeach()
515516

516517
#-------------------------------------------------------------------------------

doxygen/CMakeLists.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,13 +53,14 @@ doxygen_add_docs(asgard_doxygen
5353
src/asgard_reconstruct.hpp
5454
src/asgard_dimension.hpp
5555
src/pde/asgard_pde_base.hpp
56-
examples/continuity_2d.cpp
5756
examples/inputs_1d.cpp
57+
examples/continuity_2d.cpp
5858
src/pde/continuity.cpp
5959
src/pde/diffusion.cpp
6060
src/pde/elliptic.cpp
6161
src/pde/sinwav.cpp
6262
src/pde/two_stream.cpp
63+
src/pde/vplb.cpp
6364
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/../
6465
COMMENT "Building the ${PROJECT_NAME} documentation")
6566

examples/CMakeLists.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,3 +20,9 @@ if (asgard_PYTHON_FOUND)
2020

2121
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/inputs_1d.py" "${CMAKE_CURRENT_BINARY_DIR}/inputs_1d.py" COPYONLY)
2222
endif()
23+
24+
# additional examples following the same pattern
25+
foreach (_example continuity diffusion elliptic sinwav two_stream vplb)
26+
add_executable(${_example} ${_example}.cpp)
27+
target_link_libraries(${_example} asgard::asgard)
28+
endforeach()

examples/continuity_2d.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,9 @@
1212

1313
/*!
1414
* \ingroup asgard_examples
15-
* \addtogroup asgard_examples_continuity_2d Example 1, 2D continuity equation
15+
* \addtogroup asgard_examples_continuity_2d Example: 2D continuity equation
1616
*
17-
* \par Example 1
17+
* \par 2D continuity equation
1818
* Solves the continuity partial differential equation
1919
* \f[ \frac{\partial}{\partial t} f + \nabla \cdot f = s \f]
2020
* where both \b f and \b s are defined over the two dimensional domain

examples/inputs_1d.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,9 @@
1212

1313
/*!
1414
* \ingroup asgard_examples
15-
* \addtogroup asgard_examples_input_1d Example 2, Simple 1D equation
15+
* \addtogroup asgard_examples_input_1d Example: Simple 1D equation
1616
*
17-
* \par Example 2
17+
* \par Simple 1D equation
1818
* Solves the continuity partial differential equation
1919
* \f[ \frac{\partial}{\partial t} f + \frac{\partial}{\partial x} f = s \f]
2020
* where both \b f and \b s are defined over domain

python/asgard.py

Lines changed: 90 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,10 @@ def __del__(self):
5454

5555
def __init__(self, filename, verbose = False):
5656
self.verbose = verbose
57+
if filename == "::aux-filed":
58+
self.recsol = None
59+
return
60+
5761
if self.verbose:
5862
print(' -- reading from: %s' % filename)
5963

@@ -98,6 +102,9 @@ def __init__(self, filename, verbose = False):
98102

99103
self.num_dimensions = fdata['num_dims'][()]
100104

105+
self.num_position = fdata['num_pos'][()]
106+
self.num_velocity = fdata['num_vel'][()]
107+
101108
self.cells = fdata['grid_indexes'][()]
102109
self.time = fdata['dtime_time'][()] # numeric time
103110

@@ -114,6 +121,15 @@ def __init__(self, filename, verbose = False):
114121
self.dimension_min[i] = drange[2 * i]
115122
self.dimension_max[i] = drange[2 * i + 1]
116123

124+
num_aux = fdata['num_aux_fields'][()]
125+
self.aux_fields = [None for i in range(num_aux)]
126+
for i in range(num_aux):
127+
self.aux_fields[i] = {
128+
'name' : fdata[f"aux_field_{i}_name"][()].decode("utf-8"),
129+
'data' : fdata[f"aux_field_{i}_data"][()],
130+
'grid' : fdata[f"aux_field_{i}_grid"][()]
131+
}
132+
117133
# for plotting purposes, say aways from the domain edges
118134
# rounding error at the edge may skew the plots
119135
self.eps = 1.E-6 * np.min(self.dimension_max - self.dimension_min)
@@ -158,6 +174,66 @@ def __init__(self, filename, verbose = False):
158174
np.ctypeslib.as_ctypes(self.dimension_min.reshape(-1,)),
159175
np.ctypeslib.as_ctypes(self.dimension_max.reshape(-1,)))
160176

177+
def get_aux_field(self, auxid):
178+
assert isinstance(auxid, int) or isinstance(auxid, string), "auxid must be in int or a string"
179+
if isinstance(auxid, int):
180+
assert 0 <= auxid and auxid < len(self.aux_fields), f"the auxid {auxid} must point to a valid entry in the list with size {len(self.aux_fields)}"
181+
182+
idnum = auxid
183+
else: # must be a string due to the assertion on top
184+
idnum = -1
185+
for i in range(len(self.aux_fields)):
186+
if self.aux_fields[i].name == auxid:
187+
idnum = i
188+
break
189+
assert idnum != -1, f"the auxid '{auxid}' is not in the list of aux-fields"
190+
191+
aux = pde_snapshot("::aux-filed", self.verbose)
192+
193+
aux.title = self.aux_fields[idnum]['name']
194+
aux.subtitle = "aux-field"
195+
aux.degree = self.degree
196+
aux.state = self.aux_fields[idnum]['data']
197+
aux.cells = self.aux_fields[idnum]['grid']
198+
199+
aux.default_view = self.default_view
200+
201+
aux.num_dimensions = self.num_dimensions
202+
aux.num_position = self.num_position
203+
aux.num_velocity = self.num_velocity
204+
aux.num_cells = aux.cells.shape[0] / aux.num_dimensions
205+
206+
aux.time = self.time
207+
aux.time = self.time
208+
209+
aux.dimension_names = self.dimension_names
210+
aux.dimension_min = self.dimension_min
211+
aux.dimension_max = self.dimension_max
212+
213+
aux.aux_fields = []
214+
215+
aux.eps = self.eps
216+
217+
if self.state.dtype == np.float64:
218+
aux.double_precision = True
219+
220+
aux.recsol = libasgard.asgard_make_dreconstruct_solution_v2(
221+
self.num_dimensions, self.num_cells, np.ctypeslib.as_ctypes(aux.cells.reshape(-1,)),
222+
self.degree, np.ctypeslib.as_ctypes(aux.state.reshape(-1,)))
223+
224+
else:
225+
aux.double_precision = False
226+
227+
aux.recsol = libasgard.asgard_make_freconstruct_solution_v2(
228+
self.num_dimensions, self.num_cells, np.ctypeslib.as_ctypes(aux.cells.reshape(-1,)),
229+
self.degree, np.ctypeslib.as_ctypes(aux.state.reshape(-1,)))
230+
231+
libasgard.asgard_reconstruct_solution_setbounds(aux.recsol,
232+
np.ctypeslib.as_ctypes(self.dimension_min.reshape(-1,)),
233+
np.ctypeslib.as_ctypes(self.dimension_max.reshape(-1,)))
234+
235+
return aux
236+
161237
def plot_data1d(self, dims, num_points = 32):
162238
'''
163239
Generates two 1d arrays (vals, x), so that vals is the values
@@ -301,8 +377,11 @@ def cell_centers(self):
301377
def __str__(self):
302378
s = "title: %s\n" % self.title
303379
if self.subtitle != "":
304-
s += " sub: %s\n" % self.subtitle
305-
s += " num-dimensions: %d\n" % self.num_dimensions
380+
s += " %s\n" % self.subtitle
381+
if self.num_position == 0 and self.num_velocity == 0:
382+
s += " num-dimensions: %d\n" % self.num_dimensions
383+
else: # have position/velocity dimensions
384+
s += f" num-dimensions: {self.num_dimensions} ({self.num_position}x{self.num_velocity}v)\n"
306385
s += " degree: %d\n" % self.degree
307386
s += " num-indexes: %d\n" % self.num_cells
308387
s += " state size: %d\n" % self.state.size
@@ -374,6 +453,7 @@ def __str__(self):
374453
# we are plotting, consider extra options
375454
plotview = None
376455
savefig = None
456+
auxfield = None
377457
addgrid = False
378458
if len(sys.argv) > 2:
379459
i = 2
@@ -385,13 +465,21 @@ def __str__(self):
385465
elif sys.argv[i] == "-fig":
386466
savefig = sys.argv[i + 1] if i + 1 < n else None
387467
i += 2
468+
elif sys.argv[i] == "-aux":
469+
auxfield = sys.argv[i + 1] if i + 1 < n else None
470+
i += 2
471+
assert auxfield is not None, "-aux requires an filed number"
472+
auxfield = int(auxfield)
388473
elif sys.argv[i] == "-grid":
389474
addgrid = True
390475
i += 1
391476
else:
392477
savefig = sys.argv[i]
393478
i += 1
394479

480+
if auxfield is not None:
481+
shot = shot.get_aux_field(auxfield)
482+
395483
asgplot.title(shot.title, fontsize = 'large')
396484

397485
if shot.num_dimensions == 1:

src/asgard_coefficients_mats.hpp

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -379,7 +379,7 @@ void gen_diag_cmat(legendre_basis<P> const &basis, P xleft, P xright, int level,
379379
//! moment over moment zero
380380
template<typename P, int multsign, pterm_dependence dep>
381381
void gen_diag_mom_cases(
382-
legendre_basis<P> const &basis, P xleft, P xright, int level, int mindex,
382+
legendre_basis<P> const &basis, int level, int mindex,
383383
std::vector<P> const &moms, block_diag_matrix<P> &coefficients)
384384
{
385385
static_assert(multsign == 1 or multsign == -1);
@@ -392,9 +392,6 @@ void gen_diag_mom_cases(
392392

393393
coefficients.resize_and_zero(pdof * pdof, num_cells);
394394

395-
P const dx = (xright - xleft) / num_cells;
396-
P const vscale = P{1} / dx; // volume scale
397-
398395
size_t const wsize = [&]() -> size_t {
399396
if constexpr (dep == pterm_dependence::moment_divided_by_density)
400397
return num_quad * pdof + 2 * num_quad;

src/asgard_dimension.hpp

Lines changed: 33 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -243,14 +243,11 @@ class pde_domain
243243

244244
private:
245245
void check_init() {
246-
if (num_dims_ < 1)
247-
throw std::runtime_error("pde_domain created with zero or negative dimensions");
248-
if (num_dims_ > max_num_dimensions)
249-
throw std::runtime_error("pde_domain created with too many dimensions, max is 6D");
250-
if (num_pos_ < 0)
251-
throw std::runtime_error("pde_domain created with negative position dimensions");
252-
if (num_vel_ < 0)
253-
throw std::runtime_error("pde_domain created with negative velocity dimensions");
246+
rassert(num_dims_ >= 1, "pde_domain created with zero or negative dimensions");
247+
rassert(num_dims_ <= max_num_dimensions,
248+
"pde_domain created with too many dimensions, max is 6D");
249+
rassert(num_pos_ >= 0, "pde_domain created with negative position dimensions");
250+
rassert(num_vel_ >= 0, "pde_domain created with negative velocity dimensions");
254251

255252
if (num_pos_ == 0 and num_vel_ == 0) {
256253
for (int d : iindexof(num_dims_))
@@ -426,4 +423,32 @@ class separable_func
426423
scalar_func<P> time_func_;
427424
};
428425

426+
/*!
427+
* \ingroup asgard_discretization
428+
* \brief Extra data-entry for plotting and post-processing
429+
*
430+
* In plotting and post-processing, it is sometime desirable to store
431+
* additional data that sits on the sparse grid mesh, e.g.,
432+
* deviation from a nominal state or initial condition.
433+
* Since the data is defined on a sparse grid, it has to be accessed with
434+
* the asgard::reconstruct_solution class (e.g., via python), but the data
435+
* has to be saved/loaded in the asgard::discretization_manager
436+
*/
437+
template<typename P>
438+
struct aux_field_entry {
439+
//! default constructor, creates and empty entry
440+
aux_field_entry() = default;
441+
//! constructor, set the name and data
442+
aux_field_entry(std::string nm, std::vector<P> dat)
443+
: name(std::move(nm)), data(std::move(dat))
444+
{}
445+
//! reference name for the field, should be unique
446+
std::string name;
447+
//! vector data
448+
std::vector<P> data;
449+
//! multi-indexes
450+
std::vector<int> grid;
451+
};
452+
453+
429454
} // namespace asgard

0 commit comments

Comments
 (0)