aboutsummaryrefslogtreecommitdiffstats
path: root/lib/compiler/test/inline_SUITE_data/barnes2.erl
diff options
context:
space:
mode:
Diffstat (limited to 'lib/compiler/test/inline_SUITE_data/barnes2.erl')
-rw-r--r--lib/compiler/test/inline_SUITE_data/barnes2.erl160
1 files changed, 160 insertions, 0 deletions
diff --git a/lib/compiler/test/inline_SUITE_data/barnes2.erl b/lib/compiler/test/inline_SUITE_data/barnes2.erl
new file mode 100644
index 0000000000..a986331060
--- /dev/null
+++ b/lib/compiler/test/inline_SUITE_data/barnes2.erl
@@ -0,0 +1,160 @@
+% file: "barnes.erl"
+
+-module(barnes2).
+-export([?MODULE/0]).
+
+?MODULE() ->
+ Stars = create_scenario(1000, 1.0),
+ R = hd(loop(10,1000.0,Stars,0)),
+ Str = lists:flatten(io:lib_format("~s", [R])),
+ {R,Str =:= {1.00000,-1.92269e+4,-1.92269e+4,2.86459e-2,2.86459e-2}}.
+
+create_scenario(N, M) ->
+ create_scenario0(0, 0, trunc(math:sqrt(N)), M).
+
+create_scenario0(_X, _SN, _SN, _M) ->
+ [];
+create_scenario0(SN, Y, SN, M) ->
+ create_scenario0(0, Y+1, SN, M);
+create_scenario0(X, Y, SN, M) ->
+ XPos0 = (((20000.0 * 2) / SN) * X) - 20000.0,
+ YPos0 = (((20000.0 * 2) / SN) * Y) - 20000.0,
+ Calibrate = ((20000.0 * 2) / SN) / 2,
+ XPos = XPos0 + Calibrate,
+ YPos = YPos0 + Calibrate,
+ [{M, XPos, YPos, 0.0, 0.0} | create_scenario0(X+1, Y, SN, M)].
+
+relpos_to_quadrant(DX, DY) when DX >= 0 ->
+ if
+ DY >= 0 -> 0;
+ true -> 3
+ end;
+relpos_to_quadrant(_, DY) ->
+ if
+ DY >= 0 -> 1;
+ true -> 2
+ end.
+
+quadrant_to_dx(0, D) -> D;
+quadrant_to_dx(1, D) -> -D;
+quadrant_to_dx(2, D) -> -D;
+quadrant_to_dx(3, D) -> D.
+
+quadrant_to_dy(Q,D) ->
+ if
+ Q < 2 -> D;
+ true -> -D
+ end.
+
+create_tree(Stars) ->
+ create_tree0(Stars, empty).
+
+create_tree0([],Tree) ->
+ Tree;
+create_tree0([{M,X,Y,_,_} | Stars], Tree) ->
+ create_tree0(Stars, insert_tree_element(Tree, M, X, Y, 0.0, 0.0, 20000.0)).
+
+insert_tree_element(empty, M, X, Y, _OX, _OY, _D) ->
+ {body,M,X,Y};
+insert_tree_element({branch,M0,SubTree}, M, X, Y, OX, OY, D) ->
+ Q = relpos_to_quadrant(X-OX,Y-OY),
+ D2 = D / 2,
+ DX = quadrant_to_dx(Q,D2),
+ DY = quadrant_to_dy(Q,D2),
+ {branch,M0+M,setelement(Q+1,SubTree,
+ insert_tree_element(element(Q+1,SubTree),
+ M, X, Y, OX+DX, OY+DY,D2))};
+insert_tree_element({body,M0,X0,Y0},M,X,Y,OX,OY,D) ->
+ resolve_body_conflict(M,X,Y,M0,X0,Y0,OX,OY,D).
+
+resolve_body_conflict(M0, X0, Y0, M1, X1, Y1, OX, OY, D) ->
+ T = {empty,empty,empty,empty},
+ Q0 = relpos_to_quadrant(X0-OX,Y0-OY),
+ Q1 = relpos_to_quadrant(X1-OX,Y1-OY),
+ D2 = D / 2,
+ if
+ Q0 == Q1 -> DX = quadrant_to_dx(Q0,D2),
+ DY = quadrant_to_dy(Q1,D2),
+ {branch,M0+M1,setelement(Q0+1,T,
+ resolve_body_conflict(M0,X0,Y0,
+ M1,X1,Y1,
+ OX+DX,OY+DY,
+ D2))} ;
+ true -> {branch,M0+M1, setelement(Q1+1,
+ setelement(Q0+1,T,{body,M0,X0,Y0}),
+ {body,M1,X1,Y1})}
+ end.
+
+compute_acceleration(empty, _, _, _, _, _,L) ->
+ {{0.0, 0.0},L+1};
+compute_acceleration({body,BM,BX,BY}, _D, _OX, _OY, X, Y,L) ->
+ DX = BX - X,
+ DY = BY - Y,
+ R2 = (DX * DX) + (DY * DY),
+ Divisor = R2 * math:sqrt(R2),
+ if
+ Divisor < 0.000001 -> % was: Divisor < ?EPSILON ->
+ {{0.0, 0.0},L+1};
+ true ->
+ Expr = BM / Divisor,
+ {{DX * Expr, DY * Expr},L+1}
+ end;
+compute_acceleration({branch,M,SubTree}, D, OX, OY, X, Y,L) ->
+ DX = OX - X,
+ DY = OY - Y,
+ R2 = (DX * DX) + (DY * DY),
+ DD = D*D,
+ R2_THETA2 = 0.09 * R2, % TRY 2.0 *R2, !!! was: R2_THETA2 = ?THETA2*R2,
+ if
+ % Ok to approximate?
+ DD < R2_THETA2 ->
+ Divisor = R2 * math:sqrt(R2),
+ if
+ Divisor < 0.000001 ->
+ {{0.0,0.0},L};
+ true ->
+ Expr = M / Divisor,
+ {{DX*Expr, DY*Expr},L+1}
+ end;
+ % Not ok to approximate...
+ true ->
+ D2 = D / 2,
+ {{AX0, AY0},L1} = compute_acceleration(element(1,SubTree),
+ D2, OX + quadrant_to_dx(0,D2),
+ OY + quadrant_to_dy(0,D2),X,Y,L),
+ {{AX1, AY1},L2} = compute_acceleration(element(2,SubTree),
+ D2, OX + quadrant_to_dx(1,D2),
+ OY + quadrant_to_dy(1,D2),X,Y,L1),
+ {{AX2, AY2},L3} = compute_acceleration(element(3,SubTree),
+ D2,OX + quadrant_to_dx(2,D2),
+ OY + quadrant_to_dy(2,D2),X,Y,L2),
+ {{AX3, AY3},L4} = compute_acceleration(element(4,SubTree),
+ D2, OX + quadrant_to_dx(3,D2),
+ OY + quadrant_to_dy(3,D2),X,Y,L3),
+ {{AX0+AX1+AX2+AX3, AY0+AY1+AY2+AY3},L4+1}
+ end.
+
+compute_star_accelerations(_Tree,[],L) ->
+ {[],L};
+compute_star_accelerations(Tree,[{_,X, Y,_,_}|Stars],L) ->
+ {A,AL} = compute_acceleration(Tree, 20000.0, 0.0, 0.0, X, Y,L),
+ {B,BL} = compute_star_accelerations(Tree, Stars,AL),
+ {[A | B],BL}.
+
+compute_next_state([],_,_) ->
+ [];
+compute_next_state([{M,X,Y,VX,VY}|Stars],[{AX,AY}|Accs],Time) ->
+ VX0 = VX + (AX * Time),
+ VY0 = VY + (AY * Time),
+ [{M,X+(VX*Time),Y+(VY*Time),VX0,VY0} | compute_next_state(Stars,Accs,Time)].
+
+advance_time(Time,Stars,L) ->
+ Tree = create_tree(Stars),
+ {Acc,NL} = compute_star_accelerations(Tree, Stars,L),
+ {compute_next_state(Stars, Acc, Time),NL}.
+
+loop(0,_Time,Stars,_L) ->
+ Stars;
+loop(N,Time,Stars,L) ->
+ {NS,NL} = advance_time(Time,Stars,L),
+ loop(N-1,Time,NS,NL).