量子力学与科学计算应用(Quantum Mechanics
直播中

ygpotsyyz

6年用户 322经验值
擅长:可编程逻辑
私信 关注
[讨论]

易辛二维度模拟正负电荷的2D阵列进化

!***********************************************
!***********************************************
! 易辛二维度模拟正负电荷的2D阵列进化
! 每个很会“翻转”与邻居一致
!***********************************************
! SINOMACH
!
! 易辛二维度模拟正负电荷的2D阵列进化
! 每个很会“翻转”与邻居一致
!
! 周勇,PotsyYZ,GoldbergJr.,JohnBktJr.
!
! Sept.2022
!***********************************************
Program main

!*********************************************************************72
!
!c MAIN is the main program for ISING_2D_SIMULATION.
!
! Usage:
!
! ising_2d_simulation m n iterations thresh seed
!
! * M, N, the number of rows and columns.
! * ITERATIONS, the number of iterations.
! * THRESH, the threshhold.
! * SEED, a seed for the random number generator.
!
Implicit None

Integer i
Integer iterations
Integer m
Integer n
Double Precision prob(5)
Integer seed
Integer step
Double Precision thresh

Save prob

Data prob/0.97D+00, 0.86D+00, 0.51D+00, 0.16D+00, 0.03D+00/

Call timestamp()
Write (, '(a)') ' '
Write (
, '(a)') 'ISING_2D_SIMULATION'
Write (, '(a)') ' FORTRAN95,2013&18 version'
Write (
, '(a)') ' Monte Carlo simulation of a 2D Ising model.'
!
! Get input from commandline or user.
!
Call get_input(m, n, iterations, thresh, seed)

Write (, '(a)') ' '
Write (
, '(a,i8)') ' The number of rows is M = ', m
Write (, '(a,i8)') ' The number of columns is N = ', n
Write (
, '(a,i8)') ' The number of iterations taken is ITERATIONS = ', iterations
Write (, '(a,g14.6)') ' The threshhold THRESH = ', thresh
Write (
, '(a,i12)') ' The seed SEED = ', seed
Write (, '(a)') ' '
Write (
, '(a)') ' The transition probability table, d on the number of'
Write (, '(a)') ' neighbors with the same spin.'
Write (
, '(a)') ' '
Write (, '(a)') ' 1 2 3 4 5'
Write (
, '(a)') ' '
Write (, '(7f10.4)')(prob(i), i=1, 5)
!
! Do the simulation.
! I have to do this in a subroutine, so that I can dimension C1 on the fly.
!
Call handle(m, n, iterations, prob, thresh, seed)
!
! Terminate.
!
Write (
, '(a)') ' '
Write (, '(a)') 'ISING_2D_SIMULATION'
Write (
, '(a)') ' Normal end of execution.'

Write (*, '(a)') ' '
Call timestamp()

Stop
End Program main
Subroutine ch_cap(ch)

!*********************************************************************72
!
!c CH_CAP capitalizes a single character.
!
! Parameters:
!
! Input/output, character CH, the character to capitalize.
!
Implicit None

Character ch
Integer itemp

itemp = ichar(ch)

If (97<=itemp .And. itemp<=122) Then
ch = char(itemp-32)
End If

Return
End Subroutine ch_cap
Function ch_eqi(c1, c2)

!*********************************************************************72
!
!c CH_EQI is a case insensitive comparison of two characters for equality.
!
! Example:
!
! CH_EQI ( 'A', 'a' ) is TRUE.
!
! Parameters:
!
! Input, character C1, C2, the characters to compare.
!
! Output, logical CH_EQI, the result of the comparison.
!
Implicit None

Character c1
Character c1_cap
Character c2
Character c2_cap
Logical ch_eqi

c1_cap = c1
c2_cap = c2

Call ch_cap(c1_cap)
Call ch_cap(c2_cap)

If (c1_cap==c2_cap) Then
ch_eqi = .True.
Else
ch_eqi = .False.
End If

Return
End Function ch_eqi
Subroutine ch_to_digit(c, digit)

!*********************************************************************72
!
!c CH_TO_DIGIT returns the integer value of a 10 digit.
!
! Example:
!
! C DIGIT
! --- -----
! '0' 0
! '1' 1
! ... ...
! '9' 9
! ' ' 0
! 'X' -1
!
! Parameters:
!
! Input, character C, the decimal digit, '0' through '9' or blank
! are legal.
!
! Output, integer DIGIT, the corresponding integer value. If C was
! 'illegal', then DIGIT is -1.
!
Implicit None

Character c
Integer digit

If (lge(c,'0') .And. lle(c,'9')) Then

digit = ichar(c) - 48

Else If (c==' ') Then

digit = 0

Else

digit = -1

End If

Return
End Subroutine ch_to_digit
Subroutine get_input(m, n, iterations, thresh, seed)

!*********************************************************************72
!
!c GET_INPUT gets input parameters.
!
! Parameters:
!
! Output, integer M, N, the number of rows and columns.
!
! Output, integer ITERATIONS, the number of iterations.
!
! Output, double precision THRESH, the threshhold.
!
! Output, integer SEED, a seed for the random
! number generator.
!
Implicit None

Integer arg_num
Integer iarg
Integer iargc
Integer ierror
Integer iterations
Integer last
Integer m
Integer n
Integer seed
Character *(80) string
Double Precision thresh

arg_num = iargc()

If (1<=arg_num) Then
iarg = 1
Call getarg(iarg, string)
Call s_to_i4(string, m, ierror, last)
Else If (.True.) Then
m = 15
Else
Write (, '(a)') ' '
Write (
, '(a)') ' Enter M, the number of rows:'
Read (*, *) m
End If

If (2<=arg_num) Then
iarg = 2
Call getarg(iarg, string)
Call s_to_i4(string, n, ierror, last)
Else If (.True.) Then
n = 20
Else
Write (, '(a)') ' '
Write (
, '(a)') ' Enter N, the number of columns:'
Read (*, *) n
End If

If (3<=arg_num) Then
iarg = 3
Call getarg(iarg, string)
Call s_to_i4(string, iterations, ierror, last)
Else If (.True.) Then
iterations = 35
Else
Write (, '(a)') ' '
Write (
, '(a)') ' Enter the number of iterations to take.'
Read (*, *) iterations
End If

If (4<=arg_num) Then
iarg = 4
Call getarg(iarg, string)
Call s_to_r8(string, thresh, ierror, last)
Else If (.True.) Then
thresh = 0.50D+00
Else
Write (, '(a)') ' '
Write (
, '(a)') ' Enter the threshhold.'
Read (*, *) thresh
End If

If (5<=arg_num) Then
iarg = 5
Call getarg(iarg, string)
Call s_to_i4(string, seed, ierror, last)
Else If (.True.) Then
seed = 123456789
Else
Write (, '(a)') ' '
Write (
, '(a)') ' Enter the random number seed.'
Read (*, *) seed
End If

Return
End Subroutine get_input
Subroutine get_unit(iunit)

!*********************************************************************72
!
!c GET_UNIT returns a free FORTRAN unit number.
!
! Discussion:
!
! A "free" FORTRAN unit number is a value between 1 and 99 which
! is not currently associated with an I/O device. A free FORTRAN unit
! number is needed in order to open a file with the OPEN command.
!
! If IUNIT = 0, then no free FORTRAN unit could be found, although
! all 99 units were checked (except for units 5, 6 and 9, which
! are commonly reserved for console I/O).
!
! Otherwise, IUNIT is a value between 1 and 99, representing a
! free FORTRAN unit. Note that GET_UNIT assumes that units 5 and 6
! are special, and will never return those values.
!
! Parameters:
!
! Output, integer IUNIT, the free unit number.
!
Implicit None

Integer i
Integer iunit
Logical value

iunit = 0

Do i = 1, 99

If (i/=5 .And. i/=6 .And. i/=9) Then

  Inquire (Unit=i, Opened=value, Err=10)

  If (.Not. value) Then
    iunit = i
    Return
  End If

End If

10 Continue

End Do

Return
End Subroutine get_unit
Subroutine handle(m, n, iterations, prob, thresh, seed)

!*********************************************************************72
!
!c HANDLE does initialization, computation and output.
!
! Discussion:
!
! The main program picks up the dimensions M and N, so we have to
! call this subroutine so we can essentially allocate C1 on the fly.
!
! Parameters:
!
! Input, integer M, N, the number of rows and columns.
!
! Input, integer ITERATIONS, the number of iterations.
!
! Input, double precision PROB(1:5). PROB(I) represents the probability
! that the spin of a given cell will be reversed, given that it has I
! immediate neighbors (including itself) with spin the same as its own.
!
! Input, double precision THRESH, the threshhold.
!
! Input/output, integer SEED, a seed for the random number
! generator.
!
Implicit None

Integer m
Integer n

Integer c1(m, n)
Integer iterations
Double Precision prob(1:5)
Integer seed
Double Precision thresh
!
! Initialize the system.
!
Call ising_2d_initialize(m, n, thresh, seed, c1)
!
! Write the initial state to a gnuplot file.
!
Call plot_file(m, n, c1, 'Initial Configuration', 'ising_2d_initial.txt', &
'ising_2d_initial.png')
!
! Do the simulation.
!
Call transition(m, n, iterations, prob, seed, c1)
!
! Write the final state to a gnuplot file.
!
Call plot_file(m, n, c1, 'Final Configuration', 'ising_2d_final.txt',&
'ising_2d_final.png')

Return
End Subroutine handle
Function i4_modp(i, j)

!*********************************************************************72
!
!c I4_MODP returns the nonnegative remainder of integer division.
!
! Discussion:
!
! If
! NREM = I4_MODP ( I, J )
! NMULT = ( I - NREM ) / J
! then
! I = J * NMULT + NREM
! where NREM is always nonnegative.
!
! The MOD function computes a result with the same sign as the
! quantity being divided. Thus, suppose you had an angle A,
! and you wanted to ensure that it was between 0 and 360.
! Then mod(A,360) would do, if A was positive, but if A
! was negative, your result would be between -360 and 0.
!
! On the other hand, I4_MODP(A,360) is between 0 and 360, always.
!
! Example:
!
! I J MOD I4_MODP Factorization
!
! 107 50 7 7 107 = 2 * 50 + 7
! 107 -50 7 7 107 = -2 * -50 + 7
! -107 50 -7 43 -107 = -3 * 50 + 43
! -107 -50 -7 43 -107 = 3 * -50 + 43
!
! Parameters:
!
! Input, integer I, the number to be divided.
!
! Input, integer J, the number that divides I.
!
! Output, integer I4_MODP, the nonnegative remainder when I is
! divided by J.
!
Implicit None

Integer i
Integer i4_modp
Integer j
Integer value

If (j==0) Then
Write (, '(a)') ' '
Write (
, '(a)') 'I4_MODP - Fatal error!'
Write (*, '(a,i8)') ' Illegal divisor J = ', j
Stop
End If

value = mod(i, j)

If (value<0) Then
value = value + abs(j)
End If

i4_modp = value

Return
End Function i4_modp
Function i4_wrap(ival, ilo, ihi)

!*********************************************************************72
!
!c I4_WRAP forces an I4 to lie between given limits by wrapping.
!
! Example:
!
! ILO = 4, IHI = 8
!
! I Value
!
! -2 8
! -1 4
! 0 5
! 1 6
! 2 7
! 3 8
! 4 4
! 5 5
! 6 6
! 7 7
! 8 8
! 9 4
! 10 5
! 11 6
! 12 7
! 13 8
! 14 4
!
! Parameters:
!
! Input, integer IVAL, an integer value.
!
! Input, integer ILO, IHI, the desired bounds for the integer value.
!
! Output, integer I4_WRAP, a "wrapped" version of IVAL.
!
Implicit None

Integer i4_modp
Integer i4_wrap
Integer ihi
Integer ilo
Integer ival
Integer jhi
Integer jlo
Integer value
Integer wide

jlo = min(ilo, ihi)
jhi = max(ilo, ihi)

wide = jhi - jlo + 1

If (wide==1) Then
value = jlo
Else
value = jlo + i4_modp(ival-jlo, wide)
End If

i4_wrap = value

Return
End Function i4_wrap
Subroutine ising_2d_agree(m, n, c1, c5)

!*********************************************************************72
!
!c ISING_2D_AGREE returns the number of neighbors agreeing with each cell.
!
! Discussion:
!
! The count includes the cell itself, so it is between 1 and 5.
!
! Parameters:
!
! Input, integer M, N, the number of cells in each
! spatial dimension.
!
! Input, integer C1(M,N), an array of 1's and -1's.
!
! Output, integer C5(M,N), the number of neighbors
! that agree. 1, 2, 3, 4, or 5.
!
Implicit None

Integer m
Integer n

Integer c1(m, n)
Integer c5(m, n)
Integer i
Integer i4_wrap
Integer im
Integer ip
Integer j
Integer jm
Integer jp

Do j = 1, n
jp = i4_wrap(j+1, 1, n)
jm = i4_wrap(j-1, 1, n)
Do i = 1, m
ip = i4_wrap(i+1, 1, m)
im = i4_wrap(i-1, 1, m)
c5(i, j) = c1(i, j) + c1(ip, j) + c1(im, j) + c1(i, jm) + c1(i, jp)
End Do
End Do

Do j = 1, n
Do i = 1, m
If (0<c1(i,j)) Then
c5(i, j) = (5+c5(i,j))/2
Else
c5(i, j) = (5-c5(i,j))/2
End If
End Do
End Do

Return
End Subroutine ising_2d_agree
Subroutine ising_2d_initialize(m, n, thresh, seed, c1)

!*********************************************************************72
!
!c ISING_2D_INITIALIZE initializes the Ising array.
!
! Parameters:
!
! Input, integer M, N, the number of rows and columns.
!
! Input, double precision THRESH, the threshhold.
!
! Input/output, integer SEED, a seed for the random
! number generator.
!
! Output, integer C1(M,N), the initial Ising array.
!
Implicit None

Integer m
Integer n

Integer c1(m, n)
Integer i
Integer j
Double Precision r(m, n)
Double Precision thresh
Integer seed

Call r8mat_uniform_01(m, n, seed, r)

Do j = 1, n
Do i = 1, m
If (r(i,j)<=thresh) Then
c1(i, j) = -1
Else
c1(i, j) = +1
End If
End Do
End Do

Return
End Subroutine ising_2d_initialize
Subroutine ising_2d_stats(step, m, n, c1)

!*********************************************************************72
!
!c ISING_2D_STATS prints information about the current step.
!
! Parameters:
!
! Input, integer STEP, the step number.
!
! Input, integer M, N, the number of rows and columns.
!
! Input, integer C1(M,N), the current state of the system.
!
Implicit None

Integer m
Integer n

Integer c1(m, n)
Integer i
Integer j
Integer pos_count
Double Precision pos_percent
Integer step
Integer neg_count
Double Precision neg_percent

If (step==0) Then
Write (, '(a)') ' '
Write (
, '(a)') ' Step Positives Negatives'
Write (, '(a)') ' # % # %'
Write (
, '(a)') ' '
End If

pos_count = 0
Do j = 1, n
Do i = 1, m
If (0<c1(i,j)) Then
pos_count = pos_count + 1
End If
End Do
End Do

neg_count = mn - pos_count
pos_percent = dble(100
pos_count)/dble(mn)
neg_percent = dble(100
neg_count)/dble(m*n)

Write (*, '(2x,i4,2x,i6,2x,f7.3,2x,i6,2x,f7.3)') step, pos_count, &
pos_percent, neg_count, neg_percent

Return
End Subroutine ising_2d_stats
Subroutine neighbor_2d_stats(step, m, n, c1, c5)

!*********************************************************************72
!
!c NEIGHBOR_2D_STATS prints neighbor statistics about the current step.
!
! Parameters:
!
! Input, integer STEP, the step number.
!
! Input, integer M, N, the number of rows and columns.
!
! Input, integer C1(M,N), the current state of the system.
!
! Input, integer C5(M,N), the number of agreeable neighbors.
!
Implicit None

Integer m
Integer n

Integer c1(m, n)
Integer c5(m, n)
Integer i
Integer j
Integer k
Integer stats(-5:5)
Integer step

If (step==0) Then
Write (, '(a)') ' '
Write (
, '(a)') ' Step Neighborhood Charge:'
Write (, '(a)') ' -5 -4 -3 -2 -1' //&
' +1 +2 +3 +4 +5'
Write (
, '(a)') ' '
End If

Do i = -5, 5
stats(i) = 0
End Do

Do j = 1, n
Do i = 1, m
stats(c5(i,j)) = stats(c5(i,j)) + 1
End Do
End Do
Write (*, '(2x,i4,10(2x,i4))') step, (stats(i), i=-5, -1), (stats(i), i=1, 5)

Return
End Subroutine neighbor_2d_stats
Subroutine plot_file(m, n, c1,title, plot_filename, png_filename)

!*********************************************************************72
!
!c PLOT_FILE writes the current configuration to a GNUPLOT plot file.
!
! Parameters:
!
! Input, integer M, N, the number of rows and columns.
!
! Input, integer C1(M,N), the current state of the system.
!
! Input, character * ( * ) , a for the plot.
!
! Input, character * ( * ) PLOT_FILENAME, a name for the GNUPLOT
! command file to be created.
!
! Input, character * ( * ) PNG_FILENAME, the name of the PNG graphics
! file to be created.
!
Implicit None

Integer m
Integer n

Integer c1(m, n)
Integer i
Integer j
Character () plot_filename
Integer plot_unit
Character () png_filename
Double Precision ratio
Character () title
Integer x1
Integer x2
Integer y1
Integer y2

Call get_unit(plot_unit)

Open (Unit=plot_unit, File=plot_filename, Status='replace')

ratio = dble(n)/dble(m)

Write (plot_unit, '(a)') 'set term png'
Write (plot_unit, '(a)') 'set output "' // trim(png_filename) // '"'
Write (plot_unit, '(a,i4,a)') 'set xrange [ 0 : ', m, ' ]'
Write (plot_unit, '(a,i4,a)') 'set yrange [ 0 : ', n, ' ]'
Write (plot_unit, '(a)') 'set nokey'
Write (plot_unit, '(a)') 'set title"' // trim(title ) // '"'
Write (plot_unit, '(a)') 'unset tics'

Write (plot_unit, '(a,g15.7)') 'set size ratio ', ratio
Do j = 1, n
y1 = j - 1
y2 = j
Do i = 1, m
x1 = m - i
x2 = m + 1 - i
If (c1(i,j)<0) Then
Write (plot_unit, '(a,i3,a,i3,a,i3,a,i3,a)') &
'set rectangle from ', x1, ',', y1, ' to ', x2, ',', y2, &
' fc rgb "blue"'
Else
Write (plot_unit, '(a,i3,a,i3,a,i3,a,i3,a)')&
'set rectangle from ', x1, ',', y1, ' to ', x2, ',', y2,&
' fc rgb "red"'
End If
End Do
End Do

Write (plot_unit, '(a)') 'plot 1'
Write (plot_unit, '(a)') 'quit'

Close (Unit=plot_unit)

Write (, '(a)') ' '
Write (
, '(a)') ' Created the gnuplot graphics file "' // &
trim(plot_filename) // '".'

Return
End Subroutine plot_file
Subroutine r8mat_uniform_01(m, n, seed, r)

!*********************************************************************72
!
!c R8MAT_UNIFORM_01 returns a unit pseudorandom R8MAT.
!
! Discussion:
!
! An R8MAT is an array of R8's.
!
! Parameters:
!
! Input, integer M, N, the number of rows and columns in the array.
!
! Input/output, integer SEED, the "seed" value, which should NOT be 0.
! On output, SEED has been updated.
!
! Output, double precision R(M,N), the array of pseudorandom values.
!
Implicit None

Integer m
Integer n

Integer i
Integer j
Integer k
Integer seed
Double Precision r(m, n)

If (seed==0) Then
Write (, '(a)') ' '
Write (
, '(a)') 'R8MAT_UNIFORM_01 - Fatal error!'
Write (*, '(a)') ' Input value of SEED = 0.'
Stop
End If

Do j = 1, n

Do i = 1, m

  k = seed/127773

  seed = 16807*(seed-k*127773) - k*2836

  If (seed<0) Then
    seed = seed + 2147483647
  End If

  r(i, j) = dble(seed)*4.656612875D-10

End Do

End Do

Return
End Subroutine r8mat_uniform_01
Function s_len_trim(s)

!*******************************************************************72
!
!c S_LEN_TRIM returns the length of a string to the last nonblank.
!
! Parameters:
!
! Input, character
(
) S, a string.
!
! Output, integer S_LEN_TRIM, the length of the string to the last nonblank.
!
Implicit None

Integer i
Character () s
Integer s_len_trim

Do i = len(s), 1, -1

If (s(i:i)/=' ') Then
  s_len_trim = i
  Return
End If

End Do

s_len_trim = 0

Return
End Function s_len_trim
Subroutine s_to_i4(s, ival, ierror, length)

!*********************************************************************72
!
!c S_TO_I4 reads an I4 from a string.
!
! Parameters:
!
! Input, character * ( * ) S, a string to be examined.
!
! Output, integer IVAL, the integer value read from the string.
! If the string is blank, then IVAL will be returned 0.
!
! Output, integer IERROR, an error flag.
! 0, no error.
! 1, an error occurred.
!
! Output, integer LENGTH, the number of characters of S
! used to make IVAL.
!
Implicit None

Character c
Integer i
Integer ierror
Integer isgn
Integer istate
Integer ival
Integer length
Character () s
Integer s_len_trim

ierror = 0
istate = 0
isgn = 1
ival = 0

Do i = 1, s_len_trim(s)

c = s(i:i)

!
! Haven't read anything.
!
If (istate==0) Then

If (c==' ') Then

  Else If (c=='-') Then
    istate = 1
    isgn = -1
  Else If (c=='+') Then
    istate = 1
    isgn = +1
  Else If (lle('0',c) .And. lle(c,'9')) Then
    istate = 2
    ival = ichar(c) - ichar('0')
  Else
    ierror = 1
    Return
  End If

!
! Have read the sign, expecting digits.
!
Else If (istate==1) Then

If (c==' ') Then

  Else If (lle('0',c) .And. lle(c,'9')) Then
    istate = 2
    ival = ichar(c) - ichar('0')
  Else
    ierror = 1
    Return
  End If

!
! Have read at least one digit, expecting more.
!
Else If (istate==2) Then

If (lle('0',c) .And. lle(c,'9')) Then
    ival = 10*ival + ichar(c) - ichar('0')
  Else
    ival = isgn*ival
    length = i - 1
    Return
  End If

End If

End Do
!
! If we read all the characters in the string, see if we're OK.
!
If (istate==2) Then
ival = isgn*ival
length = s_len_trim(s)
Else
ierror = 1
length = 0
End If

Return
End Subroutine s_to_i4
Subroutine s_to_r8(s, dval, ierror, length)

!*********************************************************************72
!
!c S_TO_R8 reads an R8 from a string.
!
! Discussion:
!
! The routine will read as many characters as possible until it reaches
! the end of the string, or encounters a character which cannot be
! part of the number.
!
! Legal input is:
!
! 1 blanks,
! 2 '+' or '-' sign,
! 2.5 blanks
! 3 integer part,
! 4 decimal point,
! 5 fraction part,
! 6 'E' or 'e' or 'D' or 'd', exponent marker,
! 7 exponent sign,
! 8 exponent integer part,
! 9 exponent decimal point,
! 10 exponent fraction part,
! 11 blanks,
! 12 final comma or semicolon,
!
! with most quantities optional.
!
! Example:
!
! S DVAL
!
! '1' 1.0
! ' 1 ' 1.0
! '1A' 1.0
! '12,34,56' 12.0
! ' 34 7' 34.0
! '-1E2ABCD' -100.0
! '-1X2ABCD' -1.0
! ' 2E-1' 0.2
! '23.45' 23.45
! '-4.2E+2' -420.0
! '17d2' 1700.0
! '-14e-2' -0.14
! 'e2' 100.0
! '-12.73e-9.23' -12.73 * 10.0^(-9.23)
!
! Parameters:
!
! Input, character * ( * ) S, the string containing the
! data to be read. Reading will begin at position 1 and
! terminate at the end of the string, or when no more
! characters can be read to form a legal real. Blanks,
! commas, or other nonnumeric data will, in particular,
! cause the conversion to halt.
!
! Output, double precision DVAL, the value read from the string.
!
! Output, integer IERROR, error flag.
! 0, no errors occurred.
! 1, 2, 6 or 7, the input number was garbled. The
! value of IERROR is the last type of input successfully
! read. For instance, 1 means initial blanks, 2 means
! a plus or minus sign, and so on.
!
! Output, integer LENGTH, the number of characters read
! to form the number, including any terminating
! characters such as a trailing comma or blanks.
!
Implicit None

Logical ch_eqi
Character c
Double Precision dval
Integer ierror
Integer ihave
Integer isgn
Integer iterm
Integer jbot
Integer jsgn
Integer jtop
Integer length
Integer nchar
Integer ndig
Double Precision rbot
Double Precision rexp
Double Precision rtop
Character () s
Integer s_len_trim

nchar = s_len_trim(s)

ierror = 0
dval = 0.0D+00
length = -1
isgn = 1
rtop = 0
rbot = 1
jsgn = 1
jtop = 0
jbot = 1
ihave = 1
iterm = 0

10 Continue

length = length + 1

If (nchar<length+1) Then
Goto 20
End If

c = s(length+1:length+1)
!
! Blank character.
!
If (c==' ') Then

If (ihave==2) Then

Else If (ihave==6 .Or. ihave==7) Then
  iterm = 1
Else If (1<ihave) Then
  ihave = 11
End If

!
! Comma.
!
Else If (c==',' .Or. c==';') Then

If (ihave/=1) Then
  iterm = 1
  ihave = 12
  length = length + 1
End If

!
! Minus sign.
!
Else If (c=='-') Then

If (ihave==1) Then
  ihave = 2
  isgn = -1
Else If (ihave==6) Then
  ihave = 7
  jsgn = -1
Else
  iterm = 1
End If

!
! Plus sign.
!
Else If (c=='+') Then

If (ihave==1) Then
  ihave = 2
Else If (ihave==6) Then
  ihave = 7
Else
  iterm = 1
End If

!
! Decimal point.
!
Else If (c=='.') Then

If (ihave<4) Then
  ihave = 4
Else If (6<=ihave .And. ihave<=8) Then
  ihave = 9
Else
  iterm = 1
End If

!
! Scientific notation exponent marker.
!
Else If (ch_eqi(c,'E') .Or. ch_eqi(c,'D')) Then

If (ihave<6) Then
  ihave = 6
Else
  iterm = 1
End If

!
! Digit.
!
Else If (ihave<11 .And. lle('0',c) .And. lle(c,'9')) Then

If (ihave<=2) Then
  ihave = 3
Else If (ihave==4) Then
  ihave = 5
Else If (ihave==6 .Or. ihave==7) Then
  ihave = 8
Else If (ihave==9) Then
  ihave = 10
End If

Call ch_to_digit(c, ndig)

If (ihave==3) Then
  rtop = 10.0D+00*rtop + dble(ndig)
Else If (ihave==5) Then
  rtop = 10.0D+00*rtop + dble(ndig)
  rbot = 10.0D+00*rbot
Else If (ihave==8) Then
  jtop = 10*jtop + ndig
Else If (ihave==10) Then
  jtop = 10*jtop + ndig
  jbot = 10*jbot
End If

!
! Anything else is regarded as a terminator.
!
Else
iterm = 1
End If
!
! If we haven't seen a terminator, and we haven't examined the
! entire string, go get the next character.
!
If (iterm==1) Then
Goto 20
End If

Goto 10

20 Continue
!
! If we haven't seen a terminator, and we have examined the
! entire string, then we're done, and LENGTH is equal to NCHAR.
!
If (iterm/=1 .And. length+1==nchar) Then
length = nchar
End If
!
! Number seems to have terminated. Have we got a legal number?
! Not if we terminated in states 1, 2, 6 or 7.
!
If (ihave==1 .Or. ihave==2 .Or. ihave==6 .Or. ihave==7) Then
ierror = ihave
Write (*, '(a)') ' '
Write (*, '(a)') 'S_TO_R8 - Serious error!'
Write (*, '(a)') ' Illegal or nonnumeric input:'
Write (*, '(a,a)') ' ', s
Return
End If
!
! Number seems OK. Form it.
!
If (jtop==0) Then
rexp = 1.0D+00
Else
If (jbot==1) Then
rexp = 10.0D+00**(jsgn*jtop)
Else
rexp = 10.0D+00**(dble(jsgn*jtop)/dble(jbot))
End If
End If

dval = dble(isgn)rexprtop/rbot

Return
End Subroutine s_to_r8
Subroutine timestamp()

!*********************************************************************72
!
!c TIMESTAMP prints out the current YMDHMS date as a timestamp.
!
! Discussion:
!
! This FORTRAN version is made available for cases where the
! FORTRAN90 version cannot be used.
!
! Parameters:
!
! None
!
Implicit None

Character *(8) ampm
Integer d
Character *(8) date
Integer h
Integer m
Integer mm
Character *(9) month(12)
Integer n
Integer s
Character *(10) time
Integer y

Save month

Data month/'January ', 'February ', 'March ', 'April ', &
'May ', 'June ', 'July ', 'August ', 'September',&
'October ', 'November ', 'December '/

Call date_and_time(date, time)

Read (date, '(i4,i2,i2)') y, m, d
Read (time, '(i2,i2,i2,1x,i3)') h, n, s, mm

If (h<12) Then
ampm = 'AM'
Else If (h==12) Then
If (n==0 .And. s==0) Then
ampm = 'Noon'
Else
ampm = 'PM'
End If
Else
h = h - 12
If (h<12) Then
ampm = 'PM'
Else If (h==12) Then
If (n==0 .And. s==0) Then
ampm = 'Midnight'
Else
ampm = 'AM'
End If
End If
End If

Write (*, '(i2,1x,a,1x,i4,2x,i2,a1,i2.2,a1,i2.2,a1,i3.3,1x,a)') d, &
month(m), y, h, ':', n, ':', s, '.', mm, ampm

Return
End Subroutine timestamp
Subroutine transition(m, n, iterations, prob, seed, c1)

!*********************************************************************72
!
!c TRANSITION carries out a Monte Carlo simulation of a 3D Ising model.
!
! Parameters:
!
! Input, integer M, N, the number of rows and columns.
!
! Input, integer ITERATIONS, the number of iterations.
!
! Input, double precision PROB(1:5). PROB(I) represents the probability
! that the spin of a given cell will be reversed, given that it has I
! immediate neighbors (including itself) with spin the same as its own.
!
! Input/output, integer SEED, a seed for the random number
! generator.
!
! Input/output, integer C1(M,N). On input, the current
! state of the system. On output, the state of the system after
! the iterations.
!
Implicit None

Integer m
Integer n

Integer c1(m, n)
Integer c5(m, n)
Integer i
Integer iterations
Integer j
Double Precision prob(1:5)
Integer step
Double Precision r(m, n)
Integer seed
Double Precision thresh

step = 0
Call ising_2d_stats(step, m, n, c1)

Do step = 1, iterations
!
! C5 contains 1 through 5, the number of cells that agree with the center cell.
!
Call ising_2d_agree(m, n, c1, c5)

If (.False.) Then
  Call neighbor_2d_stats(step, m, n, c1, c5)
End If

!
! Determine the chances of flipping cell (I,J).
!
Call r8mat_uniform_01(m, n, seed, r)

Do j = 1, n
  Do i = 1, m
    If (r(i,j)<prob(c5(i,j))) Then
      c1(i, j) = -c1(i, j)
    End If
  End Do
End Do

Call ising_2d_stats(step, m, n, c1)

End Do

Return
End Subroutine transition


!c$$Run, Output:


7 September 2022 7:00:19.714 AM ISING_2D_SIMULATION FORTRAN95,
2013&18 version Monte Carlo simulation of a 2D Ising model.
The number of rows is M = 15
The number of columns is N = 20
The number of iterations taken is ITERATIONS = 35
The threshhold THRESH = 0.500000
The seed SEED = 123456789

The transition probability table, d on the number of
neighbors with the same spin.

1         2         3         4         5

0.9700    0.8600    0.5100    0.1600    0.0300

Created the gnuplot graphics file "ising_2d_initial.txt".

Step Positives Negatives

% # %

0     147   49.000     153   51.000
 1     147   49.000     153   51.000
 2     147   49.000     153   51.000
 3     147   49.000     153   51.000
 4     151   50.333     149   49.667
 5     152   50.667     148   49.333
 6     155   51.667     145   48.333
 7     153   51.000     147   49.000
 8     164   54.667     136   45.333
 9     163   54.333     137   45.667
10     160   53.333     140   46.667
11     167   55.667     133   44.333
12     165   55.000     135   45.000
13     169   56.333     131   43.667
14     162   54.000     138   46.000
15     165   55.000     135   45.000
16     167   55.667     133   44.333
17     172   57.333     128   42.667
18     167   55.667     133   44.333
19     160   53.333     140   46.667
20     156   52.000     144   48.000
21     158   52.667     142   47.333
22     163   54.333     137   45.667
23     155   51.667     145   48.333
24     161   53.667     139   46.333
25     163   54.333     137   45.667
26     143   47.667     157   52.333
27     144   48.000     156   52.000
28     137   45.667     163   54.333
29     140   46.667     160   53.333
30     137   45.667     163   54.333
31     136   45.333     164   54.667
32     140   46.667     160   53.333
33     144   48.000     156   52.000
34     144   48.000     156   52.000
35     144   48.000     156   52.000

Created the gnuplot graphics file "ising_2d_final.txt".

ISING_2D_SIMULATION
Normal end of execution.
April 2022
Program finished with exit code 0
Press ENTER to exit console.


set term png
set output "ising_2d_final.png"
set xrange [ 0 : 15 ]
set yrange [ 0 : 20 ]
set nokey
set "Final Configuration"
unset tics
set size ratio 1.333333
set rectangle from 14, 0 to 15, 1 fc rgb "blue"
set rectangle from 13, 0 to 14, 1 fc rgb "blue"
set rectangle from 12, 0 to 13, 1 fc rgb "blue"
......................................
set rectangle from 3, 19 to 4, 20 fc rgb "blue"
set rectangle from 2, 19 to 3, 20 fc rgb "blue"
set rectangle from 1, 19 to 2, 20 fc rgb "blue"
set rectangle from 0, 19 to 1, 20 fc rgb "red"
plot 1
quit


set term png
set output "ising_2d_initial.png"
set xrange [ 0 : 15 ]
set yrange [ 0 : 20 ]
set nokey
set "Initial Configuration"
unset tics
set size ratio 1.333333
set rectangle from 14, 0 to 15, 1 fc rgb "blue"
set rectangle from 13, 0 to 14, 1 fc rgb "red"
set rectangle from 12, 0 to 13, 1 fc rgb "red"
set rectangle from 11, 0 to 12, 1 fc rgb "red"
set rectangle from 10, 0 to 11, 1 fc rgb "blue"
set rectangle from 9, 0 to 10, 1 fc rgb "blue"
.......................................
set rectangle from 2, 19 to 3, 20 fc rgb "blue"
set rectangle from 1, 19 to 2, 20 fc rgb "red"
set rectangle from 0, 19 to 1, 20 fc rgb "blue"
plot 1
quit
Created the gnuplot graphics file "ising_2d_final.txt".
ISING_2D_SIMULATION Normal end of execution.
7 September 2022 7:00:19.716 AM


易辛二维度模拟正负电荷的2D阵列进化每个很会“翻转”与邻居一致,
程序运行验证演示数值如上
及图形处理命令,若按其执行应该可以会获得图形表达示意.


广州

更多回帖

发帖
×
20
完善资料,
赚取积分