Changeset 1822 for palm/trunk/SOURCE/lpm_exchange_horiz.f90
- Timestamp:
- Apr 7, 2016 7:49:42 AM (8 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
palm/trunk/SOURCE/lpm_exchange_horiz.f90
r1818 r1822 19 19 ! Current revisions: 20 20 ! ------------------ 21 ! 21 ! Tails removed. Unused variables removed. 22 22 ! 23 23 ! Former revisions: … … 67 67 ! Description: 68 68 ! ------------ 69 ! > Exchange of particles (and tails)between the subdomains.69 ! Exchange of particles between the subdomains. 70 70 !------------------------------------------------------------------------------! 71 71 MODULE lpm_exchange_horiz_mod … … 93 93 94 94 USE particle_attributes, & 95 ONLY: alloc_factor, deleted_particles, deleted_tails, grid_particles, & 96 ibc_par_lr, ibc_par_ns, maximum_number_of_tails, & 97 maximum_number_of_tailpoints, min_nr_particle, & 98 mpi_particle_type, number_of_tails, number_of_particles, & 99 offset_ocean_nzt, particles, & 100 particle_tail_coordinates, particle_type, prt_count, & 101 tail_mask, trlp_count_sum, & 95 ONLY: alloc_factor, deleted_particles, grid_particles, & 96 ibc_par_lr, ibc_par_ns, min_nr_particle, & 97 mpi_particle_type, number_of_particles, & 98 offset_ocean_nzt, offset_ocean_nzt_m1, particles, & 99 particle_type, prt_count, trlp_count_sum, & 102 100 trlp_count_recv_sum, trnp_count_sum, trnp_count_recv_sum, & 103 101 trrp_count_sum, trrp_count_recv_sum, trsp_count_sum, & 104 trsp_count_recv_sum, use_particle_tails,zero_particle102 trsp_count_recv_sum, zero_particle 105 103 106 104 USE pegrid … … 156 154 INTEGER(iwp) :: j !< 157 155 INTEGER(iwp) :: jp !< 158 INTEGER(iwp) :: k !<159 156 INTEGER(iwp) :: kp !< 160 157 INTEGER(iwp) :: n !< 161 INTEGER(iwp) :: nn !<162 INTEGER(iwp) :: tlength !<163 158 INTEGER(iwp) :: trlp_count !< 164 159 INTEGER(iwp) :: trlp_count_recv !< … … 178 173 INTEGER(iwp) :: trspt_count_recv !< 179 174 180 REAL(wp), DIMENSION(:,:,:), ALLOCATABLE :: trlpt !<181 REAL(wp), DIMENSION(:,:,:), ALLOCATABLE :: trnpt !<182 REAL(wp), DIMENSION(:,:,:), ALLOCATABLE :: trrpt !<183 REAL(wp), DIMENSION(:,:,:), ALLOCATABLE :: trspt !<184 185 175 TYPE(particle_type), DIMENSION(:), ALLOCATABLE :: rvlp !< 186 176 TYPE(particle_type), DIMENSION(:), ALLOCATABLE :: rvnp !< … … 196 186 #if defined( __parallel ) 197 187 188 ! 189 !-- Exchange between subdomains. 190 !-- As soon as one particle has moved beyond the boundary of the domain, it 191 !-- is included in the relevant transfer arrays and marked for subsequent 192 !-- deletion on this PE. 193 !-- First sweep for crossings in x direction. Find out first the number of 194 !-- particles to be transferred and allocate temporary arrays needed to store 195 !-- them. 196 !-- For a one-dimensional decomposition along y, no transfer is necessary, 197 !-- because the particle remains on the PE, but the particle coordinate has to 198 !-- be adjusted. 198 199 trlp_count = 0 199 200 trlpt_count = 0 … … 226 227 IF ( i < nxl ) THEN 227 228 trlp_count = trlp_count + 1 228 IF ( particles(n)%tail_id /= 0 ) trlpt_count = trlpt_count + 1229 229 ELSEIF ( i > nxr ) THEN 230 230 trrp_count = trrp_count + 1 231 IF ( particles(n)%tail_id /= 0 ) trrpt_count = trrpt_count + 1232 231 ENDIF 233 232 ENDIF … … 247 246 trlp = zero_particle 248 247 trrp = zero_particle 249 250 IF ( use_particle_tails ) THEN251 ALLOCATE( trlpt(maximum_number_of_tailpoints,5,trlpt_count), &252 trrpt(maximum_number_of_tailpoints,5,trrpt_count) )253 tlength = maximum_number_of_tailpoints * 5254 ENDIF255 248 256 249 trlp_count = 0 … … 269 262 particles => grid_particles(kp,jp,ip)%particles(1:number_of_particles) 270 263 DO n = 1, number_of_particles 271 272 nn = particles(n)%tail_id273 264 ! 274 265 !-- Only those particles that have not been marked as 'deleted' may … … 292 283 particles(n)%origin_x = ( nx + 1 ) * dx + & 293 284 particles(n)%origin_x 294 IF ( use_particle_tails .AND. nn /= 0 ) THEN295 i = particles(n)%tailpoints296 particle_tail_coordinates(1:i,1,nn) = ( nx + 1 ) * dx &297 + particle_tail_coordinates(1:i,1,nn)298 ENDIF299 285 ELSE 300 286 trlp_count = trlp_count + 1 … … 312 298 ENDIF 313 299 314 IF ( use_particle_tails .AND. nn /= 0 ) THEN315 trlpt_count = trlpt_count + 1316 trlpt(:,:,trlpt_count) = particle_tail_coordinates(:,:,nn)317 trlpt(:,1,trlpt_count) = ( nx + 1 ) * dx + &318 trlpt(:,1,trlpt_count)319 tail_mask(nn) = .FALSE.320 deleted_tails = deleted_tails + 1321 ENDIF322 300 ENDIF 323 301 … … 327 305 particles(n)%particle_mask = .FALSE. 328 306 deleted_particles = deleted_particles + 1 329 IF ( use_particle_tails .AND. nn /= 0 ) THEN330 tail_mask(nn) = .FALSE.331 deleted_tails = deleted_tails + 1332 ENDIF333 307 334 308 ELSEIF ( ibc_par_lr == 2 ) THEN … … 348 322 deleted_particles = deleted_particles + 1 349 323 350 IF ( use_particle_tails .AND. nn /= 0 ) THEN351 trlpt_count = trlpt_count + 1352 trlpt(:,:,trlpt_count) = particle_tail_coordinates(:,:,nn)353 tail_mask(nn) = .FALSE.354 deleted_tails = deleted_tails + 1355 ENDIF356 324 ENDIF 357 325 … … 367 335 particles(n)%origin_x = particles(n)%origin_x - & 368 336 ( nx + 1 ) * dx 369 IF ( use_particle_tails .AND. nn /= 0 ) THEN370 i = particles(n)%tailpoints371 particle_tail_coordinates(1:i,1,nn) = - ( nx+1 ) * dx &372 + particle_tail_coordinates(1:i,1,nn)373 ENDIF374 337 ELSE 375 338 trrp_count = trrp_count + 1 … … 381 344 deleted_particles = deleted_particles + 1 382 345 383 IF ( use_particle_tails .AND. nn /= 0 ) THEN384 trrpt_count = trrpt_count + 1385 trrpt(:,:,trrpt_count) = particle_tail_coordinates(:,:,nn)386 trrpt(:,1,trrpt_count) = trrpt(:,1,trrpt_count) - &387 ( nx + 1 ) * dx388 tail_mask(nn) = .FALSE.389 deleted_tails = deleted_tails + 1390 ENDIF391 346 ENDIF 392 347 … … 396 351 particles(n)%particle_mask = .FALSE. 397 352 deleted_particles = deleted_particles + 1 398 IF ( use_particle_tails .AND. nn /= 0 ) THEN399 tail_mask(nn) = .FALSE.400 deleted_tails = deleted_tails + 1401 ENDIF402 353 403 354 ELSEIF ( ibc_par_lr == 2 ) THEN … … 417 368 deleted_particles = deleted_particles + 1 418 369 419 IF ( use_particle_tails .AND. nn /= 0 ) THEN420 trrpt_count = trrpt_count + 1421 trrpt(:,:,trrpt_count) = particle_tail_coordinates(:,:,nn)422 tail_mask(nn) = .FALSE.423 deleted_tails = deleted_tails + 1424 ENDIF425 370 ENDIF 426 371 … … 452 397 DEALLOCATE(rvrp) 453 398 454 IF ( use_particle_tails ) THEN455 456 CALL MPI_SENDRECV( trlpt_count, 1, MPI_INTEGER, pleft, 0, &457 trrpt_count_recv, 1, MPI_INTEGER, pright, 0, &458 comm2d, status, ierr )459 460 IF ( number_of_tails+trrpt_count_recv > maximum_number_of_tails ) &461 THEN462 IF ( netcdf_data_format < 3 ) THEN463 message_string = 'maximum_number_of_tails ' // &464 'needs to be increased ' // &465 '&but this is not allowed wi'// &466 'th netcdf_data_format < 3'467 CALL message( 'lpm_exch_horiz', 'PA0147', 2, 2, -1, 6, 1 )468 ELSE469 CALL lpm_extend_tail_array( trrpt_count_recv )470 ENDIF471 ENDIF472 473 CALL MPI_SENDRECV( trlpt(1,1,1), trlpt_count*tlength, MPI_REAL, &474 pleft, 1, &475 particle_tail_coordinates(1,1,number_of_tails+1), &476 trrpt_count_recv*tlength, MPI_REAL, pright, 1, &477 comm2d, status, ierr )478 !479 !-- Update the tail ids for the transferred particles480 nn = number_of_tails481 DO n = number_of_particles+1, number_of_particles+trrp_count_recv482 IF ( particles(n)%tail_id /= 0 ) THEN483 nn = nn + 1484 particles(n)%tail_id = nn485 ENDIF486 ENDDO487 488 ENDIF489 490 399 ! 491 400 !-- Send right boundary, receive left boundary … … 503 412 IF ( trlp_count_recv > 0 ) CALL Add_particles_to_gridcell(rvlp(1:trlp_count_recv)) 504 413 505 DEALLOCATE(rvlp) 506 507 IF ( use_particle_tails ) THEN 508 509 CALL MPI_SENDRECV( trrpt_count, 1, MPI_INTEGER, pright, 0, & 510 trlpt_count_recv, 1, MPI_INTEGER, pleft, 0, & 511 comm2d, status, ierr ) 512 513 IF ( number_of_tails+trlpt_count_recv > maximum_number_of_tails ) & 514 THEN 515 IF ( netcdf_data_format < 3 ) THEN 516 message_string = 'maximum_number_of_tails ' // & 517 'needs to be increased ' // & 518 '&but this is not allowed wi'// & 519 'th netcdf_data_format < 3' 520 CALL message( 'lpm_exch_horiz', 'PA0147', 2, 2, -1, 6, 1 ) 521 ELSE 522 CALL lpm_extend_tail_array( trlpt_count_recv ) 523 ENDIF 524 ENDIF 525 526 CALL MPI_SENDRECV( trrpt(1,1,1), trrpt_count*tlength, MPI_REAL, & 527 pright, 1, & 528 particle_tail_coordinates(1,1,number_of_tails+1), & 529 trlpt_count_recv*tlength, MPI_REAL, pleft, 1, & 530 comm2d, status, ierr ) 531 ! 532 !-- Update the tail ids for the transferred particles 533 nn = number_of_tails 534 DO n = number_of_particles+1, number_of_particles+trlp_count_recv 535 IF ( particles(n)%tail_id /= 0 ) THEN 536 nn = nn + 1 537 particles(n)%tail_id = nn 538 ENDIF 539 ENDDO 540 541 ENDIF 542 543 ! number_of_particles = number_of_particles + trlp_count_recv 544 ! number_of_tails = number_of_tails + trlpt_count_recv 545 546 IF ( use_particle_tails ) THEN 547 DEALLOCATE( trlpt, trrpt ) 548 ENDIF 414 DEALLOCATE( rvlp ) 549 415 DEALLOCATE( trlp, trrp ) 550 416 … … 589 455 IF ( j < nys ) THEN 590 456 trsp_count = trsp_count + 1 591 IF ( particles(n)%tail_id /= 0 ) trspt_count = trspt_count + 1592 457 ELSEIF ( j > nyn ) THEN 593 458 trnp_count = trnp_count + 1 594 IF ( particles(n)%tail_id /= 0 ) trnpt_count = trnpt_count + 1595 459 ENDIF 596 460 ENDIF … … 609 473 trsp = zero_particle 610 474 trnp = zero_particle 611 612 IF ( use_particle_tails ) THEN613 ALLOCATE( trspt(maximum_number_of_tailpoints,5,trspt_count), &614 trnpt(maximum_number_of_tailpoints,5,trnpt_count) )615 tlength = maximum_number_of_tailpoints * 5616 ENDIF617 475 618 476 trsp_count = nr_move_south … … 633 491 particles => grid_particles(kp,jp,ip)%particles(1:number_of_particles) 634 492 DO n = 1, number_of_particles 635 636 nn = particles(n)%tail_id637 493 ! 638 494 !-- Only those particles that have not been marked as 'deleted' may … … 655 511 particles(n)%origin_y = ( ny + 1 ) * dy + & 656 512 particles(n)%origin_y 657 IF ( use_particle_tails .AND. nn /= 0 ) THEN658 i = particles(n)%tailpoints659 particle_tail_coordinates(1:i,2,nn) = &660 ( ny+1 ) * dy + particle_tail_coordinates(1:i,2,nn)661 ENDIF662 513 ELSE 663 514 trsp_count = trsp_count + 1 … … 677 528 ENDIF 678 529 679 IF ( use_particle_tails .AND. nn /= 0 ) THEN680 trspt_count = trspt_count + 1681 trspt(:,:,trspt_count) = &682 particle_tail_coordinates(:,:,nn)683 trspt(:,2,trspt_count) = ( ny + 1 ) * dy + &684 trspt(:,2,trspt_count)685 tail_mask(nn) = .FALSE.686 deleted_tails = deleted_tails + 1687 ENDIF688 530 ENDIF 689 531 … … 693 535 particles(n)%particle_mask = .FALSE. 694 536 deleted_particles = deleted_particles + 1 695 IF ( use_particle_tails .AND. nn /= 0 ) THEN696 tail_mask(nn) = .FALSE.697 deleted_tails = deleted_tails + 1698 ENDIF699 537 700 538 ELSEIF ( ibc_par_ns == 2 ) THEN … … 714 552 deleted_particles = deleted_particles + 1 715 553 716 IF ( use_particle_tails .AND. nn /= 0 ) THEN717 trspt_count = trspt_count + 1718 trspt(:,:,trspt_count) = particle_tail_coordinates(:,:,nn)719 tail_mask(nn) = .FALSE.720 deleted_tails = deleted_tails + 1721 ENDIF722 554 ENDIF 723 555 … … 733 565 particles(n)%origin_y = & 734 566 particles(n)%origin_y - ( ny + 1 ) * dy 735 IF ( use_particle_tails .AND. nn /= 0 ) THEN736 i = particles(n)%tailpoints737 particle_tail_coordinates(1:i,2,nn) = &738 - (ny+1) * dy + particle_tail_coordinates(1:i,2,nn)739 ENDIF740 567 ELSE 741 568 trnp_count = trnp_count + 1 … … 747 574 particles(n)%particle_mask = .FALSE. 748 575 deleted_particles = deleted_particles + 1 749 IF ( use_particle_tails .AND. nn /= 0 ) THEN750 trnpt_count = trnpt_count + 1751 trnpt(:,:,trnpt_count) = &752 particle_tail_coordinates(:,:,nn)753 trnpt(:,2,trnpt_count) = &754 trnpt(:,2,trnpt_count) - ( ny + 1 ) * dy755 tail_mask(nn) = .FALSE.756 deleted_tails = deleted_tails + 1757 ENDIF758 576 ENDIF 759 577 … … 763 581 particles(n)%particle_mask = .FALSE. 764 582 deleted_particles = deleted_particles + 1 765 IF ( use_particle_tails .AND. nn /= 0 ) THEN766 tail_mask(nn) = .FALSE.767 deleted_tails = deleted_tails + 1768 ENDIF769 583 770 584 ELSEIF ( ibc_par_ns == 2 ) THEN … … 784 598 deleted_particles = deleted_particles + 1 785 599 786 IF ( use_particle_tails .AND. nn /= 0 ) THEN787 trnpt_count = trnpt_count + 1788 trnpt(:,:,trnpt_count) = particle_tail_coordinates(:,:,nn)789 tail_mask(nn) = .FALSE.790 deleted_tails = deleted_tails + 1791 ENDIF792 600 ENDIF 793 601 … … 819 627 DEALLOCATE(rvnp) 820 628 821 IF ( use_particle_tails ) THEN822 823 CALL MPI_SENDRECV( trspt_count, 1, MPI_INTEGER, psouth, 0, &824 trnpt_count_recv, 1, MPI_INTEGER, pnorth, 0, &825 comm2d, status, ierr )826 827 IF ( number_of_tails+trnpt_count_recv > maximum_number_of_tails ) &828 THEN829 IF ( netcdf_data_format < 3 ) THEN830 message_string = 'maximum_number_of_tails ' // &831 'needs to be increased ' // &832 '&but this is not allowed wi' // &833 'th netcdf_data_format < 3'834 CALL message( 'lpm_exch_horiz', 'PA0147', 2, 2, -1, 6, 1 )835 ELSE836 CALL lpm_extend_tail_array( trnpt_count_recv )837 ENDIF838 ENDIF839 840 CALL MPI_SENDRECV( trspt(1,1,1), trspt_count*tlength, MPI_REAL, &841 psouth, 1, &842 particle_tail_coordinates(1,1,number_of_tails+1), &843 trnpt_count_recv*tlength, MPI_REAL, pnorth, 1, &844 comm2d, status, ierr )845 846 !847 !-- Update the tail ids for the transferred particles848 nn = number_of_tails849 DO n = number_of_particles+1, number_of_particles+trnp_count_recv850 IF ( particles(n)%tail_id /= 0 ) THEN851 nn = nn + 1852 particles(n)%tail_id = nn853 ENDIF854 ENDDO855 856 ENDIF857 858 ! number_of_particles = number_of_particles + trnp_count_recv859 ! number_of_tails = number_of_tails + trnpt_count_recv860 861 629 ! 862 630 !-- Send back boundary, receive front boundary … … 876 644 DEALLOCATE(rvsp) 877 645 878 IF ( use_particle_tails ) THEN879 880 CALL MPI_SENDRECV( trnpt_count, 1, MPI_INTEGER, pnorth, 0, &881 trspt_count_recv, 1, MPI_INTEGER, psouth, 0, &882 comm2d, status, ierr )883 884 IF ( number_of_tails+trspt_count_recv > maximum_number_of_tails ) &885 THEN886 IF ( netcdf_data_format < 3 ) THEN887 message_string = 'maximum_number_of_tails ' // &888 'needs to be increased ' // &889 '&but this is not allowed wi'// &890 'th NetCDF output switched on'891 CALL message( 'lpm_exch_horiz', 'PA0147', 2, 2, -1, 6, 1 )892 ELSE893 CALL lpm_extend_tail_array( trspt_count_recv )894 ENDIF895 ENDIF896 897 CALL MPI_SENDRECV( trnpt(1,1,1), trnpt_count*tlength, MPI_REAL, &898 pnorth, 1, &899 particle_tail_coordinates(1,1,number_of_tails+1), &900 trspt_count_recv*tlength, MPI_REAL, psouth, 1, &901 comm2d, status, ierr )902 !903 !-- Update the tail ids for the transferred particles904 nn = number_of_tails905 DO n = number_of_particles+1, number_of_particles+trsp_count_recv906 IF ( particles(n)%tail_id /= 0 ) THEN907 nn = nn + 1908 particles(n)%tail_id = nn909 ENDIF910 ENDDO911 912 ENDIF913 914 646 number_of_particles = number_of_particles + trsp_count_recv 915 number_of_tails = number_of_tails + trspt_count_recv 916 917 IF ( use_particle_tails ) THEN 918 DEALLOCATE( trspt, trnpt ) 919 ENDIF 647 920 648 DEALLOCATE( trsp, trnp ) 921 649 … … 928 656 DO n = 1, number_of_particles 929 657 930 nn = particles(n)%tail_id931 932 658 IF ( particles(n)%x < -0.5_wp * dx ) THEN 933 659 … … 936 662 !-- Cyclic boundary. Relevant coordinate has to be changed. 937 663 particles(n)%x = ( nx + 1 ) * dx + particles(n)%x 938 IF ( use_particle_tails .AND. nn /= 0 ) THEN 939 i = particles(n)%tailpoints 940 particle_tail_coordinates(1:i,1,nn) = ( nx + 1 ) * dx + & 941 particle_tail_coordinates(1:i,1,nn) 942 ENDIF 664 943 665 ELSEIF ( ibc_par_lr == 1 ) THEN 944 666 ! … … 946 668 particles(n)%particle_mask = .FALSE. 947 669 deleted_particles = deleted_particles + 1 948 IF ( use_particle_tails .AND. nn /= 0 ) THEN 949 tail_mask(nn) = .FALSE. 950 deleted_tails = deleted_tails + 1 951 ENDIF 670 952 671 ELSEIF ( ibc_par_lr == 2 ) THEN 953 672 ! … … 963 682 !-- Cyclic boundary. Relevant coordinate has to be changed. 964 683 particles(n)%x = particles(n)%x - ( nx + 1 ) * dx 965 IF ( use_particle_tails .AND. nn /= 0 ) THEN 966 i = particles(n)%tailpoints 967 particle_tail_coordinates(1:i,1,nn) = - ( nx + 1 ) * dx + & 968 particle_tail_coordinates(1:i,1,nn) 969 ENDIF 684 970 685 ELSEIF ( ibc_par_lr == 1 ) THEN 971 686 ! … … 973 688 particles(n)%particle_mask = .FALSE. 974 689 deleted_particles = deleted_particles + 1 975 IF ( use_particle_tails .AND. nn /= 0 ) THEN 976 tail_mask(nn) = .FALSE. 977 deleted_tails = deleted_tails + 1 978 ENDIF 690 979 691 ELSEIF ( ibc_par_lr == 2 ) THEN 980 692 ! … … 992 704 !-- Cyclic boundary. Relevant coordinate has to be changed. 993 705 particles(n)%y = ( ny + 1 ) * dy + particles(n)%y 994 IF ( use_particle_tails .AND. nn /= 0 ) THEN 995 i = particles(n)%tailpoints 996 particle_tail_coordinates(1:i,2,nn) = ( ny + 1 ) * dy + & 997 particle_tail_coordinates(1:i,2,nn) 998 ENDIF 706 999 707 ELSEIF ( ibc_par_ns == 1 ) THEN 1000 708 ! … … 1002 710 particles(n)%particle_mask = .FALSE. 1003 711 deleted_particles = deleted_particles + 1 1004 IF ( use_particle_tails .AND. nn /= 0 ) THEN 1005 tail_mask(nn) = .FALSE. 1006 deleted_tails = deleted_tails + 1 1007 ENDIF 712 1008 713 ELSEIF ( ibc_par_ns == 2 ) THEN 1009 714 ! … … 1019 724 !-- Cyclic boundary. Relevant coordinate has to be changed. 1020 725 particles(n)%y = particles(n)%y - ( ny + 1 ) * dy 1021 IF ( use_particle_tails .AND. nn /= 0 ) THEN 1022 i = particles(n)%tailpoints 1023 particle_tail_coordinates(1:i,2,nn) = - ( ny + 1 ) * dy + & 1024 particle_tail_coordinates(1:i,2,nn) 1025 ENDIF 726 1026 727 ELSEIF ( ibc_par_ns == 1 ) THEN 1027 728 ! … … 1029 730 particles(n)%particle_mask = .FALSE. 1030 731 deleted_particles = deleted_particles + 1 1031 IF ( use_particle_tails .AND. nn /= 0 ) THEN 1032 tail_mask(nn) = .FALSE. 1033 deleted_tails = deleted_tails + 1 1034 ENDIF 732 1035 733 ELSEIF ( ibc_par_ns == 2 ) THEN 1036 734 ! … … 1287 985 INTEGER(iwp), INTENT(in) :: j !< 1288 986 INTEGER(iwp), INTENT(in) :: k !< 1289 INTEGER(iwp), INTENT(in), optional:: size_in !<987 INTEGER(iwp), INTENT(in), OPTIONAL :: size_in !< 1290 988 1291 989 INTEGER(iwp) :: old_size !< … … 1300 998 new_size = size_in 1301 999 ELSE 1302 new_size = old_size * ( 1.0 + alloc_factor / 100.0)1000 new_size = old_size * ( 1.0_wp + alloc_factor / 100.0_wp ) 1303 1001 ENDIF 1304 1002
Note: See TracChangeset
for help on using the changeset viewer.