Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
59 commits
Select commit Hold shift + click to select a range
de5e449
First pass at an omegaH based cfl scaling factor for the collisionles…
Maxwell-Rosen Nov 8, 2025
f2bbc06
Implement element-wise minimum operations for arrays and update relat…
Maxwell-Rosen Nov 8, 2025
5a25029
Finish the densified implementation of the cfl scaling, with array op…
Maxwell-Rosen Nov 8, 2025
230f47e
Merge branch 'main' into slowdown-to-omega-cfl
Maxwell-Rosen Nov 8, 2025
6246572
Merge branch 'main' into slowdown-to-omega-cfl
Maxwell-Rosen Nov 8, 2025
71b072f
The functionality works now. Add P0 inverse basis function and integr…
Maxwell-Rosen Nov 8, 2025
48e342c
Add the diagnostic to this module
Maxwell-Rosen Nov 8, 2025
e5c4f0c
Work with the reset function to integrate the time dilation method. I…
Maxwell-Rosen Nov 8, 2025
d7938cd
Rename min functions to min_by_cell for clarity and consistency; upda…
Maxwell-Rosen Nov 8, 2025
22d32b8
Fix GPU build
Maxwell-Rosen Nov 9, 2025
622e84e
Update a comment for the cfl_dt_min_value
Maxwell-Rosen Nov 10, 2025
392cd6c
Merge branch 'main' into slowdown-to-omega-cfl
Maxwell-Rosen Nov 21, 2025
01bf991
Merge branch 'main' into slowdown-to-omega-cfl
Maxwell-Rosen Nov 24, 2025
bf81fd5
Merge branch 'skip-cell-general-mask' into gk-time-dilation-small-f
Maxwell-Rosen Nov 24, 2025
66f32d7
Merge branch 'init_from_file_w_pos' into gk-time-dilation-small-f
Maxwell-Rosen Nov 24, 2025
ffbcc4b
Implement a mask for the time dilation which masks cells with f > thr…
Maxwell-Rosen Nov 24, 2025
0595368
Remove debug output and file writing for time dilation mask in fdot s…
Maxwell-Rosen Nov 24, 2025
da857fa
Merge branch 'skip-cell-general-mask' into gk-time-dilation-small-f
Maxwell-Rosen Nov 24, 2025
e5a0972
Remove unused test cases for array and CUDA multiply by cell functions
Maxwell-Rosen Nov 24, 2025
59fad80
Merge branch 'skip-cell-general-mask' into gk-time-dilation-small-f
Maxwell-Rosen Nov 24, 2025
f760390
Merge branch 'skip-cell-general-mask' into gk-time-dilation-small-f
Maxwell-Rosen Nov 25, 2025
e62c4d0
Merge branch 'skip-cell-general-mask' into gk-time-dilation-small-f
Maxwell-Rosen Nov 25, 2025
8c9ecee
Remove boolean array operations and refactor skip cell mask inversion
Maxwell-Rosen Nov 25, 2025
359edf9
Fix ser_inv_list initialization by removing NULL from the first entry
Maxwell-Rosen Nov 25, 2025
0f2ffee
Apply the new skip_cell mask being doubles to the collisionless scali…
Maxwell-Rosen Nov 25, 2025
0a9b915
Merge branch 'skip-cell-general-mask' into gk-time-dilation-small-f
Maxwell-Rosen Nov 25, 2025
28c0359
Merge branch 'main' into gk-time-dilation-small-f
Maxwell-Rosen Dec 14, 2025
f130238
Merge branch 'skip-cell-general-mask' into gk-time-dilation-small-f
Maxwell-Rosen Dec 14, 2025
4f8f0fb
Update the collisionless time dilation to use the new gkyl_dg_array_m…
Maxwell-Rosen Dec 14, 2025
8732377
Refactor conditional statements in gk_species_fdot_multiplier functio…
Maxwell-Rosen Jan 15, 2026
92a5185
Add an f_multiplier in the app for the new way of doing time dilation…
Maxwell-Rosen Jan 15, 2026
2dd4faa
Merge some changes from the skip_cell mask branch into here. Remove t…
Maxwell-Rosen Jan 15, 2026
1846146
Add the determination of the time dilation based on CFL back in. I ha…
Maxwell-Rosen Jan 16, 2026
511899b
Merge branch 'skip-cell-general-mask' into time-dilation-reorg
Maxwell-Rosen Jan 27, 2026
f229c80
Merge branch 'skip-cell-general-mask' into time-dilation-reorg
Maxwell-Rosen Jan 31, 2026
498d23e
Refactor time dilation structure so that it's inside the fdot multipl…
Maxwell-Rosen Jan 31, 2026
4d50530
Merge branch 'skip-cell-general-mask' into time-dilation-reorg
Maxwell-Rosen Jan 31, 2026
f9dbe99
Add comment about gk_species_rhs
Maxwell-Rosen Jan 31, 2026
c6a2f07
Merge branch 'skip-cell-general-mask' into time-dilation-reorg
Maxwell-Rosen Feb 10, 2026
7170534
Merge branch 'main' into time-dilation-reorg
Maxwell-Rosen Feb 12, 2026
48e81c0
Separate the different fdot multiplier advances to different function…
Maxwell-Rosen Feb 16, 2026
6a05b66
Add more regression tests with this feature to include all forms of t…
Maxwell-Rosen Feb 16, 2026
7d76963
Now the regression tests are valgrind clean
Maxwell-Rosen Feb 16, 2026
6287d85
Add a constant offset scale factor, which multiplies the omegaH dt fa…
Maxwell-Rosen Feb 16, 2026
570708e
Remove .evolve, since this was messing with some of the masks
Maxwell-Rosen Feb 16, 2026
0646ff8
Change the array_mask updater to update the threshold of the mask on …
Maxwell-Rosen Feb 18, 2026
f77a985
Code compiles on GPU and all unit tests pass
Maxwell-Rosen Feb 18, 2026
4c94b42
Remove a free so the code compiles
Maxwell-Rosen Feb 24, 2026
b02c9a2
Merge branch 'main' into time-dilation-reorg
Maxwell-Rosen Feb 24, 2026
fa344a3
Update the evolve flag to be consistent with main
Maxwell-Rosen Feb 24, 2026
ae53050
Add a clear constant multiplier to the time dilation scheme
Maxwell-Rosen Mar 6, 2026
b0cbd1e
Merge branch 'main' into time-dilation-reorg
Maxwell-Rosen Mar 6, 2026
f305728
Merge branch 'main' into time-dilation-reorg
Maxwell-Rosen Mar 19, 2026
89cd528
Add a option for a constant factor to multiply omega_max
Maxwell-Rosen Mar 19, 2026
089e455
Remove print statement
Maxwell-Rosen Mar 19, 2026
7760ec6
Add support for time dilation based on species dt and refactor relate…
Maxwell-Rosen Mar 20, 2026
9bd7191
Set kinetic ion time dilation to the electron species
Maxwell-Rosen Mar 20, 2026
143a40a
Refactor time rate multipliers to support multiple df/dt multiplier t…
Maxwell-Rosen Mar 20, 2026
8493bfd
Merge branch 'main' into time-dilation-reorg
Maxwell-Rosen Mar 24, 2026
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
221 changes: 221 additions & 0 deletions core/unit/ctest_array_ops.c
Original file line number Diff line number Diff line change
Expand Up @@ -498,6 +498,29 @@ void test_array_shiftc()
gkyl_array_release(a2);
}

void test_array_invert_by_cell()
{
struct gkyl_array *a1 = gkyl_array_new(GKYL_DOUBLE, 3, 8);
double *a1_d = a1->data;

// Set values: 1.0, 2.0, 4.0, 5.0, 10.0, 0.5, 0.25, 0.1
double test_vals[] = {1.0, 2.0, 4.0, 5.0, 10.0, 0.5, 0.25, 0.1};
double expected_inv[] = {1.0, 0.5, 0.25, 0.2, 0.1, 2.0, 4.0, 10.0};

for (unsigned i=0; i<a1->size; ++i)
for (size_t k=0; k<a1->ncomp; ++k)
a1_d[i*a1->ncomp+k] = test_vals[i];

gkyl_array_invert_by_cell(a1);

// Check inverted values
for (unsigned i=0; i<a1->size; ++i)
for (size_t k=0; k<a1->ncomp; ++k)
TEST_CHECK( gkyl_compare(a1_d[i*a1->ncomp+k], expected_inv[i], 1e-14) );

gkyl_array_release(a1);
}

void test_array_shiftc_range(bool on_gpu)
{
int lower[] = {1}, upper[] = {10};
Expand Down Expand Up @@ -582,6 +605,151 @@ void test_array_shiftc_range(bool on_gpu)
if (on_gpu) gkyl_array_release(a2);
}

void test_array_min_by_cell(bool on_gpu)
{
struct gkyl_array *a1_ho = gkyl_array_new(GKYL_DOUBLE, 3, 10);
struct gkyl_array *a1 = a1_ho;
if (on_gpu) a1 = gkyl_array_cu_dev_new(GKYL_DOUBLE, a1_ho->ncomp, a1_ho->size);

double *a1_ho_d = a1_ho->data;
for (unsigned i=0; i<a1_ho->size; ++i) {
for (size_t k=0; k<a1_ho->ncomp; ++k)
a1_ho_d[i*a1_ho->ncomp+k] = i*10.0+k;
}

if (on_gpu) gkyl_array_copy(a1, a1_ho);

// Apply min with threshold 15.0
gkyl_array_min_by_cell(a1, 15.0);

if (on_gpu) gkyl_array_copy(a1_ho, a1);

// Check that values > 15.0 are clamped to 15.0
for (unsigned i=0; i<a1_ho->size; ++i) {
for (size_t k=0; k<a1_ho->ncomp; ++k) {
double expected = (i*10.0+k < 15.0) ? i*10.0+k : 15.0;
TEST_CHECK( gkyl_compare(a1_ho_d[i*a1_ho->ncomp+k], expected, 1e-14) );
}
}

gkyl_array_release(a1_ho);
if (on_gpu) gkyl_array_release(a1);

// Test with negative threshold
struct gkyl_array *a2_ho = gkyl_array_new(GKYL_DOUBLE, 4, 8);
struct gkyl_array *a2 = a2_ho;
if (on_gpu) a2 = gkyl_array_cu_dev_new(GKYL_DOUBLE, a2_ho->ncomp, a2_ho->size);

double *a2_ho_d = a2_ho->data;
for (unsigned i=0; i<a2_ho->size; ++i) {
for (size_t k=0; k<a2_ho->ncomp; ++k)
a2_ho_d[i*a2_ho->ncomp+k] = (double)i - 5.0 + k*0.1;
}

if (on_gpu) gkyl_array_copy(a2, a2_ho);

gkyl_array_min_by_cell(a2, -2.5);

if (on_gpu) gkyl_array_copy(a2_ho, a2);

for (unsigned i=0; i<a2_ho->size; ++i) {
for (size_t k=0; k<a2_ho->ncomp; ++k) {
double orig = (double)i - 5.0 + k*0.1;
double expected = (orig < -2.5) ? orig : -2.5;
TEST_CHECK( gkyl_compare(a2_ho_d[i*a2_ho->ncomp+k], expected, 1e-14) );
}
}

gkyl_array_release(a2_ho);
if (on_gpu) gkyl_array_release(a2);
}

void test_array_min_range(bool on_gpu)
{
int lower[] = {1}, upper[] = {10};
struct gkyl_range range;
gkyl_range_init(&range, 1, lower, upper);

struct gkyl_array *a1_ho = gkyl_array_new(GKYL_DOUBLE, 3, range.volume);
struct gkyl_array *a1 = a1_ho;
if (on_gpu) a1 = gkyl_array_cu_dev_new(GKYL_DOUBLE, a1_ho->ncomp, a1_ho->size);

double *a1_ho_d = a1_ho->data;
for (unsigned i=0; i<a1_ho->size; ++i)
for (size_t k=0; k<a1_ho->ncomp; ++k)
a1_ho_d[i*a1_ho->ncomp+k] = i*10.0+k;

if (on_gpu) gkyl_array_copy(a1, a1_ho);

// Apply min only to subrange [2, 6]
int lowerSub[] = {2}, upperSub[] = {6};
struct gkyl_range subrange;
gkyl_sub_range_init(&subrange, &range, lowerSub, upperSub);

gkyl_array_min_by_cell_range(a1, 12.0, &subrange);

if (on_gpu) gkyl_array_copy(a1_ho, a1);

// Check cells outside subrange are unchanged
for (size_t k=0; k<a1_ho->ncomp; ++k) {
for (unsigned i=0; i<1; ++i)
TEST_CHECK( gkyl_compare(a1_ho_d[i*a1_ho->ncomp+k], i*10.0+k, 1e-14) );
for (unsigned i=6; i<10; ++i)
TEST_CHECK( gkyl_compare(a1_ho_d[i*a1_ho->ncomp+k], i*10.0+k, 1e-14) );
}

// Check cells in subrange have min applied
for (unsigned i=1; i<6; ++i) {
for (size_t k=0; k<a1_ho->ncomp; ++k) {
double orig = i*10.0+k;
double expected = (orig < 12.0) ? orig : 12.0;
TEST_CHECK( gkyl_compare(a1_ho_d[i*a1_ho->ncomp+k], expected, 1e-14) );
}
}

gkyl_array_release(a1_ho);
if (on_gpu) gkyl_array_release(a1);

// Test with different range and threshold
lower[0] = 1; upper[0] = 8;
struct gkyl_range range2;
gkyl_range_init(&range2, 1, lower, upper);

struct gkyl_array *a2_ho = gkyl_array_new(GKYL_DOUBLE, 4, range2.volume);
struct gkyl_array *a2 = a2_ho;
if (on_gpu) a2 = gkyl_array_cu_dev_new(GKYL_DOUBLE, a2_ho->ncomp, a2_ho->size);

double *a2_ho_d = a2_ho->data;
for (unsigned i=0; i<a2_ho->size; ++i) {
for (size_t k=0; k<a2_ho->ncomp; ++k)
a2_ho_d[i*a2_ho->ncomp+k] = i*5.0+k;
}

if (on_gpu) gkyl_array_copy(a2, a2_ho);

gkyl_array_min_by_cell_range(a2, 8.0, &subrange);

if (on_gpu) gkyl_array_copy(a2_ho, a2);

for (size_t k=0; k<a2_ho->ncomp; ++k) {
for (unsigned i=0; i<1; ++i)
TEST_CHECK( gkyl_compare(a2_ho_d[i*a2_ho->ncomp+k], i*5.0+k, 1e-14) );
for (unsigned i=6; i<8; ++i)
TEST_CHECK( gkyl_compare(a2_ho_d[i*a2_ho->ncomp+k], i*5.0+k, 1e-14) );
}

for (unsigned i=1; i<6; ++i) {
for (size_t k=0; k<a2_ho->ncomp; ++k) {
double orig = i*5.0+k;
double expected = (orig < 8.0) ? orig : 8.0;
TEST_CHECK( gkyl_compare(a2_ho_d[i*a2_ho->ncomp+k], expected, 1e-14) );
}
}

gkyl_array_release(a2_ho);
if (on_gpu) gkyl_array_release(a2);
}

void test_array_opcombine()
{
struct gkyl_array *a1 = gkyl_array_new(GKYL_DOUBLE, 1, 10);
Expand Down Expand Up @@ -882,6 +1050,14 @@ void test_array_shiftc_range_ho() {
test_array_shiftc_range(false);
}

void test_array_min_by_cell_ho() {
test_array_min_by_cell(false);
}

void test_array_min_range_ho() {
test_array_min_range(false);
}

// Cuda specific tests
#ifdef GKYL_HAVE_CUDA

Expand Down Expand Up @@ -1607,6 +1783,37 @@ void test_cu_array_shiftc()
gkyl_array_release(a2_cu);
}

void test_cu_array_invert_by_cell()
{
struct gkyl_array *a1_ho = gkyl_array_new(GKYL_DOUBLE, 3, 8);
struct gkyl_array *a1 = gkyl_array_cu_dev_new(GKYL_DOUBLE, 3, 8);
double *a1_ho_d = a1_ho->data;

// Set values: 1.0, 2.0, 4.0, 5.0, 10.0, 0.5, 0.25, 0.1
double test_vals[] = {1.0, 2.0, 4.0, 5.0, 10.0, 0.5, 0.25, 0.1};
double expected_inv[] = {1.0, 0.5, 0.25, 0.2, 0.1, 2.0, 4.0, 10.0};

for (unsigned i=0; i<a1_ho->size; ++i)
for (size_t k=0; k<a1_ho->ncomp; ++k)
a1_ho_d[i*a1_ho->ncomp+k] = test_vals[i];

// Copy to device
gkyl_array_copy(a1, a1_ho);

gkyl_array_invert_by_cell(a1);

// Copy back from device
gkyl_array_copy(a1_ho, a1);

// Check inverted values
for (unsigned i=0; i<a1_ho->size; ++i)
for (size_t k=0; k<a1_ho->ncomp; ++k)
TEST_CHECK( gkyl_compare(a1_ho_d[i*a1_ho->ncomp+k], expected_inv[i], 1e-14) );

gkyl_array_release(a1_ho);
gkyl_array_release(a1);
}

void test_cu_array_copy_buffer()
{
int shape[] = {10, 20};
Expand Down Expand Up @@ -1852,6 +2059,14 @@ void test_array_shiftc_range_dev() {
test_array_shiftc_range(true);
}

void test_array_min_by_cell_dev() {
test_array_min_by_cell(true);
}

void test_array_min_range_dev() {
test_array_min_range(true);
}

#endif

TEST_LIST = {
Expand All @@ -1868,8 +2083,11 @@ TEST_LIST = {
{ "array_set_offset_range", test_array_set_offset_range },
{ "array_scale", test_array_scale },
{ "array_scale_by_cell", test_array_scale_by_cell },
{ "array_invert_by_cell", test_array_invert_by_cell },
{ "array_shiftc", test_array_shiftc },
{ "array_shiftc_range", test_array_shiftc_range_ho },
{ "array_min_by_cell", test_array_min_by_cell_ho },
{ "array_min_range", test_array_min_range_ho },
{ "array_opcombine", test_array_opcombine },
{ "array_ops_comp", test_array_ops_comp },
{ "array_copy_buffer", test_array_copy_buffer },
Expand All @@ -1892,8 +2110,11 @@ TEST_LIST = {
{ "cu_array_set_offset_range", test_cu_array_set_offset_range },
{ "cu_array_scale", test_cu_array_scale },
{ "cu_array_scale_by_cell", test_cu_array_scale_by_cell },
{ "cu_array_invert_by_cell", test_cu_array_invert_by_cell },
{ "cu_array_shiftc", test_cu_array_shiftc },
{ "cu_array_shiftc_range", test_array_shiftc_range_dev },
{ "cu_array_min_by_cell", test_array_min_by_cell_dev },
{ "cu_array_min_by_cell_range", test_array_min_range_dev },
{ "cu_array_copy_buffer", test_cu_array_copy_buffer },
{ "cu_array_copy_buffer_fn", test_cu_array_copy_buffer_fn },
{ "cu_array_flip_copy_buffer_fn", test_cu_array_flip_copy_buffer_fn },
Expand Down
48 changes: 48 additions & 0 deletions core/zero/array_ops.c
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,40 @@ gkyl_array_scale_by_cell(struct gkyl_array* out, const struct gkyl_array* a)
return out;
}

struct gkyl_array*
gkyl_array_min_by_cell(struct gkyl_array* out, double a)
{
assert(out->type == GKYL_DOUBLE);
#ifdef GKYL_HAVE_CUDA
if (gkyl_array_is_cu_dev(out)) { gkyl_array_min_by_cell_cu(out, a); return out; }
#endif

double *out_d = out->data;
for (size_t i=0; i<NELM(out); ++i)
out_d[i] = fmin(out_d[i], a);
return out;
}

struct gkyl_array*
gkyl_array_min_by_cell_range(struct gkyl_array* out, double a, const struct gkyl_range *range)
{
assert(out->type == GKYL_DOUBLE);
#ifdef GKYL_HAVE_CUDA
if (gkyl_array_is_cu_dev(out)) { gkyl_array_min_by_cell_range_cu(out, a, range); return out; }
#endif

struct gkyl_range_iter iter;
gkyl_range_iter_init(&iter, range);

while (gkyl_range_iter_next(&iter)) {
long start = gkyl_range_idx(range, iter.idx);
double *out_d = gkyl_array_fetch(out, start);
for (size_t c=0; c<NCOM(out); ++c)
out_d[c] = fmin(out_d[c], a);
}
return out;
}

struct gkyl_array*
gkyl_array_divide_by_cell(struct gkyl_array* out, const struct gkyl_array* a)
{
Expand All @@ -169,6 +203,20 @@ gkyl_array_divide_by_cell(struct gkyl_array* out, const struct gkyl_array* a)
return out;
}

struct gkyl_array*
gkyl_array_invert_by_cell(struct gkyl_array* out)
{
assert(out->type == GKYL_DOUBLE);
#ifdef GKYL_HAVE_CUDA
if (gkyl_array_is_cu_dev(out)) { gkyl_array_invert_by_cell_cu(out); return out; }
#endif

double *out_d = out->data;
for (size_t i=0; i<NELM(out); ++i)
out_d[i] = 1.0/out_d[i];
return out;
}

struct gkyl_array*
gkyl_array_shiftc(struct gkyl_array* out, double a, unsigned k)
{
Expand Down
Loading
Loading