Skip to content

Commit 287ca4a

Browse files
committed
Updates and progress on cmfd
1 parent 41d956b commit 287ca4a

22 files changed

+845
-403
lines changed

.DS_Store

-8 KB
Binary file not shown.

QMC-NDA-Woes.ipynb

-380
This file was deleted.

QMC-NDA_is_Better.ipynb

+494
Large diffs are not rendered by default.

ctk_nda_src/NDA_QMC.jl

+10-1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,12 @@ using PyPlot
1111
using Printf
1212
using Sobol
1313

14+
export sn_flux
15+
export plot_test
16+
export cmfd_si
17+
export cmfd_krylov
18+
export ftoc
19+
export ctof
1420
export ndaerr
1521
export averop
1622
export fprintTeX
@@ -58,14 +64,17 @@ include("compare.jl")
5864
include("nda.jl")
5965
include("nda_iteration.jl")
6066
include("siewert.jl")
67+
include("sn_flux.jl")
6168
include("Tim_QMC/qmc_nda.jl")
6269
include("Tim_QMC/ctk_qmc_init.jl")
6370
include("Tim_QMC/qmc_krylov.jl")
6471
include("Tim_QMC/ctk_qmc_sweep.jl")
6572
include("Tim_QMC/ctk_qmc_nda_test.jl")
6673
include("Tim_QMC/sn_test.jl")
6774
include("fprintTex.jl")
68-
include("averop.jl")
75+
include("Tim_CMFD/averop.jl")
6976
include("Tim_NDA/sanity.jl")
7077
include("Tim_NDA/ndaerr.jl")
78+
include("Tim_CMFD/cmfd.jl")
79+
include("Tim_CMFD/plot_test.jl")
7180
end

ctk_nda_src/Tim_CMFD/'

+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
function plot_test(N, Nx, Nc)
2+
tau=5.0; dx=tau/Nc; x=.5*dx:dx:tau-.5*dx;
3+
z=dx:dx:tau-dx;
4+
gm_out=cmfd_krylov(N, Nx, Nc)
5+
dsola=zeros(Nc)
6+
#
7+
# cell centered flux
8+
#
9+
sol=gm_out.sol
10+
#
11+
# derivative of flux at interior cell edges
12+
#
13+
@views dsol=(sol[2:Nc]-sol[1:Nc-1])/dx
14+
#
15+
# Map to cell centers
16+
#
17+
@views dsola[2:Nc-1] = .5*(dsol[1:Nc-2] + dsol[2:Nc-1])
18+
dsola[1]=2.0 * dsol[1]-dsol[2]
19+
dsola[Nc]=2.0 * dsol[Nc-1]-dsol[Nc-2]
20+
#
21+
# Now do the currents and D-hat
22+
#
23+
J_c = gm_out.J_c
24+
Dhat = ((dsola/(3.0*dx)) + J_c)./sol
25+
#
26+
# You can see why we need large N in the plots
27+
#
28+
plot(x,sol,"k-", x, dsola, "k--", x, J_c, "k.", x, Dhat, "k-.))
29+
title("Flux data: N = $N, Nx = $Nx, Nc = $Nc")
30+
legend([L" \phi", L"d \phi/dx", L"J_c", L"\hat D "])
31+
end

ctk_nda_src/Tim_CMFD/averop.jl

+61
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
function averop(p,n)
2+
d=2.0*ones(n)/4.0;
3+
d[1]=2.0/3.0;
4+
d[n]=2.0/3.0;
5+
du=ones(n-1)/4.0;
6+
du[1]=1.0/3.0;
7+
dl=ones(n-1)/4.0;
8+
dl[n-1]=1.0/3.0;
9+
T=Tridiagonal(dl,d,du);
10+
A=sparse(T^p);
11+
return A
12+
end
13+
14+
15+
"""
16+
ftoc(uf, uc)
17+
18+
fine to coarse intergrid transfer. This is a cell average deal and
19+
the number of cells must be a power of 2
20+
"""
21+
function ftoc(uf, uc)
22+
nf=length(uf)
23+
nc=length(uc)
24+
lnf=Int(log2(nf))
25+
(2^lnf == nf) || error("number of cells must be power of 2")
26+
lnc=Int(log2(nc))
27+
(2^lnc == nc) || error("number of cells must be power of 2")
28+
ncells = Int(nf/nc)
29+
for ic=1:nc
30+
cbase=(ic - 1) * ncells + 1
31+
@views uc[ic]=sum(uf[cbase:cbase+ncells-1])
32+
end
33+
uc ./= ncells
34+
return uc
35+
end
36+
37+
38+
"""
39+
ctof(uc,uf)
40+
41+
coarse to fine intergrid transfer. This is a cell average deal and
42+
the number of cells must be a power of 2
43+
"""
44+
function ctof(uc,uf)
45+
nf=length(uf)
46+
nc=length(uc)
47+
lnf=Int(log2(nf))
48+
(2^lnf == nf) || error("number of cells must be power of 2")
49+
lnc=Int(log2(nc))
50+
(2^lnc == nc) || error("number of cells must be power of 2")
51+
ncells = Int(nf/nc)
52+
for ic=1:nc
53+
cbase=(ic - 1) * ncells + 1
54+
uf[cbase:cbase+ncells-1] .= uc[ic]
55+
end
56+
return uf
57+
end
58+
59+
60+
61+

ctk_nda_src/Tim_CMFD/avplot.jl

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
function avplot(N=4096, Nx=512, Nc=64, na2=11; s=1.0, tol=1.e-10)
2+
kout=qmc_krylov(N, Nx, na2; s=s, tol=tol)
3+
uf=kout.sol
4+
uc=zeros(Nc)
5+
ftoc(uf,uc)
6+
plot(uc)
7+
return uc
8+
end

ctk_nda_src/Tim_CMFD/cmfd.jl

+102
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
function cmfd_si(N=4096*4, Nx=512, Nc=64, na2=11; s=1.0, tol=1.e-10)
2+
outputok=true
3+
phi_c = zeros(Nc)
4+
phi_c0 = zeros(Nc)
5+
cmfd_data=cmfd_init(N, Nx, Nc, na2, s)
6+
linop_data=linop_init(Nc, cmfd_data)
7+
reshist=Float64[]
8+
resid=1.0
9+
for iz=1:20
10+
(phi_c, J_c) = cmfd_sweep(phi_c, cmfd_data)
11+
resid=norm(phi_c - phi_c0, Inf)
12+
push!(reshist, resid)
13+
phi_c0 .= phi_c
14+
end
15+
if outputok == true
16+
lin_resid=cmfd_matvec(phi_c, linop_data) - linop_data.frhs
17+
println(norm(lin_resid,Inf))
18+
plot(phi_c)
19+
end
20+
return (sol=phi_c, reshist=reshist)
21+
end
22+
23+
24+
"""
25+
cmfd_krylov(N=4096*4, Nx=512, Nc=64, na2=11; s=1.0, tol=1.e-10)
26+
Solves the linear system you get from CMFD with GMRES.
27+
"""
28+
function cmfd_krylov(N=4096*4, Nx=512, Nc=64, na2=11; s=1.0, tol=1.e-10)
29+
phi_c = zeros(Nc)
30+
phi_c0 = zeros(Nc)
31+
cmfd_data=cmfd_init(N, Nx, Nc, na2, s)
32+
linop_data=linop_init(Nc, cmfd_data)
33+
b=linop_data.frhs
34+
V=zeros(Nc,20)
35+
eta=tol
36+
#
37+
# kl_gmres and kl_bicgstab solve the problem.
38+
#
39+
gout = kl_gmres(phi_c, b, cmfd_matvec, V, tol; pdata = linop_data)
40+
sol=gout.sol
41+
reshistg=gout.reshist
42+
(phi, J_c) = cmfd_sweep(sol, cmfd_data)
43+
return(sol=sol, J_c=J_c, reshistg=reshistg)
44+
end
45+
46+
"""
47+
cmfd_sweep(phi_c, cmfd_data)
48+
49+
Returns coarse mesh cell average flux and current
50+
"""
51+
function cmfd_sweep(phi_c, cmfd_data)
52+
#
53+
# Map coarse mesh flux to fine mesh
54+
#
55+
phi_f = cmfd_data.phi_f
56+
ctof(phi_c,phi_f)
57+
#
58+
# Do Sam's QMC sweep
59+
#
60+
qmc_data=cmfd_data.qmc_data
61+
qmc_out=qmc_sweep(phi_f, qmc_data)
62+
phi_f = qmc_out.phi_avg
63+
#
64+
# Map output flux and current to coarse mesh
65+
#
66+
phi_c = ftoc(phi_f, phi_c)
67+
J_f = qmc_out.J_avg
68+
J_c = cmfd_data.J_c
69+
J_c = ftoc(J_f, J_c)
70+
return (phi_c, J_c)
71+
end
72+
73+
"""
74+
cmfd_matvec(phi,linop_data)
75+
Matvec for CMFD-QMC
76+
Does a QMC transport sweep with flux phi, subtracts off the zero bc solution
77+
to obtain the linear integral operator. Then subtract that from the identity.
78+
"""
79+
function cmfd_matvec(phic,linop_data)
80+
phi_copy=linop_data.phi_copy
81+
phi_copy .= phic
82+
frhs=linop_data.frhs
83+
cmfd_data=linop_data.cmfd_data
84+
(phi_c, J_c) =cmfd_sweep(phi_copy,cmfd_data)
85+
Mprod=phic-(phi_c - frhs)
86+
return Mprod
87+
end
88+
89+
90+
function cmfd_init(N, Nx, Nc, na2, s)
91+
phi_f = zeros(Nx)
92+
J_c = zeros(Nc)
93+
qmc_data = qmc_init(N, Nx, na2, s);
94+
return(phi_f=phi_f, J_c = J_c, qmc_data=qmc_data)
95+
end
96+
97+
function linop_init(Nc, cmfd_data)
98+
nullin=zeros(Nc)
99+
phi_copy=zeros(Nc)
100+
(frhs, Jrhs)=cmfd_sweep(nullin, cmfd_data)
101+
return (frhs = frhs, cmfd_data = cmfd_data, phi_copy = phi_copy)
102+
end

ctk_nda_src/Tim_CMFD/plot_test.jl

+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
function plot_test(N, Nx, Nc)
2+
tau=5.0; dx=tau/Nc; x=.5*dx:dx:tau-.5*dx;
3+
z=dx:dx:tau-dx;
4+
gm_out=cmfd_krylov(N, Nx, Nc)
5+
dsola=zeros(Nc)
6+
#
7+
# cell centered flux
8+
#
9+
sol=gm_out.sol
10+
#
11+
# derivative of flux at interior cell edges
12+
#
13+
@views dsol=(sol[2:Nc]-sol[1:Nc-1])/dx
14+
#
15+
# Map to cell centers
16+
#
17+
@views dsola[2:Nc-1] = .5*(dsol[1:Nc-2] + dsol[2:Nc-1])
18+
dsola[1]=2.0 * dsol[1]-dsol[2]
19+
dsola[Nc]=2.0 * dsol[Nc-1]-dsol[Nc-2]
20+
#
21+
# Now do the currents and D-hat
22+
#
23+
J_c = gm_out.J_c
24+
Dhat = ((dsola/3.0) + J_c)./sol
25+
#
26+
# You can see why we need large N in the plots
27+
#
28+
plot(x,sol,"k-", x, dsola, "k--", x, J_c, "k.", x, Dhat, "k-.")
29+
title("Flux data: N = $N, Nx = $Nx, Nc = $Nc")
30+
legend([L" \phi", L"d \phi/dx", L"J_c", L"\hat{D}"])
31+
end

ctk_nda_src/Tim_NDA/sanity.jl

+37-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
function sanity(Nx=2048, na=40, s=1.0)
1+
function sanity(Nx=2048, na=40, s=1.0, N=10^4)
22
#
33
# NDA and NDA-Newton
44
#
@@ -23,5 +23,41 @@ snvsnda=kout.sol-ndaout.sol
2323
snndadiff=norm(snvsnda,Inf)
2424
snndaok=(snndadiff<2.e-6)
2525
snndaok || println("SN vs NDA consistency error")
26+
#
27+
# Compare SN and QMC
28+
#
29+
qout=qmc_krylov(N, Nx, na)
30+
qmdiff=qout.sol-kout.sol
31+
println(norm(qmdiff,2)/sqrt(Float64(Nx)))
32+
#
33+
# Now see if there is any hope for a correct current
34+
#
35+
qmc_data=qmc_init(N, Nx, na, s)
36+
qdout=qmc_sweep(kout.sol,qmc_data)
37+
qediff=qdout.phi_avg-kout.sol
38+
subplot(121)
39+
semilogy(qediff)
40+
println(norm(qediff,2)/sqrt(Float64(Nx)))
41+
(flux, current) = getJ(kout.sol, sn_data)
42+
cdiff=qdout.J_avg - current
43+
println(norm(cdiff,2)/sqrt(Float64(Nx)))
44+
subplot(122)
45+
semilogy(cdiff)
46+
#
2647
return (snndaok && snok && ndaok)
2748
end
49+
50+
function getJ(phi,sn_data)
51+
psi = sn_data.psi
52+
psi = transport_sweep!(psi, phi, sn_data)
53+
#
54+
# Take the 0th moment to get the flux.
55+
#
56+
weights = sn_data.weights
57+
angles = sn_data.angles
58+
flux=copy(phi)
59+
flux .= (weights' * psi)'
60+
current = copy(phi)
61+
current .= ((weights.*angles)' * psi)'
62+
return (flux=flux, current=current)
63+
end

ctk_nda_src/Tim_QMC/ctk_qmc_init.jl

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ function qmc_init(N, Nx, na2, s)
1010
dxs = high_edges - low_edges
1111
midpoints = 0.5*(high_edges + low_edges)
1212
edges = range(0, stop=Lx, length=Nx+1)
13-
p=2
13+
p=4
1414
# AV=[]
1515
AV=averop(p,Nx+1)
1616
#define angular flux mesh

ctk_nda_src/Tim_QMC/qmc_krylov.jl

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
qmc_krylov(N=10^4, Nx=100, na2=11; s=1.0)
33
Solves the linear system you get from QMC with GMRES.
44
"""
5-
function qmc_krylov(N=10^3, Nx=100, na2=11; s=1.0, tol=1.e-10, onlygmres=true)
5+
function qmc_krylov(N=1024, Nx=128, na2=11; s=1.0, tol=1.e-10, onlygmres=true)
66
mdata=mdata_init(N, Nx, na2, s)
77
phi0=zeros(Nx,);
88
b=mdata.frhs;

ctk_nda_src/Tim_QMC/qmc_nda.jl

+11-5
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ dphi[id]=(aphi[id+1]-aphi[id])/dx
5757
end
5858
#return (phi_edge=phi_edge, dphi=dphi)
5959
phi_edge .= aphi
60-
return (phi_edge=aphi, dphi=dphi)
60+
return (phi_edge=phi_edge, dphi=dphi)
6161
end
6262

6363
function nda_qmc_fixed(phi,qmc_nda_data)
@@ -69,9 +69,11 @@ phi_edge=zeros(Nx+1,)
6969
dphi=zeros(Nx,)
7070
dx=1.0/Nx
7171
qout=qmc_sweep(phi,qmc_data)
72-
#avg2edge!(phi_edge, dphi, qout.phi_avg,qmc_nda_data)
7372
avg2edge!(phi_edge, dphi, qout.phi_avg, dx,AVE)
74-
dhat=(qout.J_avg + (dphi./3.0))./qout.phi_avg
73+
JAV=AVE*qout.J_edge
74+
#dhat=(qout.J_avg + (dphi./3.0))./qout.phi_avg
75+
Javg=.5*(JAV[1:Nx] + JAV[2:Nx+1])
76+
dhat=(Javg + (dphi./3.0))./qout.phi_avg
7577
#println(norm(dhat-dhatp,Inf)," ",norm(dphi-dphip))
7678
#
7779
# Something's busted here. My normal code has phi at edges. The
@@ -85,17 +87,21 @@ D1=nda_data.D1
8587
AV=nda_data.AV
8688
LT = L2 + (D1*(Dhat * AV))
8789
LT[1,1]=1.0; LT[2:Nx].=0.0;
88-
LT[Nx,Nx]=1.0; LT[NX,1:Nx-1].=0.0;
90+
LT[Nx,Nx]=1.0; LT[Nx,1:Nx-1].=0.0;
8991
bcl=phi_edge[1];
9092
bcr=phi_edge[Nx+1];
9193
#bcl=qout.phi_avg[1];
9294
#bcr=qout.phi_avg[Nx];
95+
ravg=AVE*qout.phi_edge;
96+
#bcl=ravg[1];
97+
#bcr=ravg[Nx];
9398
rhs=zeros(Nx+1,)
9499
rhs[1]=bcl
95100
rhs[Nx+1]=bcr
101+
println(bcl," ",bcr)
96102
phiout=LT\rhs
97103
phiave=.5*(phiout[1:Nx]+phiout[2:Nx+1])
98-
#phiout=qout.phi_avg
104+
return phiave
99105
end
100106

101107

ctk_nda_src/averop.jl

-12
This file was deleted.

0 commit comments

Comments
 (0)