function [U]=Solve3D(Uini,nmod,iscale) clear MedianFilter if nargin<3,iscale=1;end pscale=2^(iscale-1); ttic=cputime; load(fullfile('TMP','params'),'param'); param0=param; [~,filreso,~]=fileparts(param0.result_file); save(fullfile('TMP',sprintf('%s-scale-%d-restart',filreso,iscale)),'param'); roi=param0.roi; if iscell(param0.deformed_image) nim=length(param0.deformed_image); else nim=1; end if isfield(param0,'restart') restart=param0.restart; else restart=1; end if restart nmax=nim; else if iscale==1 nmax=nim; else if nim<2 nmax=nim; else nmax=2; end end end inorm=false; if isfield(param0,'normalize_grey_level') inorm=param0.normalize_grey_level; end reg_type='none'; mfilter=0; if isfield(param0,'regularization_type') reg_type=param0.regularization_type; if iscale>1&&~(strcmp(reg_type,'none')) reg_type='tiko'; end if strcmp(param0.regularization_type,'median') reg_type='median'; mfilter=1; lmed=1; if isfield(param0,'regularization_parameter') lmed=param0.regularization_parameter; end elseif strcmp(param0.regularization_type,'tiko') mfilter=1;lmed=1; end end maxiter=param0.iter_max; conv=param0.convergance_limit; load(fullfile('TMP',sprintf('%d_params',nmod)),'param'); disp(sprintf('Starting resolution for scale %d...',iscale)); mesh_file=fullfile('TMP',sprintf('%d_3d_mesh_%d.mat',nmod,iscale-1)); load(mesh_file,'rflag','rint','xo','yo','zo','Nnodes','Nelems','Smesh','conn','elt','ng','ns'); invmap=~rflag; pstep=1; if isfield(param0,'psample') pstep=param0.psample; end face_elts=[]; face_nodes=[]; if isfield(param,'enrichment')&&(iscale==1) if iscell(param.levelset_file) error('not coded yet'); else ncrack=1; end for ic=1:ncrack if ncrack==1,lvl7file=param.levelset_file;end load(lvl7file,'crack','front','zone'); [iface_nodes,iface_elts,crackn]=TreatmentofEnrichment3D(ic,nmod,crack,front,zone); clear front face_elts=[face_elts,iface_elts]; face_nodes=[face_nodes,iface_nodes]; end if size(Uini,1)==(3*prod(Nnodes)) Uini=[Uini;zeros(3*numel(face_nodes),size(Uini,2))]; end end load(fullfile('TMP',sprintf('sample0_%d',iscale-1)),'sizeim'); switch param0.stack_format case 'bin' fidi=fopen(fullfile('TMP',sprintf('dsample0_%d',iscale-1))); im0=fread(fidi,prod(sizeim)); fclose(fidi); im0=reshape(im0,sizeim); case 'mat' load(fullfile('TMP',sprintf('sample0_%d',iscale-1)),'im0'); end [mean0,std0]=mexImScalling3D(int64(im0)); mean1=0;std1=1; dynamic=max(im0(:))-min(im0(:)); F=zeros(3*prod(Nnodes)+3*numel(face_nodes),1); M=0; im1=0; restart_file=''; if isfield(param0,'restart_file') restart_file=param0.restart_file; end if isempty(restart_file) imin=1; U=Uini; else load(param0.restart_file,'U','ijm') imin=ijm; Uini=U; end if ~strcmp(reg_type,'none')&&~strcmp(reg_type,'median') lc=(min(sizeim)/10); lm=lc; if isfield(param0,'regularization_parameter') lm=param0.regularization_parameter/pscale; end ki=1/lc; V=repmat(cos(2*pi*(xo)*ki).*cos(2*pi*(yo)*ki).*cos(2*pi*(zo)*ki),3,1); if isfield(param,'enrichment')&&(iscale==1) V=[V;zeros(3*numel(face_nodes),1)]; end hh=min(sqrt(diff(xo(conn(:,1:2)),[],2).^2+diff(yo(conn(:,1:2)),[],2).^2+diff(zo(conn(:,1:2)),[],2).^2)); if param0.regularization_parameter>5*hh mfilter=0; end end fid=fopen(fullfile('TMP',sprintf('%d_error_%d.mat',nmod,iscale-1)),'w'); if dynamic>255 fwrite(fid,255); else fwrite(fid,dynamic); end model=param; save(fullfile('TMP',sprintf('%s-scale-%d-restart',filreso,iscale)),'model','rint','Nnodes','Nelems','xo','yo','zo','conn','elt','ng','ns','-append'); for ijm=imin:nmax display(sprintf('Image %d/%d',ijm,nim)); res=1; ii=1; if ~restart&&ijm>2 Ui=2*U(:,ijm-1)-U(:,ijm-2); else Ui=Uini(:,ijm); end merrorp=Inf; while ( res>conv && ii< maxiter) [merror,disc]=Assemble(ijm); if (ii==1)&&(ijm==imin) switch reg_type case 'tiko' CreateGradBasisFunction3D(iscale,nmod); R=AssembleRegularizationOperator3D(nmod,iscale,isfield(param,'coupling_parameter')); a=(V'*M*V)/(V'*R*V); a=a*(2*lm/lc)^2; R=a*R; P=sparse(size(M,1),size(M,2)); case 'equilibrium_gap' CreateGradBasisFunction3D(iscale,nmod); Rb=AssembleRegularizationOperator3D(nmod,iscale,1); D=diag(abs(diag(Rb))>0); a=(V'*D*M*V)/(V'*Rb*V); a=a*(2*lm/lc)^2; Rb=a*Rb; disp(sprintf(' Equilibrium Gap regularization...')); LoadMat(nmod); AssembleMechanicalOperator(iscale,nmod,ijm) AssembleEquilibriumGapOperator(iscale,nmod,1) load(fullfile('TMP',sprintf('%d_kk_operator_%d',nmod,iscale-1)),'K'); R=K; clear K a=(V'*M*V)/(V'*R*V); a=a*(2*lm/lc)^4; R=a*R; R=R+Rb; P=sparse(size(M,1),size(M,2)); case 'constitutive_gap' disp(sprintf(' Constitutive Gap regularization...')); CreateGradBasisFunction3D(iscale,nmod); LoadMat(nmod); AssembleMechanicalOperator(iscale,nmod,ijm) AssembleEquilibriumGapOperator(iscale,nmod,0) load(fullfile('TMP',sprintf('%d_k_operator_%d',nmod,iscale-1)),'K'); load(fullfile('TMP',sprintf('%d_kk_operator_%d',nmod,iscale-1)),'select'); R=K; clear K P=diag(1.e9*sparse((~diag(select))).*diag(R)); a=(V'*M*V)/(V'*R*V); a=a*(2*lm/lc)^2; R=a*R; P=a*P; otherwise R=sparse(size(M,1),size(M,2)); P=sparse(size(M,1),size(M,2)); end M=M+R+P; try M1 = ichol(M,struct('type','ict','droptol',1e-3)); M2 = M1'; catch err disp([err.identifier ' : ' err.message ' => using diagonal compensation']) diagcomp=((sum(abs(M),2)./diag(M))-2)/100; try M1 = ichol(M,struct('type','ict','droptol',1e-3,'diagcomp',max(diagcomp))); M2 = M1'; catch err disp([err.identifier ' : ' err.message ' => removing zero diag']) ido=isnan(diagcomp); M(ido,ido)=1; disp([err.identifier ' : ' err.message ' => using lumped operator']) M=full(sum(M,2)); M1=[]; M2=[]; end end end F=F-R*Ui; if issparse(M) F=F+M*Ui; dU=pcg(M,F,1e-6,1000,M1,M2,Ui); dU=dU-Ui; else dU=F./M; end disp(sprintf('At iteration # %d',ii)); disp(sprintf('Discrepancy wrt dyn. =%6.2f %%',merror*100/dynamic)); nU0=max(1,norm(Ui+dU(:))); res=norm(dU(:))/nU0; disp(sprintf('|dU|=%f',res)); if mfilter res=min(res,abs(merrorp-merror)/abs(merror)); end Ui=Ui+dU; ii=ii+1; if mfilter Ui=MedianFilter(Ui,mesh_file,lmed); end merrorp=merror; U(:,ijm)=Ui; save(fullfile('TMP',sprintf('%s-scale-%d-restart',filreso,iscale)),'U','ijm','-append'); end % if mfilter % Uii=zeros(size(Ui)); % Nnn=prod(Nnodes); % for ii1=1:prod(Nelems) % if mfilter % for iin=1:elt(ii1) % nod=conn(ii1,iin); % if abs(Uii(nod))==0 % ee=sum(conn==nod,2)>0; % ee=conn(ee,:); % ee=unique(ee(:)); % Uii(nod)=median(Ui(ee)); % Uii(nod+Nnn)=median(Ui(ee+Nnn)); % Uii(nod+2*Nnn)=median(Ui(ee+2*Nnn)); % end % end % Ui=Uii; % U(:,ijm)=Ui; % save(fullfile('TMP',sprintf('%s-scale-%d-restart',filreso,iscale)),'U','-append'); % end % end % end if dynamic>255 disc=255*disc/dynamic; end fwrite(fid,abs(disc)); end disp(sprintf('Enlapsed time for resolution = %6.2f s',cputime -ttic)); fclose(fid); function [mdisc,disc]=Assemble(kkk) mdisc=0; F=0*F; % Fels=zeros(size(conn,1),3*size(conn,2)); roip=(roi-1)/pscale+1; % roip(1:2:end)=floor(roip(1:2:end)); % roip(2:2:end)=ceil(roip(2:2:end)); if (kkk==imin)&&(ii==1) do_matrix=true; nind=(3*6)^2*sum(elt==6)+(3*8)^2*(sum(elt==8)-numel(face_elts))+(2*3*8)^2*numel(face_elts); indig=zeros(nind,1); indjg=zeros(nind,1); val=zeros(nind,1); disc=zeros(length(elt),1); nel=0; else do_matrix=false; end Nn=prod(Nnodes); nenr=numel(face_nodes); if ii==1 if nim==1 fildef=param0.deformed_image; else fildef=param0.deformed_image{kkk}; end clear im1 if isfield(param0,'stack_size') imsiz0=param0.stack_size; fidi=fopen(fildef,'r'); im1=fread(fidi,prod(imsiz0)); im1=reshape(im1,imsiz0); fclose(fidi); else [~, ~, ext] = fileparts(fildef); switch ext case '.mat' load(fildef,'jm3'); im1=(jm3); clear jm3 case {'.tif','.tiff'} im1=readTIFFasRAW(fildef); end end if iscale>1 for ip=1:(iscale-1) scale=2; imsiz0=size(im1); imsiz1=floor(imsiz0/2); nn=2*imsiz1; if nn(1)0 if any(elt==4) [xgt,ygt,zgt,wgt]=GetGaussPointsTetrahedron(ng,ns); Nt=[1-xgt-ygt-zgt,xgt,ygt,zgt]; Nt_r=[-1+0*xgt,1+0*xgt,0*ygt,0*zgt]; Nt_s=[-1+0*xgt,0*xgt,1+0*ygt,0*zgt]; Nt_t=[-1+0*xgt,0*xgt,0*ygt,1+0*zgt]; % Nt_r=Nt_r(:,[3,4,1,2]); % Nt_s=Nt_s(:,[3,4,1,2]); % Nt_t=Nt_t(:,[3,4,1,2]); end if any(elt==6) [xgw,ygw,zgw,wgw]=GetGaussPointsWedge(ng,ns); Nw=[0.5*(1-xgw-ygw).*(1-zgw),0.5*(xgw).*(1-zgw),0.5*(ygw).*(1-zgw),... 0.5*(1-xgw-ygw).*(1+zgw),0.5*(xgw).*(1+zgw),0.5*(ygw).*(1+zgw)]; Nw_r=[-0.5*(1-zgw),0.5*(1-zgw),(0*ygw),... -0.5*(1+zgw),0.5*(1+zgw),(0*ygw)]; Nw_s=[-0.5*(1-zgw),(0*xgw),0.5*(1-zgw),... -0.5*(1-zgw),(0*xgw),0.5*(1-zgw)]; Nw_t=[-0.5*(1-xgw-ygw),-0.5*xgw,-0.5*ygw,... 0.5*(1-xgw-ygw),0.5*xgw,0.5*ygw]; end if any(elt==8) [xgq,ygq,zgq,wgq]=GetGaussPointsHexaedron(ng,ns); Nq=[0.125*(1-xgq).*(1-ygq).*(1-zgq),0.125*(1+xgq).*(1-ygq).*(1-zgq),0.125*(1+xgq).*(1+ygq).*(1-zgq),0.125*(1-xgq).*(1+ygq).*(1-zgq),... 0.125*(1-xgq).*(1-ygq).*(1+zgq),0.125*(1+xgq).*(1-ygq).*(1+zgq),0.125*(1+xgq).*(1+ygq).*(1+zgq),0.125*(1-xgq).*(1+ygq).*(1+zgq)]; Nq_r=[-0.125*(1-ygq).*(1-zgq),0.125*(1-ygq).*(1-zgq),0.125*(1+ygq).*(1-zgq),-0.125*(1+ygq).*(1-zgq),... -0.125*(1-ygq).*(1+zgq),0.125*(1-ygq).*(1+zgq),0.125*(1+ygq).*(1+zgq),-0.125*(1+ygq).*(1+zgq)]; Nq_s=[-0.125*(1-xgq).*(1-zgq),-0.125*(1+xgq).*(1-zgq),0.125*(1+xgq).*(1-zgq),0.125*(1-xgq).*(1-zgq),... -0.125*(1-xgq).*(1+zgq),-0.125*(1+xgq).*(1+zgq),0.125*(1+xgq).*(1+zgq),0.125*(1-xgq).*(1+zgq)]; Nq_t=[-0.125*(1-xgq).*(1-ygq),-0.125*(1+xgq).*(1-ygq),-0.125*(1+xgq).*(1+ygq),-0.125*(1-xgq).*(1+ygq),... 0.125*(1-xgq).*(1-ygq),0.125*(1+xgq).*(1-ygq),0.125*(1+xgq).*(1+ygq),0.125*(1-xgq).*(1+ygq)]; end end for i1=1:prod(Nelems) % display(sprintf('elemen %d /%d\n',i1,prod(Nelems))); inods=conn(i1,1:elt(i1)); % if mfilter % Un=zeros(numel(inods),1); % Vn=zeros(numel(inods),1); % Wn=zeros(numel(inods),1); % for in=1:elt(i1) % ee=sum(conn==inods(in),2)>0; % ee=conn(ee,:); % ee=unique(ee(:)); % Un(in)=median(Ui(ee)); % Vn(in)=median(Ui(ee+1*Nn)); % Wn(in)=median(Ui(ee+2*Nn)); % end % else Un=Ui(inods+0*Nn); Vn=Ui(inods+1*Nn); Wn=Ui(inods+2*Nn); % end xn=xo(inods); yn=yo(inods); zn=zo(inods); inde=[]; if ng==0||any(face_elts==i1) ipix=max(1,ceil(min(xn)-2)):min(sizeim(1),floor(max(xn)+2)); jpix=max(1,ceil(min(yn)-2)):min(sizeim(2),floor(max(yn)+2)); kpix=max(1,ceil(min(zn)-2)):min(sizeim(3),floor(max(zn)+2)); im0e=double(im0(ipix,jpix,kpix)); if pstep>1 % ipixo=int32(1:pstep:size(im0e,1))'; % jpixo=int32(1:pstep:size(im0e,2))'; % kpixo=int32(1:pstep:size(im0e,3))'; % [ypix,xpix,zpix]=meshgrid(jpix(jpixo),ipix(ipixo),kpix(kpixo)); [ypix,xpix,zpix]=meshgrid(jpix(1:pstep:end),ipix(1:pstep:end),kpix(1:pstep:end)); else [ypix,xpix,zpix]=meshgrid(jpix,ipix,kpix); end if invmap||~(elt(i1)==8) [xg,yg,zg,wg]=GetGaussPointsVoxels(elt(i1),xn,yn,zn,xpix(:),ypix(:),zpix(:)); else xg=-1+2*(xpix(:)-min(xn))/(max(xn)-min(xn)); yg=-1+2*(ypix(:)-min(yn))/(max(yn)-min(yn)); zg=-1+2*(zpix(:)-min(zn))/(max(zn)-min(zn)); switch elt(i1) case 6 wg=~(xg<0|yg<0|1-xg-yg<0|abs(zg)>1); case 4 wg=~(xg<0|yg<0|zg<0|1-xg-yg-zg<0); case 8 wg=~(abs(xg)>1|abs(yg)>1|abs(zg)>1); end end N=GetFiniteElementShapeFunctions3D(elt(i1),xg(:),yg(:),zg(:)); if elt(i1)<8 N=N(:,1:elt(i1)); end if any(face_elts==i1) heaviside=double(crack(ipix+roi(1)-zone(1),jpix+roi(3)-zone(3),kpix+roi(5)-zone(5))>=0); for in=1:elt(i1) ienr=find(face_nodes==inods(in)); if ~isempty(ienr) hn=double(crackn(ienr)>=0); N=[N,N(:,in).*(heaviside(:)-hn)]; inde=[inde,ienr]; Un=[Un;Ui(3*Nn+ienr+0*nenr)]; Vn=[Vn;Ui(3*Nn+ienr+1*nenr)]; Wn=[Wn;Ui(3*Nn+ienr+2*nenr)]; end end end phidf=mexPhidf3D(im0e,N,pstep); if pstep>1 im0e=im0e(1:pstep:end,1:pstep:end,1:pstep:end); end else if elt(i1)==4 N=Nt;wg=wgt; N_r=Nt_r;N_s=Nt_s;N_t=Nt_t; elseif elt(i1)==6 N=Nw;wg=wgw; N_r=Nw_r;N_s=Nw_s;N_t=Nw_t; elseif elt(i1)==8 N=Nq;wg=wgq; N_r=Nq_r;N_s=Nq_s;N_t=Nq_t; end xpix=N*xn; ypix=N*yn; zpix=N*zn; dxdr=N_r*xn; dydr=N_r*yn; dzdr=N_r*zn; dxds=N_s*xn; dyds=N_s*yn; dzds=N_s*zn; dxdt=N_t*xn; dydt=N_t*yn; dzdt=N_t*zn; detJ=dxdr.*dyds.*dzdt+dxds.*dydt.*dzdr+dxdt.*dydr.*dzds... -dzdr.*dyds.*dxdt-dzds.*dydt.*dxdr-dzdt.*dydr.*dxds; wg=wg.*detJ; [gx,gy,gz]=mexGradLinear3D(xpix(:),ypix(:),zpix(:),im0); gx=diag(sparse(gx(:))); gy=diag(sparse(gy(:))); gz=diag(sparse(gz(:))); phidf=[gx*N,gy*N,gz*N]; im0e=mexInterpLinear3D(xpix(:),ypix(:),zpix(:),im0); end xpix=xpix(:)+(N*Un)/pscale+roip(1)-1; ypix=ypix(:)+(N*Vn)/pscale+roip(3)-1; zpix=zpix(:)+(N*Wn)/pscale+roip(5)-1; xmin=max(floor(min(xpix))-2,1);xmax=min(ceil(max(xpix))+2,size(im1,1)); ymin=max(floor(min(ypix))-2,1);ymax=min(ceil(max(ypix))+2,size(im1,2)); zmin=max(floor(min(zpix))-2,1);zmax=min(ceil(max(zpix))+2,size(im1,3)); im1el=double(im1(xmin:xmax,ymin:ymax,zmin:zmax)); im1e=mexInterpLinear3D(xpix-xmin+1,ypix-ymin+1,zpix-zmin+1,im1el); % im1e=mexInterpLinear3D(xpix(:)+(N*Un)/pscale+roip(1)-1,... % ypix(:)+(N*Vn)/pscale+roip(3)-1,... % zpix(:)+(N*Wn)/pscale+roip(5)-1,... % im1); if inorm im0e=im0e-mean(im0e(:)); im1e=im1e-mean(im1e(:)); sc=max(1,std(im0e(:)))/max(1,std(im1e(:))); im1e=sc*im1e; else im0e=im0e-mean0; im1e=im1e-mean1; sc=max(1,std0)/max(1,std1); im1e=sc*im1e; end im1e=im0e(:)-im1e(:); wg=diag(sparse(wg(:))); indo=[inods,3*Nn+inde+0*nenr,inods+Nn,3*Nn+inde+1*nenr,inods+2*Nn,3*Nn+inde+2*nenr]; if do_matrix [indj,indi]=meshgrid(indo,indo); ne=1:(3*size(N,2))^2; Mel=(wg*phidf); Mel=phidf'*Mel; indig(nel+ne)=indi(:); indjg(nel+ne)=indj(:); val(nel+ne)=Mel(:); nel=nel+numel(Mel); end Fel=wg*(im1e(:)); Fel=phidf'*Fel; % Fels(i1,[1:elt(i1),size(conn,2)+(1:elt(i1)),2*size(conn,2)+(1:elt(i1))])=Fel; F(indo(:))=F(indo(:))+Fel(:); mdisce=sum(wg*abs(im1e(:)))/sum(diag(wg)); mdisc=mdisc+mdisce; disc(i1)=mdisce; end mdisc=mdisc/length(elt); if do_matrix if nel