Skip to content

Commit 98c8932

Browse files
committed
Alfven test case using the same parameters as Fluxo
1 parent 7d24f33 commit 98c8932

2 files changed

Lines changed: 197 additions & 0 deletions

File tree

examples/ideal_MHD_alfven_fluxo.m

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
%clc
2+
clear
3+
close all
4+
5+
addpath('../matlab')
6+
7+
BalanceLaws.prepare_vars();
8+
global I_Mesh I_TI I_BalanceLaws I_Tech I_RunOps I_Results
9+
10+
% Alfven wave testcase used in [Fluxo](https://github.com/project-fluxo/fluxo), domain [-1,1]^3.
11+
N = uint32(40);
12+
I_Mesh('NODES_X') = N; I_Mesh('NODES_Y') = N; I_Mesh('NODES_Z') = uint32(5);
13+
I_Mesh('XMIN') = -1.0; I_Mesh('XMAX') = 1.0;
14+
I_Mesh('YMIN') = -1.0; I_Mesh('YMAX') = 1.0;
15+
I_Mesh('ZMIN') = -1.0; I_Mesh('ZMAX') = 1.0;
16+
17+
I_TI('final_time') = 125;
18+
I_TI('cfl') = 0.4;
19+
20+
dt = I_TI('cfl') * 2.0 / double(I_Mesh('NODES_Y'));
21+
num_steps = ceil(I_TI('final_time')/dt);
22+
dt = I_TI('final_time') / num_steps;
23+
24+
%Time integrator: SSPRK33 SSPRK104 CalvoFrancoRandez2R64
25+
%KennedyCarpenterLewis2R54C CarpenterKennedy2N54 ToulorgeDesmet2N84F
26+
I_TI('time_integrator') = 'CarpenterKennedy2N54';
27+
28+
I_TI('DT') = dt;
29+
I_TI('num_steps') = num_steps;
30+
31+
I_Tech('device') = 1;
32+
I_Tech('REAL') = 'double'; % float, double
33+
I_Tech('REAL4') = sprintf('%s4',I_Tech('REAL')); %Vector datatype
34+
I_Tech('memory_layout') = 'USE_STRUCTURE_OF_ARRAYS'; % USE_ARRAY_OF_STRUCTURES, USE_STRUCTURE_OF_ARRAYS
35+
36+
% Use as kernel defines to keep consistency with header files?
37+
I_BalanceLaws('NUM_CONSERVED_VARS') = 8;
38+
I_BalanceLaws('NUM_AUXILIARY_VARS') = 4;
39+
I_BalanceLaws('NUM_TOTAL_VARS') = I_BalanceLaws('NUM_CONSERVED_VARS') + I_BalanceLaws('NUM_AUXILIARY_VARS');
40+
41+
%Compiler based optimizations
42+
if strcmp(I_Tech('REAL'),'float')
43+
I_Tech('optimizations') = ' -cl-mad-enable -cl-no-signed-zeros -cl-finite-math-only -cl-single-precision-constant';
44+
else
45+
I_Tech('optimizations') = ' -cl-mad-enable -cl-no-signed-zeros -cl-finite-math-only';
46+
end
47+
48+
I_RunOps('periodic') = 'USE_PERIODIC'; % 'NONE', 'USE_PERIODIC'; must be set to 'USE_PERIODIC'
49+
% if periodic boundary conditions should be used
50+
51+
I_RunOps('order') = 6; I_RunOps('operator_form') = 'classical'; % order: 2, 4, 6; operator_form: classical, extended
52+
I_RunOps('conservation_laws') = 'ideal_MHD';
53+
I_RunOps('testcase') = 'alfven_fluxo';
54+
I_RunOps('plot_numerical_solution') = 'z';
55+
I_RunOps('save_integrals_over_time') = false;
56+
% Choose between L2 and LInfinity norm for error calculation
57+
I_RunOps('norm') = 'LInf'; % L2, LInf
58+
%% Initialize variables
59+
[field_u1, field_u2] = BalanceLaws.initialize();
60+
61+
fprintf('Testcase: %s \nOrder: %d \nTime integrator: %s\nDT: %.16e N_STEPS: %5d FINAL_TIME: %.16e\nDX: %.16e NODES_X: %5d\nDY: %.16e NODES_Y: %5d\nDZ: %.16e NODES_Z: %5d \nREAL: %s\n\n',...
62+
I_RunOps('testcase'), I_RunOps('order'), I_TI('time_integrator'), I_TI('DT'), I_TI('num_steps'), I_TI('final_time'), I_Mesh('DX'), I_Mesh('NODES_X'), I_Mesh('DY'), I_Mesh('NODES_Y'), I_Mesh('DZ'), I_Mesh('NODES_Z'), I_Tech('REAL'));
63+
%% Compute numerical solution
64+
BalanceLaws.compute_numerical_solution(field_u1, field_u2);
65+
fprintf('Total runtime: %.3f seconds Kernel runtime: %d\n', I_Results('runtime'), I_Results('kernel_runtime'));
66+
67+
rel_err = I_Results('rel_err');
68+
for comp=0:I_BalanceLaws('NUM_CONSERVED_VARS') - 1
69+
fprintf('Relative Error of Field Component %d: %.15f %%\n', comp, 100*rel_err(comp + 1))
70+
end
71+
72+
%% Plot numerical solution
73+
num_nodes = I_Mesh('NODES_X')*I_Mesh('NODES_Y')*I_Mesh('NODES_Z');
74+
if strcmp(I_Tech('memory_layout'), 'USE_ARRAY_OF_STRUCTURES')
75+
field_u1_plot = reshape(field_u1(1:num_nodes*I_BalanceLaws('NUM_TOTAL_VARS')), [I_BalanceLaws('NUM_TOTAL_VARS'), num_nodes]);
76+
elseif strcmp(I_Tech('memory_layout'), 'USE_STRUCTURE_OF_ARRAYS')
77+
field_u1_tmp = reshape(field_u1, I_Tech('NUM_NODES_PAD'), I_BalanceLaws('NUM_TOTAL_VARS'));
78+
field_u1_plot = field_u1_tmp(1:num_nodes, :)';
79+
else
80+
error('You must USE_ARRAY_OF_STRUCTURES or USE_STRUCTURE_OF_ARRAYS.')
81+
end
82+
83+
%Optional plots
84+
if ismember(lower(char(I_RunOps('plot_numerical_solution'))),{'x','y','z','xy', 'xz', 'yz', 'xyz'})
85+
plot_2D(field_u1_plot, I_RunOps('plot_numerical_solution'),...
86+
I_Mesh('NODES_X'), I_Mesh('NODES_Y'), I_Mesh('NODES_Z'), 'Numerical Solution', 6, 8);
87+
end
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
// This project is licensed under the terms of the Creative Commons CC BY-NC-ND 4.0 license.
2+
3+
//--------------------------------------------------------------------------------------------------
4+
// Functions for field initialisation
5+
//--------------------------------------------------------------------------------------------------
6+
7+
/*
8+
Alfven wave testcase used in [Fluxo](https://github.com/project-fluxo/fluxo), domain [-1,1]^3.
9+
*/
10+
11+
// paramters of the Alfven wave test case
12+
#define CONST_FREQUENCY 1
13+
REAL constant CONST_omega = 6.283185307179586 * CONST_FREQUENCY;
14+
REAL constant CONST_r = 2; // lenght-variable = lenght of computational domain
15+
REAL constant CONST_e = 0.2; // epsilon = 0.2
16+
17+
/*
18+
Analytical solution of the velocity field.
19+
*/
20+
inline REAL4 u_analytical(uint ix, uint iy, uint iz, REAL time) {
21+
22+
REAL x = (REAL)XMIN + ix*(REAL)DX;
23+
REAL y = (REAL)YMIN + iy*(REAL)DY;
24+
REAL z = (REAL)ZMIN + iz*(REAL)DZ;
25+
26+
REAL nx = rsqrt(CONST_r*CONST_r + 1);
27+
REAL ny = CONST_r * rsqrt(CONST_r*CONST_r + 1);
28+
REAL sqr = 1;
29+
REAL Va = CONST_omega / (ny * sqr);
30+
REAL phi_alv = CONST_omega / ny * (nx * (x - 0.5*CONST_r) + ny * (y - 0.5*CONST_r)) - Va * time;
31+
32+
REAL u1 = - CONST_e * ny * cos(phi_alv);
33+
REAL u2 = CONST_e * nx * cos(phi_alv);
34+
REAL u3 = CONST_e * sin(phi_alv);
35+
36+
return (REAL4) {u1, u2, u3, (REAL)(0)};
37+
}
38+
39+
/*
40+
Analytical solution of the magnetic field.
41+
*/
42+
inline REAL4 b_analytical(uint ix, uint iy, uint iz, REAL time) {
43+
44+
REAL x = (REAL)XMIN + ix*(REAL)DX;
45+
REAL y = (REAL)YMIN + iy*(REAL)DY;
46+
REAL z = (REAL)ZMIN + iz*(REAL)DZ;
47+
48+
REAL nx = rsqrt(CONST_r*CONST_r + 1);
49+
REAL ny = CONST_r * rsqrt(CONST_r*CONST_r + 1);
50+
REAL sqr = 1;
51+
REAL Va = CONST_omega / (ny * sqr);
52+
REAL phi_alv = CONST_omega / ny * (nx * (x - 0.5*CONST_r) + ny * (y - 0.5*CONST_r)) - Va * time;
53+
54+
REAL B1 = nx + CONST_e * ny * cos(phi_alv) * sqr;
55+
REAL B2 = ny - CONST_e * nx * cos(phi_alv) * sqr;
56+
REAL B3 = - CONST_e * sin(phi_alv) * sqr;
57+
58+
return (REAL4) {B1, B2, B3, (REAL)(0)};
59+
}
60+
61+
/*
62+
Boundary condition of the magnetic field.
63+
*/
64+
inline REAL4 b_boundary(uint ix, uint iy, uint iz, REAL time) {
65+
66+
return b_analytical(ix, iy, iz, time);
67+
}
68+
69+
/*
70+
Boundary condition of the velocity field.
71+
*/
72+
inline REAL4 u_boundary(uint ix, uint iy, uint iz, REAL time) {
73+
74+
return u_analytical(ix, iy, iz, time);
75+
}
76+
77+
78+
/* Boundary condition of the pressure and density */
79+
80+
inline REAL p_boundary(uint ix, uint iy, uint iz, REAL time) {
81+
82+
return (REAL)(1);
83+
}
84+
85+
inline REAL rho_boundary(uint ix, uint iy, uint iz, REAL time) {
86+
87+
return (REAL)(1);
88+
}
89+
90+
91+
/* initial conditions for the simulation */
92+
93+
inline REAL4 b_initial(uint ix, uint iy, uint iz, REAL time){
94+
95+
return b_analytical(ix, iy, iz, time);
96+
}
97+
98+
inline REAL4 u_initial(uint ix, uint iy, uint iz, REAL time){
99+
100+
return u_analytical(ix, iy, iz, time);
101+
}
102+
103+
inline REAL p_initial(uint idx, uint iy, uint iz, REAL time){
104+
return (REAL)(1);
105+
}
106+
107+
inline REAL rho_initial(uint idx, uint iy, uint iz, REAL time){
108+
109+
return (REAL)(1);
110+
}

0 commit comments

Comments
 (0)