Skip to content

Commit d4eb752

Browse files
committed
add tests
1 parent 7d5ded6 commit d4eb752

File tree

4 files changed

+161
-70
lines changed

4 files changed

+161
-70
lines changed

.github/workflows/matlab.yml

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
name: MATLAB CI
2+
3+
on:
4+
push:
5+
pull_request:
6+
7+
jobs:
8+
test:
9+
strategy:
10+
matrix:
11+
os: [ubuntu-latest] # add macos-latest, windows-latest if desired
12+
runs-on: ${{ matrix.os }}
13+
14+
steps:
15+
- name: Checkout
16+
uses: actions/checkout@v4
17+
18+
- name: Setup MATLAB
19+
uses: matlab-actions/setup-matlab@v2
20+
21+
- name: Run MATLAB unit tests
22+
uses: matlab-actions/run-tests@v2
23+
with:
24+
select-by-folder: tests
25+
test-results-junit: test-results/results.xml
26+
27+
- name: Upload test results
28+
if: always()
29+
uses: actions/upload-artifact@v4
30+
with:
31+
name: test-results
32+
path: test-results

cylinder.m

Lines changed: 78 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
1-
21
clc;
32
clear;
43

4+
%% Check if running in CI environment
5+
isCI = strcmpi(getenv('CI'), 'true');
6+
doPlot = ~isCI;
7+
58
%%
69
addpath("distmesh/")
710

@@ -99,26 +102,26 @@
99102

100103

101104
%%
102-
figure;
103-
104-
105-
scatter(xy(:,1),xy(:,2),'k.'); hold on; axis square;
106-
scatter(boundary_in(:,1),boundary_in(:,2),'b+');
107-
scatter(boundary_y(:,1),boundary_y(:,2),'r+');
108-
scatter(boundary_out(:,1),boundary_out(:,2),'b+');
109-
scatter(boundary_c(:,1),boundary_c(:,2),'m+');
110-
111-
%
112-
% scatter(xy_s(:,1),xy_s(:,2),'r.'); hold on; axis square;
113-
% %
114-
% scatter(boundary_in_s(:,1),boundary_in_s(:,2),'k*');
115-
% %
116-
% scatter(boundary_out_s(:,1),boundary_out_s(:,2),'k*');
117-
% scatter(boundary_y_s(:,1),boundary_y_s(:,2),'b*');
118-
% scatter(boundary_c_s(:,1),boundary_c_s(:,2),'b .');
119-
120-
axis equal;
121-
105+
if doPlot
106+
figure;
107+
108+
scatter(xy(:,1),xy(:,2),'k.'); hold on; axis square;
109+
scatter(boundary_in(:,1),boundary_in(:,2),'b+');
110+
scatter(boundary_y(:,1),boundary_y(:,2),'r+');
111+
scatter(boundary_out(:,1),boundary_out(:,2),'b+');
112+
scatter(boundary_c(:,1),boundary_c(:,2),'m+');
113+
114+
%
115+
% scatter(xy_s(:,1),xy_s(:,2),'r.'); hold on; axis square;
116+
% %
117+
% scatter(boundary_in_s(:,1),boundary_in_s(:,2),'k*');
118+
% %
119+
% scatter(boundary_out_s(:,1),boundary_out_s(:,2),'k*');
120+
% scatter(boundary_y_s(:,1),boundary_y_s(:,2),'b*');
121+
% scatter(boundary_c_s(:,1),boundary_c_s(:,2),'b .');
122+
123+
axis equal;
124+
end
122125

123126
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
124127
% xy1: V-grid; xy1_s: P-grid.
@@ -394,6 +397,12 @@
394397
%
395398
nu =1/100; dt = 1e-2;
396399

400+
% Set reduced number of time steps for CI environment
401+
Nt = 5000;
402+
if isCI
403+
Nt = 20; % Keep tests fast in CI
404+
end
405+
397406
%
398407
L = L0;
399408
L(length(xy)+1:end,:) = zeros(length(boundary),length(xy1));
@@ -434,8 +443,6 @@
434443
W0 = [U0;V0];
435444

436445

437-
Nt = 5000;
438-
439446
W = zeros(length(xy1)*2,Nt+1);
440447

441448
W(:,1) = W0;
@@ -486,53 +493,54 @@
486493

487494
%%
488495

489-
490-
figure('Name','1/Re = 1e-2');
491-
492-
colormap(jet)
493-
494-
% for j =1:1:5000
495-
j = Nt;
496-
497-
% colormap(bluered)
498-
499-
% j = (j1-1)* 1600 +3;
500-
U = W(1:length(xy1),(j-1)*1+1);
501-
V = W(length(xy1)+1:end,(j-1)*1+1);
502-
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
503-
subplot(2,1,1);
504-
scatter(x1,y1,15*ones(length(xy1),1),1*(U-1),'.');
505-
axis equal, axis tight, hold on;
506-
% colorbar
507-
xlim([x_min x_max]);
508-
ylim([y_min y_max]);
509-
yticks([-5 0 5])
510-
xticks([-5 0 5 10 15])
511-
title(['u']);
512-
ylabel('y');
513-
xlabel('x');
514-
shading interp;
515-
caxis([-1e-0 1e-0]);
516-
517-
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
518-
subplot(2,1,2);
519-
scatter(x1,y1,15*ones(length(xy1),1),1*V,'.');
520-
axis equal, axis tight, hold on;
521-
% colorbar
522-
shading interp;
523-
524-
xlim([x_min x_max]);
525-
ylim([y_min y_max]);
526-
yticks([-5 0 5])
527-
xticks([-5 0 5 10 15])
528-
title(['v' ]);
529-
530-
xlabel('x');
531-
ylabel('y');
532-
set(gca,'Ytick',[]);
533-
caxis([-1e-0 1e-0]);
534-
535-
drawnow;
496+
if doPlot
497+
figure('Name','1/Re = 1e-2');
498+
499+
colormap(jet)
500+
501+
% for j =1:1:5000
502+
j = Nt;
503+
504+
% colormap(bluered)
505+
506+
% j = (j1-1)* 1600 +3;
507+
U = W(1:length(xy1),(j-1)*1+1);
508+
V = W(length(xy1)+1:end,(j-1)*1+1);
509+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
510+
subplot(2,1,1);
511+
scatter(x1,y1,15*ones(length(xy1),1),1*(U-1),'.');
512+
axis equal, axis tight, hold on;
513+
% colorbar
514+
xlim([x_min x_max]);
515+
ylim([y_min y_max]);
516+
yticks([-5 0 5])
517+
xticks([-5 0 5 10 15])
518+
title(['u']);
519+
ylabel('y');
520+
xlabel('x');
521+
shading interp;
522+
caxis([-1e-0 1e-0]);
523+
524+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
525+
subplot(2,1,2);
526+
scatter(x1,y1,15*ones(length(xy1),1),1*V,'.');
527+
axis equal, axis tight, hold on;
528+
% colorbar
529+
shading interp;
530+
531+
xlim([x_min x_max]);
532+
ylim([y_min y_max]);
533+
yticks([-5 0 5])
534+
xticks([-5 0 5 10 15])
535+
title(['v' ]);
536+
537+
xlabel('x');
538+
ylabel('y');
539+
set(gca,'Ytick',[]);
540+
caxis([-1e-0 1e-0]);
541+
542+
drawnow;
543+
end
536544

537545
% end
538546

readme.md

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,31 @@ This MATLAB code implements a mesh-free method to solve the incompressible Navie
3131
- The simulation is computationally intensive and may take time to complete
3232
- For a full simulation with 5000 time steps, expect several minutes of computation time depending on your hardware
3333

34+
### Testing with GitHub Actions
35+
36+
This repository includes automated testing using GitHub Actions to ensure the code runs correctly across different environments.
37+
38+
1. **Test Configuration**:
39+
- Tests are defined in the `tests/TestCylinder.m` file using MATLAB's unit testing framework
40+
- The GitHub Actions workflow is configured in `.github/workflows/matlab.yml`
41+
- In CI environments, the simulation runs with a reduced number of time steps (20 instead of 5000)
42+
43+
2. **What the Tests Verify**:
44+
- Basic smoke test to ensure the code runs without errors
45+
- Verification of output dimensions and data integrity
46+
- Confirmation that boundary conditions are properly enforced
47+
- No NaN or Inf values in the solution
48+
49+
3. **Running Tests Locally**:
50+
- You can run the tests locally using MATLAB's test framework:
51+
```matlab
52+
runtests('tests')
53+
```
54+
55+
4. **Adding New Tests**:
56+
- Additional tests can be added to the `tests/TestCylinder.m` file
57+
- Follow MATLAB's unit testing framework conventions for new test methods
58+
3459
#### Key Components
3560

3661
##### 1. Domain and Mesh Generation

tests/TestCylinder.m

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
classdef TestCylinder < matlab.unittest.TestCase
2+
methods (Test)
3+
function smokeRun(testCase)
4+
% On GitHub Actions, CI=true is already set.
5+
% Run the main script; variables land in this workspace.
6+
cylinder
7+
8+
% Basic existence checks
9+
testCase.verifyTrue(exist('W','var')==1);
10+
testCase.verifyTrue(exist('xy1','var')==1);
11+
12+
% Dimensions consistent
13+
testCase.verifyEqual(size(W,1), 2*length(xy1));
14+
15+
% No NaNs or Infs
16+
testCase.verifyFalse(any(isnan(W(:))));
17+
testCase.verifyFalse(any(isinf(W(:))));
18+
19+
% Enforce no-slip on cylinder at final step (U,V zero on cylinder nodes)
20+
U = W(1:length(xy1), end);
21+
V = W(length(xy1)+1:end, end);
22+
testCase.verifyLessThan(max(abs(U(end-length(boundary_c)+1:end))), 1e-8);
23+
testCase.verifyLessThan(max(abs(V(end-length(boundary_c)+1:end))), 1e-8);
24+
end
25+
end
26+
end

0 commit comments

Comments
 (0)