File: example_sparse_grids_02.f90

package info (click to toggle)
tasmanian 8.2-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 4,852 kB
  • sloc: cpp: 34,523; python: 7,039; f90: 5,080; makefile: 224; sh: 64; ansic: 8
file content (75 lines) | stat: -rw-r--r-- 2,807 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75

subroutine example_sparse_grid_02()
    use Tasmanian
    use, intrinsic :: iso_c_binding
    implicit none
    type(TasmanianSparseGrid) :: grid
    integer :: dimension = 2, exactness = 20
    integer :: i, num_points
    ! using the static array API requires only allocatable variables
    ! but the allocation has to be made before the call
    real(C_DOUBLE), dimension(:), allocatable :: weights
    real(C_DOUBLE), dimension(:,:), allocatable :: points
    ! pointer variables can be returned through the functional API
    ! allowing for more expressive calls
    real(C_DOUBLE), dimension(:), pointer :: pweights
    real(C_DOUBLE), dimension(:,:), pointer :: ppoints
    real(C_DOUBLE), dimension(2) :: lower, upper
    double precision :: exact = 1.861816427518323D+00;
    double precision :: integral, err

    write(*,*) "-------------------------------------------------------------------------------------------------"
    write(*,*) "Example 2: integrate f(x,y) = exp(-x^2) * cos(y) over [-5,5] x [-2,3]"
    write(*,*) "           using  Gauss-Patterson nodes and total degree polynomial space"

    grid = TasmanianGlobalGrid(dimension, 0, exactness, tsg_type_qptotal, tsg_rule_gausspatterson)
    num_points = grid%getNumPoints()

    lower = [ -5.0D-0, -2.0D-0 ]
    upper = [  5.0D-0,  3.0D-0 ]
    call grid%setDomainTransform(lower, upper)

    allocate(weights(num_points))
    call grid%getQuadratureWeights(weights)
    allocate(points(dimension, num_points))
    call grid%getPoints(points(:,1))

    integral = 0.0D-0
    do i = 1, num_points
        integral = integral + weights(i) * exp( -points(1,i)**2 ) * cos( points(2,i) )
    enddo
    err = abs(integral - exact)

    write(*,*) "     at polynomial exactness: ", exactness
    write(*,*) "     the grid has:            ", num_points
    write(*,*) "     integral: ", integral
    write(*,*) "     error:    ", err
    write(*,*)
    deallocate(weights, points)
    call grid%release()

    exactness = 40
    grid = TasmanianGlobalGrid(dimension, 0, exactness, tsg_type_qptotal, tsg_rule_gausspatterson)
    num_points = grid%getNumPoints()

    call grid%setDomainTransform(lower, upper)

    ! using the functional API, saves the need to manually allocate the sizes
    pweights => tsgGetQuadratureWeights(grid)
    ppoints => tsgGetPoints(grid)

    integral = 0.0D-0
    do i = 1, num_points
        integral = integral + pweights(i) * exp( -ppoints(1,i)**2 ) * cos( ppoints(2,i) )
    enddo
    err = abs(integral - exact)

    write(*,*) "     at polynomial exactness: ", exactness
    write(*,*) "     the grid has:            ", num_points
    write(*,*) "     integral: ", integral
    write(*,*) "     error:    ", err
    write(*,*)

    deallocate(pweights, ppoints)
    call grid%release()
end subroutine