Skip to content

Commit c8bbc13

Browse files
authored
Merge pull request #147 from fastalgorithms/for-saw
For saw
2 parents 4ffc084 + 65b298c commit c8bbc13

4 files changed

Lines changed: 153 additions & 77 deletions

File tree

chunkie/+chnk/+rcip/Rcompchunk.m

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -53,19 +53,18 @@
5353
opts = [];
5454
end
5555

56-
savedeep = false;
57-
if isfield(opts,'savedeep')
58-
savedeep = opts.savedeep;
56+
savedepth = 10;
57+
if isfield(opts,'rcip_savedepth')
58+
savedepth = opts.rcip_savedepth;
5959
end
60+
savedepth = max(savedepth,0);
61+
savedepth = min(savedepth,nsub);
6062

61-
rcipsav.savedeep = savedeep;
62-
63-
if savedeep
64-
rcipsav.R = cell(nsub+1,1);
65-
rcipsav.MAT = cell(nsub,1);
66-
rcipsav.chnkrlocals = cell(nsub,1);
67-
end
63+
rcipsav.savedepth = savedepth;
6864

65+
rcipsav.R = cell(nsub+1,1);
66+
rcipsav.MAT = cell(nsub,1);
67+
rcipsav.chnkrlocals = cell(nsub,1);
6968

7069
% grab only those kernels relevant to this vertex
7170

@@ -260,12 +259,15 @@
260259
if level==1 % Dumb and lazy initializer for R, for now
261260
%R=eye(nR);
262261
R = inv(MAT(starL,starL));
263-
if savedeep
262+
if level >= nsub-savedepth+1
264263
rcipsav.R{1} = R;
265264
end
266265
end
266+
if savedepth < nsub && level == nsub-savedepth+1
267+
rcipsav.R{level} = R;
268+
end
267269
R=chnk.rcip.SchurBana(Pbc,PWbc,MAT,R,starL,circL,starS,circS);
268-
if savedeep
270+
if level >= nsub-savedepth+1
269271
rcipsav.R{level+1} = R;
270272
rcipsav.MAT{level} = MAT(starL,circL);
271273
rcipsav.chnkrlocals{level} = merge(chnkrlocal);

chunkie/+chnk/+rcip/rhohatInterp.m

Lines changed: 66 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@
33
% density rhohat to the requested depth using the backward recursion
44
%
55
% When using an RCIP preconditioner (in the style of eq 34 of the RCIP
6-
% tutorial), the resulting coarse level density is
7-
% accurate for interactions separated from the vertex
8-
% *at the coarse scale*.
6+
% tutorial), the resulting coarse level density is accurate for
7+
% interactions separated from the vertex *at the coarse scale*.
8+
%
99
% By running the recursion for the RCIP preconditioner backwards, an
1010
% equivalent density can be reconstructed on the fine mesh which is
1111
% appropriate for closer interactions (at a distance well-separated from
@@ -53,26 +53,42 @@
5353
% wts - a set of weights for integrating functions sampled at these
5454
% points
5555

56-
% author: Travis Askham
56+
% author: Travis Askham
5757

58-
rhohatinterp = [];
59-
srcinfo = [];
60-
wts = [];
61-
62-
k = rcipsav.k;
63-
ndim = rcipsav.ndim;
6458
nedge = rcipsav.nedge;
6559
Pbc = rcipsav.Pbc;
66-
PWbc = rcipsav.PWbc;
67-
starL = rcipsav.starL;
68-
starL1 = rcipsav.starL1;
69-
starS = rcipsav.starS;
70-
circL = rcipsav.circL;
71-
circL1 = rcipsav.circL1;
72-
circS = rcipsav.circS;
73-
ilist = rcipsav.ilist;
60+
61+
starL1 = sort(rcipsav.starL1);
62+
starS = sort(rcipsav.starS);
63+
64+
circL1 = sort(rcipsav.circL1);
65+
circS = sort(rcipsav.circS);
66+
67+
nrho = numel([circS,starS]);
68+
ndens = numel(rhohat)/nrho;
69+
rhohat = reshape(rhohat,[nrho, ndens]);
70+
7471
nsub = rcipsav.nsub;
7572

73+
rhohatinterp = cell(nedge,1);
74+
srcinfo = cell(nedge,1);
75+
wts = cell(nedge,1);
76+
77+
ileftright = rcipsav.ileftright;
78+
79+
% figure out which edge the indices belong to
80+
% THIS ASSUMES WE HAVE THE SAME ORDER ON EDGES
81+
circSedge = cell(nedge,1); ncS = numel(circS)/nedge;
82+
circL1edge = cell(nedge,1); ncL1 = numel(circL1)/nedge;
83+
starSedge = cell(nedge,1); nsS = numel(starS)/nedge;
84+
starL1edge = cell(nedge,1); nsL1 = numel(starL1)/nedge;
85+
for j = 1:nedge
86+
circSedge{j} = circS((j-1)*ncS+1:j*ncS);
87+
circL1edge{j} = circL1((j-1)*ncL1+1:j*ncL1);
88+
starSedge{j} = starS((j-1)*nsS+1:j*nsS);
89+
starL1edge{j} = starL1((j-1)*nsL1+1:j*nsL1);
90+
end
91+
7692
if nargin < 3
7793
ndepth = nsub;
7894
end
@@ -84,58 +100,58 @@
84100
ndepth = nsub;
85101
end
86102

87-
savedeep = rcipsav.savedeep;
103+
savedepth = rcipsav.savedepth;
88104

89-
if savedeep
105+
if ndepth <= savedepth
90106

91107
% all relevant quantities are stored, just run backward recursion
92108

93109
rhohat0 = rhohat;
94-
rhohatinterp = [rhohatinterp; rhohat0(circS)];
95-
r = [];
96-
d = [];
97-
d2 = [];
98-
n = [];
99-
h = [];
100110
cl = rcipsav.chnkrlocals{nsub};
101111
wt = weights(cl);
102-
r = [r, cl.rstor(:,circL1)];
103-
d = [d, cl.dstor(:,circL1)];
104-
d2 = [d2, cl.d2stor(:,circL1)];
105-
n = [n, cl.nstor(:,circL1)];
106-
wts = [wts; wt(circL1(:))];
112+
113+
for j = 1:nedge
114+
rhohatinterp{j} = rhohat0(circSedge{j},:);
115+
srcinfo{j}.r = cl.rstor(:,circL1edge{j});
116+
srcinfo{j}.d = cl.dstor(:,circL1edge{j});
117+
srcinfo{j}.d2 = cl.d2stor(:,circL1edge{j});
118+
srcinfo{j}.n = cl.nstor(:,circL1edge{j});
119+
wts{j} = wt(circL1edge{j});
120+
end
107121

108122
R0 = rcipsav.R{nsub+1};
109123
for i = 1:ndepth
110124
R1 = rcipsav.R{nsub-i+1};
111125
MAT = rcipsav.MAT{nsub-i+1};
112126
rhotemp = R0\rhohat0;
113-
rhohat0 = R1*(Pbc*rhotemp(starS) - MAT*rhohat0(circS));
127+
rhohat0 = R1*(Pbc*rhotemp(starS,:) - MAT*rhohat0(circS,:));
114128
if i == ndepth
115-
rhohatinterp = [rhohatinterp; rhohat0];
116-
r = [r, cl.rstor(:,starL1)];
117-
d = [d, cl.dstor(:,starL1)];
118-
d2 = [d2, cl.d2stor(:,starL1)];
119-
n = [n, cl.nstor(:,starL1)];
120129
wt = weights(cl);
121-
122-
wts = [wts; wt(starL1(:))];
130+
for j = 1:nedge
131+
if ileftright(j) == 1
132+
rhohatinterp{j} = [rhohatinterp{j}; rhohat0([circSedge{j} starSedge{j}],:)];
133+
else
134+
rhohatinterp{j} = [rhohatinterp{j}; rhohat0([starSedge{j} circSedge{j}],:)];
135+
end
136+
srcinfo{j}.r = [srcinfo{j}.r, cl.rstor(:,starL1edge{j})];
137+
srcinfo{j}.d = [srcinfo{j}.d, cl.dstor(:,starL1edge{j})];
138+
srcinfo{j}.d2 = [srcinfo{j}.d2, cl.d2stor(:,starL1edge{j})];
139+
srcinfo{j}.n = [srcinfo{j}.n, cl.nstor(:,starL1edge{j})];
140+
wts{j} = [wts{j}, wt(starL1edge{j})];
141+
end
123142
else
124143
cl = rcipsav.chnkrlocals{nsub-i};
125-
rhohatinterp = [rhohatinterp; rhohat0(circS)];
126-
r = [r, cl.rstor(:,circL1)];
127-
d = [d, cl.dstor(:,circL1)];
128-
d2 = [d2, cl.d2stor(:,circL1)];
129-
n = [n, cl.nstor(:,circL1)];
130144
wt = weights(cl);
131-
wts = [wts; wt(circL1(:))];
145+
for j = 1:nedge
146+
rhohatinterp{j} = [rhohatinterp{j}; rhohat0(circSedge{j},:)];
147+
srcinfo{j}.r = [srcinfo{j}.r, cl.rstor(:,circL1edge{j})];
148+
srcinfo{j}.d = [srcinfo{j}.d, cl.dstor(:,circL1edge{j})];
149+
srcinfo{j}.d2 = [srcinfo{j}.d2, cl.d2stor(:,circL1edge{j})];
150+
srcinfo{j}.n = [srcinfo{j}.n, cl.nstor(:,circL1edge{j})];
151+
wts{j} = [wts{j}, wt(circL1edge{j})];
152+
end
132153
end
133154
R0 = R1;
134155
end
135156

136-
srcinfo.r = r;
137-
srcinfo.d = d;
138-
srcinfo.d2 = d2;
139-
srcinfo.n = n;
140-
141157
end

chunkie/chunkermat.m

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@
6565
% corrections for near corners if input chnkobj is
6666
% of type chunkergraph
6767
% opts.rcip_ignore = [], list of vertices to ignore in rcip
68+
% opts.rcip_savedepth = (10), depth to save rcip info
6869
% opts.nsub_or_tol = (40) specify the level of refinements in rcip
6970
% or a tolerance where the number of levels is given by
7071
% ceiling(log_{2}(1/tol^2));
@@ -83,6 +84,9 @@
8384
% Optional output
8485
% opts - with the updated opts structure which stores the relevant
8586
% quantities in opts.auxquads.<opts.quad><opts.type>
87+
% rcipsav - precomputed structure of rcip data at corners
88+
% for subsequent postprocessing of the solution at targets close
89+
% to the corner
8690
%
8791
% Examples:
8892
% sysmat = chunkermat(chnkr,kern); % standard options
@@ -135,6 +139,7 @@
135139
isrcip = true;
136140
rcip_ignore = [];
137141
nsub = 40;
142+
rcip_savedepth = 10;
138143
adaptive_correction = false;
139144
sing = 'log';
140145

@@ -162,6 +167,9 @@
162167
if(isfield(opts,'rcip'))
163168
isrcip = opts.rcip;
164169
end
170+
if(isfield(opts,'rcip_savedepth'))
171+
rcip_savedepth = opts.rcip_savedepth;
172+
end
165173
if(isfield(opts,'rcip_ignore'))
166174
rcip_ignore = opts.rcip_ignore;
167175
if ~isrcip && isempty(rcip_ignore)
@@ -466,6 +474,8 @@
466474
npt_all = horzcat(chnkobj.echnks.npt);
467475
[~,nv] = size(chnkobj.verts);
468476
ngl = chnkrs(1).k;
477+
478+
rcipsav = cell(nv,1);
469479

470480
for ivert=setdiff(1:nv,rcip_ignore)
471481
clist = chnkobj.vstruc{ivert}{1};
@@ -512,11 +522,14 @@
512522
optsrcip = opts;
513523
optsrcip.nonsmoothonly = false;
514524
optsrcip.corrections = false;
525+
optsrcip.rcip_savedepth = rcip_savedepth;
515526

516-
R = chnk.rcip.Rcompchunk(chnkrs,iedgechunks,kern,ndim, ...
527+
[R,rcipsav{ivert}] = chnk.rcip.Rcompchunk(chnkrs,iedgechunks,kern,ndim, ...
517528
Pbc,PWbc,nsub,starL,circL,starS,circS,ilist,starL1,circL1,...
518529
sbclmat,sbcrmat,lvmat,rvmat,u,optsrcip);
519-
530+
531+
rcipsav{ivert}.starind = starind;
532+
520533
sysmat_tmp = inv(R) - eye(2*ngl*nedge*ndim);
521534
if (~nonsmoothonly)
522535

@@ -574,6 +587,11 @@
574587
vsysmat = [vsysmat;sysmat_tmp(:)];
575588
end
576589
end
590+
591+
if nargout > 2
592+
varargout{2} = rcipsav;
593+
end
594+
577595

578596
end
579597

0 commit comments

Comments
 (0)