2014 dxdy logo

Научный форум dxdy

Математика, Физика, Computer Science, Machine Learning, LaTeX, Механика и Техника, Химия,
Биология и Медицина, Экономика и Финансовая Математика, Гуманитарные науки




Начать новую тему Ответить на тему
 
 fortran 90 trilinear interpolation
Сообщение06.04.2011, 18:41 


08/03/11
186
Привет,

написал 3D линейную интерполяцию для функции вида $f=f(x,y,z)$, которая задана таблично $x, y, z, f$.
Про сам метод есть, например, здесь paulbourke.net/miscellaneous/interpolation/index.html.
Вроде все работает для разного числа точек и для разного шага по направлениям.
Но мне нужно сделать быстрее код, так как эта функция используется очень часто.
Мне интересно на сколько "долгие" стейтменты типа,

xmin = minval(array(1,:))

Может мне лучше отказаться от них вообще и задавать их руками там же где и nx, ny, nz?


код: [ скачать ] [ спрятать ]
Используется синтаксис Fortran
 
! common data
module array_mod
        real, dimension(:,:), allocatable :: array
        ! number of greed points
        integer :: nx = 5
        integer :: ny = 10
        integer :: nz = 15
end module array_mod

! interface for data manipulation      
module field_in_mod
        interface field_in_inter
                subroutine field_in(i,field)
                        use dynamic
                        implicit none
                        integer :: i, k
                        character(7) :: field
                end subroutine field_in
        end interface field_in_inter
end module field_in_mod

! interpolation function interface
module trilinear_mod
        interface trilinear_int
                function trilinear(x,y,z)
                        use array_mod                  
                        implicit none
                        real :: x,y,z,dx,dy,dz,xmin,xmax,ymin,ymax,zmin,zmax
                        real :: trilinear
                        integer :: a,b,c,d
                end function trilinear
        end interface trilinear_int
end module trilinear_mod

! test program
program test
        ! use modules
        use array_mod
        use field_in_mod
        use trilinear_mod
        implicit none
        integer :: i = 4  ! number of rows
        integer :: j      ! number of lines
        character(7) :: in = "in01.in" ! file name
        integer :: a,b,c
        real, dimension(3) :: coord=(/3.1*0.15, 8.2*0.13, 7.4*0.17/)
       
        j = nx*ny*nz

        ! create input file
        open(unit=12, file=in, form='formatted')       
        do a=1,5,1
                do b=1,10,1
                        do c=1,15,1
                                write(12,fmt=*) a*0.15, b*0.13, c*0.17, 5.0
                        end do
                end do
        end do
        close(12)
       
        allocate(array(i,j))
        ! create i x j array
        call field_in(j,in)
        ! 3d interpolation
        write(*,*) trilinear(coord(1), coord(2), coord(3))
        deallocate(array)
       
end program test

function trilinear(x,y,z)
        use array_mod  
        implicit none
        ! paulbourke.net/miscellaneous/interpolation/index.html
        real :: x,y,z,dx,dy,dz,xmin,xmax,ymin,ymax,zmin,zmax
        real :: trilinear
        integer :: a,b,c,d
       
        xmin = minval(array(1,:))      
        xmax = maxval(array(1,:))      
        ymin = minval(array(2,:))      
        ymax = maxval(array(2,:))      
        zmin = minval(array(3,:))      
        zmax = maxval(array(3,:))      

        dx = (xmax-xmin)/(nx-1)
        dy = (ymax-ymin)/(ny-1)
        dz = (zmax-zmin)/(nz-1)
       
        a = int((x-xmin)/dx)  ! (a)-time x value has changed
        b = int((y-ymin)/dy)  ! (b)-time y value has changed
        c = int((z-zmin)/dz)  ! (c)-time z value has changed

        d = ny*nz*a + nz*b + c + 1 ! current file position     

        x = x-(a+1)*dx
        y = y-(b+1)*dy
        z = z-(c+1)*dz
       
        !V000|V100|V010|V001|V101|V011|V110|V111

        trilinear   =   1.0/(dx*dy*dz)*(array(4,d)*(dx-x)*(dy-y)*(dz-z) + &
                        array(4,d+ny*nz)*x*(dy-y)*(dz-z) + &
                        array(4,d+nz)*(dx-x)*y*(dz-z) + &
                        array(4,d+1)*(dx-x)*(dy-y)*z + &
                        array(4,d+nz*ny+1)*x*(dy-y)*z + &
                        array(4,d+nz+1)*(dx-x)*y*z + &
                        array(4,d+ny*nz+nz)*x*y*(dz-z) + &
                        array(4,d+ny*nz+nz+1)*x*y*z)   

end function trilinear

subroutine field_in(i, field)
        use array_mod
        implicit none
        integer :: i, k
        character(7) :: field
        open(unit=10, file=field, form='formatted')
        ! suggestion => do do, field_in(i,j,field) in new version
        do k=1,i,1
                read(10,*)      array(1,k), & ! x
                                array(2,k), & ! y
                                array(3,k), & ! z
                                array(4,k)
                               
        end do
        close(10)
end subroutine field_in
 

 Профиль  
                  
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ 1 сообщение ] 

Модераторы: Karan, Toucan, PAV, maxal, Супермодераторы



Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group