!-----------------------------------------------------------------------------------------! ! Copyright (c) 2016 Peter Grünberg Institut, Forschungszentrum Jülich, Germany ! ! This file is part of kk-prime@juKKR and available as free software under the conditions ! ! of the MIT license as expressed in the LICENSE file in more detail. ! !-----------------------------------------------------------------------------------------! module mod_fermisurf_2D implicit none private public :: find_fermisurface_2D integer, parameter :: nkpmax = 512, nedges=5 ! shall be >> 32 to contain enough triangles per cube and band integer :: tridiags(2,2) = -1, squedges(2,5)=-1, tricorners(3,2)=-1, triedges(3,2)=-1 contains subroutine find_fermisurface_2D( inc, lattice, cluster, tgmatrx, symmetries, nCub3, nFSiter, nROOTiter, nstepsconnect, & & nCut_iter, roottype, rooteps, lrefine, nrefinenew, nkpts_int, kpoints_int, areas_int ) use type_inc, only: inc_type use type_data, only: lattice_type, cluster_type, tgmatrx_type use mod_symmetries, only: symmetries_type, get_2DIBZwedge_lines use mod_mympi, only: myrank, nranks, master use mod_ioformat, only: filename_cubesinfo, ext_formatted, fmt_fn_ext use mod_iohelp, only: file_present use mod_fermisurf_basic, only: get_cubesinfo_filename, read_cubesfile, save_cubesfile, mark_cubes_FScross, mark_cubes_FScross_memopt, find_kpoints_irredset, save_kpointsfile_vis implicit none type(inc_type), intent(in) :: inc type(lattice_type), intent(in) :: lattice type(cluster_type), intent(in) :: cluster type(tgmatrx_type), intent(inout) :: tgmatrx type(symmetries_type), intent(in) :: symmetries integer, intent(inout) :: nCub3(3) integer, intent(in) :: nFSiter, nROOTiter, lrefine, nrefinenew, nCut_iter(:), roottype(:), nstepsconnect(:) double precision, intent(in) :: rooteps(:) integer, intent(out) :: nkpts_int double precision, allocatable, intent(out) :: kpoints_int(:,:), areas_int(:) integer :: nBZlines double precision :: bounds(3,2) double precision, allocatable :: nvec(:,:), dscal(:) integer :: nmarked, ntotal integer, allocatable :: imarked(:) integer :: nkpts_vis, nkpts_irr integer, allocatable :: kpt2irr(:), irr2kpt(:), vis2int(:) double precision, allocatable :: kpoints_vis(:,:) integer :: isqu, iter, iter2, ierr, ii, nCub3test(3), iterstart double precision :: dtmp character(len=256) :: filename, filetest logical :: l_cubesfile, l_exist call get_2DIBZwedge_lines(lattice%recbv, symmetries%nsym_used, symmetries%rotmat, symmetries%isym_used, nBZlines, nvec, dscal, bounds) if(nCub3(3)/=1) then if(myrank==master) write(*,*) 'WARNING!!!!!!!!!! nCub(3) =/=1 in 2D mode. set nCub(3) = 1' nCub3(3) = 1 end if !initialize square indices arrays call init_square2triangles() !=====================================! !=== generate or read a cubesfile ====! !=====================================! write(filename,fmt_fn_ext) filename_cubesinfo, ext_formatted if(.not.file_present(trim(filename)).and.lrefine==1) stop 'cannot refine dataset: no cubesinfo present' if(file_present(trim(filename)))then call read_cubesfile(nCub3test, nmarked, imarked) if(any(nCub3 /= nCub3test).and.(myrank==master)) write(*,*) 'Warning!!! nCub3 inconsistent with cubesfile. Taking the values from cubesfile' nCub3 = nCub3test if(lrefine==1)then deallocate(imarked) call read_squaresrefine(nCub3test, nmarked, imarked) if(any(nCub3/=nCub3test)) stop 'nCub3 not consistent between cubesinfo and cubesrefine' if(myrank==master)then write(filename,'("squares_refine_step=",I0,"_",A".txt")') 0, 'read' call squares2TXT(filename, nCub3, nmarked, imarked, bounds) end if!myrank==master call cut_and_update_squares(nrefinenew, nCub3, nmarked, imarked) if(myrank==master)then write(filename,'("squares_refine_step=",I0,"_",A".txt")') 1, 'cut' call squares2TXT(filename, nCub3, nmarked, imarked, bounds) end if!myrank==master call mark_squares_in_IBZ(nCub3, nBZlines, nvec, dscal, bounds, nmarked, imarked) if(myrank==master)then write(filename,'("squares_refine_step=",I0,"_",A".txt")') 2, 'ibz' call squares2TXT(filename, nCub3, nmarked, imarked, bounds) end if!myrank==master end if!lrefine==1 else!cubesfile_present !search for existing cubesfiles that match the grid of an iteration within the iterative refinements iterstart=1 !try to take the densest file, therefore count from top to bottom: iter_loop: do iter=nFSiter,1,-1 !find the density of the cubes of iteration #iter nCub3test = nCub3 do iter2=2,iter nCub3test(1:2) = nCub3test(1:2)*nCut_iter(iter2-1) end do!iter2 !search for the existing cubesfile filetest = get_cubesinfo_filename(nCub3test,.true.) l_exist = file_present(trim(filetest)) if(l_exist)then iterstart=iter+1 call read_cubesfile(nCub3, nmarked, imarked, nCub3test) call cut_and_update_squares(nCut_iter(iter), nCub3, nmarked, imarked) ntotal = nmarked if(myrank==master) then write(filename,'("squares_iter=",I0,"_step=",I0,"_",(A),".txt")') iter, 3, 'cut' call squares2TXT(filename, nCub3, nmarked, imarked, bounds) end if!myrank==master !cubesfile found, so exit loop exit iter_loop end if!l_exist end do iter_loop if(iterstart==1)then !initialize cubes indices nmarked = product(nCub3) ntotal = product(nCub3) allocate(imarked(nmarked), STAT=ierr) if(ierr/=0) stop 'Problem allocating imarked in fermisurface' do isqu=1,nmarked imarked(isqu) = isqu end do!icube end if!iterstart==1 !====== != scan the cubes for intersections !====== do iter=iterstart,nFSiter !=== mark the cubes that lie (at least with one corner) within the first BZ ===! call mark_squares_in_IBZ(nCub3, nBZlines, nvec, dscal, bounds, nmarked, imarked) if(myrank==master) then write(filename,'("squares_iter=",I0,"_step=",I0,"_",(A),".txt")') iter, 1, 'IBZ' call squares2TXT(filename, nCub3, nmarked, imarked, bounds) write(*,'("***** Iteration ",I0," *****")') iter write(*,'(2X,2(A,I0),(A,F5.1,A))') 'Cubes found within the IBZ: ', nmarked, ' of ', ntotal, ' (= ', real(nmarked*100)/ntotal,' %)' end if!myrank==master !========= mark the cubes that cross the Fermi surface =========! !=== (only searching across the four diagonals of the cubes) ===! ntotal = nmarked if(inc%memopt==.true.) then call mark_cubes_FScross_memopt( inc, lattice, cluster, tgmatrx, nCub3, & & nstepsconnect(iter), 4, 2, tridiags, bounds, & & roottype(iter), rooteps(iter), nmarked, imarked ) else call mark_cubes_FScross( inc, lattice, cluster, tgmatrx, nCub3, & & nstepsconnect(iter), 4, 2, tridiags, bounds, & & roottype(iter), rooteps(iter), nmarked, imarked ) end if!inc%memopt==.true. if(myrank==master) then write(filename,'("squares_iter=",I0,"_step=",I0,"_",(A),".txt")') iter, 2, 'mark' call squares2TXT(filename, nCub3, nmarked, imarked, bounds) write(*,'(2X,2(A,I0),(A,F5.1,A))') 'Cubes found intersecting with FS: ', nmarked, ' of ', ntotal, ' (= ', real(nmarked*100)/ntotal,' %)' call save_cubesfile(nCub3, nmarked, imarked, lintermediate=.true.) end if!myrank==master !=== cut the remaining cubes into smaller pieces and update the indices ===! ! write(1000+myrank,*) iter, nCut_iter(iter) call cut_and_update_squares(nCut_iter(iter), nCub3, nmarked, imarked) ntotal = nmarked if(myrank==master) then write(filename,'("squares_iter=",I0,"_step=",I0,"_",(A),".txt")') iter, 3, 'cut' call squares2TXT(filename, nCub3, nmarked, imarked, bounds) end if!myrank==master end do!iter !=== mark the cubes that lie (maybe only partly) within the first BZ ===! iter = nFSiter+1 call mark_squares_in_IBZ(nCub3, nBZlines, nvec, dscal, bounds, nmarked, imarked) if(myrank==master) then write(filename,'("squares_iter=",I0,"_step=",I0,"_",(A),".txt")') iter, 1, 'IBZ' call squares2TXT(filename, nCub3, nmarked, imarked, bounds) call save_cubesfile(nCub3, nmarked, imarked) end if!myrank==master end if!cubesfile_present !=====================================! !=== generate or read a cubesfile ====! !=====================================! iter = nFSiter+1 if(inc%memopt==.true.)then call find_intesection_lines_memopt( inc, lattice, cluster, tgmatrx, symmetries, & & nCub3, bounds, nmarked, imarked, & & nstepsconnect(iter), nROOTiter, & & roottype(iter), rooteps(iter), nBZlines, & & nvec, dscal, nkpts_vis, nkpts_int, & & kpoints_vis, kpoints_int, areas_int, vis2int ) else call find_intesection_lines( inc, lattice, cluster, tgmatrx, symmetries, & & nCub3, bounds, nmarked, imarked, & & nstepsconnect(iter), nROOTiter, & & roottype(iter), rooteps(iter), nBZlines, & & nvec, dscal, nkpts_vis, nkpts_int, & & kpoints_vis, kpoints_int, areas_int, vis2int ) end if! write(1368,*) nkpts_vis call find_kpoints_irredset( bounds, nkpts_vis, kpoints_vis, nkpts_irr, kpt2irr, irr2kpt) !save the visualization k-points to a file if(myrank==master) call save_kpointsfile_vis(nkpts_vis, nkpts_irr, kpoints_vis, symmetries%nsym_used, symmetries%isym_used, kpt2irr, irr2kpt, vis2int) end subroutine find_fermisurface_2D !*******************************************************! !***************** BEGIN BIG SUBROUTINE ****************! !*******************************************************! subroutine find_intesection_lines( inc, lattice, cluster, tgmatrx, symmetries, & & nCub3, bounds, nmarked, imarked, & & nsteps, niter, roottype, rooteps, & & nfaces, nvec, dscal, npoints_vis_tot, & & npoints_int_tot, kpoints_vis_all, & & kpoints_int_all, areas_int_all, vis2int_all ) use type_inc, only: inc_type use type_data, only: lattice_type, cluster_type, tgmatrx_type use mod_symmetries, only: symmetries_type use mod_parutils, only: distribute_linear_on_tasks use mod_mympi, only: myrank, nranks, master use mod_mathtools, only: bubblesort, findminindex ! use mod_vtkxml, only: write_pointdata_rot use mod_ioformat, only: fmt_fn_ext, fmt_fn_sub_ext, filemode_rot, filename_vtktest, fmt_fn_rank_ext, filename_outinfo, ext_formatted use mod_fermisurf_basic, only: roots_along_edge, compare_two_eigv_in_substeps, ROOT_IMAG, ROOT_REAL, generate_squarevertices #ifdef CPP_MPI use mpi #endif implicit none type(inc_type), intent(in) :: inc type(lattice_type), intent(in) :: lattice type(cluster_type), intent(in) :: cluster type(tgmatrx_type), intent(in) :: tgmatrx type(symmetries_type), intent(in) :: symmetries integer, intent(in) :: nCub3(3), nmarked, imarked(nmarked),& & nsteps, roottype, niter, nfaces double precision, intent(in) :: bounds(3,2), rooteps, nvec(3,nfaces), dscal(nfaces) integer, intent(out) :: npoints_vis_tot, npoints_int_tot integer, allocatable, intent(out) :: vis2int_all(:) double precision, allocatable, intent(out) :: kpoints_vis_all(:,:),& & kpoints_int_all(:,:),& & areas_int_all(:) integer :: irank, npoints_vis,& & npoints_vis_tmpa(0:nranks-1),& & npoints_int_tmpa(0:nranks-1),& & ioffs_tmpa(0:nranks-1),& & ioffs_save(0:nranks-1),& & isendarr(0:nranks-1),& & ioffsarr(0:nranks-1) double precision, allocatable :: kpoints_vis(:,:),& & kpoints_int(:,:),& & areas_int(:), & & scalardata(:,:), & & vectordata(:,:,:) character(len=256) :: scalarstring(3), vectorstring(1) integer, allocatable :: vis2int(:) double complex, allocatable :: eigw_vis(:), eigw_vis_all(:) integer :: curid, nbands, nroots(nedges), lmid(inc%nrootmax,nedges), lmroot(inc%nrootmax,nedges) double precision :: kverts(3,4),& & kends(3,2),& & kmidsquare(3),& & kroot_in_cube(3,inc%nrootmax,nedges),& & kline(3,3),& & kroot_lm_tri(3,nkpmax) ! nkpmax >> (3 intersections per triangle) * (2 triangles per tetrahedron) * (6 tetrahedra) x ! (multiplication-factor for splitting the triangle if BZ-face is crossed) double complex :: eigw_lm_tri(nkpmax),& & eigw_line(3) double complex, allocatable :: LVroot(:,:,:,:), & & RVroot(:,:,:,:), & & eigwroot(:,:,:) double precision :: ksub(3,nsteps+1) double complex :: eigwends(2,inc%nrootmax,nedges) integer :: iproblems, isquareproblems(2,10*nmarked/nranks), iproblems_tmpa(0:nranks-1), iproblems_tot integer, allocatable :: isquareproblems_all(:,:) integer :: ioff, nkpt, ntot_pT(0:nranks-1), ioff_pT(0:nranks-1), lb, ub integer :: ierr, ii, ivc, icub, itmp, itri, iedge, itriedge, itetroot,& & icount, iedge1, iedge2, iroot1, iroot2, lm0, lm1, lm2, & & nfound_band, nfound_tet, lookup_tri(2,2), iverts_picked(4),& & sorted(4), sorted_tmp(4), i4edge(4), i4tet(4), isave, & & kcounter_lm, kcounter_cub, printstep, itmparr(1) double precision :: dtmp_ri(4), dist(nkpmax), weight_lm, kdiff(3), dtmp double complex :: eigw_picked(4) logical :: match character(len=256) :: filename character(len=1024) :: errormessage integer, parameter :: iofile=69823 ! write(*,*) 'in find_intesection_lines ok' !Parallelize call distribute_linear_on_tasks(nranks,myrank,master,nmarked,ntot_pT,ioff_pT,.true.) nkpt = ntot_pT(myrank) ioff = ioff_pT(myrank) !initialize isquareproblems = 0 iproblems = 0 !allocate arrays allocate( LVroot(inc%almso,inc%almso,inc%nrootmax,nedges),& & RVroot(inc%almso,inc%almso,inc%nrootmax,nedges),& & eigwroot(inc%almso,inc%nrootmax,nedges), & & STAT=ierr, ERRMSG=errormessage ) ! dtmp = dble(inc%almso)**2*inc%nrootmax*nedges*2 + dble(inc%almso)*inc%nrootmax*nedges ! if(myrank==master) write(*,*) 'Trying to allocate ', dtmp*16d0/1024**3, ' GB' ! write(13200+myrank,*) 'Trying to allocate ', dtmp*16d0/1024**3, ' GB' ! write(13200+myrank,*) inc%almso, inc%nrootmax, nedges, dtmp if(ierr/=0)then write(*,*) 'Problem allocating LVroot etc. in find_intesection_lines' dtmp = dble(inc%almso)**2*inc%nrootmax*nedges*2 + dble(inc%almso)*inc%nrootmax*nedges write(*,*) 'Error Status=', ierr write(*,*) 'Error message=', trim(errormessage) write(*,*) 'Trying to allocate ', dtmp*16d0/1024**3, ' GB' stop 'Problem allocating LVroot etc. in find_intesection_lines' end if npoints_vis = 0 allocate(kpoints_vis(3,200*nkpt), eigw_vis(200*nkpt), kpoints_int(3,20*nkpt), areas_int(20*nkpt), vis2int(200*nkpt), STAT=ierr) if(ierr/=0) stop 'Problem allocating kpoints_vis etc.' !print header of statusbar if(myrank==master) write(*,'("Loop over cubes: |",5(1X,I2,"%",5X,"|"),1X,I3,"%")') 0, 20, 40, 60, 80, 100 printstep = nkpt/50 if(printstep==0) printstep=1 #ifdef CPP_DEBUG write(filename,fmt_fn_rank_ext) filename_outinfo, myrank, ext_formatted open(unit=iofile, file=trim(filename), action='write', form='formatted') #endif !**************************************! !************* B E G I N **************! !**************************************! !*** (parallelized) loop over cubes ***! !**************************************! if(myrank==master) write(*,FMT=190) !beginning of statusbar kcounter_cub=0 areas_int = 0d0 do icub=1,nkpt !update statusbar if(mod(icub,printstep)==0 .and. myrank==master) write(*,FMT=200) #ifdef CPP_DEBUG write(iofile,'(A,I8)') 'starting cube ', imarked(icub+ioff) #endif call generate_squarevertices(nCub3,imarked(icub+ioff), bounds, kverts) !find middle point of the cube kmidsquare = (kverts(:,1)+kverts(:,4))/2 #ifdef CPP_DEBUG write(iofile,'(2X,"kverts(:,i)= ",3ES18.9)') kverts #endif !==================================! !=== find roots along the edges ===! !==================================! do iedge=1,nedges !pick k-points kends(:,1) = kverts(:,squedges(1,iedge)) kends(:,2) = kverts(:,squedges(2,iedge)) call roots_along_edge( inc, lattice, cluster, tgmatrx, nsteps, kends, niter,& & roottype, rooteps, nroots(iedge), lmroot(:,iedge), & & kroot_in_cube(:,:,iedge), LVroot(:,:,:,iedge), & & RVroot(:,:,:,iedge), eigwroot(:,:,iedge), -1, & & eigwends(:,:,iedge) ) end do!iedge #ifdef CPP_DEBUG write(iofile,'(2X,"#roots found on the edges:")') do iedge=1,nedges write(iofile,'(4X,"iedge= ",I0,", # = ",I0)') iedge, nroots(iedge) end do #endif !======================================================! !=== determine which kroots belong to the same band ===! !======================================================! lmid=0 ! the array lmid(iroot,iedge) will contain a unique id to which band a k-point belongs. curid=0 do iedge1=1,nedges do iroot1=1,nroots(iedge1) !pick a first root lm1 = lmroot(iroot1,iedge1) if(lmid(iroot1,iedge1)>0) cycle !this root has already an ID curid = curid+1 lmid(iroot1,iedge1)=curid #ifdef CPP_DEBUG write(iofile,'(4X,"Set (iedge,iroot)=( ",I0,",",I0,") to curid= ",I0)') iedge1, iroot1, curid #endif ! write(*,'("Next cur-id= ",I0)'), curid !compare to all other roots on different edges which are not yet treated loop3: do iedge2=iedge1+1,nedges loop4: do iroot2=1,nroots(iedge2) if(lmid(iroot2,iedge2)>0) cycle lm2 = lmroot(iroot2,iedge2) kends(:,1) = kroot_in_cube(:,iroot1,iedge1) kends(:,2) = kroot_in_cube(:,iroot2,iedge2) call compare_two_eigv_in_substeps( inc, lattice, cluster, tgmatrx, nsteps,& & kends, lm1, LVroot(:,:,iroot1,iedge1), & & RVroot(:,lm2,iroot2,iedge2), & & eigwroot(lm2,iroot2,iedge2), match ) #ifdef CPP_DEBUG write(iofile,'(6X,"Compare (iedge,iroot)=( ",I0,",",I0,") with (iedge,iroot)=( ",I0,",",I0,"), matching=",L1)') iedge1, iroot1, iedge2, iroot2, match #endif if(match) then lmid(iroot2,iedge2)=curid cycle loop3 end if!match end do loop4!iroot2 end do loop3!iedge2 end do!iroot1 end do!iedge1 nbands = curid #ifdef CPP_DEBUG write(iofile,'(2X,A)') 'LM-check' do iedge=1,nedges write(iofile,'(4X,"iedge= ",I0," - ",20I8)') iedge, lmid(1:nroots(iedge),iedge) end do!iedge write(iofile,'(2X,A,I0)') 'nbands= ', nbands #endif !==========================================! !=== scan the tetrahedra for each band ===! !=== and find the triangles and areas ===! !==========================================! #ifdef CPP_DEBUG write(iofile,'(2X,A)') 'Scan all bands ands tetraheda' #endif !loop over all bands do lm0=1,nbands kcounter_lm=0 !scan all tetrahedra do itri=1,2 #ifdef CPP_DEBUG write(iofile,'(4X,2(A,I0))') 'lm0= ', lm0, ', itri= ', itri #endif nfound_tet = 0 !find all roots belonging to this this tetrahedron and this band edgeloop: do iedge1=1,3 itriedge = triedges(iedge1,itri) ! write(*,'(20(A,I0))') 'itetedge= ', itetedge, ', #roots=', nroots(itetedge) do iroot1=1,nroots(itriedge) if(lmid(iroot1,itriedge)==lm0)then nfound_tet = nfound_tet+1 if(nfound_tet>2)then #ifdef CPP_DEBUG write(iofile,'(I0,A)') imarked(icub+ioff), ' =imarked: more than 2 intersections of band with triangle --> skip' #endif iproblems = iproblems+1 isquareproblems(1,iproblems) = imarked(icub+ioff) isquareproblems(2,iproblems) = 1 nfound_tet=0 exit edgeloop end if lookup_tri(:,nfound_tet) = (/ iroot1, itriedge /) end if end do!iroot1 end do edgeloop!iedge1 #ifdef CPP_DEBUG write(iofile,'(6X,A,I0)') 'nfound_tet= ', nfound_tet #endif select case ( nfound_tet ) case( 0 ); cycle case( 2 ) !store the triangle k-points kline(:,1) = kroot_in_cube(:,lookup_tri(1,1),lookup_tri(2,1)) kline(:,2) = kroot_in_cube(:,lookup_tri(1,2),lookup_tri(2,2)) eigw_line(1) = eigwroot(lmroot(lookup_tri(1,1),lookup_tri(2,1)),lookup_tri(1,1),lookup_tri(2,1)) eigw_line(2) = eigwroot(lmroot(lookup_tri(1,2),lookup_tri(2,2)),lookup_tri(1,2),lookup_tri(2,2)) #ifdef CPP_DEBUG write(iofile,'(8X,A,3ES25.16," | ",2ES25.16)') 'k1=', kline(:,1), eigw_line(1) write(iofile,'(8X,A,3ES25.16," | ",2ES25.16)') 'k2=', kline(:,2), eigw_line(2) #endif !truncate line if BZ-face is crossed call split_line(kline, eigw_line, kroot_lm_tri(:,:), eigw_lm_tri(:), kcounter_lm, nfaces, nvec, dscal) case default #ifdef CPP_DEBUG write(iofile,'(I0,A)') imarked(icub+ioff), ' =imarked: neither 0 nor 2 intesections found for --> skip' #endif iproblems = iproblems+1 isquareproblems(1,iproblems) = imarked(icub+ioff) isquareproblems(2,iproblems) = 2 end select end do!itri #ifdef CPP_DEBUG write(iofile,'(6X,A,I0)') 'cut lines; kcounter_lm = ', kcounter_lm do ii=1,kcounter_lm write(iofile,'(8X,A,3ES25.16," | ",2ES25.16)') 'k=', kroot_lm_tri(:,ii), eigw_lm_tri(ii) end do!ii #endif !if cube is empty, proceed to next cube if(kcounter_lm==0) cycle !==============================! !=== Find the k-point and ===! !=== weight for integration ===! !==============================! !update the counter for integration k-points kcounter_cub = kcounter_cub+1 !find kpoint-index representing this cube do ii=1,kcounter_lm dist(ii) = sum((kroot_lm_tri(:,ii) - kmidsquare)**2) end do call findminindex(kcounter_lm, dist(1:kcounter_lm), isave) !save the k-point !kpoints_int(:,kcounter_cub) = kroot_lm_tri(:,isave) ! shift the kpoint toward the center of the cube by a tiny change ! to be able to identify the cube later on kpoints_int(:,kcounter_cub) = kroot_lm_tri(:,isave) +(kmidsquare-kroot_lm_tri(:,isave))*1d-6 !find the weight of the representing cube (=area of all triangles) weight_lm = 0d0 do ii=1,kcounter_lm/2 kdiff = kroot_lm_tri(:,ii*2) - kroot_lm_tri(:,ii*2-1) dtmp = sqrt(sum(kdiff**2)) weight_lm = weight_lm + dtmp end do!ii areas_int(kcounter_cub) = weight_lm !if weight for this triangle is negligible, forget this k-point if(abs(weight_lm)<1d-16) kcounter_cub = kcounter_cub - 1 !=================================! !=== Store the visualization ===! !=== information in temp array ===! !=================================! !add the visualization-triangles to the temporary storage array kpoints_vis(:,npoints_vis+1:npoints_vis+kcounter_lm) = kroot_lm_tri(:,1:kcounter_lm) eigw_vis(npoints_vis+1:npoints_vis+kcounter_lm) = eigw_lm_tri(1:kcounter_lm) vis2int(npoints_vis+1:npoints_vis+kcounter_lm) = kcounter_cub npoints_vis = npoints_vis + kcounter_lm end do!lm0 end do!icub if(myrank==master) write(*,*) !**************************************! !*** (parallelized) loop over cubes ***! !**************************************! !*************** E N D ****************! !**************************************! !***************************************! !************* B E G I N ***************! !***************************************! !*** collect the problematic squares ***! !***************************************! #ifdef CPP_MPI !collect the numbers of problematic arrays call MPI_Allgather( iproblems, 1, MPI_INTEGER, & & iproblems_tmpa, 1, MPI_INTEGER, & & MPI_COMM_WORLD, ierr ) if(ierr/=MPI_SUCCESS) stop 'Problem in allgather npoints_vis_glob' iproblems_tot = sum(iproblems_tmpa) allocate(isquareproblems_all(2,iproblems_tot), STAT=ierr) if(ierr/=0) stop 'Problem allocating isquareproblems_all' !calculate offsets ioffs_tmpa=0 do irank=1,nranks-1 ioffs_tmpa(irank) = ioffs_tmpa(irank-1)+iproblems_tmpa(irank-1) end do!irank ioffs_save = ioffs_tmpa !collect the problematic squares isendarr = 2*iproblems_tmpa ioffsarr = 2*ioffs_tmpa call MPI_Allgatherv( isquareproblems, isendarr(myrank), MPI_INTEGER, & & isquareproblems_all, isendarr, ioffsarr, & & MPI_INTEGER, MPI_COMM_WORLD, ierr ) if(ierr/=MPI_SUCCESS) stop 'Problem in allgatherv isquareproblems' #else iproblems_tot = iproblems allocate(isquareproblems_all(2,iproblems_tot), STAT=ierr) if(ierr/=0) stop 'Problem allocating isquareproblems_all' isquareproblems_all = isquareproblems(:,1:iproblems_tot) #endif #ifndef CPP_DEBUG if(myrank==master)then write(filename,fmt_fn_rank_ext) filename_outinfo, myrank, ext_formatted open(unit=13512, file=trim(filename), action='write', form='formatted') do ii=1,iproblems_tot select case (isquareproblems_all(2,ii)) case(1); write(13512,'(I0,A)') isquareproblems_all(1,ii), ' =imarked: more than 2 intersections of band with triangle --> skip' case(2); write(13512,'(I0,A)') isquareproblems_all(1,ii), ' =imarked: neither 0 nor 2 intesections found for --> skip' case default; write(13512,'(I0,A,I0,A)') isquareproblems_all(1,ii), ' =imarked: identifier ', isquareproblems_all(2,ii), ' not known' end select end do!ii close(13512) end if!myrank==master #endif !***************************************! !*** collect the problematic squares ***! !***************************************! !*************** E N D *****************! !***************************************! !************************************! !************ B E G I N *************! !************************************! !*** output of visualization data ***! !************************************! #ifdef CPP_MPI !collect the number of points call MPI_Allgather( npoints_vis, 1, MPI_INTEGER, & & npoints_vis_tmpa, 1, MPI_INTEGER, & & MPI_COMM_WORLD, ierr ) if(ierr/=MPI_SUCCESS) stop 'Problem in allgather npoints_vis_glob' npoints_vis_tot = sum(npoints_vis_tmpa) ioffs_tmpa=0 do irank=1,nranks-1 ioffs_tmpa(irank) = ioffs_tmpa(irank-1)+npoints_vis_tmpa(irank-1) end do!irank ioffs_save = ioffs_tmpa !allocate result arrays allocate(kpoints_vis_all(3,npoints_vis_tot), eigw_vis_all(npoints_vis_tot), vis2int_all(npoints_vis_tot), STAT=ierr) if(ierr/=0) stop 'Problem allocating kpoints_vis_all etc.' !collect the k-points isendarr = 3*npoints_vis_tmpa ioffsarr = 3*ioffs_tmpa call MPI_Allgatherv( kpoints_vis, isendarr(myrank), MPI_DOUBLE_PRECISION,& & kpoints_vis_all, isendarr, ioffsarr, & & MPI_DOUBLE_PRECISION, MPI_COMM_WORLD, ierr ) if(ierr/=MPI_SUCCESS) stop 'Problem in allgatherv kpoints_vis_glob' !collect the eigenvalues isendarr = npoints_vis_tmpa ioffsarr = ioffs_tmpa call MPI_Allgatherv( eigw_vis, isendarr(myrank), MPI_DOUBLE_COMPLEX,& & eigw_vis_all, isendarr, ioffsarr, & & MPI_DOUBLE_COMPLEX, MPI_COMM_WORLD, ierr ) if(ierr/=MPI_SUCCESS) stop 'Problem in allgatherv eigv_vis_glob' !collect the translation array isendarr = npoints_vis_tmpa ioffsarr = ioffs_tmpa call MPI_Allgatherv( vis2int, isendarr(myrank), MPI_INTEGER, & & vis2int_all, isendarr, ioffsarr, & & MPI_INTEGER, MPI_COMM_WORLD, ierr ) if(ierr/=MPI_SUCCESS) stop 'Problem in allgatherv vis2int_glob' !adapt the offsets for the translation array --> done below (!!!!!) #else npoints_vis_tot = npoints_vis allocate(kpoints_vis_all(3,npoints_vis_tot), eigw_vis_all(npoints_vis_tot), vis2int_all(npoints_vis_tot), STAT=ierr) if(ierr/=0) stop 'Problem allocating kpoints_vis_all etc.' kpoints_vis_all = kpoints_vis(:,1:npoints_vis_tot) eigw_vis_all = eigw_vis(1:npoints_vis_tot) vis2int_all = vis2int(1:npoints_vis_tot) #endif deallocate( kpoints_vis, eigw_vis, STAT=ierr ) if(ierr/=0) stop 'Problem deallocating kpoints_vis etc.' if(myrank==master)then write(filename,fmt_fn_ext) 'fstest_eigw0', ext_formatted open(unit=3654,file=filename,form='formatted',action='write') write(3654,'(2ES25.16)') eigw_vis_all close(3654) end if!myrank==master !************************************! !*** output of visualization data ***! !************************************! !************** E N D ***************! !************************************! !*************************************! !************ B E G I N **************! !*************************************! !*** gathering of integration data ***! !*************************************! #ifdef CPP_MPI !collect the number of points call MPI_Allgather( kcounter_cub, 1, MPI_INTEGER, & & npoints_int_tmpa, 1, MPI_INTEGER, & & MPI_COMM_WORLD, ierr ) if(ierr/=MPI_SUCCESS) stop 'Problem in allgather npoints_int_tmpa' npoints_int_tot = sum(npoints_int_tmpa) ioffs_tmpa=0 do irank=1,nranks-1 ioffs_tmpa(irank) = ioffs_tmpa(irank-1)+npoints_int_tmpa(irank-1) end do!irank !allocate result arrays allocate(kpoints_int_all(3,npoints_int_tot), areas_int_all(npoints_int_tot), STAT=ierr) if(ierr/=0) stop 'Problem allocating kpoints_int_all etc.' !collect the k-points isendarr = 3*npoints_int_tmpa ioffsarr = 3*ioffs_tmpa call MPI_Allgatherv( kpoints_int, isendarr(myrank), MPI_DOUBLE_PRECISION,& & kpoints_int_all, isendarr, ioffsarr, & & MPI_DOUBLE_PRECISION, MPI_COMM_WORLD, ierr ) if(ierr/=MPI_SUCCESS) stop 'Problem in allgatherv kpoints_int_all' !collect the areas isendarr = npoints_int_tmpa ioffsarr = ioffs_tmpa call MPI_Allgatherv( areas_int, isendarr(myrank), MPI_DOUBLE_PRECISION,& & areas_int_all, isendarr, ioffsarr, & & MPI_DOUBLE_PRECISION, MPI_COMM_WORLD, ierr ) if(ierr/=MPI_SUCCESS) stop 'Problem in allgatherv kpoints_int_all' !adapt the offsets for the translation array --> from above (!!!!!) do irank=1,nranks-1 lb = ioffs_save(irank)+1 ub = ioffs_save(irank)+npoints_vis_tmpa(irank) vis2int_all(lb:ub) = vis2int_all(lb:ub) + ioffs_tmpa(irank) end do!irank #else npoints_int_tot = kcounter_cub allocate(kpoints_int_all(3,npoints_int_tot), areas_int_all(npoints_int_tot), STAT=ierr) if(ierr/=0) stop 'Problem allocating kpoints_int_all etc.' kpoints_int_all = kpoints_int(:,1:npoints_int_tot) areas_int_all = areas_int(1:npoints_int_tot) #endif #ifdef CPP_DEBUG close(iofile) #endif 190 FORMAT(' |'$) 200 FORMAT('|'$) end subroutine find_intesection_lines !*******************************************************! !***************** END BIG SUBROUTINE ****************! !*******************************************************! subroutine find_intesection_lines_memopt( inc, lattice, cluster, tgmatrx, symmetries, & & nCub3, bounds, nmarked, imarked, & & nsteps, niter, roottype, rooteps, & & nfaces, nvec, dscal, npoints_vis_tot, & & npoints_int_tot, kpoints_vis_all, & & kpoints_int_all, areas_int_all, vis2int_all ) use type_inc, only: inc_type use type_data, only: lattice_type, cluster_type, tgmatrx_type use mod_symmetries, only: symmetries_type use mod_parutils, only: distribute_linear_on_tasks use mod_mympi, only: myrank, nranks, master use mod_mathtools, only: bubblesort, findminindex ! use mod_vtkxml, only: write_pointdata_rot use mod_ioformat, only: fmt_fn_ext, fmt_fn_sub_ext, filemode_rot, filename_vtktest, fmt_fn_rank_ext, filename_outinfo, ext_formatted use mod_iohelp, only: file_present2 use mod_fermisurf_basic, only: roots_along_edge, compare_two_eigv_in_substeps, ROOT_IMAG, ROOT_REAL, generate_squarevertices, & & roots_along_edge_memopt, compare_two_eigv_in_substeps_memopt #ifdef CPP_MPI use mpi #endif implicit none type(inc_type), intent(in) :: inc type(lattice_type), intent(in) :: lattice type(cluster_type), intent(in) :: cluster type(tgmatrx_type), intent(in) :: tgmatrx type(symmetries_type), intent(in) :: symmetries integer, intent(in) :: nCub3(3), nmarked, imarked(nmarked),& & nsteps, roottype, niter, nfaces double precision, intent(in) :: bounds(3,2), rooteps, nvec(3,nfaces), dscal(nfaces) integer, intent(out) :: npoints_vis_tot, npoints_int_tot integer, allocatable, intent(out) :: vis2int_all(:) double precision, allocatable, intent(out) :: kpoints_vis_all(:,:),& & kpoints_int_all(:,:),& & areas_int_all(:) integer :: irank, npoints_vis,& & npoints_vis_tmpa(0:nranks-1),& & npoints_int_tmpa(0:nranks-1),& & ioffs_tmpa(0:nranks-1),& & ioffs_save(0:nranks-1),& & isendarr(0:nranks-1),& & ioffsarr(0:nranks-1) double precision, allocatable :: kpoints_vis(:,:),& & kpoints_int(:,:),& & areas_int(:), & & scalardata(:,:), & & vectordata(:,:,:) character(len=256) :: scalarstring(3), vectorstring(1) integer, allocatable :: vis2int(:) double complex, allocatable :: eigw_vis(:), eigw_vis_all(:) integer :: curid, nbands, nroots(nedges), lmid(inc%nrootmax,nedges), lmroot(inc%nrootmax,nedges) double precision :: kverts(3,4),& & kends(3,2),& & kmidsquare(3),& & kroot_in_cube(3,inc%nrootmax,nedges),& & kline(3,3),& & kroot_lm_tri(3,nkpmax) ! nkpmax >> (3 intersections per triangle) * (2 triangles per tetrahedron) * (6 tetrahedra) x ! (multiplication-factor for splitting the triangle if BZ-face is crossed) double complex :: eigw_lm_tri(nkpmax),& & eigw_line(3) double complex, allocatable :: LVroot(:,:,:,:), & & RVroot(:,:,:,:), & & eigwroot(:,:,:) double precision :: ksub(3,nsteps+1) double complex :: eigwends(2,inc%nrootmax,nedges) integer :: iproblems, isquareproblems(2,10*nmarked/nranks), iproblems_tmpa(0:nranks-1), iproblems_tot integer, allocatable :: isquareproblems_all(:,:) integer :: ioff, nkpt, ntot_pT(0:nranks-1), ioff_pT(0:nranks-1), lb, ub, i integer :: ierr, ii, ivc, icub, itmp, itri, iedge, itriedge, itetroot,& & icount, iedge1, iedge2, iroot1, iroot2, lm0, lm1, lm2, & & nfound_band, nfound_tet, lookup_tri(2,2), iverts_picked(4),& & sorted(4), sorted_tmp(4), i4edge(4), i4tet(4), isave, & & kcounter_lm, kcounter_cub, printstep, itmparr(1) integer :: kcounter_cub_file, kcounter_lm_file double precision :: dtmp_ri(4), dist(nkpmax), weight_lm, kdiff(3), dtmp double complex :: eigw_picked(4) logical :: match character(len=256) :: filename character(len=256) :: filename_cube character(len=1024) :: errormessage integer, parameter :: iofile=69823 integer, parameter :: iofile_cube=69824 ! write(*,*) 'in find_intesection_lines ok' !Parallelize call distribute_linear_on_tasks(nranks,myrank,master,nmarked,ntot_pT,ioff_pT,.true.) nkpt = ntot_pT(myrank) ioff = ioff_pT(myrank) !initialize isquareproblems = 0 iproblems = 0 !allocate arrays allocate( LVroot(inc%almso,inc%neig,inc%nrootmax,nedges),& & RVroot(inc%almso,inc%neig,inc%nrootmax,nedges),& & eigwroot(inc%neig,inc%nrootmax,nedges), & & STAT=ierr, ERRMSG=errormessage ) ! dtmp = dble(inc%almso)**2*inc%nrootmax*nedges*2 + dble(inc%almso)*inc%nrootmax*nedges ! if(myrank==master) write(*,*) 'Trying to allocate ', dtmp*16d0/1024**3, ' GB' ! write(13200+myrank,*) 'Trying to allocate ', dtmp*16d0/1024**3, ' GB' ! write(13200+myrank,*) inc%almso, inc%nrootmax, nedges, dtmp if(ierr/=0)then write(*,*) 'Problem allocating LVroot etc. in find_intesection_lines' dtmp = dble(inc%almso)*inc%neig*inc%nrootmax*nedges*2 + inc%neig*inc%nrootmax*nedges write(*,*) 'Error Status=', ierr write(*,*) 'Error message=', trim(errormessage) write(*,*) 'Trying to allocate ', dtmp*16d0/1024**3, ' GB' stop 'Problem allocating LVroot etc. in find_intesection_lines' end if npoints_vis = 0 allocate(kpoints_vis(3,200*nkpt), eigw_vis(200*nkpt), kpoints_int(3,20*nkpt), areas_int(20*nkpt), vis2int(200*nkpt), STAT=ierr) if(ierr/=0) stop 'Problem allocating kpoints_vis etc.' !print header of statusbar if(myrank==master) write(*,'("Loop over cubes: |",5(1X,I2,"%",5X,"|"),1X,I3,"%")') 0, 20, 40, 60, 80, 100 printstep = nkpt/50 if(printstep==0) printstep=1 #ifdef CPP_DEBUG write(filename,fmt_fn_rank_ext) filename_outinfo, myrank, ext_formatted open(unit=iofile, file=trim(filename), action='write', form='formatted') #endif !**************************************! !************* B E G I N **************! !**************************************! !*** (parallelized) loop over cubes ***! !**************************************! if(myrank==master) write(*,FMT=190) !beginning of statusbar kcounter_cub=0 areas_int = 0d0 do icub=1,nkpt kcounter_cub_file=0 kcounter_lm_file=0 !update statusbar if(mod(icub,printstep)==0 .and. myrank==master) write(*,FMT=200) #ifdef CPP_DEBUG write(iofile,'(A,I8)') 'starting cube ', imarked(icub+ioff) #endif write(filename_cube,'(1I6,A)') imarked(icub+ioff), ".cube" write(*,*) "looking for ", filename_cube ! compute a cube only if no file was found from previous calculation write(*,*) "file_present2(filename) : ",file_present2(trim(filename_cube)) if(.not.file_present2(trim(filename_cube))) then call generate_squarevertices(nCub3,imarked(icub+ioff), bounds, kverts) !find middle point of the cube kmidsquare = (kverts(:,1)+kverts(:,4))/2 #ifdef CPP_DEBUG write(iofile,'(2X,"kverts(:,i)= ",3ES18.9)') kverts #endif !==================================! !=== find roots along the edges ===! !==================================! do iedge=1,nedges !pick k-points kends(:,1) = kverts(:,squedges(1,iedge)) kends(:,2) = kverts(:,squedges(2,iedge)) call roots_along_edge_memopt( inc, lattice, cluster, tgmatrx, nsteps, kends, niter,& & roottype, rooteps, nroots(iedge), lmroot(:,iedge), & & kroot_in_cube(:,:,iedge), LVroot(:,:,:,iedge), & & RVroot(:,:,:,iedge), eigwroot(:,:,iedge), 1, & & eigwends(:,:,iedge) ) end do!iedge #ifdef CPP_DEBUG write(iofile,'(2X,"#roots found on the edges:")') do iedge=1,nedges write(iofile,'(4X,"iedge= ",I0,", # = ",I0)') iedge, nroots(iedge) end do #endif !======================================================! !=== determine which kroots belong to the same band ===! !======================================================! lmid=0 ! the array lmid(iroot,iedge) will contain a unique id to which band a k-point belongs. curid=0 do iedge1=1,nedges do iroot1=1,nroots(iedge1) !pick a first root lm1 = lmroot(iroot1,iedge1) if(lmid(iroot1,iedge1)>0) cycle !this root has already an ID curid = curid+1 lmid(iroot1,iedge1)=curid #ifdef CPP_DEBUG write(iofile,'(4X,"Set (iedge,iroot)=( ",I0,",",I0,") to curid= ",I0)') iedge1, iroot1, curid #endif ! write(*,'("Next cur-id= ",I0)'), curid !compare to all other roots on different edges which are not yet treated loop3: do iedge2=iedge1+1,nedges loop4: do iroot2=1,nroots(iedge2) if(lmid(iroot2,iedge2)>0) cycle lm2 = lmroot(iroot2,iedge2) kends(:,1) = kroot_in_cube(:,iroot1,iedge1) kends(:,2) = kroot_in_cube(:,iroot2,iedge2) call compare_two_eigv_in_substeps_memopt( inc, lattice, cluster, tgmatrx, nsteps,& & kends, lm1, LVroot(:,:,iroot1,iedge1), & & RVroot(:,lm2,iroot2,iedge2), & & eigwroot(lm2,iroot2,iedge2), match ) #ifdef CPP_DEBUG write(iofile,'(6X,"Compare (iedge,iroot)=( ",I0,",",I0,") with (iedge,iroot)=( ",I0,",",I0,"), matching=",L1)') iedge1, iroot1, iedge2, iroot2, match #endif if(match) then lmid(iroot2,iedge2)=curid cycle loop3 end if!match end do loop4!iroot2 end do loop3!iedge2 end do!iroot1 end do!iedge1 nbands = curid #ifdef CPP_DEBUG write(iofile,'(2X,A)') 'LM-check' do iedge=1,nedges write(iofile,'(4X,"iedge= ",I0," - ",20I8)') iedge, lmid(1:nroots(iedge),iedge) end do!iedge write(iofile,'(2X,A,I0)') 'nbands= ', nbands #endif !==========================================! !=== scan the tetrahedra for each band ===! !=== and find the triangles and areas ===! !==========================================! #ifdef CPP_DEBUG write(iofile,'(2X,A)') 'Scan all bands ands tetraheda' #endif !loop over all bands do lm0=1,nbands kcounter_lm=0 !scan all tetrahedra do itri=1,2 #ifdef CPP_DEBUG write(iofile,'(4X,2(A,I0))') 'lm0= ', lm0, ', itri= ', itri #endif nfound_tet = 0 !find all roots belonging to this this tetrahedron and this band edgeloop: do iedge1=1,3 itriedge = triedges(iedge1,itri) ! write(*,'(20(A,I0))') 'itetedge= ', itetedge, ', #roots=', nroots(itetedge) do iroot1=1,nroots(itriedge) if(lmid(iroot1,itriedge)==lm0)then nfound_tet = nfound_tet+1 if(nfound_tet>2)then #ifdef CPP_DEBUG write(iofile,'(I0,A)') imarked(icub+ioff), ' =imarked: more than 2 intersections of band with triangle --> skip' #endif iproblems = iproblems+1 isquareproblems(1,iproblems) = imarked(icub+ioff) isquareproblems(2,iproblems) = 1 nfound_tet=0 exit edgeloop end if lookup_tri(:,nfound_tet) = (/ iroot1, itriedge /) end if end do!iroot1 end do edgeloop!iedge1 #ifdef CPP_DEBUG write(iofile,'(6X,A,I0)') 'nfound_tet= ', nfound_tet #endif select case ( nfound_tet ) case( 0 ); cycle case( 2 ) !store the triangle k-points kline(:,1) = kroot_in_cube(:,lookup_tri(1,1),lookup_tri(2,1)) kline(:,2) = kroot_in_cube(:,lookup_tri(1,2),lookup_tri(2,2)) eigw_line(1) = eigwroot(lmroot(lookup_tri(1,1),lookup_tri(2,1)),lookup_tri(1,1),lookup_tri(2,1)) eigw_line(2) = eigwroot(lmroot(lookup_tri(1,2),lookup_tri(2,2)),lookup_tri(1,2),lookup_tri(2,2)) #ifdef CPP_DEBUG write(iofile,'(8X,A,3ES25.16," | ",2ES25.16)') 'k1=', kline(:,1), eigw_line(1) write(iofile,'(8X,A,3ES25.16," | ",2ES25.16)') 'k2=', kline(:,2), eigw_line(2) #endif !truncate line if BZ-face is crossed call split_line(kline, eigw_line, kroot_lm_tri(:,:), eigw_lm_tri(:), kcounter_lm, nfaces, nvec, dscal) case default #ifdef CPP_DEBUG write(iofile,'(I0,A)') imarked(icub+ioff), ' =imarked: neither 0 nor 2 intesections found for --> skip' #endif iproblems = iproblems+1 isquareproblems(1,iproblems) = imarked(icub+ioff) isquareproblems(2,iproblems) = 2 end select end do!itri #ifdef CPP_DEBUG write(iofile,'(6X,A,I0)') 'cut lines; kcounter_lm = ', kcounter_lm do ii=1,kcounter_lm write(iofile,'(8X,A,3ES25.16," | ",2ES25.16)') 'k=', kroot_lm_tri(:,ii), eigw_lm_tri(ii) end do!ii #endif !if cube is empty, proceed to next cube if(kcounter_lm==0) cycle !==============================! !=== Find the k-point and ===! !=== weight for integration ===! !==============================! !update the counter for integration k-points kcounter_cub = kcounter_cub+1 kcounter_cub_file = kcounter_cub_file+1 !find kpoint-index representing this cube do ii=1,kcounter_lm dist(ii) = sum((kroot_lm_tri(:,ii) - kmidsquare)**2) end do call findminindex(kcounter_lm, dist(1:kcounter_lm), isave) !save the k-point kpoints_int(:,kcounter_cub) = kroot_lm_tri(:,isave) !find the weight of the representing cube (=area of all triangles) weight_lm = 0d0 do ii=1,kcounter_lm/2 kdiff = kroot_lm_tri(:,ii*2) - kroot_lm_tri(:,ii*2-1) dtmp = sqrt(sum(kdiff**2)) weight_lm = weight_lm + dtmp end do!ii areas_int(kcounter_cub) = weight_lm !if weight for this triangle is negligible, forget this k-point if(abs(weight_lm)<1d-16) then kcounter_cub = kcounter_cub - 1 kcounter_cub_file = kcounter_cub_file - 1 endif!abs(weight_lm)<1d-16 !=================================! !=== Store the visualization ===! !=== information in temp array ===! !=================================! !add the visualization-triangles to the temporary storage array kpoints_vis(:,npoints_vis+1:npoints_vis+kcounter_lm) = kroot_lm_tri(:,1:kcounter_lm) eigw_vis(npoints_vis+1:npoints_vis+kcounter_lm) = eigw_lm_tri(1:kcounter_lm) vis2int(npoints_vis+1:npoints_vis+kcounter_lm) = kcounter_cub npoints_vis = npoints_vis + kcounter_lm kcounter_lm_file = kcounter_lm_file + kcounter_lm end do!lm0 ! save results for this cube in a separate cube file write(*,*) "writing in ", trim(filename_cube) open(unit=iofile_cube, file=trim(filename_cube), action='write', form='formatted') write(iofile_cube,'(1I2)') kcounter_cub_file if(kcounter_cub_file>0) then do i=1,kcounter_cub_file write(iofile_cube,'(3ES25.16)') kpoints_int(:,kcounter_cub) write(iofile_cube,'(1ES25.16)') areas_int(kcounter_cub) end do!i=1,kcounter_cub_file end if!kcounter_cub_file>0 write(iofile_cube,'(1I2)') kcounter_lm_file if(kcounter_lm_file>0) then write(iofile_cube,'(3ES25.16)') kpoints_vis(:,npoints_vis+1-kcounter_lm_file:npoints_vis) write(iofile_cube,'(1I8)') vis2int(npoints_vis+1-kcounter_lm_file:npoints_vis) end if!kcounter_cub_file>0 close(unit=iofile_cube) else ! if file exist for this cube, read the content write(*,*) "reading ", trim(filename_cube) open(unit=iofile_cube, file=trim(filename_cube), action='read', form='formatted') read(iofile_cube,'(1I2)') kcounter_cub_file if(kcounter_cub_file>0) then do i=1,kcounter_cub_file kcounter_cub = kcounter_cub +1 read(iofile_cube,'(3ES25.16)') kpoints_int(:,kcounter_cub) read(iofile_cube,'(1ES25.16)') areas_int(kcounter_cub) end do!i=1,kcounter_cub_file end if!kcounter_cub_file>0 read(iofile_cube,'(1I2)') kcounter_lm_file if(kcounter_lm_file>0) then read(iofile_cube,'(3ES25.16)') kpoints_vis(:,npoints_vis+1:npoints_vis+kcounter_lm_file) read(iofile_cube,'(1I8)') vis2int(npoints_vis+1:npoints_vis+kcounter_lm_file) npoints_vis = npoints_vis + kcounter_lm_file end if!kcounter_cub_file>0 close(unit=iofile_cube) end if!file_present(filename_cube) end do!icub if(myrank==master) write(*,*) !**************************************! !*** (parallelized) loop over cubes ***! !**************************************! !*************** E N D ****************! !**************************************! !***************************************! !************* B E G I N ***************! !***************************************! !*** collect the problematic squares ***! !***************************************! #ifdef CPP_MPI !collect the numbers of problematic arrays call MPI_Allgather( iproblems, 1, MPI_INTEGER, & & iproblems_tmpa, 1, MPI_INTEGER, & & MPI_COMM_WORLD, ierr ) if(ierr/=MPI_SUCCESS) stop 'Problem in allgather npoints_vis_glob' iproblems_tot = sum(iproblems_tmpa) allocate(isquareproblems_all(2,iproblems_tot), STAT=ierr) if(ierr/=0) stop 'Problem allocating isquareproblems_all' !calculate offsets ioffs_tmpa=0 do irank=1,nranks-1 ioffs_tmpa(irank) = ioffs_tmpa(irank-1)+iproblems_tmpa(irank-1) end do!irank ioffs_save = ioffs_tmpa !collect the problematic squares isendarr = 2*iproblems_tmpa ioffsarr = 2*ioffs_tmpa call MPI_Allgatherv( isquareproblems, isendarr(myrank), MPI_INTEGER, & & isquareproblems_all, isendarr, ioffsarr, & & MPI_INTEGER, MPI_COMM_WORLD, ierr ) if(ierr/=MPI_SUCCESS) stop 'Problem in allgatherv isquareproblems' #else iproblems_tot = iproblems allocate(isquareproblems_all(2,iproblems_tot), STAT=ierr) if(ierr/=0) stop 'Problem allocating isquareproblems_all' isquareproblems_all = isquareproblems(:,1:iproblems_tot) #endif #ifndef CPP_DEBUG if(myrank==master)then write(filename,fmt_fn_rank_ext) filename_outinfo, myrank, ext_formatted open(unit=13512, file=trim(filename), action='write', form='formatted') do ii=1,iproblems_tot select case (isquareproblems_all(2,ii)) case(1); write(13512,'(I0,A)') isquareproblems_all(1,ii), ' =imarked: more than 2 intersections of band with triangle --> skip' case(2); write(13512,'(I0,A)') isquareproblems_all(1,ii), ' =imarked: neither 0 nor 2 intesections found for --> skip' case default; write(13512,'(I0,A,I0,A)') isquareproblems_all(1,ii), ' =imarked: identifier ', isquareproblems_all(2,ii), ' not known' end select end do!ii close(13512) end if!myrank==master #endif !***************************************! !*** collect the problematic squares ***! !***************************************! !*************** E N D *****************! !***************************************! !************************************! !************ B E G I N *************! !************************************! !*** output of visualization data ***! !************************************! #ifdef CPP_MPI !collect the number of points call MPI_Allgather( npoints_vis, 1, MPI_INTEGER, & & npoints_vis_tmpa, 1, MPI_INTEGER, & & MPI_COMM_WORLD, ierr ) if(ierr/=MPI_SUCCESS) stop 'Problem in allgather npoints_vis_glob' npoints_vis_tot = sum(npoints_vis_tmpa) ioffs_tmpa=0 do irank=1,nranks-1 ioffs_tmpa(irank) = ioffs_tmpa(irank-1)+npoints_vis_tmpa(irank-1) end do!irank ioffs_save = ioffs_tmpa !allocate result arrays allocate(kpoints_vis_all(3,npoints_vis_tot), eigw_vis_all(npoints_vis_tot), vis2int_all(npoints_vis_tot), STAT=ierr) if(ierr/=0) stop 'Problem allocating kpoints_vis_all etc.' !collect the k-points isendarr = 3*npoints_vis_tmpa ioffsarr = 3*ioffs_tmpa call MPI_Allgatherv( kpoints_vis, isendarr(myrank), MPI_DOUBLE_PRECISION,& & kpoints_vis_all, isendarr, ioffsarr, & & MPI_DOUBLE_PRECISION, MPI_COMM_WORLD, ierr ) if(ierr/=MPI_SUCCESS) stop 'Problem in allgatherv kpoints_vis_glob' !collect the eigenvalues isendarr = npoints_vis_tmpa ioffsarr = ioffs_tmpa call MPI_Allgatherv( eigw_vis, isendarr(myrank), MPI_DOUBLE_COMPLEX,& & eigw_vis_all, isendarr, ioffsarr, & & MPI_DOUBLE_COMPLEX, MPI_COMM_WORLD, ierr ) if(ierr/=MPI_SUCCESS) stop 'Problem in allgatherv eigv_vis_glob' !collect the translation array isendarr = npoints_vis_tmpa ioffsarr = ioffs_tmpa call MPI_Allgatherv( vis2int, isendarr(myrank), MPI_INTEGER, & & vis2int_all, isendarr, ioffsarr, & & MPI_INTEGER, MPI_COMM_WORLD, ierr ) if(ierr/=MPI_SUCCESS) stop 'Problem in allgatherv vis2int_glob' !adapt the offsets for the translation array --> done below (!!!!!) #else npoints_vis_tot = npoints_vis allocate(kpoints_vis_all(3,npoints_vis_tot), eigw_vis_all(npoints_vis_tot), vis2int_all(npoints_vis_tot), STAT=ierr) if(ierr/=0) stop 'Problem allocating kpoints_vis_all etc.' kpoints_vis_all = kpoints_vis(:,1:npoints_vis_tot) eigw_vis_all = eigw_vis(1:npoints_vis_tot) vis2int_all = vis2int(1:npoints_vis_tot) #endif deallocate( kpoints_vis, eigw_vis, STAT=ierr ) if(ierr/=0) stop 'Problem deallocating kpoints_vis etc.' if(myrank==master)then write(filename,fmt_fn_ext) 'fstest_eigw0', ext_formatted open(unit=3654,file=filename,form='formatted',action='write') write(3654,'(2ES25.16)') eigw_vis_all close(3654) end if!myrank==master !************************************! !*** output of visualization data ***! !************************************! !************** E N D ***************! !************************************! !*************************************! !************ B E G I N **************! !*************************************! !*** gathering of integration data ***! !*************************************! #ifdef CPP_MPI !collect the number of points call MPI_Allgather( kcounter_cub, 1, MPI_INTEGER, & & npoints_int_tmpa, 1, MPI_INTEGER, & & MPI_COMM_WORLD, ierr ) if(ierr/=MPI_SUCCESS) stop 'Problem in allgather npoints_int_tmpa' npoints_int_tot = sum(npoints_int_tmpa) ioffs_tmpa=0 do irank=1,nranks-1 ioffs_tmpa(irank) = ioffs_tmpa(irank-1)+npoints_int_tmpa(irank-1) end do!irank !allocate result arrays allocate(kpoints_int_all(3,npoints_int_tot), areas_int_all(npoints_int_tot), STAT=ierr) if(ierr/=0) stop 'Problem allocating kpoints_int_all etc.' !collect the k-points isendarr = 3*npoints_int_tmpa ioffsarr = 3*ioffs_tmpa call MPI_Allgatherv( kpoints_int, isendarr(myrank), MPI_DOUBLE_PRECISION,& & kpoints_int_all, isendarr, ioffsarr, & & MPI_DOUBLE_PRECISION, MPI_COMM_WORLD, ierr ) if(ierr/=MPI_SUCCESS) stop 'Problem in allgatherv kpoints_int_all' !collect the areas isendarr = npoints_int_tmpa ioffsarr = ioffs_tmpa call MPI_Allgatherv( areas_int, isendarr(myrank), MPI_DOUBLE_PRECISION,& & areas_int_all, isendarr, ioffsarr, & & MPI_DOUBLE_PRECISION, MPI_COMM_WORLD, ierr ) if(ierr/=MPI_SUCCESS) stop 'Problem in allgatherv kpoints_int_all' !adapt the offsets for the translation array --> from above (!!!!!) do irank=1,nranks-1 lb = ioffs_save(irank)+1 ub = ioffs_save(irank)+npoints_vis_tmpa(irank) vis2int_all(lb:ub) = vis2int_all(lb:ub) + ioffs_tmpa(irank) end do!irank #else npoints_int_tot = kcounter_cub allocate(kpoints_int_all(3,npoints_int_tot), areas_int_all(npoints_int_tot), STAT=ierr) if(ierr/=0) stop 'Problem allocating kpoints_int_all etc.' kpoints_int_all = kpoints_int(:,1:npoints_int_tot) areas_int_all = areas_int(1:npoints_int_tot) #endif #ifdef CPP_DEBUG close(iofile) #endif 190 FORMAT(' |'$) 200 FORMAT('|'$) end subroutine find_intesection_lines_memopt subroutine split_line(kline, eigw_line, kstore, eigw_store, kcounter, nfaces, nvec, dscal) use mod_symmetries, only: singlepoint_in_wedge implicit none integer, intent(in) :: nfaces double precision, intent(in) :: kline(3,2), nvec(3,nfaces), dscal(nfaces) double complex, intent(in) :: eigw_line(2) integer, intent(inout) :: kcounter double precision, intent(inout) :: kstore(3,nkpmax) double complex, intent(inout) :: eigw_store(nkpmax) integer :: ii, iface ! integer :: ntri, ii, iface, itri, cutcase, its(0:2), ikp(3), nLines, nLinesINP ! double precision :: dtmp, ktmp1(3,nkpmax), ktmp2(3,nkpmax), denom, rscal, ki0new(3,2) double complex :: etmp(2), enew, ediff double precision :: ktmp(3,2), kdiff(3), knew(3), rscal, dtmp logical :: linIBZ(3), lplane(2) double precision, parameter :: eps=1d-10 !test whether the points lie inside the IBZ do ii=1,2 linIBZ(ii) = singlepoint_in_wedge(nfaces, nvec, dscal, kline(:,ii)) end do!ii !^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ if(all(linIBZ))then ! DISTINGUISH THE DIFFERENT CASES ! !^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ !the line lies completely inside the IBZ --> just copy do ii=1,2 kstore(:,ii+kcounter) = kline(:,ii) eigw_store(ii+kcounter) = eigw_line(ii) end do kcounter = kcounter+2 !^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ elseif(any(linIBZ))then ! DISTINGUISG THE DIFFERENT CASES ! !^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ !the line lies partly in the IBZ --> cut it ktmp = kline etmp = eigw_line !===== BEGIN =====! ! loop over faces ! do iface=1,nfaces !check if points are inside or outside the plane lplane(:) = .true. do ii=1,2 dtmp = sum(nvec(:,iface)*ktmp(:,ii))-dscal(iface)+eps if(dtmp<0d0)then lplane(ii) = .false. end if!eps end do!ii !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++! if(all(lplane))then ! distinguish the different cases --- part 2 ! !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++! !-- do nothing !++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++! elseif(any(lplane))then ! distinguish the different cases --- part 2 ! !++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++! !find intersection point of line with BZ face kdiff = ktmp(:,2)-ktmp(:,1) rscal = (dscal(iface) - sum(ktmp(:,1)*nvec(:,iface)))/sum(kdiff*nvec(:,iface)) knew = ktmp(:,1) + rscal*kdiff !interpolate eigenvalue ediff = etmp(2)-etmp(1) enew = etmp(1) + rscal*ediff if(lplane(1))then ktmp(:,2) = knew etmp(2) = enew elseif(lplane(2))then ktmp(:,1) = knew etmp(1) = enew else stop 'this case should not happen in "split_line": case 1 ' end if !+++++++++++++++++++++++++++++++++++++++++++++++++! else ! distinguish the different cases --- part 2 ! !+++++++++++++++++++++++++++++++++++++++++++++++++! stop 'this case should not happen in "split_line": case 2' !++++++++++++++++++++++++++++++++++++++++++++++++++! end if! distinguish the different cases --- part 2 ! !++++++++++++++++++++++++++++++++++++++++++++++++++! end do!iface ! loop over faces ! !===== END =====! !copy here to big array do ii=1,2 kstore(:,ii+kcounter) = ktmp(:,ii) eigw_store(ii+kcounter) = etmp(ii) end do kcounter = kcounter+2 !^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ else ! DISTINGUISG THE DIFFERENT CASES ! !^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ !the line lies completely outside of the IBZ --> throw it away !^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ end if!DISTINGUISG THE DIFFERENT CASES ! !^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ end subroutine split_line subroutine mark_squares_in_IBZ(nCub3, nfaces, nvec, dscal, bounds, nmarked, imarked) use mod_parutils, only: distribute_linear_on_tasks use mod_mympi, only: myrank, nranks, master use mod_symmetries, only: points_in_wedge use mod_fermisurf_basic, only: generate_squarevertices #ifdef CPP_MPI use mpi #endif implicit none integer, intent(in) :: nCub3(3), nfaces double precision, intent(in) :: nvec(3,nfaces), dscal(nfaces), bounds(3,2) integer, intent(inout) :: nmarked integer, allocatable, intent(inout) :: imarked(:) integer :: nsqumarked_tmp, ioff, nkpt, ntot_pT(0:nranks-1), ioff_pT(0:nranks-1) integer :: nsqumarked_pT(0:nranks-1), iioff(0:nranks-1) double precision :: kverts(3,4) integer, allocatable :: isqumarked_tmp(:) integer :: irank, isqu, ierr logical :: squareinwedge !Parallelize call distribute_linear_on_tasks(nranks, myrank, master, nmarked, ntot_pT, ioff_pT, .false.) nkpt = ntot_pT(myrank) ioff = ioff_pT(myrank) !Create temp arrays allocate(isqumarked_tmp(nkpt), STAT=ierr) if(ierr/=0) stop 'Problem allocating isqumarked_tmp in mark_squares_in_IBZ' nsqumarked_tmp = 0 isqumarked_tmp = -1 !Test whether squares lie in wedge do isqu=1,nkpt call generate_squarevertices(nCub3,imarked(isqu+ioff), bounds, kverts) squareinwedge = points_in_wedge(nfaces, nvec, dscal, 4, kverts, 'any') if(squareinwedge)then nsqumarked_tmp = nsqumarked_tmp + 1 isqumarked_tmp(nsqumarked_tmp) = imarked(isqu+ioff) end if!squareinwedge end do!isqu deallocate(imarked) #ifdef CPP_MPI !Combine results call MPI_Allgather(nsqumarked_tmp, 1, MPI_INTEGER, nsqumarked_pT, 1, MPI_INTEGER, MPI_COMM_WORLD, ierr ) if(ierr/=MPI_SUCCESS) stop 'Problem in Allgather(nsqumarked_tmp) in mark_squares_in_IBZ' nmarked = sum(nsqumarked_pT) allocate(imarked(nmarked), STAT=ierr) if(ierr/=0) stop 'Problem allocating imarked in mark_squares_in_IBZ' iioff = 0 do irank=1,nranks-1 iioff(irank) = sum(nsqumarked_pT(0:irank-1)) end do call MPI_Allgatherv( isqumarked_tmp, nsqumarked_tmp, MPI_INTEGER, & & imarked, nsqumarked_pT, iioff, MPI_INTEGER, & & MPI_COMM_WORLD, ierr ) if(ierr/=MPI_SUCCESS) stop 'Problem in Allgatherv(isqumarked_tmp) in mark_squares_in_IBZ' #else nmarked=nsqumarked_tmp allocate(imarked(nmarked), STAT=ierr) if(ierr/=0) stop 'Problem allocating imarked in mark_squares_in_IBZ' imarked = isqumarked_tmp(1:nsqumarked_tmp) #endif end subroutine mark_squares_in_IBZ subroutine cut_and_update_squares(ncut, nCub3, nmarked, imarked) use mod_fermisurf_basic, only: unroll_ixyz use mod_mympi, only: myrank, master implicit none integer, intent(in) :: ncut integer, intent(inout) :: nCub3(3) integer, intent(inout) :: nmarked integer, allocatable, intent(inout) :: imarked(:) integer :: nCub3in(3), nmarked_tmp, imarked_tmp(nmarked) integer :: ii3(3), ix, iy, iz, icub, icount, ierr !save input to temporary arrays nCub3in = nCub3 nmarked_tmp = nmarked imarked_tmp = imarked deallocate(imarked) !determine size of output-array nmarked = nmarked_tmp * ncut**2 allocate( imarked(nmarked), STAT=ierr ) if(ierr/=0) stop 'Problem allocating imarked in "cut_and_update_squares"' nCub3 = nCub3in*ncut nCub3(3) = 1 icount = 0 do icub=1,nmarked_tmp call unroll_ixyz(imarked_tmp(icub), nCub3in, ii3) ! do iz=0,ncut-1 do iy=0,ncut-1 do ix=0,ncut-1 icount = icount+1 imarked(icount) = (ii3(1)*ncut+ix+1) + (ii3(2)*ncut+iy)*nCub3(1) end do!ix end do!iy ! end do!iz end do!icub if(icount/=nmarked .and. myrank==master) write(*,*) 'WARNING!! icount =/= nmarked in cut_and_update_squares' end subroutine cut_and_update_squares subroutine read_squaresrefine(nCub3, nmarked, imarked) use mod_mympi, only: myrank, nranks, master use mod_ioformat, only: filename_cubesrefine, ext_formatted, fmt_fn_ext use mod_iohelp, only: get_nLines use mod_mathtools, only: bubblesort_int #ifdef CPP_MPI use mpi #endif implicit none integer, intent(out) :: nCub3(3), nmarked integer, allocatable, intent(out) :: imarked(:) integer :: ierr, ii, ipointer, iline, istart, istop, nlines, ncubsplit, nCub3in(3), icubtmp, nrefine, nmarkedtmp integer, allocatable :: imarkedtmp(:), srtidx(:), imarked2(:), imarked3(:) character(len=256) :: filename integer, parameter :: iounit=15369 if(myrank==master)then write(filename,fmt_fn_ext) filename_cubesrefine, ext_formatted open(unit=iounit, file=filename, form='formatted', action='read') ncubsplit = 0 nlines = get_nLines( iounit ) !check the input data and get total number of split cubes rewind(iounit) do iline = 1,nlines read(iounit,*) nCub3in, nrefine, icubtmp ! write(*,'(5I8)') nCub3in, nrefine, icubtmp if(iline==1) nCub3 = nCub3in*nrefine if(any(nCub3in*nrefine/=nCub3)) stop 'nCub3 not consistent in refine' ncubsplit = ncubsplit + nrefine**2 end do!iline nCub3(3) = 1!set 3rd component to 1 for 2D-mode allocate(imarked2(ncubsplit), imarked3(ncubsplit), STAT=ierr) if(ierr/=0) stop 'Problem allocating imarked in readin on master' rewind(iounit) istart=1 istop =0 do iline = 1,nlines allocate(imarkedtmp(1)) nmarkedtmp = 1 read(iounit,'(5I8)') nCub3in, nrefine, imarkedtmp call cut_and_update_squares(nrefine, nCub3in, nmarkedtmp, imarkedtmp) if(nmarkedtmp/=nrefine**3)then write(*,'(A,I0,A,I0)') 'Something went wrong. nmarkedtmp= ', nmarkedtmp, ', nrefine=', nrefine stop 'Error in read_squaresrefine' end if istop =istart-1+nrefine**2 imarked2(istart:istop) = imarkedtmp deallocate(imarkedtmp) istart=istop+1 end do!iline nmarkedtmp = istart-1 close(iounit) if(nmarkedtmp/=ncubsplit) then write(*,'(A,I0,A,I0)') 'Something went wrong. nmarkedtmp= ', nmarkedtmp, ', ncubsplit=', ncubsplit stop 'Error in read_squaresrefine' end if ! write(111,'(A,I0)') 'ncubsplit=', ncubsplit ! write(111,"(10I8)") imarked2(1:ncubsplit) !sort the index and filter out double indices allocate(srtidx(ncubsplit), STAT=ierr) if(ierr/=0) stop 'Problem allocating srtidx in readin on master' call bubblesort_int(nmarkedtmp, imarked2, srtidx) ! write(111,*) 'sorted:' ! write(111,'(I8)') imarked2(srtidx) imarked3 = -1 imarked3(1) = imarked2(srtidx(1)) ipointer = 1 do iline=2,nmarkedtmp if(imarked2(srtidx(iline))>imarked3(ipointer))then imarked3(ipointer+1) = imarked2(srtidx(iline)) ipointer = ipointer+1 end if end do nmarked = ipointer allocate(imarked(nmarked), STAT=ierr) imarked = imarked3(1:nmarked) ! write(111,'(A,I0)') 'nmarked=', nmarked ! write(111,"(10I8)") imarked ! write(666,'(I8)') nmarked, imarked end if!myrank==master #ifdef CPP_MPI call MPI_Bcast(nCub3, 3, MPI_INTEGER, master, MPI_COMM_WORLD, ierr) if(ierr/=MPI_SUCCESS) stop 'Problem in Bcast(nCub3)' call MPI_Bcast(nmarked, 1, MPI_INTEGER, master, MPI_COMM_WORLD, ierr) if(ierr/=MPI_SUCCESS) stop 'Problem in Bcast(nmarked)' if(myrank/=master)then allocate(imarked(nmarked), STAT=ierr) if(ierr/=0) stop 'Problem allocating imarked in readin on slaves' end if!myrank/=master call MPI_Bcast(imarked, nmarked, MPI_INTEGER, master, MPI_COMM_WORLD, ierr) if(ierr/=MPI_SUCCESS) stop 'Problem in Bcast(imarked)' #endif ! write(*,'("myrank=",I0," imarked=",10I8)') myrank, imarked ! write(2000+myrank,'(I8)') nmarked ! write(2000+myrank,'(10I8)') imarked end subroutine read_squaresrefine subroutine squares2TXT(filename,nCub3,nmarked,imarked,bounds) use mod_fermisurf_basic, only: generate_squarevertices implicit none character(len=*), intent(in) :: filename integer, intent(in) :: nCub3(3), nmarked, imarked(nmarked) double precision, intent(in) :: bounds(3,2) double precision :: kverts(3,4) integer :: isqu, ivert character(len=80) :: fmtstr open(unit=123895, file=trim(filename), action='write', form='formatted') !write header write(123895,'(A)') '# four lines define one square' !write points do isqu=1,nmarked call generate_squarevertices(nCub3,imarked(isqu),bounds,kverts) do ivert=1,4 write(123895,'(3ES25.16)') kverts(:,ivert) end do!ivert end do!icub close(123895) end subroutine squares2TXT subroutine init_square2triangles() ! The triangles, lines and corners are labeled as follows ! ( numbers denote corners, [x] denote lines and (x) denote triangles): ! ! 3____[3]____4 ! | /| ! | (2) / | ! [4]| / |[2] ! | / (1) | ! |___________| ! 1 [1] 2 ! A square is cut into 2 triangles tridiags = reshape( (/ 1, 4, 2, 3 /), (/ 2, 2 /)) !define the endpoints of the edges of the tetraeda. cubedge(1,j) = k means: !the startpoint of the j-th edge is the k-th corner-point of the cube squedges(:,1) = (/ 1, 2 /) ! squedges(:,2) = (/ 2, 4 /) ! squedges(:,3) = (/ 3, 4 /) ! squedges(:,4) = (/ 1, 3 /) ! squedges(:,5) = (/ 1, 4 /) ! tricorners(:,1) = (/ 1, 2, 4 /) tricorners(:,2) = (/ 1, 3, 4 /) triedges(:,1) = (/ 1, 2, 5 /) triedges(:,2) = (/ 3, 4, 5 /) end subroutine init_square2triangles ! end module mod_fermisurf_2D