Skip to content

Commit e816fd3

Browse files
Add tests
1 parent f751f70 commit e816fd3

File tree

2 files changed

+136
-0
lines changed

2 files changed

+136
-0
lines changed

tests/nonlin_test.f90

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@ program main
1818
rst = test_jacobian_1()
1919
if (.not.rst) overall = .false.
2020

21+
rst = test_jacobian_2()
22+
if (.not.rst) overall = .false.
23+
2124
rst = test_quasinewton_1()
2225
if (.not.rst) overall = .false.
2326

tests/nonlin_test_jacobian.f90

Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ module nonlin_test_jacobian
88
implicit none
99
private
1010
public :: test_jacobian_1
11+
public :: test_jacobian_2
1112

1213
contains
1314
! ******************************************************************************
@@ -44,6 +45,46 @@ subroutine jac1(x, jac, args)
4445
[2, 2])
4546
end subroutine
4647

48+
! ------------------------------------------------------------------------------
49+
! FUNCTIONS:
50+
! x = Y * r * cos(theta)
51+
! y = Y * r * sin(theta)
52+
subroutine fcn2(x, f, args)
53+
real(real64), intent(in), dimension(:) :: x
54+
real(real64), intent(out), dimension(:) :: f
55+
class(*), intent(inout), optional :: args
56+
real(real64) :: r, theta, y
57+
r = x(1)
58+
theta = x(2)
59+
select type (args)
60+
type is (real(real64))
61+
y = args
62+
end select
63+
f(1) = y * r * cos(theta)
64+
f(2) = y * r * sin(theta)
65+
end subroutine
66+
67+
! JACOBIAN:
68+
! |Y * cos -Y * r * sin|
69+
! J = | |
70+
! |Y * sin Y * r * cos|
71+
subroutine jac2(x, jac, args)
72+
real(real64), intent(in), dimension(:) :: x
73+
real(real64), intent(out), dimension(:,:) :: jac
74+
class(*), intent(inout), optional :: args
75+
real(real64) :: r, theta, y
76+
r = x(1)
77+
theta = x(2)
78+
select type (args)
79+
type is (real(real64))
80+
y = args
81+
end select
82+
jac = reshape(&
83+
[y * cos(theta), y * sin(theta), &
84+
-y * r * sin(theta), y * r * cos(theta)], &
85+
[2, 2])
86+
end subroutine
87+
4788
! ------------------------------------------------------------------------------
4889
function test_jacobian_1() result(rst)
4990
! Local Variables
@@ -135,5 +176,97 @@ function test_jacobian_1() result(rst)
135176
100 format(A)
136177
end function
137178

179+
! ------------------------------------------------------------------------------
180+
function test_jacobian_2() result(rst)
181+
! Local Variables
182+
type(vecfcn_helper) :: obj
183+
procedure(vecfcn), pointer :: fcn
184+
procedure(jacobianfcn), pointer :: jac
185+
real(real64) :: numjac(2, 2), exact(2, 2), x(2), y
186+
logical :: rst
187+
integer(int32) :: i
188+
189+
! Parameters
190+
real(real64), parameter :: tol = 1.0d-4
191+
192+
! Initialization
193+
rst = .true.
194+
fcn => fcn2
195+
jac => jac2
196+
call obj%set_fcn(fcn, 2, 2)
197+
call random_number(y)
198+
199+
! Test point 1 (0, 0)
200+
x = 0.0d0
201+
call obj%jacobian(x, numjac, args = y)
202+
call jac(x, exact, args = y)
203+
if (.not.assert(numjac, exact, tol)) then
204+
rst = .false.
205+
print 100, "Test Failed: Jacobian Test 2A"
206+
print 100, "Expected:"
207+
do i = 1, size(exact, 1)
208+
print *, exact(i,:)
209+
end do
210+
print 100, "Found:"
211+
do i = 1, size(exact, 1)
212+
print *, numjac(i,:)
213+
end do
214+
end if
215+
216+
! Test point 2 (1, 0)
217+
x = [1.0d0, 0.0d0]
218+
call obj%jacobian(x, numjac, args = y)
219+
call jac(x, exact, args = y)
220+
if (.not.assert(numjac, exact, tol)) then
221+
rst = .false.
222+
print 100, "Test Failed: Jacobian Test 2B"
223+
print 100, "Expected:"
224+
do i = 1, size(exact, 1)
225+
print *, exact(i,:)
226+
end do
227+
print 100, "Found:"
228+
do i = 1, size(exact, 1)
229+
print *, numjac(i,:)
230+
end do
231+
end if
232+
233+
! Test point 3 (0, 1)
234+
x = [0.0d0, 1.0d0]
235+
call obj%jacobian(x, numjac, args = y)
236+
call jac(x, exact, args = y)
237+
if (.not.assert(numjac, exact, tol)) then
238+
rst = .false.
239+
print 100, "Test Failed: Jacobian Test 2C"
240+
print 100, "Expected:"
241+
do i = 1, size(exact, 1)
242+
print *, exact(i,:)
243+
end do
244+
print 100, "Found:"
245+
do i = 1, size(exact, 1)
246+
print *, numjac(i,:)
247+
end do
248+
end if
249+
250+
! Test point 4 (0.5, -0.5)
251+
x = [0.5d0, -0.5d0]
252+
call obj%jacobian(x, numjac, args = y)
253+
call jac(x, exact, args = y)
254+
if (.not.assert(numjac, exact, tol)) then
255+
rst = .false.
256+
print 100, "Test Failed: Jacobian Test 2D"
257+
print 100, "Expected:"
258+
do i = 1, size(exact, 1)
259+
print *, exact(i,:)
260+
end do
261+
print 100, "Found:"
262+
do i = 1, size(exact, 1)
263+
print *, numjac(i,:)
264+
end do
265+
end if
266+
267+
! Formatting
268+
100 format(A)
269+
end function
270+
138271
! ------------------------------------------------------------------------------
139272
end module

0 commit comments

Comments
 (0)