Added to repository.

This commit is contained in:
2005-03-22 10:33:08 +00:00
parent d1a54adc4a
commit bad53d7f6c
125 changed files with 42837 additions and 0 deletions

28
mutrack/com/COMPILE.COM Normal file
View File

@ -0,0 +1,28 @@
$ set noverify
$!==============================================================================
$! Author: Anselm Hofer
$!
$! Commandoprozedur fuer das Compilieren einzelner MUTRACK oder ACCEL-Sourcecode
$! Dateien. Aufzurufen mittels '$ FORMU dateiName' bzw. '$ FORAC dateiName':
$!==============================================================================
$ progr = P1 ! = 'MUTRACK' oder 'ACCEL'
$ ext = P2 ! = '_MU' oder '_AC'
$ file = P3 ! = Name der .FOR-Datei (ohne Extension)
$!==============================================================================
$ file = file - ".FOR"
$ options = "/fast"
$!options = "/align=all"
$!==============================================================================
$ archi = F$GETSYI("ARCH_NAME") ! Host OS either "VAX" or "Alpha"
$ if archi .EQS. "VAX" then options = ""
$ if P4 .NES. "" then options = "''options' ''P4'"
$ ext = "''ext'_''archi'"
$
$ sourceFile = "''progr'$SOURCEdirectory:''file'"
$ objectFile = "''progr'$OBJdirectory:''file'''ext'"
$ listFile = "''progr'$OBJdirectory:''file'''ext'.lis"
$!==============================================================================
$ set verify
$ fortran/extend 'sourceFile' /object='objectFile' 'options'
$ set noverify
$! /list='listFile'

82
mutrack/com/COPY.COM Normal file
View File

@ -0,0 +1,82 @@
$ set noverify
$!==============================================================================
$! Author: Anselm Hofer
$!
$! Diese Commandoprozedur erlaubt es, die ACCEL- oder MUTRACK-Files
$! "AC_nnn1.'P3'" bis "AC_nnn2.'P3'" (bzw. "MU_nnn1.'P3'" bis "MU_nnn2.'P3'"
$! mit nnn1 = 'P4' und nnn2 = 'P5' auf neue Files zu kopieren, deren
$! fortlaufende Nummer um jeweils 'P6' erhoeht ist.
$!
$! Aufzurufen ueber '$ ACCOPY von bis offset' bzw. '$ MUCOPY von bis offset'
$!==============================================================================
$ if P6.EQS.""
$ then
$ say = "write sys$output "
$ say "==============================================================================="
$ say "ACCOPY extension firstNumber lastNumber offset"
$ say "MUCOPY extension firstNumber lastNumber offset"
$ say "==============================================================================="
$ exit
$ endif
$ progr = P1 ! = 'MUTRACK' oder 'ACCEL'
$ Kuerzel = P2 ! = 'MU_' oder 'AC_'
$
$ extension = P3
$ Firstindx = P4
$ Lastindx = P5
$ IndxOffset = P6
$!------------------------------------------------------------------------------
$
$ write sys$output " "
$ oldIndx = firstIndx
$
$ next:
$ newIndx = 0 + oldIndx + indxOffset ! '0 + ' notwendig, damit als Dezimal-
$ ! zahl interpretiert
$! -----------------------------------------------------------------------------
$ if oldIndx.LT.10
$ then
$ oldFile = "''progr'$outDirectory:''kuerzel'_000''oldIndx'.''extension'."
$ goto label1
$ endif
$ if oldIndx.LT.100
$ then
$ oldFile = "''progr'$outDirectory:''kuerzel'_00''oldIndx'.''extension'."
$ goto label1
$ endif
$ if oldIndx.LT.1000
$ then
$ oldFile = "''progr'$outDirectory:''kuerzel'_0''oldIndx'.''extension'."
$ goto label1
$ endif
$ oldFile = "''progr'$outDirectory:''kuerzel'_''oldIndx'.''extension'."
$! -----------------------------------------------------------------------------
$ label1:
$ if newIndx.LT.10
$ then
$ newFile = "''progr'$outDirectory:''kuerzel'_000''newIndx'.''extension'."
$ goto label2
$ endif
$ if newIndx.LT.100
$ then
$ newFile = "''progr'$outDirectory:''kuerzel'_00''newIndx'.''extension'."
$ goto label2
$ endif
$ if newIndx.LT.1000
$ then
$ newFile = "''progr'$outDirectory:''kuerzel'_0''newIndx'.''extension'."
$ goto label2
$ endif
$ newFile = "''progr'$outDirectory:''kuerzel'_''newIndx'.''extension'."
$! -----------------------------------------------------------------------------
$ label2:
$ cop /log 'oldFile' 'newFile'
$
$ if oldIndx.LT.LastIndx
$ then
$ oldIndx = oldIndx + 1
$ goto next
$ endif
$
$ write sys$output " "
$

3
mutrack/com/FORMUT.COM Normal file
View File

@ -0,0 +1,3 @@
$ set ver
$ fortran 'P1' /obj=mutrack$OBJdirectory:T-'P1'
$ set nover

1
mutrack/com/GETMU.COM Normal file
View File

@ -0,0 +1 @@
copy /log PSICLU::USR_SCROOT:[AHOFER]MU_'P1'.*. mutrack$OUTdirectory:*.*.

1
mutrack/com/GETMUG.COM Normal file
View File

@ -0,0 +1 @@
copy /log PSICLB::DSA999:[SCR142.GLUECKLER]MU_'p1'.*. mutrack$OUTdirectory:*.*.

1
mutrack/com/GETMUM.COM Normal file
View File

@ -0,0 +1 @@
copy /log PSICLB::DSA999:[SCR142.MHEUBERGER]MU_'P1'.*. mutrack$OUTdirectory:*.*.

View File

@ -0,0 +1,11 @@
$! fuer Tests mit zusaetlicher Linse 'NL':
$!==============================================================================
$ DEFINE mutrack$SOURCEdirectory UD1:[SIMULA.MUTRACK.TEST2]
$ FORMUT :== "@mutrack$COMdirectory:formut.com"
$ LINKMUT :== "@mutrack$COMdirectory:linkmut.com"
$ LINKMUTV :== "@mutrack$COMdirectory:linkmutv.com"
$ MU*TRACK :== "RUN mutrack$EXEdirectory:T-MUTRACK.EXE"
$ SUBTMU :== -
"SUBMIT/NOTIFY/NOPRINT/NAME=MUTRACK/LOG_FILE=mutrack$OUTdirectory mutrack$COMdirectory:T-MUTRACK.COM"
$ LSEMUT :== "LSE mutrack$READdirectory:mutrackT.input"
$!==============================================================================

33
mutrack/com/LINKMU.COM Normal file
View File

@ -0,0 +1,33 @@
$ set noverify
$ set noon
$!==============================================================================
$ prog= "mutrack"
$ ext = "_MU"
$!==============================================================================
$ sourceDir = "''prog'$SOURCEdirectory"
$ objectDir = "''prog'$OBJdirectory"
$ executeDir = "''prog'$EXEdirectory"
$!==============================================================================
$ archi = F$GETSYI("ARCH_NAME") ! Host OS either "VAX" or "Alpha"
$ ext = "''ext'_''archi'"
$ set verify
$!==============================================================================
$ link -
'objectDir':MUTRACK'ext', -
'objectDir':SUB_ARTLIST'ext', -
'objectDir':SUB_INTEGR_L1'ext', -
'objectDir':SUB_INTEGR_SP'ext', -
'objectDir':SUB_INTEGR_L2andFo'ext', -
'objectDir':SUB_INTEGR_FO'ext', -
'objectDir':SUB_INTEGR_L3'ext', -
'objectDir':SUB_INTEGR_M2'ext', -
'objectDir':SUB_INPUT'ext', -
'objectDir':SUB_PICTURE'ext', -
'objectDir':SUB_OUTPUT'ext',-
'objectDir':SUB_TRIGGER'ext', -
'objectDir':SUB_ELOSS'ext', -
'cernlibs' /exe='executeDir':MUTRACK_'archi'
$ purge 'executeDir':*.EXE
$ set on
$ set noverify
$!==============================================================================

16
mutrack/com/LINKMUD.COM Normal file
View File

@ -0,0 +1,16 @@
$ set verify
$ link -
mutrack$directory:[exe]MUTRACK, -
mutrack$directory:[exe]SUB_ARTLIST, -
mutrack$directory:[exe]SUB_INTEGR_KL, -
mutrack$directory:[exe]SUB_INTEGR_Sp, -
mutrack$directory:[exe]SUB_INTEGR_FO, -
mutrack$directory:[exe]SUB_INTEGR_WL, -
mutrack$directory:[exe]SUB_INTEGR_M2, -
mutrack$directory:[exe]SUB_INPUT, -
mutrack$directory:[exe]SUB_PICTURE, -
mutrack$directory:[exe]SUB_OUTPUT,-
mutrack$directory:[exe]SUB_TRIGGER, -
'cernlibs' /debug /exe=mutrack$directory:[exe]MUTRACK
$ purge mutrack$directory:[exe]
$ set noverify

18
mutrack/com/LINKMUT.COM Normal file
View File

@ -0,0 +1,18 @@
$ set verify
$ link -
mutrack$directory:[exe]T-MUTRACK, -
mutrack$directory:[exe]T-SUB_ARTLIST, -
mutrack$directory:[exe]T-SUB_INTEGR_KL, -
mutrack$directory:[exe]T-SUB_INTEGR_Sp, -
mutrack$directory:[exe]T-SUB_INTEGR_NL, -
mutrack$directory:[exe]T-SUB_INTEGR_FO, -
mutrack$directory:[exe]T-SUB_INTEGR_WL, -
mutrack$directory:[exe]T-SUB_INTEGR_M2, -
mutrack$directory:[exe]T-SUB_INPUT, -
mutrack$directory:[exe]T-SUB_PICTURE, -
mutrack$directory:[exe]T-SUB_OUTPUT,-
mutrack$directory:[exe]T-SUB_TRIGGER, -
mutrack$directory:[exe]T-SUB_ELOSS, -
'cernlibs' /exe=mutrack$directory:[exe]T-MUTRACK
$ purge mutrack$directory:[exe]
$ set noverify

46
mutrack/com/LINKMUTV.COM Normal file
View File

@ -0,0 +1,46 @@
$ set verify
$ set noon
$ fortran mutrack$SOURCEdirectory:MUTRACK -
/object=mutrack$EXEdirectory:T-MUTRACK
$ fortran mutrack$SOURCEdirectory:SUB_ARTLIST -
/object=mutrack$EXEdirectory:T-SUB_ARTLIST
$ fortran mutrack$SOURCEdirectory:SUB_INTEGR_KL -
/object=mutrack$EXEdirectory:T-SUB_INTEGR_KL
$ fortran mutrack$SOURCEdirectory:SUB_INTEGR_SP -
/object=mutrack$EXEdirectory:T-SUB_INTEGR_SP
$ fortran mutrack$SOURCEdirectory:SUB_INTEGR_NL -
/object=mutrack$EXEdirectory:T-SUB_INTEGR_NL
$ fortran mutrack$SOURCEdirectory:SUB_INTEGR_FO -
/object=mutrack$EXEdirectory:T-SUB_INTEGR_FO
$ fortran mutrack$SOURCEdirectory:SUB_INTEGR_WL -
/object=mutrack$EXEdirectory:T-SUB_INTEGR_WL
$ fortran mutrack$SOURCEdirectory:SUB_INTEGR_M2 -
/object=mutrack$EXEdirectory:T-SUB_INTEGR_M2
$ fortran mutrack$SOURCEdirectory:SUB_INPUT -
/object=mutrack$EXEdirectory:T-SUB_INPUT
$ fortran mutrack$SOURCEdirectory:SUB_PICTURE -
/object=mutrack$EXEdirectory:T-SUB_PICTURE
$ fortran mutrack$SOURCEdirectory:SUB_OUTPUT -
/object=mutrack$EXEdirectory:T-SUB_OUTPUT
$ fortran mutrack$SOURCEdirectory:SUB_TRIGGER -
/object=mutrack$EXEdirectory:T-SUB_TRIGGER
$ fortran mutrack$SOURCEdirectory:SUB_ELOSS -
/object=mutrack$EXEdirectory:T-SUB_ELOSS
$ link -
mutrack$EXEdirectory:T-MUTRACK, -
mutrack$EXEdirectory:T-SUB_ARTLIST, -
mutrack$EXEdirectory:T-SUB_INTEGR_KL, -
mutrack$EXEdirectory:T-SUB_INTEGR_SP, -
mutrack$EXEdirectory:T-SUB_INTEGR_NL, -
mutrack$EXEdirectory:T-SUB_INTEGR_FO, -
mutrack$EXEdirectory:T-SUB_INTEGR_WL, -
mutrack$EXEdirectory:T-SUB_INTEGR_M2, -
mutrack$EXEdirectory:T-SUB_INPUT, -
mutrack$EXEdirectory:T-SUB_PICTURE, -
mutrack$EXEdirectory:T-SUB_OUTPUT,-
mutrack$EXEdirectory:T-SUB_TRIGGER, -
mutrack$EXEdirectory:T-SUB_ELOSS, -
'cernlibs' /exe=mutrack$EXEdirectory:T-MUTRACK
$ purge mutrack$EXEdirectory
$ set on
$ set noverify

82
mutrack/com/LINKMUV.COM Normal file
View File

@ -0,0 +1,82 @@
$ set noverify
$!==============================================================================
$! Author: Anselm Hofer
$!
$! Commandoprozedur fuer das Compilieren und Linken des kompletten MUTRACK-
$! Quelltextes. Aufzurufen mittels '$ LINKMUV'. ('V' steht fuer 'Vollstaendig').
$!==============================================================================
$ set noon
$!==============================================================================
$ prog= "mutrack"
$ ext = "_MU"
$!==============================================================================
$ sourceDir = "''prog'$SOURCEdirectory"
$ objectDir = "''prog'$OBJdirectory"
$ executeDir = "''prog'$EXEdirectory"
$!==============================================================================
$ options = "/fast /nolist"
$! options = "/fast /nolist /warn=nogeneral"
$!==============================================================================
$ archi = F$GETSYI("ARCH_NAME") ! Host OS either "VAX" or "Alpha"
$ ext = "''ext'_''archi'"
$ if archi .EQS. "VAX" then options = ""
$ if P1 .NES. "" then options = "''options' ''P1'"
$
$ file = "MUTRACK"
$ CALL compile
$ file = "SUB_ARTLIST
$ CALL compile
$ file = "SUB_INTEGR_L1
$ CALL compile
$ file = "SUB_INTEGR_SP
$ CALL compile
$ file = "SUB_INTEGR_L2andFo
$ CALL compile
$ file = "SUB_INTEGR_FO
$ CALL compile
$ file = "SUB_INTEGR_L3
$ CALL compile
$ file = "SUB_INTEGR_M2
$ CALL compile
$ file = "SUB_INPUT
$ CALL compile
$ file = "SUB_PICTURE
$ CALL compile
$ file = "SUB_OUTPUT
$ CALL compile
$ file = "SUB_TRIGGER
$ CALL compile
$ file = "SUB_ELOSS"
$ CALL compile
$!==============================================================================
$ set verify
$ purge 'objectDir':*.OBJ
$ link -
'objectDir':MUTRACK'ext', -
'objectDir':SUB_ARTLIST'ext', -
'objectDir':SUB_INTEGR_L1'ext', -
'objectDir':SUB_INTEGR_SP'ext', -
'objectDir':SUB_INTEGR_L2andFo'ext', -
'objectDir':SUB_INTEGR_FO'ext', -
'objectDir':SUB_INTEGR_L3'ext', -
'objectDir':SUB_INTEGR_M2'ext', -
'objectDir':SUB_INPUT'ext', -
'objectDir':SUB_PICTURE'ext', -
'objectDir':SUB_OUTPUT'ext',-
'objectDir':SUB_TRIGGER'ext', -
'objectDir':SUB_ELOSS'ext', -
'cernlibs' /exe='executeDir':MUTRACK_'archi'
$ purge 'executeDir':*.EXE
$ set on
$ set noverify
$ EXIT
$
$!==============================================================================
$
$ COMPILE: SUBROUTINE
$ comp = "fortran ''sourceDir':''file' ''options' /object=''objectDir':''file'''ext'"
$ write sys$output "=============================================================================="
$ write sys$output "''COMP'"
$ comp
$ ENDSUBROUTINE
$!==============================================================================

38
mutrack/com/LINKMUVD.COM Normal file
View File

@ -0,0 +1,38 @@
$ set verify
$ fortran mutrack$SOURCEdirectory:MUTRACK /warn=nogen -
/check /list /debug /noopt /object=mutrack$EXEdirectory
$ fortran mutrack$SOURCEdirectory:SUB_ARTLIST /warn=nogen -
/check /list /debug /noopt /object=mutrack$EXEdirectory
$ fortran mutrack$SOURCEdirectory:SUB_INTEGR_KL /warn=nogen -
/check /list /debug /noopt /object=mutrack$EXEdirectory
$ fortran mutrack$SOURCEdirectory:SUB_INTEGR_SP /warn=nogen -
/check /list /debug /noopt /object=mutrack$EXEdirectory
$ fortran mutrack$SOURCEdirectory:SUB_INTEGR_FO /warn=nogen -
/check /list /debug /noopt /object=mutrack$EXEdirectory
$ fortran mutrack$SOURCEdirectory:SUB_INTEGR_WL /warn=nogen -
/check /list /debug /noopt /object=mutrack$EXEdirectory
$ fortran mutrack$SOURCEdirectory:SUB_INTEGR_M2 /warn=nogen -
/check /list /debug /noopt /object=mutrack$EXEdirectory
$ fortran mutrack$SOURCEdirectory:SUB_INPUT /warn=nogen -
/check /list /debug /noopt /object=mutrack$EXEdirectory
$ fortran mutrack$SOURCEdirectory:SUB_PICTURE /warn=nogen -
/check /list /debug /noopt /object=mutrack$EXEdirectory
$ fortran mutrack$SOURCEdirectory:SUB_OUTPUT /warn=nogen -
/check /list /debug /noopt /object=mutrack$EXEdirectory
$ fortran mutrack$SOURCEdirectory:SUB_TRIGGER /warn=nogen -
/check /list /debug /noopt /object=mutrack$EXEdirectory
$ link -
mutrack$EXEdirectory:MUTRACK, -
mutrack$EXEdirectory:SUB_ARTLIST, -
mutrack$EXEdirectory:SUB_INTEGR_KL, -
mutrack$EXEdirectory:SUB_INTEGR_SP, -
mutrack$EXEdirectory:SUB_INTEGR_FO, -
mutrack$EXEdirectory:SUB_INTEGR_WL, -
mutrack$EXEdirectory:SUB_INTEGR_M2, -
mutrack$EXEdirectory:SUB_INPUT, -
mutrack$EXEdirectory:SUB_PICTURE, -
mutrack$EXEdirectory:SUB_OUTPUT,-
mutrack$EXEdirectory:SUB_TRIGGER, -
'cernlibs' /debug /exe=mutrack$EXEdirectory:MUTRACK
$ purge mutrack$EXEdirectory
$ set noverify

53
mutrack/com/LINKMUVVD.COM Normal file
View File

@ -0,0 +1,53 @@
$ set verify
$ fortran mutrack$SOURCEdirectory:MUTRACK -
/warn=(noali,decl,gen,inline,trun,uncall,unini,unused,usa,vaxeln) -
/check /list /debug /noopt /object=mutrack$EXEdirectory
$ fortran mutrack$SOURCEdirectory:SUB_ARTLIST -
/warn=(noali,decl,gen,inline,trun,uncall,unini,unused,usa,vaxeln) -
/check /list /debug /noopt /object=mutrack$EXEdirectory
$ fortran mutrack$SOURCEdirectory:SUB_INTEGR_KL -
/warn=(noali,decl,gen,inline,trun,uncall,unini,unused,usa,vaxeln) -
/check /list /debug /noopt /object=mutrack$EXEdirectory
$ fortran mutrack$SOURCEdirectory:SUB_INTEGR_SP -
/warn=(noali,decl,gen,inline,trun,uncall,unini,unused,usa,vaxeln) -
/check /list /debug /noopt /object=mutrack$EXEdirectory
$ fortran mutrack$SOURCEdirectory:SUB_INTEGR_FO -
/warn=(noali,decl,gen,inline,trun,uncall,unini,unused,usa,vaxeln) -
/check /list /debug /noopt /object=mutrack$EXEdirectory
$ fortran mutrack$SOURCEdirectory:SUB_INTEGR_WL -
/warn=(noali,decl,gen,inline,trun,uncall,unini,unused,usa,vaxeln) -
/check /list /debug /noopt /object=mutrack$EXEdirectory
$ fortran mutrack$SOURCEdirectory:SUB_INTEGR_M2 -
/warn=(noali,decl,gen,inline,trun,uncall,unini,unused,usa,vaxeln) -
/check /list /debug /noopt /object=mutrack$EXEdirectory
$ fortran mutrack$SOURCEdirectory:SUB_INPUT -
/warn=(noali,decl,gen,inline,trun,uncall,unini,unused,usa,vaxeln) -
/check /list /debug /noopt /object=mutrack$EXEdirectory
$ fortran mutrack$SOURCEdirectory:SUB_PICTURE -
/warn=(noali,decl,gen,inline,trun,uncall,unini,unused,usa,vaxeln) -
/check /list /debug /noopt /object=mutrack$EXEdirectory
$ fortran mutrack$SOURCEdirectory:SUB_OUTPUT -
/warn=(noali,decl,gen,inline,trun,uncall,unini,unused,usa,vaxeln) -
/check /list /debug /noopt /object=mutrack$EXEdirectory
$ fortran mutrack$SOURCEdirectory:SUB_TRIGGER -
/warn=(noali,decl,gen,inline,trun,uncall,unini,unused,usa,vaxeln) -
/check /list /debug /noopt /object=mutrack$EXEdirectory
$ fortran mutrack$SOURCEdirectory:SUB_ELOSS -
/warn=(noali,decl,gen,inline,trun,uncall,unini,unused,usa,vaxeln) -
/check /list /debug /noopt /object=mutrack$EXEdirectory
$ link -
mutrack$EXEdirectory:MUTRACK, -
mutrack$EXEdirectory:SUB_ARTLIST, -
mutrack$EXEdirectory:SUB_INTEGR_KL, -
mutrack$EXEdirectory:SUB_INTEGR_SP, -
mutrack$EXEdirectory:SUB_INTEGR_FO, -
mutrack$EXEdirectory:SUB_INTEGR_WL, -
mutrack$EXEdirectory:SUB_INTEGR_M2, -
mutrack$EXEdirectory:SUB_INPUT, -
mutrack$EXEdirectory:SUB_PICTURE, -
mutrack$EXEdirectory:SUB_OUTPUT,-
mutrack$EXEdirectory:SUB_TRIGGER, -
mutrack$EXEdirectory:SUB_ELOSS, -
'cernlibs' /debug /exe=mutrack$EXEdirectory:MUTRACK
$ purge mutrack$EXEdirectory
$ set noverify

View File

@ -0,0 +1,99 @@
OPTIONS /EXTEND_SOURCE
c PROGRAM WRITELOG
c ================
c===============================================================================
c Dieses Programm uebernimmt aus der Command Zeile eine Runnummer und
c uebertraegt den Header des zugehoerigen Logfiles in WRITELOG_nnnn.OUT.
c (Arbeitet mit 'WRITELOG.COM' zusammen beim ausdrucken von Fileheadern)
c===============================================================================
IMPLICIT NONE
c Deklarationen fuer das Einlesen der Runnummer von der Commandline:
external cli$get_value
integer cli$get_value
integer status
character*4 runNumber
integer length
c sonstige Deklarationen:
character*80 zeile
integer i, iostat, marke
logical flag
c-------------------------------------------------------------------------------
c Lies Runnummer aus Commandline:
status = cli$get_value('runNumber',runNumber,length)
if (.NOT.status) call lib$signal(%val(status))
call str$trim(runNumber,runNumber,length)
c Oeffne zugehoeriges LOGfile:
open (20,file='mutrack$OUTdirectory:MU_'//runNumber//'.LOG',status='OLD',
+ readonly,iostat=iostat)
if (iostat.NE.0) then
write(*,*)
write(*,*)'can''t find mutrack$OUTdirectory:MU_'//runNumber//'.LOG'
write(*,*)'-> STOP'
write(*,*)
STOP
endif
c Oeffne WRITELOG_nnnn.OUT:
open (21,file='mutrack$OUTdirectory:WRITELOG_'//runNumber//'.OUT',
+ status='NEW')
c Uebertrage die Headerzeilen:
c do i = 1, 130
c read(20,'(A)',end=20) zeile
c write(21,'(xA)') zeile
c enddo
c write(21,*)
c write(21,*)' >>>>>>>>>> AUSDRUCK HIER ABGEBROCHEN >>>>>>>>>>'
c - Teste, ob LOGfile mehr als 140 Zeilen hat. Falls ja, drucke nur den
c Haeder. Andernfalls drucke das ganze Logfile
flag = .false.
marke = -10
do i = 1, 141
read(20,'(A)',end=10) zeile
if (index(Zeile,'>>>>> T E S T - R U N <<<<<').NE.0) marke = i
enddo
flag = .true. ! -> nur Headerzeilen schreiben
10 rewind(20)
do i = 1, 140
read(20,'(A)',end=20) zeile
if (flag .AND. index(Zeile,'>>> Schleife :').NE.0) goto 20
if (i.NE.marke .AND. i.NE.marke+1) then
write(21,'(xA)') zeile
endif
enddo
c Schliesse die Files:
20 close (20)
close (21)
END

View File

@ -0,0 +1,62 @@
$ set noverify
$!==============================================================================
$! Author: Anselm Hofer
$!
$! Commandoprozedur fuer das Erstellen von Dateien 'CODENUMMERN.LIST', welche
$! die von ACCEL bzw. MUTRACK verwendeten Code-Nummern fuer Integrationsgebiet
$! und Teilchenchicksal erstellen. Diese Dateien werden nach den Directories
$! ACCEL$SOURCEdirectory bzw. MUTRACK$SOURCEdirectory kopiert und koennen von
$! VMS-Ebene oder von PAW aus mittels 'ACCODE' bzw. 'MUCODE' ausgegeben werden.
$!
$! Der Aufruf dieser Prozedur fuer das Erstellen der Dateien geschieht ueber
$! MAKEACCODE / MAKEMUCODE.
$!==============================================================================
$ progr = P1 ! = 'MUTRACK' oder 'ACCEL'
$ ext = P2 ! = '_MU' oder '_AC'
$ flag = P3 ! = 'MAKE' oder 'TYPE'
$!==============================================================================
$ sourceFile = "mutrack$COMdirectory:MAKE_CODENUMMERN-LIST.FOR."
$ objectFile = "''progr'$COMdirectory:MAKE''ext'_CODENUMMERN-LIST.OBJ"
$ exeFile = "''progr'$COMdirectory:MAKE''ext'_CODENUMMERN-LIST.EXE"
$ listFile = "''progr'$SOURCEdirectory:CODENUMMERN.LIST"
$!==============================================================================
$ if p3.EQS."MAKE" then goto make
$ if p3.EQS."TYPE" then goto type
$ if p3.EQS." " then write sys$output "missing parameter P3 (""MAKE"" or ""TYPE"")"
$ write sys$output "unknown parameter P3: ''P3'"
$!==============================================================================
$ MAKE:
$! Compilieren und Linken des Programms fuer den Ausdruck der Liste (muss
$! jedesmal neu gemacht werden, damit die Liste wirklich die aktuellen Code-
$! Nummern enthaelt):
$!
$ archi = F$GETSYI("ARCH_NAME") ! Host OS either "VAX" or "Alpha"
$ if archi .EQS. "VAX" then options = " "
$ if archi .EQS. "Alpha" then options = " /ali=all"
$
$ define MAKE_CODENUMMERN_INCFILE1 "''progr'$SOURCEdirectory:COM_''progr'.INC"
$ define MAKE_CODENUMMERN_INCFILE2 "''progr'$SOURCEdirectory:INITIALIZE.INC"
$ set verify
$ fortran 'sourceFile' /object='objectFile' 'options'
$ link 'objectFile' /exe='exeFile'
$ set noverify
$
$ del 'objectFile'.* /nocon
$ pu 'exeFile'
$ deassign MAKE_CODENUMMERN_INCFILE1
$ deassign MAKE_CODENUMMERN_INCFILE2
$
$! Erstellen der Liste durch Aufruf des Programms:
$ tmp == F$TRNLNM("''progr'$SOURCEdirectory")
$ define MAKE_CODENUMMERN_OUTDIR "''TMP'"
$ run 'exeFile'
$ deassign MAKE_CODENUMMERN_OUTDIR
$ purge 'listFile'
$
$ EXIT
$!==============================================================================
$ TYPE:
$! Ausgabe der Liste:
$ TYPE 'listFile'
$ EXIT
$!==============================================================================

View File

@ -0,0 +1,70 @@
OPTIONS /EXTEND_SOURCE
PROGRAM WRITE_CODE_NUMBERS
c ==========================
c dieses Programm erstellt (nach neuem Kompilieren und Linken) eine jeweils
c aktuelle Liste der verwendeten Codenummern fuer die Gebiete und Teilchen-
c schicksale des Programmes 'MUTRACK' oder 'ACCEL':
INCLUDE 'MAKE_CODENUMMERN_INCFILE1'
integer i
character datum*9,uhrzeit*8,helpChar*1
INCLUDE 'MAKE_CODENUMMERN_INCFILE2'
open(20,file='CODENUMMERN.LIST',defaultfile='MAKE_CODENUMMERN_OUTDIR',
+ status='NEW',carriagecontrol='LIST')
call date(datum)
call time(uhrzeit)
write(20,*)'==============================================================================='
write(20,10) datum,uhrzeit
10 format(' Erstellt am ',A,' um ',A,' durch ''MAKE_CODENUMMERN-LIST.FOR''')
write(20,*)
write(20,*)
write(20,*) ' ========================================================='
write(20,*) ' Die Code-Nummern fuer die verschiedenen Gebiete: ''Gebiet'''
write(20,*) ' ========================================================='
write(20,*)
write(20,12) 0, 'auf Moderatorfolie'
do i = 1, Gebiete_Anzahl
indx = index(Gebiet_text(i),':')
if (indx.NE.0) then
write(20,11) i, Gebiet_text(i)(1:indx-1)
else
write(20,11) i, Gebiet_text(i)
endif
enddo
11 format(3x,i3,':'6x,A)
12 format(2x'(',i3,':'6x,A,')')
write(20,*)
write(20,*)
write(20,*) ' =========================================================='
write(20,*) ' Die Code-Nummern der moeglichen Teilchenschicksale: ''dest'''
write(20,*) ' =========================================================='
write(20,*)
do i = smallest_code_Nr, highest_code_Nr
indx = index(code_text(i),':')
if (indx.NE.0) then
write(20,11) i, code_text(i)(1:indx-1)
else
write(20,11) i, code_text(i)
endif
enddo
write(20,*)
write(20,*)'==============================================================================='
close(20)
END

8
mutrack/com/MUTRACK.COM Normal file
View File

@ -0,0 +1,8 @@
$! in case a privious submitted batchjob didn't end properly:
$ FILE = F$SEARCH("SYS$SCRATCH:MUTRACK.MESSAGE")
$ IF FILE .NES. """" THEN DELETE SYS$SCRATCH:MUTRACK.MESSAGE.* /NOCON
$! run mutrack$EXEdirectory:MUTRACK.EXE
$ MUTRACK
$! in case MUTRACK didn't end properly:
$ FILE = F$SEARCH("SYS$SCRATCH:MUTRACK.MESSAGE")
$ IF FILE .NES. """" THEN DELETE SYS$SCRATCH:MUTRACK.MESSAGE.* /NOCON

View File

@ -0,0 +1,36 @@
$!******************************************************************************
$! DIESE KOMMANDOPROZEDUR DEFINIERT ALLGEMEINE LOGICALS UND SYMBOLS FUER DIE
$! ARBEIT MIT MUTRACK (ALS BATCH UND INTERAKTIV)
$!******************************************************************************
$ node = "PSW264"
$
$ define /trans=con mutrackSRC$directory "UD1:[SIMULA.MUTRACK.]
$ define mutrack$COMdirectory "mutrackSRC$directory:[com]"
$ define mutrack$MAPPENdirectory "UD1:[simula.mappen.mutrack]","UD1:[simula.mappen.testmappen]"
$ define mutrack$AHdirectory "accel$OUTdirectory"
$ define mutrack$GEOdirectory "mutrackSRC$directory:[geo_files]"
$ define mutrack$EXEdirectory "mutrackSRC$directory:[exe]"
$ define mutrack$RDdirectory "mutrackSRC$directory:[RD-kumac]"
$!------------------------------------------------------------------------------
$ define mutrack$PHYSICASRCdirectory "UD0:[simula.physica_source.mutrack]"
$!==============================================================================
$ archi = F$GETSYI("ARCH_NAME") ! Host OS either "VAX" or "Alpha"
$ MU*TRACK :== "RUN mutrack$EXEdirectory:MUTRACK_''archi'.EXE"
$ MUDIR :== "dir mutrack$OUTdirectory:MU*.*.*
$ MULIST :== "dir mutrack$OUTdirectory:MU*.LOG.
$ LSEMU :== "LSE mutrack$READdirectory:MUTRACK.INPUT"
$ LSEMUNR :== "LSE mutrack$NRdirectory:mutrack_nr.dat
$ MUGEO :== "SET DEF UD1:[SIMULA.MUTRACK.GEO_FILES]"
$ MUSTAT :== "@ mutrack$COMdirectory:PLOT_BATCH_STATUS MUTRACK MU TRACK"
$ WRITEMULOG :== "@ mutrack$COMdirectory:WRITELOG.COM"
$ MAKEMUCODE :== "@ mutrack$COMdirectory:MAKE_CODENUMMERN-LIST.COM MUTRACK _MU MAKE
$ MUCODE :== "@ mutrack$COMdirectory:MAKE_CODENUMMERN-LIST.COM MUTRACK _MU TYPE
$ MUCOPY :== "@ mutrack$COMdirectory:COPY.COM MUTRACK MU"
$!------------------------------------------------------------------------------
$ SUBMU*TRACK :== -
"SUBMIT/NOTIFY/NOPRINT/NAME=MUTRACK/LOG_FILE=mutrack$OUTdirectory mutrack$COMdirectory:MUTRACK.COM
$ SUBMULIST*BATCH :== "@ mutrack$COMdirectory:SUB_LIST MU MUTRACK ''node'_BATCH"
$ SUBMULISTF*AST :== "@ mutrack$COMdirectory:SUB_LIST MU MUTRACK ''node'_FAST"
$ SUBMULISTS*LOW :== "@ mutrack$COMdirectory:SUB_LIST MU MUTRACK ''node'_SLOW"
$ SUBMULISTD*EAD :== "@ mutrack$COMdirectory:SUB_LIST MU MUTRACK ''node'_DEAD"
$!==============================================================================

View File

@ -0,0 +1,12 @@
$!******************************************************************************
$! DIESE KOMMANDOPROZEDUR DEFINIERT ALLGEMEINE LOGICALS UND SYMBOLS FUER DIE
$! ARBEIT MIT MUTRACK (ALS BATCH UND INTERAKTIV)
$! SIE WIRD VON LOGIN.COM AUS AUFGERUFEN.
$!******************************************************************************
$ define mutrack$directory "UD1:[simula.mutrack.calc]"
$ define mutrack$READdirectory "mutrack$directory"
$ define mutrack$OUTdirectory "mutrack$directory"
$ define mutrack$NrDirectory "mutrack$directory"
$ MUCALC :== "SET DEF mutrack$directory"
$ MUPH*YS :== "SET DEF UD1:[simula.mutrack.physica]"
$!==============================================================================

View File

@ -0,0 +1,28 @@
$!******************************************************************************
$! DIESE KOMMANDOPROZEDUR DEFINIERT SYMBOLS FUER DIE INTERAKTIVE ARBEIT MIT
$! MUTRACK
$! SIE WIRD VON LOGIN.COM AUS AUFGERUFEN.
$!******************************************************************************
$ LSEMU :== "LSE mutrack$READdirectory:mutrack.input
$ MUCALC :== "SET DEF UD1:[SIMULA.MUTRACK.CALC]"
$ MUPH*YS :== "SET DEF UD0:[SIMULA.PHYSICA_SOURCE.MUTRACK]"
$ MUSTAT :== "@ mutrack$COMdirectory:PLOT_BATCH_STATUS.COM MUTRACK MU TRACK"
$ MUGEO :== "SET DEF UD0:[SIMULA.MUTRACK.GEO_FILES]"
$ WRITEMULOG :== "@ mutrack$COMdirectory:WRITELOG.COM"
$!------------------------------------------------------------------------------
$ SUBMU*TRACK :== -
"SUBMIT/NOTIFY/NOPRINT/NAME=MUTRACK/LOG_FILE=mutrack$OUTdirectory mutrack$COMdirectory:MUTRACK.COM"
$ SUBMULIST :== "@ mutrack$COMdirectory:SUB_LIST.COM MU MUTRACK"
$!==============================================================================
$! OBSOLETE:
$ SUBMULIST1 :== -
"SUBMIT/NOTIFY/NOPRINT/QUEUE=PSW264_SLOW/NAME=MU_LIST1/LOG_FILE=mutrack$OUTdirectory mutrack$READdirectory:LIST1.COM"
$ SUBMULIST2 :== -
"SUBMIT/NOTIFY/NOPRINT/QUEUE=PSW264_SLOW/NAME=MU_LIST2/LOG_FILE=mutrack$OUTdirectory mutrack$READdirectory:LIST2.COM"
$ SUBMULIST3 :== -
"SUBMIT/NOTIFY/NOPRINT/QUEUE=PSW264_SLOW/NAME=MU_LIST3/LOG_FILE=mutrack$OUTdirectory mutrack$READdirectory:LIST3.COM"
$ SUBMULIST4 :== -
"SUBMIT/NOTIFY/NOPRINT/QUEUE=PSW264_SLOW/NAME=MU_LIST4/LOG_FILE=mutrack$OUTdirectory mutrack$READdirectory:LIST4.COM"
$ SUBMULIST5 :== -
"SUBMIT/NOTIFY/NOPRINT/QUEUE=PSW264_SLOW/NAME=MU_LIST5/LOG_FILE=mutrack$OUTdirectory mutrack$READdirectory:LIST5.COM"
$!==============================================================================

View File

@ -0,0 +1,22 @@
$!******************************************************************************
$! DIESE KOMMANDOPROZEDUR DEFINIERT LOGICALS UND SYMBOLS FUER DIE PROGRAMMIER-
$! ARBEIT, DAS KOMPILIEREN UND LINKEN VON MUTRACK (INTERAKTIV)
$! SIE WIRD VON LOGIN.COM AUS AUFGERUFEN.
$!******************************************************************************
$ define mutrack$OBJdirectory "mutrackSRC$directory:[EXE]"
$ OLDMU :== "define mutrack$SOURCEdirectory UD1:[SIMULA.MUTRACK.OLD_SOURCE]"
$ NEWMU :== "define mutrack$SOURCEdirectory UD1:[SIMULA.MUTRACK.SOURCE]"
$ NEWMU
$
$ SETMUTEST :== "SET DEF UD1:[SIMULA.MUTRACK.NEWTEST]"
$ MUPHYSRC :== "SET DEF UD0:[simula.physica_source.mutrack]"
$!------------------------------------------------------------------------------
$ MUCOM :== "SET DEF UD1:[SIMULA.MUTRACK.COM]"
$ MUSOURCE :== "SET DEF mutrack$SOURCEdirectory"
$ MUMAP :== "SET DEF mutrack$MAPPENdirectory"
$ FORMU :== "@mutrack$COMdirectory:compile.com MUTRACK _MU "
$ LINKMU :== "@mutrack$COMdirectory:linkmu.com"
$ LINKMUV :== "@mutrack$COMdirectory:linkmuv.com"
$ LINKMUD :== "@mutrack$COMdirectory:linkmud.com"
$ LINKMUVD :== "@mutrack$COMdirectory:linkmuvd.com"
$!==============================================================================

View File

@ -0,0 +1,85 @@
$ SET NOVERIFY
$! P1 = 'PROGR' = PROGRAMMNAME = "MUTRACK" bzw. "ACCEL"
$! P2 = KUERZEL = "MU" bzw. "AC"
$! P3 = OBTIONALER TEIL DES PROGRAMMAUFRUFES = "TRACK" bzw. "CEL"
$!==============================================================================
$! LAEUFT 'PROGR' ALS BATCHJOB, SO WIRD (BEI MEHR ALS EINER SCHLEIFE)
$! DER AKTUELLE NAME DER AUSGABEDATEIEN SOWIE DIE NUMMER DER GERADE
$! ABGEARBEITETEN SCHLEIFE IN EINER DATEI "''PROGR'.MESSAGE" ABGELEGT.
$! MIT DER VORLIEGENDEN KOMMANDOPROZEDUR WIRD DIESE INFORMATION AUS
$! DER .MESSAGE-DATEI AUSGELESEN UND AUF DEN BILDSCHIRM GEGEBEN.
$! AH, 12-JUN-1996
$!==============================================================================
$ SET NOVERIFY
$ SET ON
$ SAY := WRITE SYS$OUTPUT
$ SHOW TIME
$
$ MAXLISTINDX = 20
$
$ FLAG = 0
$ NOTLASTTIME = 1
$ listIndx = 1
$ ON ERROR THEN GOTO READERROR
$
$ LOOP:
$ messageName = "SYS$SCRATCH:''P2'_LIST''listIndx'.MESSAGE"
$
$ FILEOPEN:
$ OPEN/READ/SHARE=WRITE/ERROR=next messagefile 'messageName'
$ flag = 1
$ SAY "================================================================================"
$ IF NOTLASTTIME THEN READ messagefile NUMMER
$ READ messagefile TIME1
$ READ messagefile INPUTNAME
$ READ messagefile FILENAME
$ READ messagefile LOOPINFO
$ READ messagefile TIME2
$ CLOSE messagefile
$ IF NOTLASTTIME
$ THEN
$ SAY "JOB SUBMITTED WITH ""SUB''P2'LIST ''listIndx'"":"
$ ELSE
$ SAY "JOB SUBMITTED WITH ""SUB''P2'*''P3'"":"
$ ENDIF
$ SAY " NAME OF INPUT FILE : ''INPUTNAME'"
$ IF NOTLASTTIME
$ THEN
$ SAY " (''NUMMER'. file in input_file list,''TIME1')"
$ ELSE
$ SAY " (''TIME1')"
$ ENDIF
$ SAY " NAME OF OUTPUT FILES: ''FILENAME'"
$ LOOPINFO = LOOPINFO-" "
$ SAY " ''LOOPINFO'"
$ SAY " (''TIME2')"
$ GOTO next
$ !
$ READERROR:
$ SAY "reading ''messageName'"
$ CLOSE messagefile
$ !
$ NEXT:
$ IF listIndx.LE.maxListIndx
$ THEN
$ listIndx = listIndx + 1
$ IF listIndx.LE.maxListIndx
$ THEN
$ GOTO LOOP
$ ELSE
$ messageName = "SYS$SCRATCH:''P1'.MESSAGE
$ NOTLASTTIME = 0
$ GOTO FILEOPEN
$ ENDIF
$ ELSE
$ IF FLAG.EQ.0
$ THEN
$ SAY " THERE ARE NO APPROPRIATE ''P2'*.MESSAGE-FILES IN SYS$SCRATCH"
$ ELSE
$ SAY "================================================================================"
$ SAY " ( -> SYS$SCRATCH:''P2'*.MESSAGE )"
$ ENDIF
$ ENDIF
$ !
$ SAY "================================================================================"
$ EXIT

View File

@ -0,0 +1,52 @@
options /extend_source
program READ_EVENTNRS
c =====================
implicit none
c-------------------------------------------------------------------------------
c Programm, welches aus dem output eines
c
c $ SEARCH mutrack$outDirectory:MU_nnnn.LOG "MCP2 getroffen" /OUT=SEARCHLIST.TMP
c
c die je Schleife bei einem cut auf MCP2-Treffer in ein NTupel gefuellte
c Anzahl simulierter Events bestimmt.
c-------------------------------------------------------------------------------
INTEGER LOOP,NEVENT,IEVENT
CHARACTER*80 ZEILE
c-------------------------------------------------------------------------------
loop = 0
nEvent = 0
iEvent = 1
open (10,file='SEARCHLIST.TMP',status='old',readonly)
open (11,file='EVENTNRS.TMP',status='unknown')
10 read(10,'(A)',err=999,end=100) ZEILE
read(zeile(48:54),*,err=1000) nEvent
loop = loop + 1
c WRITE(*,*) loop,nEvent,iEvent
write(11,*) loop,nEvent,iEvent
iEvent = iEvent+nEvent
goto 10
100 close(10)
close(11)
call exit
999 write(*,*) 'can''t read from SEARCHLIST.TMP'
write(*,*) 'loop,nEvent,iEvent = ',loop,nEvent,iEvent
call exit
1000 write(*,*)
write(*,*) zeile
write(*,*) zeile(48:54)
end

82
mutrack/com/SUB_LIST.COM Normal file
View File

@ -0,0 +1,82 @@
$!==============================================================================
$! KOMMANDOPROZEDUR FUER DAS SUBMITTEN VON 'INPUTFILE-LISTEN' VON MUTRACK UND
$! ACCEL MITTELS 'SUBMULISTn' BZW. 'SUBACLISTn'.
$!==============================================================================
$! 1. LOESCHE GEGEBENENFALLS DAS .MESSAGE FILE
$! 2. IN DER SCHLEIFE: VERSUCHE DAS .MESSAGE-FILE ZU OEFFNEN
$! 3. GELINGT DIES NICHT, SO WURDE DIE KOMMANDOPROZEDUR GERADE ERST GESTARTET.
$! EIN PROGRAMMDURCHLAUF WIRD DANN AUF JEDEN FALL PORBIERT.
$! 4. LIES BEI NEUEM VERSUCH ERST DIE NUMMER DES ZULETZT ABGEARBEITETEN INPUT-
$! FILES. IST DIESE = 1, SO LOESCHE DAS .MESSAGE FILE UND BEENDE PROZEDUR
$!==============================================================================
$! P1 = KUERZEL DES PROGRAMMES = "MU" bzw. "AC"
$! P2 = PROGRAMMAUFRUF = "MUTRACK" bzw. "ACCEL"
$! P3 = QUEUE
$! P4 = NUMMER DER INPUTLISTE (WAHRSCHEINLICH AUF 1-9 EINGESCHRAENKT)
$! P5 = QUEUE-ENTRY, AUF DEN SYNCHRONISIERT WERDEN SOLL
$!==============================================================================
$! Definition der Filenamen:
$ INPUTLISTNAME = "LIST''P4'"
$ COMFILENAME = "SYS$SCRATCH:'P1'_LIST'P4'.COM"
$ MESSFILENAME = "SYS$SCRATCH:''P1'_LIST''P4'.MESSAGE"
$!
$! Oeffnen des files fuer die zu submittende Kommandoprozedur:
$ FILE = F$SEARCH("''COMFILENAME'")
$ IF FILE .NES. "" THEN DELETE 'COMFILENAME'.* /NOCON
$ OPEN /WRITE comfile 'COMFILENAME'
$ OUT := WRITE COMFILE
$!
$! Erstellen der zu submittenden Kommandoprozedur:
$ OUT "$! DIESE KOMMANDOPROZEDUR WURDE DURCH 'SUB_LIST.COM' ERSTELLT UND WIRD
$ OUT "$! NUR TEMPORAER BENOETIGT, BIS DER DURCH ""$ SUB''P1'LIST ''P4'"" GESTARTETE
$ OUT "$! BATCHJOB ABGEARBEITET IST. BEI NORMALEM ENDE DES BATCHJOBS WIRD DIESES
$ OUT "$! FILE ZUM SCHLUSS GELOESCHT!"
$ OUT "$!=============================================================================
$ OUT "$ SET NOON
$ OUT "$!
$ IF P5 .NES. ""
$ THEN
$ OUT "$ SYNCHRONIZE /ENTRY = ''P5'
$ OUT "$!
$ ENDIF
$ OUT "$ DEFINE/NOLOG INPUTLISTNAME ''INPUTLISTNAME'"
$ OUT "$! in case a privious submitted batchjob didn't end properly:
$ OUT "$ FILE = F$SEARCH(""''MESSFILENAME'"")
$ OUT "$ IF FILE .NES. """" THEN DELETE ''MESSFILENAME'.* /NOCON
$ OUT "$!
$ OUT "$ FIRSTTIME = ""TRUE""
$ OUT "$ LOOP_START:
$ OUT "$ OPEN /SHARE /READ /ERROR=OPEN_ERROR messagefile ''MESSFILENAME'
$ OUT "$ READ messagefile FILENR
$ OUT "$ CLOSE messagefile
$ OUT "$ IF (FILENR.EQ.1) THEN GOTO FINISH
$ OUT "$!
$ OUT "$ PROG_CALL:
$ OUT "$ ''P2'
$ OUT "$ GOTO LOOP_START
$ OUT "$!
$ OUT "$ FINISH:
$ OUT "$ FILE = F$SEARCH(""''MESSFILENAME'"")
$ OUT "$ IF FILE .NES. """" THEN DELETE ''MESSFILENAME'.* /NOCON
$ OUT "$ WRITE SYS$OUTPUT ""''P1'_LIST''P4' FINISHED PROPERLY""
$ OUT "$ EXIT
$ OUT "$!
$ OUT "$!------------------------------------------------------------------------------
$ OUT "$ OPEN_ERROR:
$ OUT "$ IF (FIRSTTIME.EQS.""TRUE"")
$ OUT "$ THEN
$ OUT "$ FIRSTTIME = ""FALSE""
$ OUT "$ GOTO PROG_CALL
$ OUT "$ ELSE
$ OUT "$! in spite of the program has already been run there is no .MESSAGE file
$ OUT "$! => all input files have already been done => exit
$ OUT "$ GOTO FINISH
$ OUT "$ ENDIF
$ OUT "$!------------------------------------------------------------------------------
$ CLOSE COMFILE
$!
$! Submitten der Kommandoprozedur:
$ SUBMIT/DELETE/NOTIFY/NOPRINT/QUEUE='P3'/NAME='P1'LIST'P4' -
/LOG_FILE='P2'$OUTdirectory 'COMFILENAME'
$!
$ EXIT

View File

@ -0,0 +1,3 @@
$ IF P1.NES."" THEN SYNCHRONIZE /ENTRY = ''P1'
$ SUBMIT/NOTIFY/NOPRINT/NAME=MUTRACK/LOG_FILE=mutrack$OUTdirectory -
mutrack$COMdirectory:MUTRACK.COM"

View File

@ -0,0 +1,7 @@
$! in case a privious submitted batchjob didn't end properly:
$ FILE = F$SEARCH("SYS$SCRATCH:MUTRACK.MESSAGE")
$ IF FILE .NES. """" THEN DELETE SYS$SCRATCH:MUTRACK.MESSAGE.* /NOCON
$ run mutrack$EXEdirectory:T-MUTRACK.EXE
$! in case MUTRACK didn't end properly:
$ FILE = F$SEARCH("SYS$SCRATCH:MUTRACK.MESSAGE")
$ IF FILE .NES. """" THEN DELETE SYS$SCRATCH:MUTRACK.MESSAGE.* /NOCON

49
mutrack/com/WRITELOG.COM Normal file
View File

@ -0,0 +1,49 @@
$! KOMMANDOPROZEDUR FUER DEN AUSDRUCK DER HEADERZEILEN VON 'MU_nnnn.LOG'-Dateien
$! =============================================================================
$!
$ SET NOON
$ SET NOVERIFY
$ SAY := WRITE SYS$OUTPUT
$ SET COMMAND mutrack$COMdirectory:DEF_MAKEWRITELOGOUT.CLD
$ ! FILE MIT HEADERZEILEN ERSTELLEN LASSEN:
$ IF P1 .EQS. ""
$ THEN
$ SAY "%WRITELOG: error: NO RUN NUMBER GIVEN IN COMMANDLINE"
$ EXIT
$ ENDIF
$ IF P1 .EQS. "?"
$ THEN
$ SAY " "
$ SAY " WRITEMULOG runNr [destinaton]"
$ SAY " "
$ SAY " destination not specified -> output to screen"
$ SAY " "
$ SAY " accepted destinations are: PSW04, PSW23, PRL, PRL2 (have to be given in upper case!)"
$ SAY " "
$ EXIT
$ ENDIF
$ IF (P2.NES."PSW04" .AND. P2.NES."PSW23" .AND. P2.NES."PRL" .AND. P2.NES."PRL2" .AND. P2.NES."")
$ THEN
$ SAY " "
$ SAY " ""''P2'"" is not an accepted destination!"
$ SAY " accepted destinations are: PSW04, PSW23, PRL, PRL2 (UPPER CASE ONLY!)"
$ SAY " "
$ EXIT
$ ENDIF
$!
$ MAKEWRITELOGOUT "''P1'"
$ OUTFILENAME = "MUTRACK$OUTdirectory:WRITELOG_" + "''P1'" + ".OUT;"
$ say "''outfilename'"
$ IF P2 .EQS. ""
$ THEN
$ TY 'OUTFILENAME'
$ DELETE /NOCON 'OUTFILENAME'
$ WRITE SYS$OUTPUT "================================================================================"
$ EXIT
$ ENDIF
$ IF (P2.EQS."PRL" .OR. P2.EQS."PRL2")
$ THEN
$ PRL2 'OUTFILENAME' /del
$ EXIT
$ ENDIF
$ VPP 'OUTFILENAME' /delete /dev=printer /form=listq /dest= "''P2'"

View File

@ -0,0 +1,144 @@
c===============================================================================
c GEO_KAMMER.INPUT
c===============================================================================
$kammer_geo
!==============================================================================
! 'HORIZONTALER' KAMMERTEIL
!
! hier wird x relativ zum Zentrum der Moderationskammer (=Kryoachse)
! gemessen! (bis auf xgrid1 und xgrid2, die relativ zur Rueckseite
! der Moderatorfolie, also 'xTarget' gemessen werden)
! mit Schleussenkammer
!==============================================================================
! Vakuumrohr:
radius_Rohr = 75.
! Target:
xtarget = 2.0 ! Position RELATIV ZUM KRYO
dytarget = 30.0 ! Breite
dztarget = 30.0 ! Hoehe
! erstes Beschleunigungsgitter:
xgrid1 = 11.0 ! -> ! Position RELATIV ZUM MODERATOR
dygrid1 = 48.0 ! Breite
dzgrid1 = 48.0 ! Hoehe
dist_wires_G1 = 1.0 ! Drahtabstand
dWires_G1 = 0.025 ! Drahtdurchmesser
! zweites Beschleunigungsgitter:
xgrid2 = 20.0 ! -> ! Position RELATIV ZUM MODERATOR
dygrid2 = 48.0 ! Breite
dzgrid2 = 48.0 ! Hoehe
dist_wires_G2 = 1.0 ! Drahtabstand
dWires_G2 = 0.025 ! Drahtdurchmesser
! He-Schild:
rHeShield = 47.25 ! Radius
dyHeShield = 45.0 ! Breite des Fensters
dzHeShield = 45.0 ! Hoehe des Fensters
! LN-Schild:
rLNShield = 52.75 ! Radius
dyLNShield = 45.0 ! Breite des Fensters
dzLNShield = 45.0 ! Hoehe des Fensters
! Linse 1:
xCenterOfLense_L1 = 250.0 ! Position der Linsenmitte
MappenName_L1 = 'L1_1mm_mesh' ! Name der Potentialmappe
! Spiegel:
xSpiegel = 499.0 ! Position (=477.0 + 22.0)
MappenName_Sp = 'mirror' ! Name der Potentialmappe
DreharmLaenge = 11.0 ! horizont. Abstand zwischen
! Aufhaengung und Spiegelmitte
BSpiegel = 114.0 ! Breite
hSpiegel = 100.0 ! Hoehe
DSpiegel = 22.5 ! Tiefe
dist_wires_Sp = 1.0 ! Drahtabstand
dWires_Sp = 0.050 ! Drahtdurchmesser
!==============================================================================
! 'VERTIKALER' KAMMERTEIL
!
! hier wird x relativ zum Zentrum des Doppelkreuzes der Spiegel-
! aufhaengung gemessen!
!==============================================================================
! Linse 2:
xCenterOfLense_L2 = 322 ! Position der Linsenmitte (1/2 Stutzten)
MappenName_L2andFo= 'L2andFo' ! Name der Potentialmappe
! TriggerDetektor: alt: 372.0 Stutzen:+150 alte TK: 250 neue TK: 296
xTD = 545.0 ! Aufhaengung des TDs == Mitte
mappenName_Fo = 'FO_1' ! des Doppelkreuzes
! Linse 3: alt: 714 Stutzen: 150 neue TK:296 neue 1/2Linse:220
! xCenterOfLense_L3 = 714.0 mm MIT eingebautem Triggerdetektor, 384.0 OHNE.
xCenterOfLense_L3 = 913.0 ! Linsenmitte (913.0alt)
MappenName_L3 = 'LENSE-3' ! Name der Potentialmappe
! MCP2:alt 1102.35, Abstand zu Flansch: 170.85
! xMCP2 war MIT eingebautem Triggerdetektor bei 1102.35, OHNE bei 772.35 mm.
! mit Schleussenkammer 161.0 (1328.35 alt)
xMCP2 = 1489.35 ! Position (incl. Reduzier-
! ! flansch mit Dicke 24.5 mm)
radius_MCP2active = 20.0 ! Radius der aktiven Flaeche
MappenName_M2 = 'MCP_RUN9' ! Name der Potentialmappe
$END
c===============================================================================
die Drahtabstaende und -durchmesser der Gitter des Triggerdetektors (in mm):
============================================================================
$trigger_grids
dist_Wires_V1 = 1.500
dWires_V1 = 0.025
dist_Wires_V2 = 1.500
dWires_V2 = 0.025
dist_Wires_V3 = 1.500
dWires_V3 = 0.025
dist_Wires_H1 = 1.500
dWires_H1 = 0.025
dist_Wires_H2 = 1.500
dWires_H2 = 0.025
dist_Wires_G = 1.500
dWires_G = 0.025
$END

View File

@ -0,0 +1,194 @@
c===============================================================================
c GEO_KAMMER.INPUT
c===============================================================================
$kammer_geo
!==============================================================================
! 'HORIZONTALER' KAMMERTEIL
!
! hier wird x relativ zum Zentrum der Moderationskammer (=Kryoachse)
! gemessen! (bis auf xgrid1 und xgrid2, die relativ zur Rueckseite
! der Moderatorfolie, also 'xTarget' gemessen werden)
! mit Schleussenkammer
!==============================================================================
! Vakuumrohr:
radius_Rohr = 75.
! Target:
xtarget = 2.0 ! Position RELATIV ZUM KRYO
dytarget = 30.0 ! Breite
dztarget = 30.0 ! Hoehe
! erstes Beschleunigungsgitter:
xgrid1 = 12.0 ! -> ! Position RELATIV ZUM MODERATOR
dygrid1 = 48.0 ! Breite
dzgrid1 = 48.0 ! Hoehe
dist_wires_G1 = 1.0 ! Drahtabstand
dWires_G1 = 0.025 ! Drahtdurchmesser
! zweites Beschleunigungsgitter:
xgrid2 = 22.0 ! -> ! Position RELATIV ZUM MODERATOR
dygrid2 = 48.0 ! Breite
dzgrid2 = 48.0 ! Hoehe
dist_wires_G2 = 1.0 ! Drahtabstand
dWires_G2 = 0.025 ! Drahtdurchmesser
! He-Schild:
rHeShield = 47.25 ! Radius
dyHeShield = 40.0 ! Breite des Fensters
dzHeShield = 36.0 ! Hoehe des Fensters
! LN-Schild:
rLNShield = 52.75 ! Radius
dyLNShield = 40.0 ! Breite des Fensters
dzLNShield = 36.0 ! Hoehe des Fensters
! Linse 1:
xCenterOfLense_L1 = 250.0 ! Position der Linsenmitte
MappenName_L1 = 'L1_1mm_mesh' ! Name der Potentialmappe
! Spiegel:
xSpiegel = 499.0 ! Position (=477.0 + 22.0)
MappenName_Sp = 'mirror' ! Name der Potentialmappe
DreharmLaenge = 11.0 ! horizont. Abstand zwischen
! Aufhaengung und Spiegelmitte
BSpiegel = 114.0 ! Breite
hSpiegel = 100.0 ! Hoehe
DSpiegel = 22.5 ! Tiefe
dist_wires_Sp = 1.0 ! Drahtabstand
dWires_Sp = 0.050 ! Drahtdurchmesser
!==============================================================================
! 'VERTIKALER' KAMMERTEIL
!
! hier wird x relativ zum Zentrum des Doppelkreuzes der Spiegel-
! aufhaengung gemessen!
!==============================================================================
! Linse 2:
xCenterOfLense_L2 = 267.0 ! Position der Linsenmitte der neuen L2
! Elektroden 50.0 (0V) 60.0 (HV) 100.0 (0V)
! Elektrodenabstaende 12.0
MappenName_L2andFo= 'L2andFo' ! es existiert keine Potentialmappe
! TriggerDetektor: alt: 372.0 Stutzen:+150 alte TK: 250 neue TK: 296
xTD = 586.0 ! Aufhaengung des TDs == Mitte
! Abstand bis auf Folie 534.0
mappenName_Fo = 'FO_1' ! des Doppelkreuzes
! Linse 3
xCenterOfLense_L3 = 1111.0 ! Linsenmitte
MappenName_L3 = 'LENSE-3' ! Name der Potentialmappe
! alter MCP2:
xMCP2 = 1688.0 ! Position MCP
radius_MCP2active = 20.0 ! Radius der aktiven Flaeche
MappenName_M2 = 'MCP_RUN9' ! Name der Potentialmappe
! neuer MCP2:
xMCP2 = 1698.0 ! Position MCP
radius_MCP2active = 23.0 ????? ! Radius der aktiven Flaeche
! es existiert keine Mappe
!
! fuer nachfolgende Teile existieren keine Feldmappen
!
! Ringanode ungesplittet
! vordere Position bei 1623.0
! HV Elektrode
! vorderer Durchmesser: 66.8
! hinterer Durchmesser: 116.0
! gerade Laenge : 90.0
! Neigungswinkel : 16 grad
! 0V Elektrode
! Abstand zu HV Elektrode: 12.0
! Durchmesser : 116.0
! Laenge : 116.0
! Probenplatte Kryostat:
! nachfolgende Masse beziehen sich auf die Montage des Saphirs mit D = 6.0mm
! wird der Saphir nicht verwendet, muessen die Positionen entsprechend korrigiert
! werden
! 1696.0
! Probenoberflaeche je nach Probendicke bei 1694.0 bis 1696.0
! Durchmesser Probenplatte: 70.0 mm
! Befestigungsring Probe : 1694 bis 1692 (hat eine Dicke von 2.0, Abstand haengt
! von Probendicke ab)
! Oeffnungsdurchmesser : 40.0 oder 45.0 mm
! Aussendurchmesser : 70.0 mm
! Guardringe
! Innendurchmesser : 58.0 mm
! Aussendurchmesser : 70.0 mm
! Dicke : 3.0 mm
! Abstand Guard1 zu
! Probenbefestigungsring : 13.0 mm !oder zu Probenplatte bei s-RG Messungen
! Abstand Guard2 zu
! Probenbefestigungsring : 29.0 mm
! Abstand Erdungsgitter Kuehlschild
! zu Probenbefestigungsring : 48.0 mm !Anstand von Probenplatte aus gemessen
! Anstand Erdungsgitter Kuehlschild - Guardringen bzw. Probenoberflaechen haengt von
! Probendicke ab.
! Position Kuehlplatte (0V) : 1706.0
! Durchmesser : 70.0 mm
! Position Kuehlfinger : 1711.0
! Durchmesser : 55.0 mm
$END
c===============================================================================
die Drahtabstaende und -durchmesser der Gitter des Triggerdetektors (in mm):
============================================================================
$trigger_grids
dist_Wires_V1 = 1.500
dWires_V1 = 0.025
dist_Wires_V2 = 1.500
dWires_V2 = 0.025
dist_Wires_V3 = 1.500
dWires_V3 = 0.025
dist_Wires_H1 = 1.500
dWires_H1 = 0.025
dist_Wires_H2 = 1.500
dWires_H2 = 0.025
dist_Wires_G = 1.500
dWires_G = 0.025
$END

View File

@ -0,0 +1,202 @@
c===============================================================================
c GEO_KAMMER.INPUT
c
c nov-dec 1999 EM+HG NOT FINAL: modified to analyse ELOSS data of run12
c xcenterODLense_L2 use old value 322. instead of new 267.
c xTD use old value 545. instead of 586.
c otherwise mutrack has run time error
c potential map of L2 still for old (run10) dimensions
c ring anode not included
c
c===============================================================================
$kammer_geo
!==============================================================================
! 'HORIZONTALER' KAMMERTEIL
!
! hier wird x relativ zum Zentrum der Moderationskammer (=Kryoachse)
! gemessen! (bis auf xgrid1 und xgrid2, die relativ zur Rueckseite
! der Moderatorfolie, also 'xTarget' gemessen werden)
! mit Schleussenkammer
!==============================================================================
! Vakuumrohr:
radius_Rohr = 75.
! Target:
xtarget = 2.0 ! Position RELATIV ZUM KRYO
dytarget = 30.0 ! Breite
dztarget = 30.0 ! Hoehe
! erstes Beschleunigungsgitter:
xgrid1 = 12.0 ! -> ! Position RELATIV ZUM MODERATOR
dygrid1 = 48.0 ! Breite
dzgrid1 = 48.0 ! Hoehe
dist_wires_G1 = 1.0 ! Drahtabstand
dWires_G1 = 0.025 ! Drahtdurchmesser
! zweites Beschleunigungsgitter:
xgrid2 = 22.0 ! -> ! Position RELATIV ZUM MODERATOR
dygrid2 = 48.0 ! Breite
dzgrid2 = 48.0 ! Hoehe
dist_wires_G2 = 1.0 ! Drahtabstand
dWires_G2 = 0.025 ! Drahtdurchmesser
! He-Schild:
rHeShield = 47.25 ! Radius
dyHeShield = 40.0 ! Breite des Fensters
dzHeShield = 36.0 ! Hoehe des Fensters
! LN-Schild:
rLNShield = 52.75 ! Radius
dyLNShield = 40.0 ! Breite des Fensters
dzLNShield = 36.0 ! Hoehe des Fensters
! Linse 1:
xCenterOfLense_L1 = 250.0 ! Position der Linsenmitte
MappenName_L1 = 'L1_1mm_mesh' ! Name der Potentialmappe
! Spiegel:
xSpiegel = 499.0 ! Position (=477.0 + 22.0)
MappenName_Sp = 'mirror' ! Name der Potentialmappe
DreharmLaenge = 11.0 ! horizont. Abstand zwischen
! Aufhaengung und Spiegelmitte
BSpiegel = 114.0 ! Breite
hSpiegel = 100.0 ! Hoehe
DSpiegel = 22.5 ! Tiefe
dist_wires_Sp = 1.0 ! Drahtabstand
dWires_Sp = 0.050 ! Drahtdurchmesser
!==============================================================================
! 'VERTIKALER' KAMMERTEIL
!
! hier wird x relativ zum Zentrum des Doppelkreuzes der Spiegel-
! aufhaengung gemessen!
!==============================================================================
! Linse 2:
xCenterOfLense_L2 = 322. ! should be 267.0 ! Position der Linsenmitte der neuen L2
! Elektroden 50.0 (0V) 60.0 (HV) 100.0 (0V)
! Elektrodenabstaende 12.0
MappenName_L2andFo= 'L2andFo' ! es existiert keine Potentialmappe
! TriggerDetektor: alt: 372.0 Stutzen:+150 alte TK: 250 neue TK: 296
xTD = 545. ! should be 586.0 ! Aufhaengung des TDs == Mitte
! Abstand bis auf Folie 534.0
mappenName_Fo = 'FO_1' ! des Doppelkreuzes
! Linse 3
xCenterOfLense_L3 = 1111.0 ! Linsenmitte
MappenName_L3 = 'LENSE-3' ! Name der Potentialmappe
! alter MCP2:
xMCP2 = 1688.0 ! Position MCP
radius_MCP2active = 20.0 ! Radius der aktiven Flaeche
MappenName_M2 = 'MCP_RUN9' ! Name der Potentialmappe
! neuer MCP2:
xMCP2 = 1698.0 ! Position MCP
radius_MCP2active = 23.0 ????? ! Radius der aktiven Flaeche
! es existiert keine Mappe
!
! fuer nachfolgende Teile existieren keine Feldmappen
!
! Ringanode ungesplittet
! vordere Position bei 1623.0
! HV Elektrode
! vorderer Durchmesser: 66.8
! hinterer Durchmesser: 116.0
! gerade Laenge : 90.0
! Neigungswinkel : 16 grad
! 0V Elektrode
! Abstand zu HV Elektrode: 12.0
! Durchmesser : 116.0
! Laenge : 116.0
! Probenplatte Kryostat:
! nachfolgende Masse beziehen sich auf die Montage des Saphirs mit D = 6.0mm
! wird der Saphir nicht verwendet, muessen die Positionen entsprechend korrigiert
! werden
! 1696.0
! Probenoberflaeche je nach Probendicke bei 1694.0 bis 1696.0
! Durchmesser Probenplatte: 70.0 mm
! Befestigungsring Probe : 1694 bis 1692 (hat eine Dicke von 2.0, Abstand haengt
! von Probendicke ab)
! Oeffnungsdurchmesser : 40.0 oder 45.0 mm
! Aussendurchmesser : 70.0 mm
! Guardringe
! Innendurchmesser : 58.0 mm
! Aussendurchmesser : 70.0 mm
! Dicke : 3.0 mm
! Abstand Guard1 zu
! Probenbefestigungsring : 13.0 mm !oder zu Probenplatte bei s-RG Messungen
! Abstand Guard2 zu
! Probenbefestigungsring : 29.0 mm
! Abstand Erdungsgitter Kuehlschild
! zu Probenbefestigungsring : 48.0 mm !Anstand von Probenplatte aus gemessen
! Anstand Erdungsgitter Kuehlschild - Guardringen bzw. Probenoberflaechen haengt von
! Probendicke ab.
! Position Kuehlplatte (0V) : 1706.0
! Durchmesser : 70.0 mm
! Position Kuehlfinger : 1711.0
! Durchmesser : 55.0 mm
$END
c===============================================================================
die Drahtabstaende und -durchmesser der Gitter des Triggerdetektors (in mm):
============================================================================
$trigger_grids
dist_Wires_V1 = 1.500
dWires_V1 = 0.025
dist_Wires_V2 = 1.500
dWires_V2 = 0.025
dist_Wires_V3 = 1.500
dWires_V3 = 0.025
dist_Wires_H1 = 1.500
dWires_H1 = 0.025
dist_Wires_H2 = 1.500
dWires_H2 = 0.025
dist_Wires_G = 1.500
dWires_G = 0.025
$END

View File

@ -0,0 +1,109 @@
c===============================================================================
c GEO_KAMMER_run2.INPUT
c
c vgl.: LB. 2, S. 78 - 80 (mittlerer Arm entfernt)
c LB. 6, S. 113
c LB. EM A2, S. 39 - 41
c===============================================================================
$kammer_geo
!==============================================================================
! 'HORIZONTALER' KAMMERTEIL
!
! hier wird x relativ zum Zentrum der Moderationskammer (=Kryoachse)
! gemessen!
!==============================================================================
! Vakuumrohr:
radius_Rohr = 75.
! Target:
xtarget = -6.5 ! Position RELATIV ZUM KRYO
dytarget = 24.0 ! Breite
dztarget = 16.0 ! Hoehe
! erstes Beschleunigungsgitter:
xgrid1 = 9.5 ! Position RELATIV ZUM MODERATOR
dygrid1 = 32.0 ! Breite
dzgrid1 = 32.0 ! Hoehe
dist_wires_G1 = 0.5 ! Drahtabstand
dWires_G1 = 0.050 ! Drahtdurchmesser
! zweites Beschleunigungsgitter:
xgrid2 = 20.0 ! Position RELATIV ZUM MODERATOR
dygrid2 = 42.0 ! Breite
dzgrid2 = 42.0 ! Hoehe
dist_wires_G2 = 1.0 ! Drahtabstand
dWires_G2 = 0.050 ! Drahtdurchmesser
! He-Schild:
rHeShield = 38.5 ! Radius vom Schild
dyHeShield = 28.0 ! Breite
dzHeShield = 20.0 ! Hoehe
! LN-Schild:
rLNShield = 45.5 ! Radius
dyLNShield = 28.0 ! Breite
dzLNShield = 20.0 ! Hoehe
! Linse 1:
xCenterOfLense_L1 = 250.0 ! Position der Linsenmitte
MappenName_L1 = 'L1_1mm_mesh' ! Name der Potentialmappe
! Spiegel:
xSpiegel = 477.0 ! Position
MappenName_Sp = 'mirror' ! Name der Potentialmappe
DreharmLaenge = 0.0 ! horizont. Abstand zwischen
! Aufhaengung und Spiegelmitte
BSpiegel = 114.0 ! Breite
hSpiegel = 100.0 ! Hoehe
DSpiegel = 22.0 ! Tiefe
dist_wires_Sp = 1.0 ! Drahtabstand
dWires_Sp = 0.050 ! Drahtdurchmesser
!==============================================================================
! 'VERTIKALER' KAMMERTEIL
!
! hier wird x relativ zum Zentrum des Doppelkreuzes der Spiegel-
! aufhaengung gemessen!
!==============================================================================
! Linse 3:
xCenterOfLense_L3 = 225.0 ! Position der Linsenmitte
MappenName_L3 = 'L3_1mm_mesh' ! Name der Potentialmappe
! MCP2:
xMCP2 = 524.0 ! Position
radius_MCP2active = 20.0 ! Radius der aktiven Flaeche
MappenName_M2 = 'MCP_run2' ! Name der Potentialmappe
$END
c===============================================================================
=> Gesamtlaenge zwischen Target und MCP2 front: 6.5 + 477 + 524 = 1007.5
c===============================================================================

View File

@ -0,0 +1,109 @@
c===============================================================================
c GEO_KAMMER_RUN3-4.INPUT
c
c EM: 22.2.96 Abstaende fuer Runs 3 und 4
c (kein TriggerDetektor, Tgt-Dimensionen = 24 x 16 mm^2)
c Abstaende aus LB EM A2/p45. Siehe auch LB8/p203,LB9/p3
c===============================================================================
$kammer_geo
!==============================================================================
! 'HORIZONTALER' KAMMERTEIL
!
! hier wird x relativ zum Zentrum der Moderationskammer (=Kryoachse)
! gemessen!
!==============================================================================
! Vakuumrohr:
radius_Rohr = 75.
! Target:
xtarget = -6.5 ! Position RELATIV ZUM KRYO
dytarget = 24.0 ! Breite
dztarget = 16.0 ! Hoehe
! erstes Beschleunigungsgitter:
xgrid1 = 9.5 ! Position RELATIV ZUM MODERATOR
dygrid1 = 32.0 ! Breite
dzgrid1 = 32.0 ! Hoehe
dist_wires_G1 = 0.5 ! Drahtabstand
dWires_G1 = 0.050 ! Drahtdurchmesser
! zweites Beschleunigungsgitter:
xgrid2 = 20.0 ! Position RELATIV ZUM MODERATOR
dygrid2 = 42.0 ! Breite
dzgrid2 = 42.0 ! Hoehe
dist_wires_G2 = 1.0 ! Drahtabstand
dWires_G2 = 0.050 ! Drahtdurchmesser
! He-Schild:
rHeShield = 38.5 ! Radius vom Schild
dyHeShield = 28.0 ! Breite
dzHeShield = 20.0 ! Hoehe
! LN-Schild:
rLNShield = 45.5 ! Radius
dyLNShield = 28.0 ! Breite
dzLNShield = 20.0 ! Hoehe
! Linse 1:
xCenterOfLense_L1 = 250.0 ! Position der Linsenmitte
MappenName_L1 = 'L1_1mm_mesh' ! Name der Potentialmappe
! Spiegel:
xSpiegel = 477.0 ! Position
MappenName_Sp = 'mirror' ! Name der Potentialmappe
DreharmLaenge = 0.0 ! horizont. Abstand zwischen
! Aufhaengung und Spiegelmitte
BSpiegel = 114.0 ! Breite
hSpiegel = 100.0 ! Hoehe
DSpiegel = 22.0 ! Tiefe
dist_wires_Sp = 1.0 ! Drahtabstand
dWires_Sp = 0.050 ! Drahtdurchmesser
!==============================================================================
! 'VERTIKALER' KAMMERTEIL
!
! hier wird x relativ zum Zentrum des Doppelkreuzes der Spiegel-
! aufhaengung gemessen!
!==============================================================================
! Linse 3:
xCenterOfLense_L3 = 384.0 ! Position der Linsenmitte
MappenName_L3 = 'L3_1mm_mesh' ! Name der Potentialmappe
! MCP2:
xMCP2 = 772.35 ! Position
radius_MCP2active = 20.0 ! Radius der aktiven Flaeche
MappenName_M2 = 'M2_1' ! Name der Potentialmappe
$END
c===============================================================================
=> Gesamtlaenge zwischen Target und MCP2 front: 6.5 + 477 + 772.35 = 1255.85
c===============================================================================

View File

@ -0,0 +1,115 @@
c===============================================================================
c GEO_KAMMER_run6-8.INPUT
c===============================================================================
$kammer_geo
!==============================================================================
! 'HORIZONTALER' KAMMERTEIL
!
! hier wird x relativ zum Zentrum der Moderationskammer (=Kryoachse)
! gemessen! (bis auf xgrid1 und xgrid2, die relativ zur Rueckseite
! der Moderatorfolie, also 'xTarget' gemessen werden)
!
!==============================================================================
! Vakuumrohr:
radius_Rohr = 75.
! Target:
xtarget = 3.5 ! Position RELATIV ZUM KRYO
dytarget = 30.0 ! Breite
dztarget = 30.0 ! Hoehe
! erstes Beschleunigungsgitter:
xgrid1 = 9.5 ! Position RELATIV ZUM MODERATOR
dygrid1 = 32.0 ! Breite
dzgrid1 = 32.0 ! Hoehe
dist_wires_G1 = 0.5 ! Drahtabstand
dWires_G1 = 0.050 ! Drahtdurchmesser
! zweites Beschleunigungsgitter:
xgrid2 = 20.0 ! Position RELATIV ZUM MODERATOR
dygrid2 = 42.0 ! Breite
dzgrid2 = 42.0 ! Hoehe
dist_wires_G2 = 1.0 ! Drahtabstand
dWires_G2 = 0.050 ! Drahtdurchmesser
! He-Schild:
rHeShield = 38.5 ! Radius
dyHeShield = 36.0 ! Breite des Fensters
dzHeShield = 36.0 ! Hoehe des Fensters
! LN-Schild:
rLNShield = 45.5 ! Radius
dyLNShield = 36.0 ! Breite des Fensters
dzLNShield = 36.0 ! Hoehe des Fensters
! Linse 1:
xCenterOfLense_L1 = 250.0 ! Position der Linsenmitte
MappenName_L1 = 'L1_1mm_mesh' ! Name der Potentialmappe
! Spiegel:
xSpiegel = 477.0 ! Position
MappenName_Sp = 'mirror' ! Name der Potentialmappe
DreharmLaenge = 0.0 ! horizont. Abstand zwischen
! Aufhaengung und Spiegelmitte
BSpiegel = 114.0 ! Breite
hSpiegel = 100.0 ! Hoehe
DSpiegel = 22.0 ! Tiefe
dist_wires_Sp = 1.0 ! Drahtabstand
dWires_Sp = 0.050 ! Drahtdurchmesser
!==============================================================================
! 'VERTIKALER' KAMMERTEIL
!
! hier wird x relativ zum Zentrum des Doppelkreuzes der Spiegel-
! aufhaengung gemessen!
!==============================================================================
! TriggerDetektor:
xTD = 372.0 ! Aufhaengung des TDs == Mitte
mappenName_Fo = 'FO_1' ! des Doppelkreuzes
! Linse 3:
xCenterOfLense_L3 = 714.0 ! Position der Linsenmitte
MappenName_L3 = 'L3_1mm_mesh' ! Name der Potentialmappe
! MCP2:
xMCP2 = 1102.35 ! Position
radius_MCP2active = 20.0 ! Radius der aktiven Flaeche
MappenName_M2 = 'M2_1' ! Name der Potentialmappe
$END
c===============================================================================
=> Gesamtlaenge zwischen Target und MCP2 front: -3.5 + 477 + 1102.35 = 1575.85
c===============================================================================

View File

@ -0,0 +1,118 @@
c===============================================================================
c GEO_KAMMER_run7_LONG.INPUT
c===============================================================================
Dieses File enthaelt die Kammergeometrie waehrend run 7 mit Rohrverlaengerung
zur Messung des Energieverlustes der Myonen in der TD-Folie
$kammer_geo
!==============================================================================
! 'HORIZONTALER' KAMMERTEIL
!
! hier wird x relativ zum Zentrum der Moderationskammer (=Kryoachse)
! gemessen! (bis auf xgrid1 und xgrid2, die relativ zur Rueckseite
! der Moderatorfolie, also 'xTarget' gemessen werden)
!
!==============================================================================
! Vakuumrohr:
radius_Rohr = 75.
! Target:
xtarget = 3.5 ! Position RELATIV ZUM KRYO
dytarget = 30.0 ! Breite
dztarget = 30.0 ! Hoehe
! erstes Beschleunigungsgitter:
xgrid1 = 9.5 ! -> ! Position RELATIV ZUM MODERATOR
dygrid1 = 32.0 ! Breite
dzgrid1 = 32.0 ! Hoehe
dist_wires_G1 = 0.5 ! Drahtabstand
dWires_G1 = 0.050 ! Drahtdurchmesser
! zweites Beschleunigungsgitter:
xgrid2 = 20.0 ! -> ! Position RELATIV ZUM MODERATOR
dygrid2 = 42.0 ! Breite
dzgrid2 = 42.0 ! Hoehe
dist_wires_G2 = 1.0 ! Drahtabstand
dWires_G2 = 0.050 ! Drahtdurchmesser
! He-Schild:
rHeShield = 38.5 ! Radius
dyHeShield = 36.0 ! Breite des Fensters
dzHeShield = 36.0 ! Hoehe des Fensters
! LN-Schild:
rLNShield = 45.5 ! Radius
dyLNShield = 36.0 ! Breite des Fensters
dzLNShield = 36.0 ! Hoehe des Fensters
! Linse 1:
xCenterOfLense_L1 = 250.0 ! Position der Linsenmitte
MappenName_L1 = 'L1_1mm_mesh' ! Name der Potentialmappe
! Spiegel:
xSpiegel = 477.0 ! Position
MappenName_Sp = 'mirror' ! Name der Potentialmappe
DreharmLaenge = 0.0 ! horizont. Abstand zwischen
! Aufhaengung und Spiegelmitte
BSpiegel = 114.0 ! Breite
hSpiegel = 100.0 ! Hoehe
DSpiegel = 22.0 ! Tiefe
dist_wires_Sp = 1.0 ! Drahtabstand
dWires_Sp = 0.050 ! Drahtdurchmesser
!==============================================================================
! 'VERTIKALER' KAMMERTEIL
!
! hier wird x relativ zum Zentrum des Doppelkreuzes der Spiegel-
! aufhaengung gemessen!
!==============================================================================
! TriggerDetektor:
xTD = 372.0 ! Aufhaengung des TDs == Mitte
mappenName_Fo = 'FO_1' ! des Doppelkreuzes
! Linse 3:
xCenterOfLense_L3 = 714.0 ! Position der Linsenmitte
MappenName_L3 = 'L3_1mm_mesh' ! Name der Potentialmappe
! MCP2:
xMCP2 = 1537.35 ! Position
radius_MCP2active = 20.0 ! Radius der aktiven Flaeche
MappenName_M2 = 'M2_1' ! Name der Potentialmappe
$END
c===============================================================================
=> Gesamtlaenge zwischen Target und MCP2 front: -3.5 + 477 + 1537.35 = 2010.85
c===============================================================================

View File

@ -0,0 +1,113 @@
c===============================================================================
c GEO_KAMMER.INPUT
c===============================================================================
$kammer_geo
!==============================================================================
! 'HORIZONTALER' KAMMERTEIL
!
! hier wird x relativ zum Zentrum der Moderationskammer (=Kryoachse)
! gemessen! (bis auf xgrid1 und xgrid2, die relativ zur Rueckseite
! der Moderatorfolie, also 'xTarget' gemessen werden)
!
!==============================================================================
! Vakuumrohr:
radius_Rohr = 75.
! Target:
xtarget = 3.5 ! Position RELATIV ZUM KRYO
dytarget = 30.0 ! Breite
dztarget = 30.0 ! Hoehe
! erstes Beschleunigungsgitter:
xgrid1 = 9.5 ! -> ! Position RELATIV ZUM MODERATOR
dygrid1 = 32.0 ! Breite
dzgrid1 = 32.0 ! Hoehe
dist_wires_G1 = 0.5 ! Drahtabstand
dWires_G1 = 0.050 ! Drahtdurchmesser
! zweites Beschleunigungsgitter:
xgrid2 = 20.0 ! -> ! Position RELATIV ZUM MODERATOR
dygrid2 = 42.0 ! Breite
dzgrid2 = 42.0 ! Hoehe
dist_wires_G2 = 1.0 ! Drahtabstand
dWires_G2 = 0.050 ! Drahtdurchmesser
! He-Schild:
rHeShield = 38.5 ! Radius
dyHeShield = 36.0 ! Breite des Fensters
dzHeShield = 36.0 ! Hoehe des Fensters
! LN-Schild:
rLNShield = 45.5 ! Radius
dyLNShield = 36.0 ! Breite des Fensters
dzLNShield = 36.0 ! Hoehe des Fensters
! Linse 1:
xCenterOfLense_L1 = 250.0 ! Position der Linsenmitte
MappenName_L1 = 'L1_1mm_mesh' ! Name der Potentialmappe
! Spiegel:
xSpiegel = 499.0 ! Position (=477.0 + 22.0)
MappenName_Sp = 'mirror' ! Name der Potentialmappe
DreharmLaenge = 11.0 ! horizont. Abstand zwischen
! Aufhaengung und Spiegelmitte
BSpiegel = 114.0 ! Breite
hSpiegel = 100.0 ! Hoehe
DSpiegel = 22.5 ! Tiefe
dist_wires_Sp = 1.0 ! Drahtabstand
dWires_Sp = 0.050 ! Drahtdurchmesser
!==============================================================================
! 'VERTIKALER' KAMMERTEIL
!
! hier wird x relativ zum Zentrum des Doppelkreuzes der Spiegel-
! aufhaengung gemessen!
!==============================================================================
! TriggerDetektor: alt: 372.0 Stutzen:+150 alte TK: 250 neue TK: 296
xTD = 545.0 ! Aufhaengung des TDs == Mitte
mappenName_Fo = 'FO_1' ! des Doppelkreuzes
! Linse 3: alt: 714 Stutzen: 150 neue TK:296 neue 1/2Linse:220
! xCenterOfLense_L3 = 714.0 mm MIT eingebautem Triggerdetektor, 384.0 OHNE.
xCenterOfLense_L3 = 913.0 ! Position der Linsenmitte
MappenName_L3 = 'LENSE-3' ! Name der Potentialmappe
! MCP2:alt 1102.35, Abstand zu Flansch: 170.85
! xMCP2 war MIT eingebautem Triggerdetektor bei 1102.35, OHNE bei 772.35 mm.
xMCP2 = 1328.35 ! Position (incl. Reduzier-
! ! flansch mit Dicke 24.5 mm)
radius_MCP2active = 20.0 ! Radius der aktiven Flaeche
MappenName_M2 = 'MCP_RUN9' ! Name der Potentialmappe
$END
c===============================================================================

View File

@ -0,0 +1,113 @@
c===============================================================================
c GEO_KAMMER.INPUT
c===============================================================================
$kammer_geo
!==============================================================================
! 'HORIZONTALER' KAMMERTEIL
!
! hier wird x relativ zum Zentrum der Moderationskammer (=Kryoachse)
! gemessen! (bis auf xgrid1 und xgrid2, die relativ zur Rueckseite
! der Moderatorfolie, also 'xTarget' gemessen werden)
!
!==============================================================================
! Vakuumrohr:
radius_Rohr = 75.
! Target:
xtarget = 3.5 ! Position RELATIV ZUM KRYO
dytarget = 30.0 ! Breite
dztarget = 30.0 ! Hoehe
! erstes Beschleunigungsgitter:
xgrid1 = 9.5 ! -> ! Position RELATIV ZUM MODERATOR
dygrid1 = 32.0 ! Breite
dzgrid1 = 32.0 ! Hoehe
dist_wires_G1 = 0.5 ! Drahtabstand
dWires_G1 = 0.050 ! Drahtdurchmesser
! zweites Beschleunigungsgitter:
xgrid2 = 20.0 ! -> ! Position RELATIV ZUM MODERATOR
dygrid2 = 42.0 ! Breite
dzgrid2 = 42.0 ! Hoehe
dist_wires_G2 = 1.0 ! Drahtabstand
dWires_G2 = 0.050 ! Drahtdurchmesser
! He-Schild:
rHeShield = 38.5 ! Radius
dyHeShield = 36.0 ! Breite des Fensters
dzHeShield = 36.0 ! Hoehe des Fensters
! LN-Schild:
rLNShield = 45.5 ! Radius
dyLNShield = 36.0 ! Breite des Fensters
dzLNShield = 36.0 ! Hoehe des Fensters
! Linse 1:
xCenterOfLense_L1 = 250.0 ! Position der Linsenmitte
MappenName_L1 = 'L1_1mm_mesh' ! Name der Potentialmappe
! Spiegel:
xSpiegel = 499.0 ! Position (=477.0 + 22.0)
MappenName_Sp = 'mirror' ! Name der Potentialmappe
DreharmLaenge = 11.0 ! horizont. Abstand zwischen
! Aufhaengung und Spiegelmitte
BSpiegel = 114.0 ! Breite
hSpiegel = 100.0 ! Hoehe
DSpiegel = 22.5 ! Tiefe
dist_wires_Sp = 1.0 ! Drahtabstand
dWires_Sp = 0.050 ! Drahtdurchmesser
!==============================================================================
! 'VERTIKALER' KAMMERTEIL
!
! hier wird x relativ zum Zentrum des Doppelkreuzes der Spiegel-
! aufhaengung gemessen!
!==============================================================================
! TriggerDetektor: alt: 372.0 Stutzen:+150 alte TK: 250 neue TK: 296
xTD = 545.0 ! Aufhaengung des TDs == Mitte
mappenName_Fo = 'FO_1' ! des Doppelkreuzes
! Linse 3: alt: 714 Stutzen: 150 neue TK:296 neue 1/2Linse:220
! xCenterOfLense_L3 = 714.0 mm MIT eingebautem Triggerdetektor, 384.0 OHNE.
xCenterOfLense_L3 = 913.0 ! Position der Linsenmitte
MappenName_L3 = 'LENSE-3' ! Name der Potentialmappe
! MCP2:alt 1102.35, Abstand zu Flansch: 170.85
! xMCP2 war MIT eingebautem Triggerdetektor bei 1102.35, OHNE bei 772.35 mm.
xMCP2 = 1328.35 ! Position (incl. Reduzier-
! ! flansch mit Dicke 24.5 mm)
radius_MCP2active = 20.0 ! Radius der aktiven Flaeche
MappenName_M2 = 'MCP2_RUN9_NEW' ! Name der Potentialmappe
$END
c===============================================================================

View File

@ -0,0 +1,139 @@
c===============================================================================
c GEO_KAMMER.INPUT
c===============================================================================
$kammer_geo
!==============================================================================
! 'HORIZONTALER' KAMMERTEIL
!
! hier wird x relativ zum Zentrum der Moderationskammer (=Kryoachse)
! gemessen! (bis auf xgrid1 und xgrid2, die relativ zur Rueckseite
! der Moderatorfolie, also 'xTarget' gemessen werden)
!
!==============================================================================
! Der Zeitnullpunkt fuer M2S1 ab Run 1097 wurde auf 1803.3 festgelegt, der-
! jenige fuer M3S1 auf 1788.1. Um bei diesen Werten optimale Uebereinstimmung
! zwischen simulierten und experimentellen Peakpositionen in M3S1 und M2S1 zu
! erhalten mussten die Flugstrecken FUER MYONEN zwischen Target und Trigger-
! detektor um 7.5 mm sowie zwischen Target und MCP2 um 4.9 mm gegenueber den
! urspruenglich verwendeten Werten verlaengert werden. Die Flugstrecke zwischen
! Triggerdetektor und MCP2 wurde also um 2.6 mm verkuerzt.
!
! Die entsprechenden Flugstreckenaenderungen FUER PROTONEN betragen 6.0 mm
! fuer M3S1 und 4.8 mm fuer M2S1 (=> -1.2 mm fuer M3M2).
!
! Diese Datei enthaelt die resultierenden Werte fuer die Myonen:
! Eingefuegt wurden:
!
! +2.5 mm zwischen Tgt und L1
! +2.5 mm zwischen L1 und Spiegel
! +2.5 mm zwischen Spiegel und TD
! -1.3 mm zwischen TD und L3 -2.3
! -1.3 mm zwischen L3 und MCP2 -0.3
! Vakuumrohr:
radius_Rohr = 75.
! Target:
xtarget = 3.5 ! Position RELATIV ZUM KRYO
dytarget = 30.0 ! Breite
dztarget = 30.0 ! Hoehe
! erstes Beschleunigungsgitter:
xgrid1 = 9.5 ! -> ! Position RELATIV ZUM MODERATOR
dygrid1 = 32.0 ! Breite
dzgrid1 = 32.0 ! Hoehe
dist_wires_G1 = 0.5 ! Drahtabstand
dWires_G1 = 0.050 ! Drahtdurchmesser
! zweites Beschleunigungsgitter:
xgrid2 = 20.0 ! -> ! Position RELATIV ZUM MODERATOR
dygrid2 = 42.0 ! Breite
dzgrid2 = 42.0 ! Hoehe
dist_wires_G2 = 1.0 ! Drahtabstand
dWires_G2 = 0.050 ! Drahtdurchmesser
! He-Schild:
rHeShield = 38.5 ! Radius
dyHeShield = 36.0 ! Breite des Fensters
dzHeShield = 36.0 ! Hoehe des Fensters
! LN-Schild:
rLNShield = 45.5 ! Radius
dyLNShield = 36.0 ! Breite des Fensters
dzLNShield = 36.0 ! Hoehe des Fensters
! Linse 1:
! xCenterOfLense_L1 = 250.0 ! Position der Linsenmitte
xCenterOfLense_L1 = 252.5 ! Position der Linsenmitte
MappenName_L1 = 'L1_1mm_mesh' ! Name der Potentialmappe
! Spiegel:
! xSpiegel = 499.0 ! Position (=477.0 + 22.0)
xSpiegel = 504.0 ! Position (=477.0 + 22.0)
MappenName_Sp = 'mirror' ! Name der Potentialmappe
DreharmLaenge = 11.0 ! horizont. Abstand zwischen
! Aufhaengung und Spiegelmitte
BSpiegel = 114.0 ! Breite
hSpiegel = 100.0 ! Hoehe
DSpiegel = 22.5 ! Tiefe
dist_wires_Sp = 1.0 ! Drahtabstand
dWires_Sp = 0.050 ! Drahtdurchmesser
!==============================================================================
! 'VERTIKALER' KAMMERTEIL
!
! hier wird x relativ zum Zentrum des Doppelkreuzes der Spiegel-
! aufhaengung gemessen!
!==============================================================================
! TriggerDetektor: alt: 372.0 Stutzen:+150 alte TK: 250 neue TK: 296
! xTD = 545.0 ! Aufhaengung des TDs == Mitte
xTD = 547.5 ! Aufhaengung des TDs == Mitte
mappenName_Fo = 'FO_1' ! des Doppelkreuzes
! Linse 3: alt: 714 Stutzen: 150 neue TK:296 neue 1/2Linse:220
! xCenterOfLense_L3 = 714.0 mm MIT eingebautem Triggerdetektor, 384.0 OHNE.
! xCenterOfLense_L3 = 913.0 ! Position der Linsenmitte
! xCenterOfLense_L3 = 914.2 ! Position der Linsenmitte
xCenterOfLense_L3 = 913.2 ! Position der Linsenmitte
MappenName_L3 = 'LENSE-3' ! Name der Potentialmappe
! MCP2:alt 1102.35, Abstand zu Flansch: 170.85
! xMCP2 war MIT eingebautem Triggerdetektor bei 1102.35, OHNE bei 772.35 mm.
! xMCP2 = 1328.35 ! Position (incl. Reduzier-
xMCP2 = 1328.25 ! Position (incl. Reduzier-
! ! flansch mit Dicke 24.5 mm)
radius_MCP2active = 20.0 ! Radius der aktiven Flaeche
MappenName_M2 = 'MCP2_RUN9_NEW' ! Name der Potentialmappe
$END
c===============================================================================

View File

@ -0,0 +1,148 @@
c===============================================================================
c GEO_KAMMER.INPUT
c===============================================================================
$kammer_geo
!==============================================================================
! 'HORIZONTALER' KAMMERTEIL
!
! hier wird x relativ zum Zentrum der Moderationskammer (=Kryoachse)
! gemessen! (bis auf xgrid1 und xgrid2, die relativ zur Rueckseite
! der Moderatorfolie, also 'xTarget' gemessen werden)
!
!==============================================================================
! Der Zeitnullpunkt fuer M2S1 ab Run 1097 wurde auf 1803.3 festgelegt, der-
! jenige fuer M3S1 auf 1788.1. Um bei diesen Werten optimale Uebereinstimmung
! zwischen simulierten und experimentellen Peakpositionen in M3S1 und M2S1 zu
! erhalten mussten die Flugstrecken FUER PROTONEN zwischen Target und Trigger-
! detektor um 6.0 mm sowie zwischen Target und MCP2 um 4.8 mm gegenueber den
! urspruenglich verwendeten Werten verlaengert werden. Die Flugstrecke zwischen
! Triggerdetektor und MCP2 wurde also um 1.2 mm verkuerzt.
!
! Die entsprechenden Flugstreckenaenderungen FUER MYONEN betragen 7.5 mm
! fuer M3S1 und 4.9 mm fuer M2S1 (=> -2.6 mm fuer M3M2).
!
! Diese Datei enthaelt die resultierenden Werte fuer die Protonen:
! Eingefuegt wurden:
!
! +2.0 mm zwischen Tgt und L1
! +2.0 mm zwischen L1 und Spiegel
! +2.0 mm zwischen Spiegel und TD
! -0.6 mm zwischen TD und L3 -2.3
! -0.6 mm zwischen L3 und MCP2 -0.3
! Wegen Meldung
! "Potentialmappen von Linse 3 und MCP2 ueberlappen!
! Dies ist in der aktuellen Implementierung des Programmes
! nicht vorgesehen!"
! musste die L3-Mappe anschliessend um 3 mm zum TD hin verschoben werden, um
! den Ueberlapp wieder zu aufzuheben!
! Vakuumrohr:
radius_Rohr = 75.
! Target:
xtarget = 3.5 ! Position RELATIV ZUM KRYO
dytarget = 30.0 ! Breite
dztarget = 30.0 ! Hoehe
! erstes Beschleunigungsgitter:
xgrid1 = 9.5 ! -> ! Position RELATIV ZUM MODERATOR
dygrid1 = 32.0 ! Breite
dzgrid1 = 32.0 ! Hoehe
dist_wires_G1 = 0.5 ! Drahtabstand
dWires_G1 = 0.050 ! Drahtdurchmesser
! zweites Beschleunigungsgitter:
xgrid2 = 20.0 ! -> ! Position RELATIV ZUM MODERATOR
dygrid2 = 42.0 ! Breite
dzgrid2 = 42.0 ! Hoehe
dist_wires_G2 = 1.0 ! Drahtabstand
dWires_G2 = 0.050 ! Drahtdurchmesser
! He-Schild:
rHeShield = 38.5 ! Radius
dyHeShield = 36.0 ! Breite des Fensters
dzHeShield = 36.0 ! Hoehe des Fensters
! LN-Schild:
rLNShield = 45.5 ! Radius
dyLNShield = 36.0 ! Breite des Fensters
dzLNShield = 36.0 ! Hoehe des Fensters
! Linse 1:
! xCenterOfLense_L1 = 250.0 ! Position der Linsenmitte
xCenterOfLense_L1 = 252.0 ! Position der Linsenmitte
MappenName_L1 = 'L1_1mm_mesh' ! Name der Potentialmappe
! Spiegel:
! xSpiegel = 499.0 ! Position (=477.0 + 22.0)
xSpiegel = 503.0 ! Position (=477.0 + 22.0)
MappenName_Sp = 'mirror' ! Name der Potentialmappe
DreharmLaenge = 11.0 ! horizont. Abstand zwischen
! Aufhaengung und Spiegelmitte
BSpiegel = 114.0 ! Breite
hSpiegel = 100.0 ! Hoehe
DSpiegel = 22.5 ! Tiefe
dist_wires_Sp = 1.0 ! Drahtabstand
dWires_Sp = 0.050 ! Drahtdurchmesser
!==============================================================================
! 'VERTIKALER' KAMMERTEIL
!
! hier wird x relativ zum Zentrum des Doppelkreuzes der Spiegel-
! aufhaengung gemessen!
!==============================================================================
! TriggerDetektor: alt: 372.0 Stutzen:+150 alte TK: 250 neue TK: 296
! xTD = 545.0 ! Aufhaengung des TDs == Mitte
xTD = 547.0 ! Aufhaengung des TDs == Mitte
mappenName_Fo = 'FO_1' ! des Doppelkreuzes
! Linse 3: alt: 714 Stutzen: 150 neue TK:296 neue 1/2Linse:220
! xCenterOfLense_L3 = 714.0 mm MIT eingebautem Triggerdetektor, 384.0 OHNE.
! xCenterOfLense_L3 = 913.0 ! Position der Linsenmitte
! xCenterOfLense_L3 = 914.4 ! Position der Linsenmitte
xCenterOfLense_L3 = 914.1 ! Position der Linsenmitte
MappenName_L3 = 'LENSE-3' ! Name der Potentialmappe
! MCP2:alt 1102.35, Abstand zu Flansch: 170.85
! xMCP2 war MIT eingebautem Triggerdetektor bei 1102.35, OHNE bei 772.35 mm.
! xMCP2 = 1328.35 ! Position (incl. Reduzier-
! xMCP2 = 1328.15 ! Position (incl. Reduzier-
xMCP2 = 1329.15 ! Position (incl. Reduzier-
! ! flansch mit Dicke 24.5 mm)
radius_MCP2active = 20.0 ! Radius der aktiven Flaeche
MappenName_M2 = 'MCP2_RUN9_NEW' ! Name der Potentialmappe
$END
c===============================================================================

View File

@ -0,0 +1,138 @@
c===============================================================================
c GEO_KAMMER.INPUT
c===============================================================================
$kammer_geo
!==============================================================================
! 'HORIZONTALER' KAMMERTEIL
!
! hier wird x relativ zum Zentrum der Moderationskammer (=Kryoachse)
! gemessen! (bis auf xgrid1 und xgrid2, die relativ zur Rueckseite
! der Moderatorfolie, also 'xTarget' gemessen werden)
!
!==============================================================================
! Der Zeitnullpunkt fuer M2S1 ab Run 1097 wurde auf 1803.3 festgelegt, der-
! jenige fuer M3S1 auf 1788.1. Um bei diesen Werten optimale Uebereinstimmung
! zwischen simulierten und experimentellen Peakpositionen in M3S1 und M2S1 zu
! erhalten mussten die Flugstrecken FUER PROTONEN zwischen Target und Trigger-
! detektor um 6.0 mm sowie zwischen Target und MCP2 um 4.8 mm gegenueber den
! urspruenglich verwendeten Werten verlaengert werden. Die Flugstrecke zwischen
! Triggerdetektor und MCP2 wurde also um 1.2 mm verkuerzt.
!
! Die entsprechenden Flugstreckenaenderungen FUER MYONEN betragen 7.5 mm
! fuer M3S1 und 4.9 mm fuer M2S1 (=> -2.6 mm fuer M3M2).
!
! Diese Datei enthaelt die resultierenden Werte fuer die Protonen:
! Eingefuegt wurden:
!
! +2.0 mm zwischen Tgt und L1
! +2.0 mm zwischen L1 und Spiegel
! +2.0 mm zwischen Spiegel und TD
! -1.1 mm zwischen TD und L3 -2.3
! -1.1 mm zwischen L3 und MCP2 -0.3
! Vakuumrohr:
radius_Rohr = 75.
! Target:
xtarget = 3.5 ! Position RELATIV ZUM KRYO
dytarget = 30.0 ! Breite
dztarget = 30.0 ! Hoehe
! erstes Beschleunigungsgitter:
xgrid1 = 9.5 ! -> ! Position RELATIV ZUM MODERATOR
dygrid1 = 32.0 ! Breite
dzgrid1 = 32.0 ! Hoehe
dist_wires_G1 = 0.5 ! Drahtabstand
dWires_G1 = 0.050 ! Drahtdurchmesser
! zweites Beschleunigungsgitter:
xgrid2 = 20.0 ! -> ! Position RELATIV ZUM MODERATOR
dygrid2 = 42.0 ! Breite
dzgrid2 = 42.0 ! Hoehe
dist_wires_G2 = 1.0 ! Drahtabstand
dWires_G2 = 0.050 ! Drahtdurchmesser
! He-Schild:
rHeShield = 38.5 ! Radius
dyHeShield = 36.0 ! Breite des Fensters
dzHeShield = 36.0 ! Hoehe des Fensters
! LN-Schild:
rLNShield = 45.5 ! Radius
dyLNShield = 36.0 ! Breite des Fensters
dzLNShield = 36.0 ! Hoehe des Fensters
! Linse 1:
! xCenterOfLense_L1 = 250.0 ! Position der Linsenmitte
xCenterOfLense_L1 = 252.0 ! Position der Linsenmitte
MappenName_L1 = 'L1_1mm_mesh' ! Name der Potentialmappe
! Spiegel:
! xSpiegel = 499.0 ! Position (=477.0 + 22.0)
xSpiegel = 503.0 ! Position (=477.0 + 22.0)
MappenName_Sp = 'mirror' ! Name der Potentialmappe
DreharmLaenge = 11.0 ! horizont. Abstand zwischen
! Aufhaengung und Spiegelmitte
BSpiegel = 114.0 ! Breite
hSpiegel = 100.0 ! Hoehe
DSpiegel = 22.5 ! Tiefe
dist_wires_Sp = 1.0 ! Drahtabstand
dWires_Sp = 0.050 ! Drahtdurchmesser
!==============================================================================
! 'VERTIKALER' KAMMERTEIL
!
! hier wird x relativ zum Zentrum des Doppelkreuzes der Spiegel-
! aufhaengung gemessen!
!==============================================================================
! TriggerDetektor: alt: 372.0 Stutzen:+150 alte TK: 250 neue TK: 296
! xTD = 545.0 ! Aufhaengung des TDs == Mitte
xTD = 547.0 ! Aufhaengung des TDs == Mitte
mappenName_Fo = 'FO_1' ! des Doppelkreuzes
! Linse 3: alt: 714 Stutzen: 150 neue TK:296 neue 1/2Linse:220
! xCenterOfLense_L3 = 714.0 mm MIT eingebautem Triggerdetektor, 384.0 OHNE.
! xCenterOfLense_L3 = 913.0 ! Position der Linsenmitte
xCenterOfLense_L3 = 913.9 ! Position der Linsenmitte
MappenName_L3 = 'LENSE-3' ! Name der Potentialmappe
! MCP2:alt 1102.35, Abstand zu Flansch: 170.85
! xMCP2 war MIT eingebautem Triggerdetektor bei 1102.35, OHNE bei 772.35 mm.
! xMCP2 = 1328.35 ! Position (incl. Reduzier-
xMCP2 = 1328.15 ! Position (incl. Reduzier-
! ! flansch mit Dicke 24.5 mm)
radius_MCP2active = 20.0 ! Radius der aktiven Flaeche
MappenName_M2 = 'MCP2_RUN9_NEW' ! Name der Potentialmappe
$END
c===============================================================================

View File

@ -0,0 +1,144 @@
c===============================================================================
c GEO_KAMMER.INPUT
c===============================================================================
$kammer_geo
!==============================================================================
! 'HORIZONTALER' KAMMERTEIL
!
! hier wird x relativ zum Zentrum der Moderationskammer (=Kryoachse)
! gemessen! (bis auf xgrid1 und xgrid2, die relativ zur Rueckseite
! der Moderatorfolie, also 'xTarget' gemessen werden)
! mit Schleussenkammer
!==============================================================================
! Vakuumrohr:
radius_Rohr = 75.
! Target:
xtarget = 2.0 ! Position RELATIV ZUM KRYO
dytarget = 30.0 ! Breite
dztarget = 30.0 ! Hoehe
! erstes Beschleunigungsgitter:
xgrid1 = 11.0 ! -> ! Position RELATIV ZUM MODERATOR
dygrid1 = 48.0 ! Breite
dzgrid1 = 48.0 ! Hoehe
dist_wires_G1 = 1.0 ! Drahtabstand
dWires_G1 = 0.025 ! Drahtdurchmesser
! zweites Beschleunigungsgitter:
xgrid2 = 20.0 ! -> ! Position RELATIV ZUM MODERATOR
dygrid2 = 48.0 ! Breite
dzgrid2 = 48.0 ! Hoehe
dist_wires_G2 = 1.0 ! Drahtabstand
dWires_G2 = 0.025 ! Drahtdurchmesser
! He-Schild:
rHeShield = 47.25 ! Radius
dyHeShield = 45.0 ! Breite des Fensters
dzHeShield = 45.0 ! Hoehe des Fensters
! LN-Schild:
rLNShield = 52.75 ! Radius
dyLNShield = 45.0 ! Breite des Fensters
dzLNShield = 45.0 ! Hoehe des Fensters
! Linse 1:
xCenterOfLense_L1 = 250.0 ! Position der Linsenmitte
MappenName_L1 = 'L1_1mm_mesh' ! Name der Potentialmappe
! Spiegel:
xSpiegel = 499.0 ! Position (=477.0 + 22.0)
MappenName_Sp = 'mirror' ! Name der Potentialmappe
DreharmLaenge = 11.0 ! horizont. Abstand zwischen
! Aufhaengung und Spiegelmitte
BSpiegel = 114.0 ! Breite
hSpiegel = 100.0 ! Hoehe
DSpiegel = 22.5 ! Tiefe
dist_wires_Sp = 1.0 ! Drahtabstand
dWires_Sp = 0.050 ! Drahtdurchmesser
!==============================================================================
! 'VERTIKALER' KAMMERTEIL
!
! hier wird x relativ zum Zentrum des Doppelkreuzes der Spiegel-
! aufhaengung gemessen!
!==============================================================================
! Linse 2:
xCenterOfLense_L2 = 322 ! Position der Linsenmitte (1/2 Stutzten)
MappenName_L2andFo= 'L2andFo' ! Name der Potentialmappe
! TriggerDetektor: alt: 372.0 Stutzen:+150 alte TK: 250 neue TK: 296
xTD = 545.0 ! Aufhaengung des TDs == Mitte
mappenName_Fo = 'FO_1' ! des Doppelkreuzes
! Linse 3: alt: 714 Stutzen: 150 neue TK:296 neue 1/2Linse:220
! xCenterOfLense_L3 = 714.0 mm MIT eingebautem Triggerdetektor, 384.0 OHNE.
xCenterOfLense_L3 = 913.0 ! Linsenmitte (913.0alt)
MappenName_L3 = 'LENSE-3' ! Name der Potentialmappe
! MCP2:alt 1102.35, Abstand zu Flansch: 170.85
! xMCP2 war MIT eingebautem Triggerdetektor bei 1102.35, OHNE bei 772.35 mm.
! mit Schleussenkammer 161.0 (1328.35 alt)
xMCP2 = 1506 ! Probenposition im Kryo
! ! flansch mit Dicke 24.5 mm)
radius_MCP2active = 22.5 ! Radius der aktiven Flaeche
MappenName_M2 = 'MCP_RUN9' ! Name der Potentialmappe
$END
c===============================================================================
die Drahtabstaende und -durchmesser der Gitter des Triggerdetektors (in mm):
============================================================================
$trigger_grids
dist_Wires_V1 = 1.500
dWires_V1 = 0.025
dist_Wires_V2 = 1.500
dWires_V2 = 0.025
dist_Wires_V3 = 1.500
dWires_V3 = 0.025
dist_Wires_H1 = 1.500
dWires_H1 = 0.025
dist_Wires_H2 = 1.500
dWires_H2 = 0.025
dist_Wires_G = 1.500
dWires_G = 0.025
$END

View File

@ -0,0 +1,52 @@
===============================================================================
Erstellt am 17-JAN-99 um 17:51:38 durch 'MAKE_CODENUMMERN-LIST.FOR'
=========================================================
Die Code-Nummern fuer die verschiedenen Gebiete: 'Gebiet'
=========================================================
( 0: auf Moderatorfolie)
1: in 1. Beschl.Stufe
2: in 2. Beschl.Stufe
3: bis He-Schild
4: bis LN-Schild
5: vor Linse-1-Mappe
6: in Linse-1-Mappe
7: bis Spiegel
8: im Spiegel
9: bis Koordinatenwechsel
10: vor Linse-2-Mappe
11: in Linse-2-Mappe
12: bis TriggerDetektor
13: im TriggerDetektor
14: vor Linse-3-Mappe
15: in Linse-3-Mappe
16: zwischen Linse-3-Mappe und MCP2-Mappe
17: vor MCP2
==========================================================
Die Code-Nummern der moeglichen Teilchenschicksale: 'dest'
==========================================================
-10: in Triggerfolie gestoppt
-9: Targethalter getroffen
-8: ACCEL
-7: ACCEL
-6: auf Rand des MCP2
-5: auf Blende des MCP2
-4: von MCP3 nicht registriert
-3: im TD abgebrochen
-2: Folienstuetzgitter getr.
-1: Spiegel durchquert
0: MCP2 getroffen
1: zerfallen
2: Element verfehlt
3: reflektiert
4: auf Gitter getroffen
5: aufgeschlagen
6: verloren (steps>maxsteps)
7: Zeitschritt kleiner dtSmall
===============================================================================

16
mutrack/src/COM_DIRS.INC Normal file
View File

@ -0,0 +1,16 @@
c-------------------------------------------------------------------------------
c Die verwendeten Directories
c-------------------------------------------------------------------------------
character*(*) MappenDir,TP_Dir,ACCEL_Dir,readDir,outDir,NrDir
character*(*) TMPDIR,geoDIR
parameter (MappenDir = 'mutrack$mappenDirectory' )
parameter (TP_Dir = 'mutrack$TPdirectory' )
parameter (ACCEL_Dir = 'mutrack$AHdirectory' )
parameter (readDir = 'mutrack$READdirectory' )
parameter (geoDir = 'mutrack$GEOdirectory' )
parameter (outDir = 'mutrack$OUTdirectory' )
parameter (NrDir = 'mutrack$NrDirectory' )
parameter (TMPDir = 'SYS$SCRATCH' )

224
mutrack/src/COM_KAMMER.INC Normal file
View File

@ -0,0 +1,224 @@
c===============================================================================
c COM_KAMMER.INC
c===============================================================================
c Veraenderungen in diesem File sind nur mit angemessener Vorsicht vorzunehmen!
c Die Groessen, die sich auf Bereiche beziehen, in denen mittels Potentialmappen
c integriert wird (und die in anderen COMMON-Bloecken als dem 'blank'-Block
c stehen) werden in den include files 'MAP_DEF_xx.INC' nochmals mit anderen
c Bezeichnungen definiert (ohne die Extensionen '_L1','_L2','_L3','_FO' und '_M2').
c Auch sind die dort definierten COMMON-Bloecke umfassender als die hier
c angegebenen Teilbereiche. Daher muessen Aenderungen in dem vorliegenden File
c im Regelfall von entsprechenden Aenderungen in diesen Files begleitet werden!
c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
c Vakuumrohr:
real radius_Rohr ! Radius
c Target:
real xtarget ! Position
real dytarget ! Breite
real dztarget ! Hoehe
c erstes Beschleunigungsgitter:
real xgrid1 ! Position
real dygrid1 ! Breite
real dzgrid1 ! Hoehe
real dWires_G1 ! Drahtdurchmesser
real dist_Wires_G1 ! Drahtabstand
c zweites Beschleunigungsgitter:
real xgrid2 ! Position
real dygrid2 ! Breite
real dzgrid2 ! Hoehe
real dWires_G2 ! Drahtdurchmesser
real dist_Wires_G2 ! Drahtabstand
c He-Schild:
real rHeShield ! Radius
real dyHeShield ! Breite
real dzHeShield ! Hoehe
c LN-Schild:
real rLNShield ! Radius
real dyLNShield ! Breite
real dzLNShield ! Hoehe
c Linse 1:
real Beschl_Faktor_L1
COMMON /Beschl_Faktor_L1/ Beschl_Faktor_L1
character*40 MappenName_L1 /' '/
real dl_max_L1
COMMON /integration_L1/ MappenName_L1,dl_max_L1
real xCenterOfLense_L1
real xEnterMap_L1
real xLeaveMap_L1
COMMON /integration_L1/ xCenterOfLense_L1,xEnterMap_L1,xLeaveMap_L1
real DistanceCyl_L1
real iRadiusCyl_L1
real LengthOuterCyl_L1
real oRadiusOuterCyl_L1
real LengthInnerCyl_L1
real oRadiusInnerCyl_L1
real RadiusVacTube_L1
COMMON /integration_L1/ DistanceCyl_L1,iRadiusCyl_L1
COMMON /integration_L1/ LengthOuterCyl_L1,oRadiusOuterCyl_L1
COMMON /integration_L1/ LengthInnerCyl_L1,oRadiusInnerCyl_L1
COMMON /integration_L1/ RadiusVacTube_L1
c Spiegel:
real Beschl_Faktor_Sp
COMMON /Beschl_Faktor_Sp/ Beschl_Faktor_Sp
character*40 MappenName_Sp /' '/
real dl_max_Sp
COMMON /integration_Sp/ MappenName_Sp,dl_max_Sp
real xSpGrid1,xSpGrid2 ! Gitterpositionen innerhalb der Mappe [mm]
real DSpiegel ! Abstand der Spiegelgitter
real dWires_Sp ! Drahtdurchmesser
real dist_Wires_Sp ! Drahtabstand
COMMON /integration_Sp/ xSpGrid1,xSpGrid2,DSpiegel,
* dWires_Sp,dist_Wires_Sp
real xmin_Sp_1,xmax_Sp_1
real xmin_Sp_2,xmax_Sp_2
real xmin_Sp_3,xmax_Sp_3
COMMON /integration_SP_1/ xmin_Sp_1,xmax_Sp_1
COMMON /integration_SP_2/ xmin_Sp_2,xmax_Sp_2
COMMON /integration_SP_3/ xmin_Sp_3,xmax_Sp_3
real xSpiegel ! Position
real DreharmLaenge ! horizontaler Abstand zwischen Spielgel-
! aufhaengung und Spiegelmittelpkt.
real BSpiegel ! Breite
real hSpiegel ! Hoehe
c Linse 2:
character*40 MappenName_L2andFo /' '/
real dl_max_L2andFo
COMMON /integration_L2andFo/ MappenName_L2andFo,dl_max_L2andFo
real xCenterOfLense_L2,xEndLense_L2
real xEnterMap_L2andFo
real xLeaveMap_L2andFo
COMMON /integration_L2andFo/ xCenterOfLense_L2,xEndLense_L2,
+ xEnterMap_L2andFo,xLeaveMap_L2andFo
real DistanceCyl_L2
real iRadiusCyl_L2
real LengthOuterCyl_L2
real oRadiusOuterCyl_L2
real LengthInnerCyl_L2
real oRadiusInnerCyl_L2
real RadiusVacTube_L2
COMMON /integration_L2andFo/ DistanceCyl_L2,iRadiusCyl_L2
COMMON /integration_L2andFo/ LengthOuterCyl_L2,oRadiusOuterCyl_L2
COMMON /integration_L2andFo/ LengthInnerCyl_L2,oRadiusInnerCyl_L2
COMMON /integration_L2andFo/ RadiusVacTube_L2
c Triggerdetektor:
real Beschl_Faktor_Fo
COMMON /Beschl_Faktor_Fo/ Beschl_Faktor_Fo
character*40 MappenName_Fo /' '/
real dl_max_Fo
real MappenLaenge_Fo
real xEnterMap_Fo
COMMON /integration_Fo/ MappenName_Fo,dl_max_Fo
COMMON /integration_Fo/ MappenLaenge_Fo,xEnterMap_Fo
real xTD,TransTDFoil
c Linse 3:
real Beschl_Faktor_L3
COMMON /Beschl_Faktor_L3/ Beschl_Faktor_L3
character*40 MappenName_L3 /' '/
real dl_max_L3
COMMON /integration_L3/ MappenName_L3,dl_max_L3
real xCenterOfLense_L3
real xEnterMap_L3
real xLeaveMap_L3
COMMON /integration_L3/ xCenterOfLense_L3,xEnterMap_L3,xLeaveMap_L3
real DistanceCyl_L3
real iRadiusCyl_L3
real LengthOuterCyl_L3
real oRadiusOuterCyl_L3
real LengthInnerCyl_L3
real oRadiusInnerCyl_L3
real RadiusVacTube_L3
COMMON /integration_L3/ DistanceCyl_L3,iRadiusCyl_L3
COMMON /integration_L3/ LengthOuterCyl_L3,oRadiusOuterCyl_L3
COMMON /integration_L3/ LengthInnerCyl_L3,oRadiusInnerCyl_L3
COMMON /integration_L3/ RadiusVacTube_L3
c MCP2:
real Beschl_Faktor_M2
COMMON /Beschl_Faktor_M2/ Beschl_Faktor_M2
character*40 MappenName_M2 /' '/
real dl_max_M2
COMMON /integration_M2/ MappenName_M2,dl_max_M2
real xMCP2
real xEnterMap_M2
real radius_MCP2 ! Radius des MCP2
COMMON /integration_M2/ xMCP2,xEnterMap_M2,radius_MCP2
real radius_MCP2active ! Radius der aktiven Flaeche des MCP2
real xBlende ! Position der Blende
real radius_Blende ! Radius der Blende
c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
COMMON /KAMMER_GEO/
+ radius_Rohr,
+ xtarget,dytarget,dztarget,
+ xgrid1,dygrid1,dzgrid1,dWires_G1,dist_Wires_G1,
+ xgrid2,dygrid2,dzgrid2,dWires_G2,dist_Wires_G2,
+ rHeShield,dyHeShield,dzHeShield,
+ rLNShield,dyLNShield,dzLNShield,
+ xSpiegel,DreharmLaenge,BSpiegel,hSpiegel,
+ xTD,TransTDFoil,
+ radius_MCP2active,
+ xBlende,radius_Blende
c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

23
mutrack/src/COM_LUNS.INC Normal file
View File

@ -0,0 +1,23 @@
c===============================================================================
c COM_LUNS.INC
c===============================================================================
c Dieses file legt die von 'MUTRACK' benutzten logischen Einheiten fuer Ein- und
c Ausgabe fest:
integer lunREAD, lunScreen, lunLOG, lunNTP, luNPHYSICA
integer lunTMP, lunFOIL, lunMESSAGE
parameter ( lunREAD = 17 )
parameter ( lunScreen = 6 )
parameter ( lunLOG = 18 )
parameter ( lunNTP = 19 )
parameter ( lunPHYSICA = 20 )
parameter ( lunTMP = 16 )
parameter ( lunFOIL = 15 )
parameter ( lunMESSAGE = 14 )
c Die Tabellenfiles werden entsprechend ihrer Nummer den Ausgabeeinheiten
c (lunPHYSICA + 1) bis (lunPHYSICA + stat_Anzahl) zugeeordnet.

768
mutrack/src/COM_MUTRACK.INC Normal file
View File

@ -0,0 +1,768 @@
c===============================================================================
c COM_MUTRACK.INC
c===============================================================================
c
c Dieses Includefile enthaelt die Deklarationen der meisten Variablen, die
c innerhalb des Programms Mutrack von mehr als einer Routine benoetigt werden
c und daher einem Commonblock zugeordnet sein muessen. Fuer diese Variablen
c wird der unbenannte ('blank') Commonblock verwendet. Dieses file wird in
c fast alle Subroutinen eingebunden (abgesehen von denen, die in der Datei
c SUB_TD.FOR zusammengefasst sind und sich auf die Trajektorienberechnung im
c Bereich des TriggerDetektors beschraenken).
c
cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
c===============================================================================
c I. Konstanten
c===============================================================================
c-------------------------------------------------------------------------------
c Die Versionsnummern
c-------------------------------------------------------------------------------
character*8 version ! Versionsnummer von MUTRACK
parameter ( version = '2.0.1' )
c===============================================================================
character*8 accelVersion /' '/ ! Versionsnummer von ACCEL
integer accelVersionIndx
character*25 mappenNameACCEL
character*8 mutrackVersion /' '/ ! Versionsnummer von 'FoilFile'
integer mutrackVersionIndx
COMMON accelVersion,accelVersionIndx,mutrackVersion,mutrackVersionIndx
COMMON mappenNameACCEL
c===============================================================================
c Ver. 1.4.1: mit richtiger Formel fuer SigmaAufstreu:
c (ausgehend von 'theta1/2 = HWHM' anstatt wie zuvor '.. = FWHM')
c
c Ver. 1.5.1: - Implementierung der neuen Linse 'L2' zwischen Spiegel und TD.
c - Alle Programmstellen in Zusammenhang mit Simulationsfiles
c von TP wurden entfernt. In der Praxis wurde die Moeglichkeit
c nie genutzt und erschwerte bei der Programmpflege die Programmier-
c arbeit. In der Folge wurde auch das logical 'USE_AH' ueber-
c fluessig. Die diesbezgl. Steuerung erfolgt jetzt nur noch
c ueber 'fromScratch', 'use_ACCEL' und 'use_MUTRACK'.
c - Umbenennung einiger Variabler. Speziell wurde die Extension
c '_AH' von Variablen in Zusammenhang mit ACCEL und 'foilfile'
c durch '_prevSim' (fuer PREVious SIMulation) ersetzt.
c - Vorbereitung der Implementierung der Magnetfelder durch Ein-
c fuehren der entsprechenden Schleifenparameter etc. Bis jetzt aber
c ohne jegliche Magnetfeldspezifische Kalkulationen.
c Ver. 1.5.2: - neues Logical 'alfaTgtVertically'
c Ver. 1.5.3: - Fehlerbereinigung: Ab Version 1.5.1 wurden bei Fortfuehrung von
c Foilfiles, welche selbst aus ACCEL-files erzeugt worden sind
c die Trajektoriendaten statt aus dem Foilfile aus dem ACCEL-file
c eingelesen. Auch wurde die Gebietskodierung nicht aktualiesiert
c Ver. 1.5.4: - 27-jan-1997 (AH): 'sigmaS1Fo' und 'smearS1Fo' implementiert
c Ver. 1.5.5: - 02-feb-1997 (AH): implementation of 'E0InterFromFile'
c Ver. 1.5.6: - praktisch gleich Ver. 1.5.5
c Ver. 2.0.0: - mit f-Funktion von Meyer als bessere Winkelaufstreuungs-
c verteilungsfunktion gegenueber bisher verwendeter Gauss-
c foermiger Winkelaufstreuung.
c - Wahlmoeglichkeit zwischen ICRU-Energieverlustdaten fuer
c Graphit (bisher ausschliesslich verwendet) und amorphen
c Kohlenstoff (mit etwas kleinerem mittleren Energieverlust)
c implementiert. (-> logical 'graphitData'). (Es werden wie
c zuvor stets die totalen Stoppingpowerdaten, also elektronisch
c + nuklear, verwendet).
c - Routinen fuer Berechnung der Breite der Energieaufstreuung in
c der Triggerfolie nach Lindhard/Scharff (theoret.) sowie nach
c Yang (semiempirisch) implementiert. Die Routinen beruhen auf
c den (sehr kurzen) Programmen, mit welchen ich die Kurven
c fuer die Diss erstellt habe. Jedoch habe ich nicht mehr aus-
c getestet, ob ich bei der Abaenderung fuer Mutrack alles richtig
c gemacht habe ...
c - Version 2.0.0 ist die letzte von mir erstellte Version.
c Ich hoffe, alles ist mittlerweile einigermassen fehlerfrei und
c ausreichend verstaendlich, so dass die Nachwelt sich bei
c anfaelligen Aenderungen nicht ueber Gebuehr echauffieren muss...
c Gruss, Anselm Hofer ...
c
c - Version 2.0.1: nTuple output contains now position
c information of muons at TD foil as well as
c the position of FE when hitting MCP3
c TP, 18-Oct-2000
c
c===============================================================================
c-------------------------------------------------------------------------------
c Zuteilung der GebietsNummern k (0 <= k <= Gebiete_Anzahl)
c zu den Gebieten
c-------------------------------------------------------------------------------
integer target,upToGrid1,upToGrid2,upToHeShield,
+ upToLNShield,upToL1Map,upToExL1,upToEnSp,upToExSp,
+ upToChKoord,upToL2andFoMap,upToExL2,upToEnTD,upToExTD,
+ upToL3Map,upToExL3,upToM2Map,upToMCP2
c GEBIET 'k'
parameter ( target = 0 ) ! <- zaehlt nicht fuer 'Gebiete_Anzahl'!
parameter ( upToGrid1 = 1 )
parameter ( upToGrid2 = 2 )
parameter ( upToHeShield = 3 )
parameter ( upToLNShield = 4 )
parameter ( upToL1Map = 5 )
parameter ( upToExL1 = 6 )
parameter ( upToEnSp = 7 )
parameter ( upToExSp = 8 )
parameter ( upToChKoord = 9 )
parameter ( upToL2andFoMap = 10 )
parameter ( upToExL2 = 11 )
parameter ( upToEnTD = 12 )
parameter ( upToExTD = 13 )
parameter ( upToL3Map = 14 )
parameter ( upToExL3 = 15 )
parameter ( upToM2Map = 16 )
parameter ( upToMCP2 = 17 )
integer Gebiete_Anzahl
parameter ( Gebiete_Anzahl=17) ! <- Startpkt 'Target' zaehlt nicht !!
character Gebiet_Text(Gebiete_Anzahl)*40
COMMON Gebiet_Text
c-------------------------------------------------------------------------------
c Zuteilungen der Schleifenparameter zu den Feldelemenkten k
c (1 <= k <= par_Anzahl) von par(i,k), n_par(k), parWert(k), par_text(k)
c-------------------------------------------------------------------------------
integer UTgt,UGua,UG1,UL1,USp,UL2,UL3, UFolie,UVorne,UHinten,UMCP3,
+ UMCP2, BTD,BHelm, alfTgt,alfSp,alfTD, mass,charge,
+ ener,yPos,zPos,thetAng,phiAng,Thickn,Eloss,DeltaL1,DeltaL2
parameter ( UTgt = 1 )
parameter ( UGua = 2 )
parameter ( UG1 = 3 )
parameter ( UL1 = 4 )
parameter ( USp = 5 )
parameter ( UL2 = 6 )
parameter ( UL3 = 7 )
parameter ( UFolie = 8 )
parameter ( UVorne = 9 )
parameter ( UHinten = 10 )
parameter ( UMCP3 = 11 )
parameter ( UMCP2 = 12 )
parameter ( BTD = 13 )
parameter ( BHelm = 14 )
parameter ( alfTgt = 15 )
parameter ( alfSp = 16 )
parameter ( alfTD = 17 )
parameter ( mass = 18 )
parameter ( charge = 19 )
parameter ( ener = 20 )
parameter ( yPos = 21 )
parameter ( zPos = 22 )
parameter ( thetAng = 23 )
parameter ( phiAng = 24 )
parameter ( Thickn = 25 )
parameter ( Eloss = 26 )
parameter ( DeltaL1 = 27 )
parameter ( DeltaL2 = 28 )
integer par_Anzahl
parameter ( par_Anzahl=28) ! <- 'Zufalls-Schleife' zu k=0 zaehlt nicht!
c-------------------------------------------------------------------------------
c Code-Nummern fuer das Schicksal des Teilchens
c-------------------------------------------------------------------------------
integer smallest_code_Nr
integer highest_code_Nr
integer code_stopped_in_foil
integer code_durchSpiegel,code_Stuetzgitter,code_lostInTD,code_NotRegInM3
integer code_hitBlende,code_hitMCP2inactive
integer code_frontOfMapAc,code_leftMapAc,code_hit_TgtHolder
integer code_ok
integer code_decay,code_vorbei,code_reflektiert,
+ code_wand,code_grid,code_lost,code_dtsmall
c SCHICKSAL 'code'
parameter ( smallest_code_Nr =-10 )
parameter ( code_ok = 0 )
parameter ( code_durchSpiegel = -1 )
parameter ( code_Stuetzgitter = -2 )
parameter ( code_lostInTD = -3 )
parameter ( code_NotRegInM3 = -4 )
parameter ( code_hitBlende = -5 )
parameter ( code_hitMCP2inactive= -6 )
parameter ( code_frontOfMapAc = -7 )
parameter ( code_leftMapAc = -8 )
parameter ( code_hit_TgtHolder = -9 )
parameter ( code_stopped_in_foil=-10 )
parameter ( code_decay = 1 )
parameter ( code_vorbei = 2 )
parameter ( code_reflektiert = 3 )
parameter ( code_grid = 4 )
parameter ( code_wand = 5 )
parameter ( code_lost = 6 )
parameter ( code_dtsmall = 7 )
parameter ( highest_code_Nr = 7 )
character code_Text(smallest_code_Nr:highest_code_Nr)*27
COMMON code_text
c-------------------------------------------------------------------------------
c Zuteilung der Statistiken zu den Feldelementen k ( 1<= k <= stat_Anzahl)
c von statInMemory(k),createTabelle(k),statNeeded(k),statMem(i,k)
c-------------------------------------------------------------------------------
integer Nr_S1xM2,Nr_S1M2,Nr_S1Fo,Nr_FoM2,Nr_S1M3,Nr_M3M2,Nr_t_FE,
+ Nr_y_Fo,Nr_z_Fo,Nr_r_Fo,Nr_y_M2,Nr_z_M2,Nr_r_M2,Nr_y_xM2,
+ Nr_z_xM2,Nr_r_xM2
c STATISTIK 'k'
parameter ( Nr_S1xM2 = 1 )
parameter ( Nr_S1M2 = 2 )
parameter ( Nr_S1Fo = 3 )
parameter ( Nr_FoM2 = 4 )
parameter ( Nr_S1M3 = 5 )
parameter ( Nr_M3M2 = 6 )
parameter ( Nr_t_FE = 7 )
parameter ( Nr_y_Fo = 8 )
parameter ( Nr_z_Fo = 9 )
parameter ( Nr_r_Fo = 10 )
parameter ( Nr_y_M2 = 11 )
parameter ( Nr_z_M2 = 12 )
parameter ( Nr_r_M2 = 13 )
parameter ( Nr_y_xM2 = 14 )
parameter ( Nr_z_xM2 = 15 )
parameter ( Nr_r_xM2 = 16 )
integer Stat_Anzahl
parameter (Stat_Anzahl = 16)
! Kurznamen der Statistiken
integer LengthStatName
parameter (LengthStatName = 8) ! hier muss zwei mal die gleich
character statName(stat_Anzahl)*8 ! Zahl stehen
integer What_Anzahl
parameter (What_Anzahl = 5)
! Kurznamen der statistischen Groessen:
integer LengthWhatName
parameter (LengthWhatName = 8) ! hier muss zwei mal die gleiche
character whatName(what_Anzahl)*8 ! Zahl stehen!
c===============================================================================
c II. Variablen in Commonbloecken
c===============================================================================
c-------------------------------------------------------------------------------
c die Gebietsnummer
c-------------------------------------------------------------------------------
integer Gebiet0 ! GebietsNummer beim Start
integer Gebiet ! aktuelle GebietsNummer
integer StartFlaeche
COMMON Gebiet0, StartFlaeche
c-------------------------------------------------------------------------------
c zufallsverteilte Startparameter
c-------------------------------------------------------------------------------
c Energie:
logical random_E0 ! Zufallsverteilung fuer Startenergie?
logical random_E0_equal ! gleichverteilte Startenergie
real lowerE0,upperE0 ! Grenzen fuer Zufallsverteilung
logical random_E0_gauss ! gaussverteilte Startenergie
real sigmaE0 ! Breite der Gaussverteilung
logical e0InterFromFile /.FALSE./
real E0Low(101)
c Position:
logical random_pos ! Zufallsverteilung fuer Startposition?
logical random_y0z0_equal ! gleichverteilt auf Viereckflaeche
logical random_r0_equal ! gleichverteilt auf Kreisflaeche
logical random_y0z0_Gauss ! Gauss-verteilt auf Viereckflaeche
logical random_r0_Gauss ! Gauss-verteilt auf Kreisflaeche
real StartBreite,StartHoehe,StartRadius, sigmaPosition
c Winkel:
logical random_angle ! Zufallsverteilung fuer Startwinkel?
logical random_lambert ! Lambert-Verteilung
logical random_gauss ! Gauss-Verteilung
real StartLambertOrd
real SigmaWinkel ! Breite der Gaussverteilung
logical ener_offset,pos_offset,angle_offset
c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
COMMON random_E0,random_E0_equal,lowerE0,upperE0
COMMON random_E0_gauss,sigmaE0
COMMON e0InterFromFile,E0Low
COMMON random_pos,random_y0z0_equal,
+ random_r0_equal,random_y0z0_Gauss,random_r0_Gauss,
+ StartBreite,StartHoehe,StartRadius,sigmaPosition
COMMON random_angle,random_lambert,random_gauss
COMMON StartLambertOrd,sigmaWinkel
COMMON ener_offset,pos_offset,angle_offset
c-------------------------------------------------------------------------------
c Schleifen-Parameter
c-------------------------------------------------------------------------------
c (par(n,0) wird fuer die 'Zufallsschleife' verwendet)
real par(3,0:par_Anzahl) ! min, max und step der ParameterSchleifen
integer n_par(0:par_Anzahl) ! die Anzahl unterschiedl. Werte je Schleife
real parWert(par_Anzahl) ! der aktuelle Wert der Schleifenvariablen
character par_text(par_Anzahl)*22 ! Beschreibung jeder Variablen fuer Ausgabezwecke
integer reihenFolge(par_Anzahl) ! Enthaelt die Reihenfolge der
! Abarbeitung der Schleifenparameter
c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
COMMON par, parWert, n_par, par_text, reihenfolge
c-------------------------------------------------------------------------------
c die Teilchenarten (artList)
c-------------------------------------------------------------------------------
integer Arten_Zahl ! Anzahl der bekannten Arten
parameter (Arten_Zahl = 36)
character*4 art_Name(Arten_Zahl) ! Bezeichnungen der bekannten Arten
real art_Masse(Arten_Zahl) ! Massen der bekannten Arten
real art_Ladung(Arten_Zahl) ! Ladungen der bekannten Arten
character artList*50 ! TeilchenArten-Liste
character artList_prevSim*50 ! TeilchenArten-Liste bei ACCEL
! und 'useFoilFile'
logical artList_defined ! wurde Teilchenart spezifiziert?
logical mu_flag ! signalisiert, ob Myon-Teilchen erkannt wurde
integer artenMax ! Maximalzahl in artList
parameter (artenMax = 9) ! akzeptierter Arten
integer art_Nr(artenMax) ! die in artList enthaltenen Arten
integer artNr ! die Nummer der aktuellen Art
c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
COMMON art_Name,art_Masse,art_Ladung
COMMON artList,artList_prevSim,artList_defined,mu_flag
COMMON art_Nr,artNr
c-------------------------------------------------------------------------------
c Trigger-Detektor
c-------------------------------------------------------------------------------
logical TriggerInBeam ! TriggerDetektor im Strahlweg?
real Thickness ! Foliendicke
logical log_aufstreu ! WinkelAufstreuung in Folie beruecksichtigen?
logical log_aufstreu_fixed ! Breite der Winkelverteilung fest vorgegeben
real sigmaAufstreu ! Sigma des Gaussverteilten Aufstreuwinkels
logical log_Meyer_Gauss ! Meyer-Formel mit Gaussfkt
logical log_Meyer_F_Function ! Meyer mit F-Funktion (genauer!)
logical log_E_Verlust ! Energieverlust in TD-Folie beruecksichtigen?
logical log_E_Verlust_defined ! mittlerer Energieverlust vorgegeben?
logical log_E_Verlust_ICRU ! mittlerer E-Verlust gemaess ICRU?
logical log_E_Straggling_sigma ! Gausfoermige Energieverschmierung?
logical log_E_Straggling_equal ! Gleichmaessige Energieverschmierung?
logical log_E_Straggling_Lindhard ! Gaussfoermig nach Lindhard/Scharff
logical log_E_Straggling_Yang ! Gaussfoermig nach Yang
logical calculate_each ! bei ICRU: fuer jedes Teilchen neu?
real mean_E_Verlust ! bei '_defined': mittlerer E-Verlust
real sigmaE ! Breite der Verteilung der Verlustfunktion
real lowerE ! untere Grenze bei '_equal'
real upperE ! obere Grenze bei '_equal'
logical graphitData
logical log_neutralize
real neutral_fract(artenMax) ! Prozentzahl der zu neutralisiserenden Teilchen
logical generate_FE ! FolienElektronen generieren?
c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
COMMON /TRIGGERINBEAM/ TriggerInBeam
COMMON Thickness
COMMON log_aufstreu,log_aufstreu_fixed,sigmaAufstreu
COMMON log_Meyer_Gauss, log_Meyer_F_Function
COMMON log_E_Verlust,log_E_Verlust_defined,log_E_Verlust_ICRU,
+ log_E_Straggling_sigma,log_E_Straggling_equal,log_E_Straggling_Lindhard,
+ log_E_Straggling_Yang,mean_E_Verlust,calculate_each,
+ sigmaE,lowerE,upperE
common /elossDataType/ graphitData
COMMON log_neutralize,neutral_fract
COMMON generate_FE
c-------------------------------------------------------------------------------
c Programmsteuerung
c-------------------------------------------------------------------------------
logical alfaTgtVertically ! vertikale Variation des Targetwinkels
real scaleFactor ! Skalierungsfaktor fuer die Kammergeometrie
logical UseDecay ! MYONEN-Zerfall beruecksichtigen?
logical UseDecay_ ! MYONEN-Zerfall beruecksichtigen und Art ist myon?
logical UseDecay_prevSim! MYONEN-Zerfall bei ACCEL-Rechnung beruecksichtigt?
logical DEBUG ! DEBUG-Version?
logical DEBUG_ ! DEBUG .AND. startNr.LE.DEBUG_Anzahl
logical DEBUG_FE ! FE in DEBUG-Info?
logical log_alpha0_KS ! Startwinkel im Kammer-System gegeben?
logical notLastLoop
logical BATCH_MODE ! -> keine Graphikausgabe; keine Ausgabe der
! Prozentzahl schon gerechneter Trajektorien
logical INPUT_LIST ! spezielle Version eines Batch-Runs
integer ListLength !
logical gotFileNr !
character inputListName*20
logical TestRun ! falls true, RunNummern zwischen 9900 und 9999
logical log_confine ! Begrenze Schrittweite in Integrationsgebieten
! -> 'dl_max_...'
logical TestOnWireHit ! Pruefen, ob Gitterstaebe getroffen werden
logical idealMirror ! Spiegel als ideal rechnen?
logical upToTDFoilOnly ! Integration nur bis zum Erreichen der TD-Folie
logical createFoilFile ! File mit Trajektoriendaten bei Erreichen der
! TD-Folie erstellen, das dann analog zu
! den ACCEL-files eingelesen werden kann.
logical lense2 ! Linse 2 zw. Spiegel und TD vorhanden ?
c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
COMMON alfaTgtVertically
COMMON scaleFactor
COMMON UseDecay,UseDecay_,UseDecay_prevSim
COMMON DEBUG,DEBUG_,DEBUG_FE
COMMON log_alpha0_KS,notLastLoop
COMMON /BATCH_MODE/ BATCH_MODE
COMMON INPUT_LIST,ListLength,gotFileNr,inputListName
COMMON TestRun,log_confine,idealMirror
COMMON /TestOnWireHit/ TestOnWireHit
COMMON upToTDFoilOnly, createFoilFile
COMMON /lense2/ lense2
c-------------------------------------------------------------------------------
c Graphikausgabe
c-------------------------------------------------------------------------------
logical graphics ! graphisch Ausgabe?
integer graphics_Anzahl ! fuer wieviele Starts je Schleife?
logical graphics_ ! GRAPHICS .AND. startNr.LE.GRAPHICS_Anzahl
logical plot_FE ! Trajektorien der Folienelektronen plotten?
integer n_postSkript ! PostSkript-files erstellen?
integer iMonitor ! Abtastfrequenz fuer Graphik
integer color ! 0=schwarzweiss, 1=farbig
integer schnitt_p ! Kammerteil fuer die Schnittebene der Graphik
real schnitt_x ! x-Koordinate der Schnittebenen
logical vertical ! Blick auf die Kammer von oben?
c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
COMMON graphics,graphics_Anzahl,graphics_
COMMON plot_FE, n_postSkript, iMonitor,schnitt_p
COMMON /PICT/ color, schnitt_x, vertical
c-------------------------------------------------------------------------------
c FileNamen
c-------------------------------------------------------------------------------
character geo_fileName*60 ! Name des Files mit der Kammergeometrie
character filename*20 ! Name der Ausgabe-Dateien
character filename_ACCEL*40 ! gegebenenfalls Name des ACCEL-files
character filename_MUTRACK*40 ! gegebenenfalls Name des 'foilfiles'
c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
COMMON geo_fileName
COMMON /filename/ filename
COMMON filename_ACCEL,filename_MUTRACK
c-------------------------------------------------------------------------------
c Vorgaben fuer das Summary (.LOG-file)
c-------------------------------------------------------------------------------
integer n_outWhere ! LogFile auf welche Ausgabekanaele geben?
logical LogFile ! Logfile erstellen?
logical smallLogFile ! minimalversion des Logfiles erstellen?
logical statsInSummary ! Statistiken in das Summary?
logical statInSummary(Stat_Anzahl) ! welche Statistiken in das Summary?
logical log_out_FE ! FolienElektronen-Statistik in das Summary?
logical log_out_pfosten(2)! getroffene TD-'Pfosten' in das Summary?
c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
COMMON n_outWhere
COMMON LogFile,smallLogFile
COMMON statsInSummary,statInSummary
COMMON log_out_FE,log_out_pfosten
c-------------------------------------------------------------------------------
c WELCHE FILES sollen erzeugt werden?
c-------------------------------------------------------------------------------
logical write_geo ! .GEO-file schreiben?
logical createPhysTab ! PAW-Gesamt-Tabelle (.PAW) erzeugen?
logical createNtp ! Ntuple (.NTP) erzeugen?
logical Fo_triggered ! nur Teilchen die die TD-Folie treffen in NTupel
logical xM2_triggered ! nur Teilchen die MCP2-Ebene erreichen ins NTupel
logical M2_triggered ! nur Teilchen die das MCP treffen ins NTupel
logical NTP_S1xM2 ! Flugzeit bis zur MCP2-EBENE ins NTupel?
logical NTP_times ! sonstige Flugzeiten ins NTupel?
logical NTP_FoM2Only ! nur TOF Folie-M2 ins NTupel? (ausser S1xM2)
logical NTP_charge ! Der Ladungszustand ins NTupel?
logical NTP_lifetime ! Die Lebensdauer ins NTupel?
logical NTP_start ! Die Startgroessen ...?
logical NTP_stop ! Die Stopgroessen ...?
logical NTP_40mm ! Die Groessen bei x=40mm ...?
logical NTP_Folie ! Everlust und Aufstreuungupel ...?
logical NTP_steps ! kleinste und groesste Schrittweiten ...?
logical NTP_Koord ! Die Trajektoriendaten ...?
logical createTabellen ! Tabellen-files erzeugen?
logical createTabelle(Stat_Anzahl) ! welche Tabellen-files erzeugen?
character TabExt(stat_Anzahl)*9 ! Extensions der Tabellenfiles
logical smearS1Fo /.false./
real sigmaS1Fo /1.6/
c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
COMMON write_geo,createPhysTab,createNtp
COMMON Fo_triggered,xM2_triggered,M2_triggered
COMMON NTP_S1xM2,NTP_times,NTP_FoM2Only,NTP_charge,NTP_lifetime,NTP_start,NTP_stop
COMMON NTP_40mm,NTP_Folie,NTP_steps,NTP_Koord
COMMON createTabellen,createTabelle,statName,whatName,TabExt
COMMON smearS1Fo,sigmaS1Fo
c-------------------------------------------------------------------------------
c Fehlerkontrolle
c-------------------------------------------------------------------------------
real eps_x ! Fehlertoleranz bei Ortsberechnung
real eps_v ! Fehlertoleranz bei Geschw.Berechnung
logical log_relativ ! relative Fehlerbetrachtung?
integer maxStep ! maximale Anzahl an Integrationsschritten
! real deltaE in / 1 / (auch in initialize einbinden)
c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
COMMON eps_x,eps_v,log_relativ
COMMON maxStep
c-------------------------------------------------------------------------------
c haeufig benutzte Faktoren
c-------------------------------------------------------------------------------
real Energie_Faktor ! Faktor bei Berechn. der Energie aus der Geschw.
c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
COMMON Energie_Faktor
c-------------------------------------------------------------------------------
c PHYSICA
c-------------------------------------------------------------------------------
integer par_Anzahl_used,statAnzahlPHY,whatAnzahlPHY
integer parList(par_Anzahl),statList(stat_Anzahl),whatList(what_Anzahl)
integer lengthParName
logical statInPHYSICA(Stat_Anzahl) ! welche Statistiken in .PHYSICA file?
logical whatInPHYSICA(What_Anzahl) ! welche Statistiken in .PHYSICA file?
integer LwPerRec ! Recordlaenge in MU_nnnn.PHYSICA in Longwords
parameter (LwPerRec = 50)
c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
COMMON par_Anzahl_used,statAnzahlPHY,whatAnzahlPHY
COMMON parList,statList,whatList
COMMON lengthParName
COMMON statInPHYSICA,whatInPHYSICA
c-------------------------------------------------------------------------------
c Programmablauf
c-------------------------------------------------------------------------------
real x0(3),v0(3),E0 ! Startort, -geschwindigkeit und -energie
real lifetime ! individuelle Myon-Lebensdauer [ns]
real theta0 ! 3D-Startwinkel gegen x_Achse
real phi0 ! azimuthaler Startwinkel (y-Achse:0, z-Achse:90)
real x(3),t,v(3) ! Ort, Zeit, Geschwindigkeit
c real spin(3) ! Teichelspin (nicht benutzt)
integer destiny ! die Codezahl fuer das Schicksal des Projektils
integer start_nr(2) ! Startnummer der Teilchen (1) und der FE (2)
integer GesamtZahl ! Gesamtzahl der Projektile
integer SchleifenZahl ! Anzahl durchzufuehrender Schleifen
integer SchleifenNr ! Nummer der aktuellen Schleife
integer Steps ! Nummer des Integrationssteps
real dtsmall ! kleinster Zeitschritt fuer Integrationen
integer n_dtSmall ! wie oft hat Teilchen dtSmall unterschritten
integer n_dtsmall_Max ! wie oft wurde dtsmall max. unterschritten
integer dtsmall_counter ! wieviele Teilchen haben dtsmall unterschritten
integer maxBelowDtSmall
integer LostInTD_counter! wieviele Teilchen wurden im TD abgeschrieben
integer Lost_counter ! wieviele Teilchen wurden sonst noch abgeschrieben
logical OneLoop ! genau eine Schleife
logical OneStartPerLoop ! Zufallsschleife macht genau einen Durchlauf
logical log_percent
logical Use_ACCEL ! ACCEL-Daten verwenden
logical Use_MUTRACK ! 'FoilFile'-Daten verwenden
logical fromScratch ! .NOT.(Use_ACCEL.OR.Use_MUTRACK)
logical previousSettings ! Parametervorgaben von ACCEL uebernehmen?
integer firstIndx(10),IndxIncr(10),parIndx(10)
integer eventNr ! korrespondierende Eventnummer im ACCEL-NTP
logical guard ! Potential am Guardring frei variierbar?
integer randomStarts_prevSim ! 'randomStarts' bei ACCEL und 'foilFile'
integer seed ! fuer Zufallsgenerator
logical reachedEndOfMap ! bei FolienMappe oder MCP2Mappe x=xmax erreicht
logical gridInFrontOfFoil
c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
c Die benannten Common-Bloecke werden fuer die NTP-Ausgabe benoetigt!
c die separaten Commonblocks sind fuer die Routine HBNAME der CERN library
c wichtig wenn es darum geht, frueher erzeugte NTP einzulesen. Ansonsten kommt
c (zumindest auf der PSW264, auf der PSICLC u.U. nicht (-> Option 'align=all'
c beim FORTRAN Befehl auf der alpha)) z.B. die Fehlermeldung
c
c Variable LIFETIME
c ***** ERROR in HBNAME : Address not word aligned :
c Variable GEBIET
c ***** ERROR in HBNAME : Address not word aligned :
c Variable T
c ***** ERROR in HBNAME : Address not word aligned :
COMMON /gebiet/ gebiet,destiny ! Reihenfolge wichtig fuer NTupel!
COMMON /lifetime/ lifetime
COMMON /x0/ x0
COMMON /v0/ v0
COMMON /E0/ E0
COMMON /theta0/ theta0,phi0
COMMON /t/ t,x,v ! Reihenfolge wichtig fuer NTupel!
COMMON /ntp_steps/ steps ! in MUTRACK wird noch weiteres angefuegt!
COMMON /loop/ SchleifenNr
COMMON start_Nr
COMMON GesamtZahl,SchleifenZahl
COMMON dtsmall, n_dtsmall, n_dtsmall_Max, dtsmall_counter
COMMON maxBelowDtSmall
COMMON LostInTD_counter,Lost_counter
COMMON OneLoop, OneStartPerLoop
COMMON log_percent
COMMON Use_ACCEL,Use_MUTRACK,fromScratch
COMMON previousSettings,firstIndx,IndxIncr,parIndx,eventNr
COMMON guard
COMMON randomStarts_prevSim
COMMON /seed/ seed ! das Common /seed/ ist auch in den Routinen
! 'GAUSS_VERTEILUNG' und 'GAUSS_VERTEILUG_THETA'
! in MUTRACK.FOR definiert
COMMON reachedEndOfMap
COMMON /foilGrid/ gridInFrontOfFoil
c-------------------------------------------------------------------------------
c Statistik
c-------------------------------------------------------------------------------
integer statTD(2,18) ! Statistik der Returncodes des TDs
integer pfostenHit(75,2) ! Statistik der Pfostentreffen im TD (75 oder 45?)
integer statDestiny(smallest_code_Nr:Gebiete_Anzahl*highest_code_Nr)
! Statistik der Teilchenschicksale
real statMem(9,stat_Anzahl) ! Statistik der Ergebnisse der Bahnberechnung
logical statNeeded(stat_Anzahl) ! welche Statistiken muessen fuer die
! geforderten Informationen gefuehrt werden?
c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
COMMON statTD,pfostenHit,statDestiny
COMMON statMem,statNeeded
c-------------------------------------------------------------------------------
c Ein- und Ausgabekanaele
c-------------------------------------------------------------------------------
INCLUDE 'mutrack$sourcedirectory:COM_LUNS.INC'
integer*4 NTP_write, NTP_read
parameter (NTP_write=5, NTP_read = NTP_write+1)
c-------------------------------------------------------------------------------
c Datenausgabe
c-------------------------------------------------------------------------------
INCLUDE 'mutrack$sourcedirectory:COM_OUTPUT.INC'

View File

@ -0,0 +1,23 @@
c===============================================================================
c COM_OUTPUT.INC
c===============================================================================
c Die Deklaration der Variablen und des Commonblocks fuer die DatenAusgabe
c im Programm 'MUTRACK' wird sowohl von den Ausgaberoutinen des Hauptprogramms
c als auch von den zum TriggerDetektor gehoerenden Routinen benoetigt und sind
c daher in diesem separaten include-file niedergelegt.
integer DEBUG_StartNr
integer DEBUG_Anzahl ! fuer wieviele Starts je Schleife sollen
! (so ueberhaupt) DEBUG-Informationen ausgegeben
! werden?
integer lun(2), indx
integer indx1, indx2
COMMON /OUTPUT/ lun, indx1,indx2, indx, DEBUG_StartNr, DEBUG_Anzahl
c 'indx' steht nur im COMMON-Block, damit die Meldungen 'declared but not used'
c unterbleiben!

View File

@ -0,0 +1,20 @@
c===============================================================================
c COM_TD_EXT.INC
c===============================================================================
c Dieser include-file declariert diejenigen Variablen, die den Routinen in
c der Fortran-Text-Datei SUB-TD-CALC und der Routine, welche das Sub. TD_CALC
c aufruft, gemeinsam sind und definiert den zugehoerigen COMMON-Block:
c - die am Trigger-Detektor anliegenden Spannungen:
real U_F ! die Spannung an der FOLIE (F)
real U_V ! die Spannung am vorderen Gitter (V)
real U_H ! die Spannung am hinteren Gitter (H)
real U_MCP3 ! die Spannung an der Vorderseite von MCP-3 (3)
c - der COMMOM-Block:
COMMON /TRIGGERSETTINGS/ U_F,U_V,U_H,U_MCP3

View File

@ -0,0 +1,25 @@
c===============================================================================
c COM_TD_INT.INC
c===============================================================================
c Dieser include-file declariert diejenigen Variablen, die den Routinen in
c der Fortran-Text-Datei SUB-TD-CALC gemeinsam zugaenglich sind, und definiert
c den zugehoerigen COMMON-Block:
c - die Teilchen-Parameter Ladung, Masse, Ort, Geschw., Startenergie
real q, m, t, x, y, z, v_x, v_y, v_z, E0
c - was ausgegeben werden soll:
logical DEBUG, GRAPHICS
c - die Return-Variable:
integer n_return
c - logicals, die anzeigen, ob das Teilchen schon einmal reflektiert wurde:
logical log_refl_Vh, log_refl_V3
c - der COMMON-Block:
COMMON /INTERN/ q, m, t, x, y, z, v_x, v_y, v_z, E0
COMMON /INTERN/ DEBUG,GRAPHICS, n_return,log_refl_VH,log_refl_V3

View File

@ -0,0 +1,24 @@
c===============================================================================
c COM_WINKEL.INC
c===============================================================================
c Da die Drehwinkel von Moderator (= Target), Spiegel und Triggerdetektor
c in mehreren Routinen des Programms 'MUTRACK' sowohl innerhalb als auch
c ausserhalb der Trigger-Komplexes benoetigt wird, steht dieser Commonblock in
c diesem separaten Include-file. (Auch in SUB_PICTURE verwendet)
real alfaTgt ! Tgt <-> Target
real Sin_alfaTgt, Cos_alfaTgt ! Target-Verdrehung
real alfaSp ! Sp <-> Spiegel
real Sin_alfaSp , Cos_alfaSp , Tan_AlfaSp ! Spiegel-Verdrehung
real alfaTD ! TD <-> TriggerDetektor
real Sin_alfaTD , Cos_alfaTD , Tan_alfaTD ! Trigger-Verdrehung
COMMON /ANGLES/ alfaTgt, Sin_alfaTgt, Cos_alfaTgt
COMMON /ANGLES/ alfaSp, Sin_alfaSp, Cos_alfaSp, Tan_AlfaSp
COMMON /ANGLES/ alfaTD, Sin_alfaTD, Cos_alfaTD, Tan_alfaTD

123
mutrack/src/GEO_TRIGGER.INC Normal file
View File

@ -0,0 +1,123 @@
c===============================================================================
c GEO_TRIGGER.INC
c===============================================================================
c*******************************************************************************
c* *
c* Diese Datei enthaelt die geometrischen Daten des NEMU-Triggerdetektors *
c* in seiner ersten Version. *
c* *
c* Die Definitionen der Groessen sind im Ordner 'MUTRACK' niedergelegt! *
c* Alle Angaben sind in [mm]. *
c* *
c* Stand: Run VI. Die Werte wurden einer Konstruktionszeichnung entnommen *
c* *
c* >> 2.12.1994 >> ahofer@psiclu.cern.ch *
c* *
c*******************************************************************************
c Laengen in x-Richtung:
real dx1,dx2,dx3,dx4,dx5,dx6,dx7,dx8,dx9,dx10,dx11
parameter (dx1 = 8, dx2 =37, dx3 =14, dx4 =42, !dx5 = 8,
+ dx6 =12, dx7 =12, dx8 =19, dx9 =23, dx10=10, dx11=14)
DATA dx5 / 8 /
COMMON /dx5/ dx5
c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
c Laengen in y-Richtung:
real dy1,dy2,dy3,dy4,dy5,dy6,dy7,dy8,dy9,dy10,dy11
real dy12,dy13,dy14,dy15
parameter (dy1 =20, dy2 =20, dy3 =25, dy4 =25, dy5 =25,
+ dy6 =32, dy7 =30, dy8 =42, dy9 =40, dy10=11,
+ dy11=32, dy12=30, dy13=30, dy14=30, dy15=30)
c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
c Laengen in z-Richtung:
real dz1, dz2
parameter (dz1 =30, dz2 =30)
c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
real d_Grid_Folie ! Abstand zwischen
parameter (d_Grid_Folie = 18) ! Gitter und Folie
c Abgeleitete Laengen:
real d_Folie_Achse ! Abstand zwischen Folie
parameter (d_Folie_Achse = dx1+dx2+dx3/2) ! und Trigger-Achse
real d_Folie_Hinten2 ! Abstand zwischen Folie
parameter (d_Folie_Hinten2 = dx1+dx2+dx3+dx4) ! und 2. Gitter von H
real radiusQuad_Folie ! in MUTRACK.INPUT?
parameter (radiusQuad_Folie = 20*20 )
real radiusQuad_Folie_max ! <------ nicht benutzt!
parameter (radiusQuad_Folie_max = 26*26) ! maximaler Folienradius
real xCenter_MCP3, radius_MCP3, radiusQuad_MCP3
parameter (radius_MCP3 = ((dx2+dy8-dx11)-(dx9))/2. )
parameter (radiusQuad_MCP3 = radius_MCP3 * radius_MCP3)
parameter (xCenter_MCP3 = dx1+dx9+radius_MCP3) ! x-Pos. der Mitte von
! MCP3 im Triggersystem
c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
c Gitterdrahtabstaende und -durchmesser:
c (Nachdem diese Groessen in Run 10 geaendert wurden muessen sie nun als
c Variable gehandhabt werden)
real dist_Wires_V1 /1.5/, dWires_V1 /.050/
real dist_Wires_V2 /1.5/, dWires_V2 /.050/
real dist_Wires_V3 /1.5/, dWires_V3 /.050/
real dist_Wires_H1 /1.5/, dWires_H1 /.050/
real dist_Wires_H2 /1.5/, dWires_H2 /.050/
real dist_Wires_G /1.5/, dWires_G /.050/
real WireRadiusQuad_V1, WireRadiusQuad_V2, WireRadiusQuad_V3
real WireRadiusQuad_H1, WireRadiusQuad_H2, WireRadiusQuad_G
COMMON /TD_GEO/
+ dist_Wires_V1,dist_Wires_V2,dist_Wires_V3,
+ dist_Wires_H1,dist_Wires_H2,dist_Wires_G,
+ dWires_V1,dWires_V2,dWires_V3,dWires_H1,dWires_H2,dWires_G,
+ WireRadiusQuad_V1,WireRadiusQuad_V2,WireRadiusQuad_V3,
+ WireRadiusQuad_H1,WireRadiusQuad_H2,WireRadiusQuad_G
c parameter (dist_Wires_V1 = 1.5 , dWires_V1 = .050)
c parameter (dist_Wires_V2 = 1.5 , dWires_V2 = .050)
c parameter (dist_Wires_V3 = 1.5 , dWires_V3 = .050)
c parameter (dist_Wires_H1 = 1.5 , dWires_H1 = .050)
c parameter (dist_Wires_H2 = 1.5 , dWires_H2 = .050)
c parameter (dist_Wires_G = 1.5 , dWires_G = .050)
c die Berechnung der Quadrate wird jetzt in SUBROUTINE READ_TRIGGER_GEO erledigt
c
c parameter (WireRadiusQuad_V1 = dwires_V1*dWires_V1/4.,
c + WireRadiusQuad_V2 = dwires_V2*dWires_V2/4.,
c + WireRadiusQuad_V3 = dwires_V3*dWires_V3/4.,
c + WireRadiusQuad_H1 = dwires_H1*dWires_H1/4.,
c + WireRadiusQuad_H2 = dwires_H2*dWires_H2/4.,
c + WireRadiusQuad_G = dwires_G *dWires_G /4.)
c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
c Effizienz von MCP3:
real efficiencyM3
parameter (efficiencyM3 = .75)
c parameter (efficiencyM3 = .50)

464
mutrack/src/INITIALIZE.INC Normal file
View File

@ -0,0 +1,464 @@
c Diese Datei enthaelt Initialisierungen fuer das Programm TOF zur Berechnung
c von Flugzeiten zwischen MCP3 und MCP2 der NEMU-Apparatur.
c Die Deklaration der Variablen findet im Include-file 'COM_MUTRACK.INC'
c statt.
c die Spezifizierungen der Schleifen-Parameter (character*22):
par_text(UTgt ) = 'U(TARGET) [kV] : '
par_text(UGua ) = 'U(GUARD) [kV] : '
par_text(UG1 ) = 'U(GITTER) [kV] : '
par_text(UL1 ) = 'U(L1) [kV] : '
par_text(USp ) = 'U(SPIEGEL)[kV] : '
par_text(UL2 ) = 'U(L2) [kV] : '
par_text(UL3 ) = 'U(L3) [kV] : '
par_text(UFolie ) = 'U(FOLIE) [kV] : '
par_text(UVorne ) = 'U(VORNE) [kV] : '
par_text(UHinten) = 'U(HINTEN) [kV] : '
par_text(UMCP3 ) = 'U(MCP3) [kV] : '
par_text(UMCP2 ) = 'U(MCP2) [kV] : '
par_text(BTD ) = 'B(TD) [Gauss] : '
par_text(BHelm ) = 'B(Helmh.) [Gauss] : '
par_text(alfTgt ) = 'alpha_Tgt [degree] : '
par_text(alfSp ) = 'alpha_Sp [degree] : '
par_text(alfTD ) = 'alpha_TD [degree] : '
par_text(mass ) = 'Masse [keV/c**2]: '
par_text(charge ) = 'Ladung [e] : '
par_text(ener ) = 'Energie [keV] : '
par_text(yPos ) = 'y0 [mm] : '
par_text(zPos ) = 'z0 [mm] : '
par_text(thetAng) = 'theta0 [degree] : '
par_text(phiAng ) = 'phi0 [degree] : '
par_text(Thickn ) = 'Thickness [ug/cm^2] : '
par_text(Eloss ) = 'E-Verlust [keV] : '
par_text(deltaL1) = 'delta_L1 [mm] : '
par_text(deltaL2) = 'delta_L2 [mm] : '
c Groesste Laenge einer Parameterbezeichnung (ohne Einheitenangabe) in
c 'par_text':
lengthParName = 10
c die Gebiets-Bezeichnungen (character*40):
Gebiet_Text(upToGrid1) = 'in 1. Beschl.Stufe:'
Gebiet_Text(upToGrid2) = 'in 2. Beschl.Stufe:'
Gebiet_Text(upToHeShield) = 'bis He-Schild:'
Gebiet_Text(upToLNShield) = 'bis LN-Schild:'
Gebiet_Text(upToL1Map) = 'vor Linse-1-Mappe:'
Gebiet_Text(upToExL1) = 'in Linse-1-Mappe:'
Gebiet_Text(upToEnSp) = 'bis Spiegel:'
Gebiet_Text(upToExSp) = 'im Spiegel:'
Gebiet_Text(upToChKoord) = 'bis Koordinatenwechsel:'
Gebiet_Text(upToEnTD) = 'bis TriggerDetektor:'
Gebiet_Text(upToExTD) = 'im TriggerDetektor:'
Gebiet_Text(upToL2andFoMap) = 'vor Linse-2-Mappe:'
Gebiet_Text(upToExL2) = 'in Linse-2-Mappe:'
Gebiet_Text(upToL3Map) = 'vor Linse-3-Mappe:'
Gebiet_Text(upToExL3) = 'in Linse-3-Mappe:'
Gebiet_Text(upToM2Map) = 'zwischen Linse-3-Mappe und MCP2-Mappe:'
Gebiet_Text(upToMCP2) = 'vor MCP2:'
c die Bezeichnungen fuer die moeglichen Teilchenschicksale (character*26):
code_text(code_ok ) = 'MCP2 getroffen: '
code_text(code_durchSpiegel ) = 'Spiegel durchquert: '
code_text(code_Stuetzgitter ) = 'Folienstuetzgitter getr.: '
code_text(code_lostInTD ) = 'im TD abgebrochen: '
code_text(code_NotRegInM3 ) = 'von MCP3 nicht registriert: '
code_text(code_hitBlende ) = 'auf Blende des MCP2: '
code_text(code_hitMCP2inactive) = 'auf Rand des MCP2: '
code_text(code_frontOfMapAc ) = 'ACCEL: vor Mappe (FEHLER!): '
code_text(code_leftMapAc ) = 'ACCEL: seitlich aus Mappe: '
code_text(code_hit_TgtHolder ) = 'Targethalter getroffen: '
code_text(code_stopped_in_foil) = 'in Triggerfolie gestoppt: '
code_text(code_decay ) = 'zerfallen: '
code_text(code_vorbei ) = 'Element verfehlt: '
code_text(code_reflektiert ) = 'reflektiert: '
code_text(code_grid ) = 'auf Gitter getroffen: '
code_text(code_wand ) = 'aufgeschlagen: '
code_text(code_lost ) = 'verloren (steps>maxsteps): '
code_text(code_dtsmall ) = 'Zeitschritt kleiner dtSmall:'
c die Bezeichnungen der Statistiken (character*8):
statName(Nr_S1xM2) = 'S1xM2 '
statName(Nr_S1M2) = 'S1M2 '
statName(Nr_S1Fo) = 'S1Fo '
statName(Nr_FoM2) = 'FoM2 '
statName(Nr_S1M3) = 'S1M3 '
statName(Nr_M3M2) = 'M3M2 '
statName(Nr_t_FE) = 't(FE) '
statName(Nr_y_Fo) = 'y(FOLIE)'
statName(Nr_z_Fo) = 'z(FOLIE)'
statName(Nr_r_Fo) = 'r(FOLIE)'
c statName(Nr_y_xFo) = 'y(xFOLIE)'
c statName(Nr_z_xFo) = 'z(xFOLIE)'
c statName(Nr_r_xFo) = 'r(xFOLIE)'
statName(Nr_y_M2) = 'y(MCP2) '
statName(Nr_z_M2) = 'z(MCP2) '
statName(Nr_r_M2) = 'r(MCP2) '
statName(Nr_y_xM2) = 'y(xMCP2)'
statName(Nr_z_xM2) = 'z(xMCP2)'
statName(Nr_r_xM2) = 'r(xMCP2)'
c die Bezeichnungen der statistischen Groessen (character*8):
whatName(1) = 'mean '
whatName(2) = 'variance'
whatName(3) = 'minimum '
whatName(4) = 'maximum '
whatName(5) = 'percent '
c die Extensions der Tabellen-files (character*9):
TabExt(Nr_S1xM2) = '._S1xM2 '
TabExt(Nr_S1M2) = '._S1M2 '
TabExt(Nr_S1Fo) = '._S1Fo '
TabExt(Nr_FoM2) = '._FoM2 '
TabExt(Nr_S1M3) = '._S1M3 '
TabExt(Nr_M3M2) = '._M3M2 '
TabExt(Nr_t_FE) = '._T_FE '
TabExt(Nr_y_Fo) = '._Y_FO '
TabExt(Nr_z_Fo) = '._Z_FO '
TabExt(Nr_r_Fo) = '._R_FO '
TabExt(Nr_y_M2) = '._Y_M2 '
TabExt(Nr_z_M2) = '._Z_M2 '
TabExt(Nr_r_M2) = '._R_M2 '
TabExt(Nr_y_xM2) = '._Y_xM2 '
TabExt(Nr_z_xM2) = '._Z_xM2 '
TabExt(Nr_r_xM2) = '._R_xM2 '
c die Reihenfolge, in welcher die Schleifen der 'Schleifenparameter' par(i,k)
c im Hauptprogramm abgearbeitet werden:
c Aenderungen in der Reihenfolge brauchen in den Routinen fuer die graphische
c Darstellung mittels 'PHYSICA' nicht durch entsprechende Aenderungen in den
c jeweiligen files beruecksichtigt werden (PHYSICA bekommt die Reihenfolge ueber
c die .PHYSICA - files selbst mitgeteilt).
c Diese files sind nur anzugleichen, falls die Zuordnungen der verschiedenen
c physikalischen Groessen zu ihren jeweiligen Code-Nummern geaendert werden,
c bzw. wenn zusaetzliche Schleifengroessen aufgenommen werden
c (-> mutrack$PHYSICAdirectory: 'xxx.FOR'- und 'xxx.PCM'-Dateien).
c Desweiteren koennen ACCEL und 'foilFile' durchaus andere Reihenfolgen ver-
c wendet haben.
DATA reihenfolge /
+ DeltaL1,DeltaL2,Eloss,Thickn,
+ UMCP2, alfTgt,alfSp,alfTD,
+ UVorne,UHinten,UMCP3,
+ UFolie,UL2, USp,UL1,UL3,
+ BHelm,BTD,
+ mass,charge, UTgt,UGua,UG1,
+ ener,thetAng,phiAng,yPos,zPos /
c====== Initialisierungen fuer die benutzerdefinierbaren Parameter ============
c Das Startgebiet 'Gebiet0' wird indirekt im SUB 'READ_INPUTFILE' via die
c lokalen Variablen 'Startflaeche', bzw. 'x0_' und 'Kammerteil' initialisiert.
c - - - - - - - - - - zufallsverteilte Startparameter - - - - - - - - - - - - -
c Energie:
DATA random_E0 /.false./
DATA random_E0_equal /.false./
DATA lowerE0 / 0.000 /
DATA upperE0 / 0.010 /
DATA random_E0_gauss /.false./
DATA sigmaE0 / 0.010 /
c Position:
DATA random_pos /.false./
DATA sigmaPosition / 15. /
DATA random_y0z0_equal /.false./
DATA random_r0_equal /.false./
DATA random_y0z0_Gauss /.false./
DATA random_r0_Gauss /.false./
DATA StartBreite / -1. /
DATA StartHoehe / -1. /
DATA StartRadius / -1. /
c Winkel:
DATA random_angle /.false./
DATA random_lambert /.false./
DATA random_gauss /.false./
DATA StartLambertOrd / 1. /
DATA sigmaWinkel / 1. /
DATA ener_offset / .true. /
DATA pos_offset / .true. /
DATA angle_offset / .true. /
c - - - - - - - - - - Schleifen-Parameter - - - - - - - - - - - - - - - - - - -
! Das Schleifenparameterfeld 'par(i,k)' (1 <= k <= par_Anzahl)
! wird indirekt im SUB 'read_inputFile' ueber die dortigen lokalen
! Variablen initialisiert (siehe dort).
! Hier wird nur die 'Zufallsschleife' par(i,0) initialisiert.
DATA par(1,0) / 1. /
DATA par(2,0) / 1. /
DATA par(3,0) / 1. /
c - - - - - - - - - - Projektile- - - - - - - - - - - - - - - - - - - - - - - -
DATA art_Name / 'm+ ', 'm- ', ! character*4
+ 'Mu ', 'Mu- ',
+ 'e+ ', 'e- ',
+ 'H+ ', 'H ', 'H- ',
+ 'H2+ ', 'H2 ', 'H2- ',
+ 'alfa',
+ 'A11+', 'A12+', 'A21+', 'A31+', 'A32+',
+ 'N11+', 'N21+',
+ 'K11+', 'K12+',
+ 'H2O1', 'H2O2', 'H2O3', 'H2O4', 'H2O5',
+ 'Hyd1', 'Hyd2', 'Hyd3', 'Hyd4', 'Hyd5',
+ 'Hyd6', 'Hyd7', 'Hyd8', 'Hyd9'
+ /
c folgende Werte wurden aus bzw. mittels 'HANDBOOK OF CHEMESTRY AND PHYSICS,
c 74th edition' und 'PHYSICAL REVIEW D, 50, S.1173-1826 (August 1994)' bestimmt:
DATA art_Masse / 105658., 105658.,
+ 106169., 106680.,
+ 510.9991, 510.9991,
+ 938272.3, 938783.3, 939294.3,
+ 1877055.6, 1877566.6, 1878077.6,
+ 3727380.2,
+ 37.96238E6,37.22371E6,74.44896E6,111.673689E6,111.673178E6,
+ 13.043273 ,26.087057,
+ 78.16258E6,78.162070E6,
+ 16.77623E6,33.55297E6,50.32971E6,67.10644E6,83.88318E6,
+ 17.71501E6,34.49175E6,51.26849E6,68.04523E6,84.82197E6,
+ 101.59870E6,118.37544E6,135.15218E6,151.92892E6
+ /
DATA art_Ladung / +1., -1.,
+ 0., -1.,
+ +1., -1.,
+ +1., 0., -1.,
+ +1., 0., -1.,
+ +2.,
+ +1., +2., +1., +1., +2.,
+ +1., +1.,
+ +1., +2.,
+ +1., +1., +1., +1., +1.,
+ +1., +1., +1., +1., +1.,
+ +1., +1., +1., +1.
+ /
DATA neutral_fract / artenMax*0. /
DATA artList / ' ' /
DATA artList_defined /.false./
c - - - - - - - - - - Trigger-Detektor- - - - - - - - - - - - - - - - - - - - -
DATA TriggerInBeam / .false. /
DATA Thickness / 3.0 /
DATA log_aufStreu / .false. /
DATA log_aufstreu_fixed / .false. /
DATA log_Meyer_Gauss / .false. /
DATA log_Meyer_F_Function / .false. /
DATA sigmaAufstreu / 5. /
DATA log_E_Verlust / .false. /
DATA log_E_Verlust_defined / .false. /
DATA log_E_Verlust_ICRU / .false. /
DATA log_E_Straggling_sigma / .false. /
DATA log_E_Straggling_equal / .false. /
DATA log_E_Straggling_Lindhard / .false. /
DATA log_E_Straggling_Yang / .false. /
DATA mean_E_Verlust / 2.5 /
DATA calculate_each / .false. /
DATA sigmaE / 0.5 /
DATA lowerE / 0. /
DATA upperE / 0.1 /
DATA graphitData / .false. /
DATA log_neutralize / .false. /
DATA generate_FE / .false. /
DATA TransTDFoil / 100. /
c - - - - - - - - - - Programmsteuerung - - - - - - - - - - - - - - - - - - - -
DATA alfaTgtVertically/ .false. /
DATA scaleFactor / 1. /
DATA UseDecay / .false. /
DATA UseDecay_ / .false. /
DATA UseDecay_prevSim / .false. /
DATA DEBUG / .false. /
DATA DEBUG_FE / .false. /
DATA log_alpha0_KS / .false. /
DATA gotFileNr / .false. /
DATA TestRun / .false. /
DATA log_confine / .false. /
DATA TestOnWireHit / .false. /
DATA upToTDFoilOnly / .false. /
DATA createFoilFile / .false. /
DATA lense2 / .false. /
c - - - - - - - - - - Graphikausgabe- - - - - - - - - - - - - - - - - - - - - -
DATA GRAPHICS / .false. /
DATA GRAPHICS_Anzahl / 25 /
DATA plot_FE / .false. /
DATA vertical / .true. /
DATA n_postSkript / 1 /
DATA imonitor / 2 /
DATA color / 0 /
DATA schnitt_p / 2 /
DATA schnitt_x / -1. /
c - - - - - - - - - - FileName- - - - - - - - - - - - - - - - - - - - - - - - -
DATA filename / 'MU_' /
c - - - - - - - - - - Vorgaben fuer das Summary - - - - - - - - - - - - - - - -
DATA n_outWhere / 2 /
DATA LogFile / .false. /
DATA smallLogFile / .false. /
DATA statsInSummary / .false. /
! 'statInSummary' wird indirekt im SUB 'read_inputFile' ueber die
! lokalen Variablen 'SUM_*' initialisiert (alle auf .false.)
DATA log_out_FE / .false. /
DATA log_out_pfosten / .false. , .false./
c - - - - - - - - WELCHE FILES sollen erzeugt werden? (ausser .SUM)- - - - - -
DATA createTabellen / .false. /
! 'createTabelle' wird indirekt im SUB 'read_inputFile' ueber die
! lokalen Variablen 'TAB_*' initialisiert (alle auf .false.)
DATA createPhysTab / .false. /
DATA createNtp / .false. /
DATA Fo_triggered / .false. /
DATA xM2_triggered / .false. /
DATA M2_triggered / .false. /
DATA NTP_Koord / .false. /
DATA NTP_S1xM2 / .false. /
DATA NTP_times / .false. /
DATA NTP_FoM2Only / .false. /
DATA NTP_charge / .false. /
DATA NTP_start / .false. /
DATA NTP_stop / .false. /
DATA NTP_40mm / .false. /
DATA NTP_Folie / .false. /
DATA NTP_steps / .false. /
DATA NTP_Koord / .false. /
c - - - - - - - - - - Fehlerkontrolle - - - - - - - - - - - - - - - - - - - - -
DATA eps_x / 1.e-5 /
DATA eps_v / 1.e-5 /
DATA log_relativ / .false. /
DATA maxStep / 6000 /
DATA dtsmall / .001 /
DATA maxBelowDtSmall / 50 /
DATA idealMirror / .false. /
c - - - - - - - - - - Programmablauf- - - - - - - - - - - - - - - - - - - - - -
DATA accelVersionIndx / -1 /
DATA mutrackVersionIndx / -1 /
DATA n_dtsmall / 0 /
DATA n_dtsmall_Max / 0 /
DATA dtsmall_counter / 0 /
DATA LostInTD_counter / 0 /
DATA Lost_counter / 0 /
DATA Startflaeche / 0 /
DATA SchleifenNr / 0 /
c Ausgabekanaele (fuer die 'do indx = indx1, indx2 ....' Anweisungen):
DATA lun / lunLOG, lunScreen /
DATA OneLoop / .false. /
DATA OneStartPerLoop / .false. /
DATA log_percent / .false. /
DATA Use_ACCEL / .false. /
DATA Use_MUTRACK / .false. /
DATA fromScratch / .true. /
DATA previousSettings / .false. /
DATA guard / .true. /
DATA gridInFrontOfFoil / .false. /
c fuer Random-Generator: 'seed' soll gross und ungerade sein. ->
c nimm den Sinus von secnds, und mache daraus durch Multiplikation mit ent-
c sprechender 10er-Potenz eine 8stellige Integer-Zahl. Sollte seed dann
c gerade sein, mache es ungerade:
help1= abs(sin(secnds(0.))) ! abs(), da sonst log10(sec) zu Fehler fuehrt
seed = int(help1* 10.**(8-int(log10(help1)) ) )
if ((seed/2)*2.EQ.seed) seed=seed-1 ! z.B. seed=3 -> seed/2=1, wegen Integer

View File

@ -0,0 +1,50 @@
c===============================================================================
c MAP_DEF_FO.INC
c===============================================================================
c in diesem File sind die notwendigen Groessen und Speicher fuer die Integration
c der Teilchenbahnen im Bereich vor der TD-Folie mittels des Programms 'MUTRACK'
c niedergelegt:
c general items:
c (also known in some other parts of the program via include file
c 'COM_KAMMER.INC')
real Beschl_Faktor
COMMON /Beschl_Faktor_Fo/ Beschl_Faktor
character*40 MappenName
real dl_max ! naeherungsweise Obergrenze fuer die einzelnen
! Schrittlaengen:
real MappenLaenge
real xEnterMap
COMMON /integration_Fo/ MappenName,dl_max,MappenLaenge,xEnterMap
c the grid characteristics:
real Dx,Dr
integer imax,jmax
real xmax,rmax
COMMON /integration_Fo/ Dx,Dr,imax,jmax,xmax,rmax
c der Uebergabebereich am MappenEnde:
real xStartUeber
real xEndUeber
COMMON /integration_FO/ xStartUeber,xEndUeber
c the map:
integer maxmem
parameter (maxmem = 20595)
real map(0:maxmem)
COMMON /integration_Fo/ map

View File

@ -0,0 +1,56 @@
c===============================================================================
c MAP_DEF_L1.INC
c===============================================================================
c in diesem File sind die notwendigen Groessen und Speicher fuer die Integration
c der Teilchenbahnen im Bereich der Linse 1 mittels des Programms 'MUTRACK'
c niedergelegt:
c general items:
c (also known in some other parts of the program via include file
c 'COM_KAMMER.INC')
real Beschl_Faktor
COMMON /Beschl_Faktor_L1/ Beschl_Faktor
character*40 MappenName
real dl_max ! naeherungsweise Obergrenze fuer die einzelnen
! Schrittlaengen:
real xCenterOfLense
real xEnterMap
real xLeaveMap
COMMON /integration_L1/ MappenName,dl_max,xCenterOfLense,xEnterMap,xLeaveMap
real DistanceCyl
real iRadiusCyl
real LengthOuterCyl
real oRadiusOuterCyl
real LengthInnerCyl
real oRadiusInnerCyl
real RadiusVacTube
COMMON /integration_L1/ DistanceCyl,iRadiusCyl
COMMON /integration_L1/ LengthOuterCyl,oRadiusOuterCyl
COMMON /integration_L1/ LengthInnerCyl,oRadiusInnerCyl
COMMON /integration_L1/ RadiusVacTube
c the grid characteristics:
real Dx,Dr
integer imax,jmax
real xmax,rmax
COMMON /integration_L1/ Dx,Dr,imax,jmax,xmax,rmax
c the map:
integer maxmem
parameter (maxmem = 13133)
real map(0:maxmem)
COMMON /integration_L1/ map

View File

@ -0,0 +1,66 @@
c===============================================================================
c MAP_DEF_L2andFo.INC
c===============================================================================
c in diesem File sind die notwendigen Groessen und Speicher fuer die Integration
c der Teilchenbahnen im Bereich der Linse 2 bis zur Folie des Triggerdetektors
c mittels des Programms 'MUTRACK' niedergelegt:
c general items:
c (also known in some other parts of the program via include file
c 'COM_KAMMER.INC')
real Beschl_Faktor
COMMON /Beschl_Faktor/ Beschl_Faktor
character*40 MappenName
real dl_max ! naeherungsweise Obergrenze fuer die einzelnen
! Schrittlaengen:
real xCenterOfLense
real xEnterMap
real xLeaveMap,xEndLense
COMMON /integration_L2andFo/ MappenName,dl_max,
+ xCenterOfLense,xEndLense,xEnterMap,xLeaveMap
real DistanceCyl
real iRadiusCyl
real LengthOuterCyl
real oRadiusOuterCyl
real LengthInnerCyl
real oRadiusInnerCyl
real RadiusVacTube
COMMON /integration_L2andFo/ DistanceCyl,iRadiusCyl
COMMON /integration_L2andFo/ LengthOuterCyl,oRadiusOuterCyl
COMMON /integration_L2andFo/ LengthInnerCyl,oRadiusInnerCyl
COMMON /integration_L2andFo/ RadiusVacTube
c the grid characteristics:
real Dx,Dr
integer imax,jmax
real xmax,rmax
COMMON /integration_L2andFo/ Dx,Dr,imax,jmax,xmax,rmax
c der Uebergabebereich am MappenEnde:
real xStartUeber
real xEndUeber
COMMON /integration_L2andFo/ xStartUeber,xEndUeber
c the map:
integer maxmem
parameter (maxmem = 26143)
real map(0:maxmem)
COMMON /integration_L2andFo/ map

View File

@ -0,0 +1,60 @@
c===============================================================================
c MAP_DEF_L3.INC
c===============================================================================
c in diesem File sind die notwendigen Groessen und Speicher fuer die Integration
c der Teilchenbahnen im Bereich der Linse 3 mittels des Programms 'MUTRACK'
c niedergelegt:
c general items:
c (also known in some other parts of the program via include file
c 'COM_KAMMER.INC')
real Beschl_Faktor
COMMON /Beschl_Faktor_L3/ Beschl_Faktor
character*40 MappenName
real dl_max ! naeherungsweise Obergrenze fuer die einzelnen
! Schrittlaengen:
real xCenterOfLense
real xEnterMap
real xLeaveMap
COMMON /integration_L3/ MappenName,dl_max,xCenterOfLense,xEnterMap,xLeaveMap
real DistanceCyl
real iRadiusCyl
real LengthOuterCyl
real oRadiusOuterCyl
real LengthInnerCyl
real oRadiusInnerCyl
real RadiusVacTube
COMMON /integration_L3/ DistanceCyl,iRadiusCyl
COMMON /integration_L3/ LengthOuterCyl,oRadiusOuterCyl
COMMON /integration_L3/ LengthInnerCyl,oRadiusInnerCyl
COMMON /integration_L3/ RadiusVacTube
c the grid characteristics:
real Dx,Dr
integer imax,jmax
real xmax,rmax
COMMON /integration_L3/ Dx,Dr,imax,jmax,xmax,rmax
c the map:
integer maxmem
parameter (maxmem = 75586)
c parameter (maxmem = 22320)
c parameter (maxmem = 20301)
c parameter (maxmem = 7523)
real map(0:maxmem)
COMMON /integration_L3/ map

View File

@ -0,0 +1,51 @@
c===============================================================================
c MAP_DEF_M2.INC
c===============================================================================
c in diesem File sind die notwendigen Groessen und Speicher fuer die Integration
c der Teilchenbahnen im Bereich vor dem MCP2 mittels des Programms 'MUTRACK'
c niedergelegt:
c general items:
c (also known in some other parts of the program via include file
c 'COM_KAMMER.INC')
real Beschl_Faktor
COMMON /Beschl_Faktor_M2/ Beschl_Faktor
character*40 MappenName
real dl_max ! naeherungsweise Obergrenze fuer die einzelnen
! Schrittlaengen:
real xMCP2
real xEnterMap
real radius_MCP2
COMMON /integration_M2/ MappenName,dl_max,xMCP2,xEnterMap,radius_MCP2
c the grid characteristics:
real Dx,Dr
integer imax,jmax
real xmax,rmax
COMMON /integration_M2/ Dx,Dr,imax,jmax,xmax,rmax
c der Uebergabebereich am MappenEnde:
real xStartUeber
real xEndUeber
COMMON /integration_M2/ xStartUeber,xEndUeber
c the map:
integer maxmem
parameter (maxmem = 38504)
real map(0:maxmem)
COMMON /integration_M2/ map

View File

@ -0,0 +1,38 @@
c===============================================================================
c MAP_DEF_SP_1.INC
c===============================================================================
real Beschl_Faktor
COMMON /Beschl_Faktor_SP/ Beschl_Faktor
character*40 MappenName
real dl_max ! naeherungsweise Obergrenze fuer die einzelnen
! Schrittlaengen:
COMMON /integration_SP/ MappenName,dl_max
real xSpGrid1,xSpGrid2 ! Gitterpositionen innerhalb der Mappe [mm]
real DSpiegel ! Abstand der Spiegelgitter
real dWires_Sp ! Drahtdurchmesser
real dist_Wires_Sp ! Drahtabstand
COMMON /integration_Sp/ xSpGrid1,xSpGrid2,DSpiegel,
* dWires_Sp,dist_Wires_Sp
c the grid characteristics:
real Dx,Dy
integer imax,jmax
real xmin,xmax,ymax
COMMON /integration_SP_1/ xmin,xmax,ymax,Dx,Dy,imax,jmax
c the map:
integer maxmem
parameter (maxmem = 3684)
real map(0:maxmem)
COMMON /integration_SP_1/ map

View File

@ -0,0 +1,32 @@
c===============================================================================
c MAP_DEF_SP_2.INC
c===============================================================================
real Beschl_Faktor
COMMON /Beschl_Faktor_SP/ Beschl_Faktor
character*40 MappenName
real dl_max ! naeherungsweise Obergrenze fuer die einzelnen
! Schrittlaengen:
COMMON /integration_SP/ MappenName,dl_max
c the grid characteristics:
real Dx,Dy
integer imax,jmax
real xmin,xmax,ymax
COMMON /integration_SP_2/ xmin,xmax,ymax,Dx,Dy,imax,jmax
c the map:
integer maxmem
parameter (maxmem = 8420)
real map(0:maxmem)
COMMON /integration_SP_2/ map

View File

@ -0,0 +1,32 @@
c===============================================================================
c MAP_DEF_SP_3.INC
c===============================================================================
real Beschl_Faktor
COMMON /Beschl_Faktor_SP/ Beschl_Faktor
character*40 MappenName
real dl_max ! naeherungsweise Obergrenze fuer die einzelnen
! Schrittlaengen:
COMMON /integration_SP/ MappenName,dl_max
c the grid characteristics:
real Dx,Dy
integer imax,jmax
real xmin,xmax,ymax
COMMON /integration_SP_3/ xmin,xmax,ymax,Dx,Dy,imax,jmax
c the map:
integer maxmem
parameter (maxmem = 6600)
real map(0:maxmem)
COMMON /integration_SP_3/ map

5466
mutrack/src/MUTRACK.FOR Normal file

File diff suppressed because it is too large Load Diff

5400
mutrack/src/MUTRACK_OLD.FOR Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,532 @@
c===============================================================================
c ERLAEUTERUNGEN : siehe Datei-Ende
c===============================================================================
c KOMMENTARZEILEN: (Zeilen beginnend mit '@')
c===============================================================================
$parameter_liste
TestRun = T ! -> fileNummern zwischen 9900 und 9999 [false]
!==============================================================================
! WEITERFUEHRUNG FRUEHERER SIMULATIONEN
!==============================================================================
fileName_ACCEL = 'ac_9915' ! ACCEL-file
fileName_MUTRACK = 'mu_9915' ! prev. MUTRACK sim. up to TD-Foil
previousSimulation = 1 ! fruehere Simulation fortfuehren? [ 0 ]
! 0 : fromScratch
! 1 : ACCEL
! 2 : MUTRACK ('FoilFile')
! im Fall von 'priviousSimulation' = 1 oder = 2 (ACCEL oder MUTRACK):
previousSettings = T ! uebernehme fruehere Schleifensettings [false]
ow_U_Tgt = f ! - aber ueberschreibe 'U_Tgt_' [false]
ow_U_Gua = f ! - aber ueberschreibe 'U_Gua_' [false]
ow_U_G1 = f ! - aber ueberschreibe 'U_G1_' [false]
ow_U_L1 = f ! - aber ueberschreibe 'U_L1_' [false]
ow_U_Sp = f ! - aber ueberschreibe 'U_Sp_' [false]
ow_U_L2 = f ! - aber ueberschreibe 'U_L2_' [false]
ow_U_Folie = f ! - aber ueberschreibe 'U_Folie_' [false]
!ow_B_TD = NICHT IMPLEMENTIERT ueberschreibe 'BTD_' [false]
!ow_B_Helm = NICHT IMPLEMENTIERT ueberschreibe 'BHelm_' [false]
ow_masse = f ! - aber ueberschreibe 'masse_' [false]
ow_ladung = f ! - aber ueberschreibe 'ladung_' [false]
ow_E0 = T ! - aber ueberschreibe 'E0_' [false]
ow_y0 = f ! - aber ueberschreibe 'y0_' [false]
ow_z0 = f ! - aber ueberschreibe 'z0_' [false]
ow_theta0 = f ! - aber ueberschreibe 'theta0_' [false]
ow_phi0 = f ! - aber ueberschreibe 'phi0_' [false]
ow_alfaTgt = f ! - aber ueberschreibe 'alfaTgt_' [false]
ow_alfaSp = f ! - aber ueberschreibe 'alfaSp_' [false]
ow_alfaTD = f ! - aber ueberschreibe 'alfaTD_' [false]
ow_deltaL1 = f ! - aber ueberschreibe 'deltaL1_' [false]
ow_artList = f ! - aber ueberschreibe 'artlist' [false]
!==============================================================================
! KAMMER-SETTINGS UND TEILCHEN-PARAMETER
!==============================================================================
! Einheiten: Spannungen in kV, Winkel in degree, Masse in keV/c**2,
! Ladung in pos.Elementarlad., Energie in keV, Laengen in mm,
! Zeiten in ns, Geschwindigkeiten in mm/ns
!------------------------------------------------------------------------------
! - - - - - - - - - - Schleifen-Parameter - - - - - - - - - - - - - - - - - - -
U_Tgt_ = 18 ! U(Target) [ 0. ]
U_Gua_ = 15 ! U(Guard) [ 0. ]
U_G1_ = 12 ! U(Gitter) [ 0. ]
U_L1_ = 5 ! U(kalte Linse) [ 0. ]
U_Sp_ = 13.5 ! U(Spiegel) [ 0. ]
U_L2_ = 4.5 ! U(warme Linse) [ 0. ]
U_L3_ = 4.5 ! U(warme Linse) [ 0. ]
U_Folie_ = -2.980 ! U(Folie) [ 0. ]
U_Vorne_ = -2.790 ! U(Vorne) [ 0. ]
U_Hinten_ = -3.230 ! U(Hinten) [ 0. ]
U_MCP3_ = -2.600 ! U(MCP3) [ 0. ]
U_MCP2_ = -1.87 ! U(MCP2) [ 0. ]
!B_TD_ = NICHT IMPLEMENTIERT ! BFeld(Kompensationsspule) [ 0. ]
!B_Helm_ = NICHT IMPLEMENTIERT ! BFeld(Helmholtzpule) [ 0. ]
alfaTgtVertically = f ! alfa(Target) = vertikale Verkippung
alfaTgt_ = 0 ! alfa(Target) (x=0,y=90) [ 0. ]
alfaSp_ = 45 ! alfa(Spiegel) (x=0,y=90) [45. ]
alfaTD_ = 0 ! alfa(Trigger) (x=0,y=90) [ 0. ]
Masse_ = 0 ! (*) Masse [105659]
Ladung_ = 0 ! (*) Ladung [ 1. ]
E0_ = 0.01 ! (*) Startenergie (in keV!) [ 0. ]
y0_ = 0 ! (*) y0 (Startposition) [ 0. ]
z0_ = 0 ! (*) z0 (Startposition) [ 0. ]
theta0_ = 0 ! (*) theta0 (Startwinkel)(x=0) [ 0. ]
phi0_ = 0 ! (*) phi0 (Startwinkel)(y=0,z=90)[ 0. ]
Thickness_ = 3 ! Foliendicke in ug/cm**2 [ 3.0]
mean_Eloss_= 15 ! mittlerer Energieverlust in keV [ 0.0]
DeltaL1_ = 0! -3,3,3 ! Verlaengerung 1 in mm [ 0.0]
DeltaL2_ = 0! -5,+5,1 ! Verlaengerung 2 in mm [ 0.0]
! (*) <-> siehe Dateiende
! - - - - - - - - - - Zufallsverteilte Startparameter - - - - - - - - - - - - -
randomStarts = 5000 ! Anzahl zufallsverteilter Starts [ 50 ]
! Start-Energie:
random_energy = 1 ! 0: gemaess 'E0_' [ 0 ]
! 1: E0_ + gleichverteilter Offset
! 2: E0_ + gaussverteilter Offset
lowerE0 = .000 ! min. Energie (in keV!) [0.000]
upperE0 = .001 ! max. Energie (in keV!) [0.010]
sigmaE0 = .005 ! Breite der Gaussverteilung [0.010]
! Start-Position:
random_position = 0 ! 0: gemaess 'y0_' und 'z0_' [ 0 ]
! 1: gleichverteilt auf Viereckflaeche
! 2: gleichverteilt auf Kreisflaeche
! 3: Gaussverteilt auf Viereckflaeche
! 4: Gaussverteilt auf Kreisflaeche
StartBreite = -1 ! [TargetBreite]
StartHoehe = -1 ! [TargetHoehe ]
StartRadius = -1 ! [ 40 ]
sigmaPosition = 15 ! Breite der Gaussverteilung [ 15 ]
! Start-Winkel:
random_winkel = 0 ! 0: gemaess 'theta0_' und 'phi0_' [ 0 ]
! 1: Lambertverteilt
! 2: Gaussverteilt
StartLambertOrd = 1 ! Ordnung der Lambert-Verteilung [ 1. ]
sigmaWinkel = 5 ! Breite der Gaussverteilung [ 1. ]
! - - - - - - - - - - Projektile (case-sensitive) - - - - - - - - - - - - - - -
! maximal 9 verschiedene aus:
! e+, e-, m+, m-, Mu, Mu-, H+, H, H-, H2+, H2, H2-, alfa ![ ' ' ]
! H2O1, H2O2, H2O3, H2O4, H2O5,
! Hyd1, Hyd2, Hyd3, Hyd4, Hyd5, Hyd6, Hyd7, Hyd8, Hyd9,
! A11+, A12+, A21+, A31+, A32+, N11+, N21+, K11+, K12+
! H2O1,H2O2,..,H2Oi,..: Wassercluster (H2O)i
! Hyd1,Hyd2,..,Hydi,..: protonierte Wassercluster [(H2O)i]H+
! A: Argon, N: Stickstoff, K: Krypton
! (alle Zeichen in artList nach einem '!' werden ignoriert)
artList = 'm+'
! nur verwendet falls 'log_neutralize = t': neutrale Anteile in %
! (eine Angabe je Projektil, '-1' -> verwende Funktion von M. Gonin
! fuer Neutralisierung von Protonen in Graphit).
neutral_fract = 0
! - - - - - - - - - - Trigger-Detektor- - - - - - - - - - - - - - - - - - - - -
TriggerInBeam = t ! TriggerDetektor im Strahlweg? [false]
transTDFoil = 88. ! Transmission der Folie in % [100.]
log_neutralize = F ! Neutralisierung in der Folie? [false]
n_E_Verlust = 5 ! 0: kein Energieverlust [ 0 ]
!<0: mittl. Verlust gemaess 'mean_Eloss_'
!>0: mittl. Verlust gemaess ICRU-Tabelle
!|1| keine Energieaufstreuung
!|2| Streuung gaussvert. gemaess 'sigmaE'
!|3| Streuung gleichvert. [lowerE,upperE]
!|4| Streuung gaussv. nach Lindhard/Scharff
!|5| Streuung gaussv. nach Yang (recommended
calculate_each = F ! bei ICRU: fuer jedes Teilchen neu? [false]
graphitData = F ! bei ICRU: Elossdaten fuer Graphit? [false]
! (Alternative: amorpher Kohlenstoff)
sigmaE = 0.5 ! GaussBreite des Energieverlustes [ .5]
lowerE = 0 ! untere Grenze fuer Energieverlust [ 0. ]
upperE = 0.050 ! obere Grenze fuer Energieverlust [ .1]
n_Aufstreu = 3 ! 0: keine Winkelaufstreuung [ 0 ]
! 1: gemaess 'sigmaAufstreu'
! 2: gemaess Meyer (gaussverteilte Winkel)
! 3: gemaess Meyer (nach f-Funktion)
sigmaAufstreu = 2. ! Gaussbreite der Aufweitung [ 5. ]
generate_FE = F ! FolienElektronen generieren? [false]
!==============================================================================
! AUSGABE - STEUERUNG
!==============================================================================
writeTraj2File = f ! Um das rausschreiben der Trajektorie in ein separates
! file 'OUT.TRAJ' zu ermoeglichen, muessen im SourceCode
! alle mit 'cMBc' herauskommentierten Zeilen aktiviert
! werden. (Dieses feature wurden fuer M.B. implementiert
! aber wegen Rechenzeitargumenten herauskommentiert)
! - - - - - - - - PHYSICA-Tabelle erstellen?- - - - - - - - - - - - - - - - - -
createPhysTab = f ! [false]
! welche Statistiken?
PHY_S1xM2 = t ! S1xM2 im PHYSICA-file? [false]
PHY_S1M2 = t ! S1M2 im PHYSICA-file? [false]
PHY_S1Fo = t ! S1Fo im PHYSICA-file? [false]
PHY_FoM2 = t ! FoM2 im PHYSICA-file? [false]
PHY_S1M3 = t ! S1M3 im PHYSICA-file? [false]
PHY_M3M2 = t ! M3M2 im PHYSICA-file? [false]
PHY_t_FE = t ! tFE im PHYSICA-file? [false]
PHY_y_Fo = t ! y(Folie) im PHYSICA-file? [false]
PHY_z_Fo = t ! z(Folie) im PHYSICA-file? [false]
PHY_r_Fo = t ! r(Folie) im PHYSICA-file? [false]
PHY_y_M2 = t ! y(MCP2) im PHYSICA-file? [false]
PHY_z_M2 = t ! z(MCP2) im PHYSICA-file? [false]
PHY_r_M2 = t ! r(MCP2) im PHYSICA-file? [false]
PHY_y_xM2 = t ! y(xMCP2) im PHYSICA-file? [false]
PHY_z_xM2 = t ! z(xMCP2) im PHYSICA-file? [false]
PHY_r_xM2 = t ! r(xMCP2) im PHYSICA-file? [false]
! welche statistischen Groessen?
PHY_mean = t ! Mittelwerte? [false]
PHY_variance = t ! Varianzen? [false]
PHY_minimum = t ! Minimalwerte? [false]
PHY_maximum = t ! Maximalwerte? [false]
PHY_percent = t ! rel. Anteil beitragender Teilchen? [false]
! - - - - - - - - NTupel-relevante Vorgaben - - - - - - - - - - - - - - - - - -
createNTP = t ! NTP-File erzeugen [false]
Fo_triggered = F ! TD-Folientreffer verlangt [false]
xM2_triggered = F ! Erreichte MCP2-Ebene verlangt [false]
M2_triggered = F ! MCP2-Treffer verlangt [false]
smearS1Fo = f ! Verschmierung von S1Fo in NTP (zur
sigmaS1fo = 1.6 ! Beruecksichtigung der Zeitaufloesung)
NTP_S1xM2 = F ! - Flugzeit bis MCP2-Ebene? [false]
NTP_times = F ! - sonstige Flugzeiten? [false]
NTP_FoM2Only = F ! - von 'times' nur FoM2 (rezessiv!) [false]
NTP_lifetime = F ! - Lebenszeiten? [false]
NTP_start = F ! - Startgroessen? [false]
NTP_stop = F ! - Stopgroessen? [false]
NTP_40mm = F ! - Groessen bei x=40mm? [false]
NTP_Folie = t ! - Everlust und Aufstreuung? [false]
NTP_charge = F ! - Ladungszustand nach Folie? [false]
NTP_steps = F ! - min. und max. Schrittweiten? [false]
! - - - - - - - - - - Vorgaben fuer das Summary - - - - - - - - - - - - - - - -
n_outWhere = 2 ! 0-> keine Ausgabe des Summarys [ 2 ]
! 1-> Ausgabe nur in Datei
! 2-> in Datei und auf Schirm
! 3-> nur auf Schirm
!-1-> nur kleines Logfile
SUM_S1xM2 = t ! S1xM2 im Summary? [false]
SUM_S1M2 = t ! S1M2 im Summary? [false]
SUM_S1Fo = t ! S1Fo im Summary? [false]
SUM_FoM2 = t ! FoM2 im Summary? [false]
SUM_S1M3 = t ! S1M3 im Summary? [false]
SUM_M3M2 = t ! M3M2 im Summary? [false]
SUM_t_FE = t ! tFE im Summary? [false]
SUM_y_Fo = t ! y(Folie) im Summary? [false]
SUM_z_Fo = t ! z(Folie) im Summary? [false]
SUM_r_Fo = t ! r(Folie) im Summary? [false]
SUM_y_M2 = t ! y(MCP2) im Summary? [false]
SUM_z_M2 = t ! z(MCP2) im Summary? [false]
SUM_r_M2 = t ! r(MCP2) im Summary? [false}SUM_FoM2SUM_FoM2
SUM_y_xM2 = t ! y(xMCP2) im Summary? [false]
SUM_z_xM2 = t ! z(xMCP2) im Summary? [false]
SUM_r_xM2 = t ! r(MxCP2) im Summary? [false}SUM_FoM2SUM_FoM2
log_out_FE = F ! die FE-Statistik im Summary? [false]
log_out_pfosten(1)= F ! P : Pfosten einzeln im Summary? [false]
log_out_pfosten(2)= F ! FE: Pfosten einzeln im Summary? [false]
! - - - - - - - - File mit zugrundeliegender Geometrie erstellen? - - - - - - -
write_geo = T ! [false]
! - - - - - - - - zu erstellende Tabellenfiles- - - - - - - - - - - - - - - - -
Tab_S1xM2 = F ! Tabelle S1xM2 [false]
Tab_S1M2 = F ! Tabelle S1M2 [false]
Tab_S1Fo = F ! Tabelle S1Fo [false]
Tab_FoM2 = F ! Tabelle FoM2 [false]
Tab_S1M3 = F ! Tabelle S1M3 [false]
Tab_M3M2 = F ! Tabelle M3M2 [false]
Tab_t_FE = F ! Tabelle tFE [false]
Tab_y_Fo = F ! Tabelle y(Folie) [false]
Tab_z_Fo = F ! Tabelle z(Folie) [false]
Tab_r_Fo = F ! Tabelle r(Folie) [false]
Tab_y_M2 = F ! Tabelle y(MCP2) [false]
Tab_z_M2 = F ! Tabelle z(MCP2) [false]
Tab_r_M2 = F ! Tabelle r(MCP2) [false]
Tab_y_xM2 = F ! Tabelle y(xMCP2) [false]
Tab_z_xM2 = F ! Tabelle z(xMCP2) [false]
Tab_r_xM2 = F ! Tabelle r(xMCP2) [false]
! - - - - - - - - - - Graphikausgabe- - - - - - - - - - - - - - - - - - - - - -
GRAPHICS = F ! Graphikausgabe der Trajektorien? [false]
GRAPHICS_Anzahl = 40 ! fuer wieviele Starts je Schleife? [ 25 ]
vertical = T ! Blick auf die Kammer VON OBEN? [true!]
log_marker = F ! Marker am Trajektorienende? [false]
plot_FE = F ! FE-Trajektorien plotten? [false]
n_postSkript = 0 ! Postskript-files erstellen? [ 1 ]
! 0 : nicht erstellen
! 1 : Abfrage nach jeder Schleife
! 2 : immer erstellen
iMonitor = 3 ! Abtastfrequenz fuer Graphik [ 2 ]
color = 1 ! 0=schwarzweiss, 1=farbig [ 0 ]
schnitt_p = 2 ! Kammerteil: 1=horiz., 2=vertikal [ 2 ]
schnitt_x = -1 ! x-Koord. der Schnittebene [MCP2]
!==============================================================================
! GRUNDEINSSTELLUNGEN
!==============================================================================
! - - - - - - - - - - Programmsteuerung - - - - - - - - - - - - - - - - - - - -
TestOnWireHit = t ! Drahttreffer beruecksichtigen? [false]
UseDecay = t ! MYONEN-Zerfall beruecksichtigen? [false]
upToTDFoilOnly = F ! Integration nur bis zur TD-Folie [false]
createFoilFile = F ! neues 'FoilFile' erstellen? [false]
idealMirror = F ! Spiegel als ideal betrachten? [false]
DEBUG = F ! Debug-Version? [false]
DEBUG_FE = F ! FE in Debug-Info? [false]
DEBUG_Anzahl = 3 ! fuer wieviele Starts je Schleife? [ 2 ]
! - - - - - - - - - - Geometrie - - - - - - - - - - - - - - - - - - - - - - - -
Geo_fileName = 'GEO_KAMMER_RUN9_NEW_MUONS'
! Geo_fileName = 'GEO_KAMMER_RUN9_NEW_PROTONS'
! Geo_fileName = '9nM' ! RunNummer bzw. Name des Geo-files
! Geo_fileName = '9' ! RunNummer bzw. Name des Geo-files
! '9n': mit laengerer Mappe fuer MCP2
gridInFrontOfFoil = f ! Gitter vor der Triggerfolie? [false]
! ('grindInFrontOfFoil' nur bei Run 9)
xBlende = -1 ! Abstand der Blende zum MCP2 (-1 => none)
radius_Blende = 0 ! Radius der Blende vor MCP2
! - - - - - - - - - - Startflaeche- - - - - - - - - - - - - - - - - - - - - - -
StartFlaeche = 0 !-1: entsprechend x0_ und Kammerteil [ 0 ]
! 0: Target
! 1: 1. Gitter
! 2: Folie (Startwinkel im Kammersystem)
! 3: Folie (Startwinkel im Triggersystem)
x0_ = 0 ! Startort rel zu. Tgt bzw. Spiegel [ 0. ]
Kammerteil = 1 ! 1: horizontal, 2: vertikal [ 1 ]
! - - - - - - - - - - Fehlerkontrolle - - - - - - - - - - - - - - - - - - - - -
eps_x = 1.e-6 ! max. Fehler im Ort [1.e-5]
eps_v = 1.e-6 ! max. Fehler in Geschw. [1.e-5]
log_relativ = F ! relative Fehlerbetrachtung? [false]
maxStep = 7000 ! max. Anzahl Integrationsschritte [ 1000]
dtsmall = 0.00001 ! kleinster Integrations-Zeitschritt [0.001]
maxBelowDtSmall = 700 ! max. Anzahl von dtSmall Unterschr. [ 50 ]
! - - - - - - - - - - seed- - - - - - - - - - - - - - - - - - - - - - - - - -
seed_ = 0 ! > 1E6, ungerade (if .LE. 0 => automatic)
$END
c********************************************************************************
c*
c* In dieser Datei werden die Parameter fuer die Flugbahnberechnung von
c* Teilchen in der NEMU-Apparatur mittels des Fortranprogramms 'MUTRACK'
c* festgelegt.
c*
c* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
c*
c* Alle Zeilen vor der Zeile ' $parameter_liste', die nicht mit 'c ' beginnen
c* und keine Leerzeilen sind, werden als Kommentarzeilen fuer das Mutrack-
c* Programm betrachtet und im Kopf des Logfiles ausgegeben.
c*
c* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
c*
c* Bleibt die rechte Seite einer Zuweisung frei (variable = ), so wird der
c* am Zeilenende in eckigen Klammern angegebene Defaultwert verwendet.
c*
c* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
c*
c* Jeder Parameter des Abschnitts 'SCHLEIFEN-PARAMETER' kann einen, zwei
c* oder mehrere aequidistante Werte annehmen. Die Eingabe geschieht
c* entsprechend in einer der Formen
c*
c* _parameter = wert
c* _parameter = wert1 , wert2
c* _parameter = wert_min , wert_max , wert_step.
c*
c* Die Zuweisungen in den mit (*) markierten Zeilen des gleichen Abschnitts
c* kommen nur zum Tragen, wenn sie nicht durch prioritaere Zuweisungen
c* ueberdeckt werden. Fuer die Massen- und die Ladungsschleife geschieht dies
c* durch Spezifizieren von 'artList' im Abschnitt 'PROJEKTILE' (vgl. unten),
c* fuer die Energie-, Positions- und Winkel-Schleifen durch die Wahl einer
c* Zufallsverteilung fuer die entsprechende Groesse im Abschnitt 'ZUFALLS-
c* VERTEILTE STARTPARAMETER' ('random_energy', 'random_position' bzw.
c* 'random_winkel' > 0).
c*
c* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
c*
c* Wird die Variable 'artList' im Abschnitt 'PROJEKTILE' mit einer Komma-
c* getrennten Liste aus
c*
c* m+, m-, Mu, Mu-, e+, e-, H+, H, H-, H2+, H2, H2-, alfa,
c* A11+, A12+, A21+, A31+, A32+, N11+, N21+, K11+, K12+, X11+, X12+
c*
c* belegt (als String: z.B. 'm+,H+' ), so werden die Parameter 'Ladung' und
c* 'Masse' der Reihe nach mit den zugehoerigen Werten belegt.
c* (m=Myon, Mu=Myonium, e=Elektron, H=Wasserstoff, alfa=alpha-Teilchen).
c* Die zweite der beiden Zeilen gibt Kuerzel fuer Ionen schwererer Atome an:
c* 'Znm+' steht fuer einen "Cluster" aus n Atomen der Art 'Z' im Ladungszustand
c* m+.
c* A: Argon, N: Stickstoff, K: Krypton, X: Xenon.
c*
c* Soll diese Moeglichkeit nicht genutzt werden, so ist 'artList' undefiniert
c* zu belassen.
c*
c* Das Einlesen der Teilchenliste geschieht CASE-SENSITIVE. Ein '!' an
c* beliebiger Stelle der Teilchenliste bewirkt, dass alle Zeichen nach
c* dem ! ignoriert werden.
c*
c* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
c*
c* Befindet sich der Trigger im Strahlweg, so kann mit n_E_Verlust die Art
c* der Beruecksichtigung des Energieverlustes in der Triggerfolie gewaehlt
c* werden:
c*
c* n_E_Verlust=0: kein Energieverlust
c* n_E_Verlust=1: mittlerer Energieverlust gemaess 'mean_E_Verlust',
c* Breite der Energieverlustverteilung gemaess 'sigmaE'.
c* n_E_Verlust=2: Funktioniert nur mit einfach positiv geladenen
c* Teilchen und wenn die Startflaeche entweder der Moderator
c* oder das 1. Gitter ist. Der Energieverlust wird hier
c* ueber Geschwindigkeitsskalierung aus Protonendaten
c* gewonnen (ICRU-Tabelle). Im so erhaltenen Energieverlust
c* ist auch die Wegstreckenverlaengerung in der Folie
c* bei nicht senkrechtem Einfall beruecksichtigt (Einfalls-
c* richtung!). Mit 'sigmaE' ungleich Null kann die Energie-
c* verlustverteilung zusaetlich verbreitert werden.
c* Bei gewuerfelten Startenergien fuer die Projektile
c* wird fuer die Berechnung des mittleren Energieverlustes
c* der Mittelwert von 'lowerE0' und 'upperE0' verwendet, es
c* sei denn, dass 'calculate_each'=.true. gesetzt wurde.
c* In diesem Fall wird der Energieverlust fuer jedes
c* Teilchen neu berechnet. Dies soll es ermoeglichen,
c* groessere Bereiche fuer die Startenergie vorzugeben und
c* trotzdem sinnvolle Energieverluste zu erhalten.
c* Allerdings kann dies die Rechenzeit u. U. stark erhoehen.
c*
c* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
c*
c* Wird das logical 'log_marker' im Abschnitt 'Graphikausgabe' gesetzt, so
c* wird gegebenenfalls bei der Graphikdarstellung der Projektiltrajektorien
c* das Trajektorienende mit einem Marker versehen, wobei der Markertyp vom
c* Teilchenschicksal abhengt. Dabei gibt es aber momentan (Stand: Feb.96) noch
c* Probleme, da vor allem fuer Teilchen, die auf der aktiven Flaeche des
c* MCP2 aufschlagen, falsche Markertypen gewaehlt werden.
c* Scheint ein spezielles Problem der CERN-library zu sein und wird bis auf
c* weiteres nicht wieter verfolgt. Dieses feature wurde speziell fuer DEBUG-
c* Taetigkeiten entwickelt und sollte ansonsten nicht von besonderer Bedeutung
c* sein.
c* Die Teilchenschicksale und die zugehoerigen Markertypen sind:
c*
c* auf Rand des MCP2 : gefuellter Kreis
c* im TD abgebrochen : Stern (3 gekreuzte Linien)
c* Spiegel durchquert : gefuellter Kreis
c* MCP2 getroffen : leere Raute
c* zerfallen : Schweizerkreuz
c* Element verfehlt : leerer Kreis
c* reflektiert : leeres Dreieck
c* aufgeschlagen : gefuellter Kreis
c* verloren (steps>maxsteps) : gefuellter fuenfstrahliger Stern
c* Zeitschritt kleiner dtSmall : leerer fuenfstrahliger Stern
c*
c* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
c*
c* Der Name der Ausgabedateien lautet 'MU_nnnn', wobei 'nnnn' eine durch-
c* laufende Nummer ist. Die Ausgabedateien erhalten je nach Inhalt eine der
c* Extensionen
c*
c* .LOG -> Summary-file
c* .NTP -> PAW-Ntupel
c* ._??? -> Statistik-Tabellen
c* .PHYSICA -> Gestamttabelle fuer Graphische Darstellung mit PHYSICA
c* .PS -> Postskript-Files mit Graphik der Bahnkurven. Bei diesen
c* Dateien wird der Dateiname um die Nummer der jeweiligen
c* Schleife, zu der die Graphik gehoert, erweitert. (Insofern
c* mehr als eine Schleife durchlaufen wird).
c* .GEO -> file mit der verwendeten Kammergeometrie.
c* .FOIL -> file mit Trajektoriendaten am Ort der Triggerfolie. Kann
c* von spaeteren MUTRACK runs eingelesen werden.
c* .INFO -> Info-file zu .FOIL mit den verwendeten Parametersettings.
c*
c* Die Dateien werden im Directory 'mutrack$OUTdirectory' abgelegt.
c*
c* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
c*
c* Das Achsensystem ist mit dem Ursprung in die Mitte des Moderators
c* gelegt. Die x-Achse verlaeuft in Strahlrichtung, die z-Achse nach oben,
c* die y-Achse so, dass ein rechtshaendiges System besteht.
c* Nach dem Spiegel wird das Koordinatendreibein so gedreht, dass die x-Achse
c* wiederum in Strahlrichtung weist. Der Ursprung wird dabei in das Zentrum
c* des Doppelkreuzes der Spiegelaufhaengung verschoben.
c*
c* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
c*
c* *****************************************************************
c* * Die Zeilen *
c* * $PARAMETER_LISTE *
c* * und *
c* * $END *
c* * MUESSEN IN SPALTE ZWEI BEGINNEN! *
c* *****************************************************************
c* * 26.09.1995 >> anselm.hofer@psi.ch *
c*******************************************************************************

48
mutrack/src/READ_MAP.INC Normal file
View File

@ -0,0 +1,48 @@
c===============================================================================
c READ_MAP.INC
c===============================================================================
c Dieser Includefile erledigt fuer die Subroutinen 'READ_MAP_xx' das Einlesen
c der Potentialmappe und falls notwendig die Fehlerausgabe.
INCLUDE 'mutrack$sourcedirectory:COM_DIRS.INC'
INCLUDE 'mutrack$sourcedirectory:COM_LUNS.INC'
integer i,j, ihelp, iostat
c Einlesen der Potentialmappe:
open (lunRead,file=mappenName//'.MAPPE',
+ defaultfile=mappenDir,status='old',
+ form='unformatted',recl=imax+1,readonly)
c + form='unformatted',recl=imax,readonly)
do j = 0, jmax
ihelp = j*(imax+1)
read(lunREAD,iostat=iostat) (map(ihelp+i),i=0,imax)
if (iostat.NE.0) then
write(*,*)
write(*,999) i,j,iostat
write(*,*)' Potentialmappe: ',mappenName
write(*,*)' Directory : ',mappenDir
write(*,*)
STOP
endif
enddo
close(lunREAD)
999 format(7x'error reading grid point (i,j) = ('i4','i4')'/7x'iostat = 'i4)
c da die Elektrodenbereiche bei RELAX3D negativ kodiert sind, nimm die
c Absolutbetraege:
ihelp = 0
do j=0, jmax
do i=0, imax
map(ihelp) = abs(map(ihelp))
ihelp = ihelp + 1
enddo
enddo

View File

@ -0,0 +1,48 @@
c===============================================================================
c READ_MAP.INC
c===============================================================================
c Dieser Includefile erledigt fuer die Subroutinen 'READ_MAP_xx' das Einlesen
c der Potentialmappe und falls notwendig die Fehlerausgabe.
INCLUDE 'mutrack$sourcedirectory:COM_DIRS.INC'
INCLUDE 'mutrack$sourcedirectory:COM_LUNS.INC'
integer i,j, ihelp, iostat
c Einlesen der Potentialmappe:
open (lunRead,file=mappenName//Nr//'.MAPPE',
+ defaultfile=mappenDir,status='old',
+ form='unformatted',recl=imax+1,readonly)
c + form='unformatted',recl=imax,readonly)
do j = 0, jmax
ihelp = j*(imax+1)
read(lunREAD,iostat=iostat) (map(ihelp+i),i=0,imax)
if (iostat.NE.0) then
write(*,*)
write(*,999) i,j,iostat
write(*,*)' Potentialmappe: ',mappenName
write(*,*)' Directory : ',mappenDir
write(*,*)
STOP
endif
enddo
close(lunREAD)
999 format(7x'error reading grid point (i,j) = ('i4','i4')'/7x'iostat = 'i4)
c da die Elektrodenbereiche bei RELAX3D negativ kodiert sind, nimm die
c Absolutbetraege:
ihelp = 0
do j=0, jmax
do i=0, imax
map(ihelp) = abs(map(ihelp))
ihelp = ihelp + 1
enddo
enddo

226
mutrack/src/SUB_ARTLIST.FOR Normal file
View File

@ -0,0 +1,226 @@
cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
c
c Die Routinen dieser Datei werden in das Programm 'MUTRACK' eingebunden und
c dort von der Routine 'READ_INPUTFILE' aufgerufen.
c
c Aufgabe dieser Routinen ist es, aus der Variablen 'ArtList' (so ihr in der
c INPUT-Datei ein Wert zugewiesen wurde) die zu verwendenden Projektilarten zu
c extrahieren und die zugehoerigen Code-Nummern in das Feld 'art_Nr'
c einzutragen. Dieses wird dann im Hauptprogramm dazu benutzt, den Massen-
c und den Ladungsspeicher entsprechend den zu den Teilchen gehoerigen Werten
c zu belegen. Wurden in 'artList' keine Teilchenarten spezifiziert, so werden
c fuer die Einstellungen der Massen- und der Ladungsschleife im Hauptprogramm
c die Vorgaben fuer '_Masse' bzw. '_Ladung' aus dem INPUT-file verwendet.
c
c Die Subroutine EXAMINE_ARTLIST kopiert zunaechst buchstabenweise die Variable
c 'ArtList' in die Variable 'helpTxt', wobei saemtliche blanks entfernt werden.
c Anschliessend wird 'artList' geloescht. (Die Artenbezeichnungen werden spaeter
c formatiert wieder in 'artList' zurueckgeschrieben).
c Als naechstes werden aus 'HelpTxt' die Artenbezeichnungen einzeln in den
c Speicher 'testName' uebernommen und geprueft, ob die jeweilige Art erkannt
c wird. Ist die Artenbezeichnung laenger als vier Buchstaben, so erfolgt
c Programmabbruch mit Fehlermeldung (Routine ART_FEHLER). Das selbe passiert
c falls die Artenbezeichnung nicht erkannt wird.
c
c Wurde die Art erkannt, und befindet sie sich nicht schon in der Liste, so
c wird ihre Codezahl in das Feld 'art_Nr' uebernommen und wieder in die
c Variable 'ArtList' zurueckgeschrieben, wobei die Arten durch Komma und
c darauffolgendes blank getrennt werden.
c
c Wurden in 'artList' letztlich gueltige Artenbezeichnungen gefunden, so wird
c das logical 'artList_defined' auf .true. gesetzt und die Parameter fuer die
c Massen- und die Ladungs-Schleifen so eingestellt, dass erstere genau einen
c (Leer-) Durchlauf macht, letztere dagegen fuer jede gefundene Projektilart
c einen Durchgang vollfuehrt, in dem dann jeweils die zugehoerigen Ladungs- UND
c Massenwerte entsprechend den Inhalten der Speicher art_Ladung(artNr) und
c art_Masse(artNr) eingestellt werden.
c
cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
OPTIONS /EXTEND_SOURCE
SUBROUTINE EXAMINE_ARTLIST
c ==========================
implicit none
integer k,k1,j ! Zaehlvariablen
logical flag
integer length ! Laenge von helpTxt
integer pos ! Position in helpTxt
integer komma ! Position eines Kommas in helpTxt
integer nummer ! Nummer der naechsten erkannten Art
integer posL ! Position in ArtList
character helpChar*1, helpTxt*60, testName*4
INCLUDE 'mutrack$sourcedirectory:COM_MUTRACK.INC'
c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
if (artList.EQ.' ') RETURN
c Es wurden noch keine Teilchen mit Myonen gefunden:
mu_flag = .false.
c 'artList' in 'helpText' uebernehmen, dabei alle Blanks entfernen. Taucht ein
c '!' auf, so ignoriere den Rest.
helpTxt = ' '
length = 0
do pos = 1, len(artList)
helpChar = artlist(pos:pos)
if (helpChar.EQ.'!') goto 1
if (helpChar.NE.' ') then
length = length+1
helpTxt(length:length) = helpChar
endif
enddo
c write(*,*) 'artList = ',artList
c write(*,*) 'helpTxt = ',helpTxt
1 artList = ' '
c die Arten nacheinander in testName uebernehmen, und pruefen, ob sie erkannt
c werden:
nummer = 1
pos = 1
posL = 1
komma = 0
do while (komma.LT.length+1)
komma = INDEX(helpTxt,',') ! Position des ersten Kommas
if (komma.EQ.0) komma = length+1 ! falls kein ',' mehr, nimm Rest
c write(*,*) 'pos = ',pos
c write(*,*) 'komma = ',komma
if (komma-pos.GT.4) then ! ArtName hat max. 4 Lettern
call art_Fehler (helpTxt(pos:komma-1))
STOP
elseif (komma.NE.pos) then ! sonst: 2 Kommas hintereinander
testName = helpTxt(pos:komma-1)
!c Pruefen, ob die Art bekannt ist. Wenn ja, pruefe, ob die Art
!c nicht schon in der Liste ist. Falls Nein, gib die Nummer der
!c entsprechenden Art in Art_Nr(nummer) und haenge den ArtNamen
!c gefolgt von Komma und Leerzeichen an artList an:
do k = 1, arten_zahl ! arten_Zahl = Anzahl bekannter Teilchenarten
if (testName.EQ.art_Name(k)) then ! Teilchenart erkannt
if (nummer.GT.1) then
do k1 = 1, nummer-1 ! Test, ob Art schon in Liste
if (Art_Nr(k1).EQ.k) then
! -> Teilchen schon in Liste
if (.NOT.log_neutralize .OR. upToTDFoilOnly) then
! ueberspringen:
goto 2
elseif (neutral_fract(nummer).EQ.neutral_fract(k1)) then
! -> Teilchen hat auch gleichen neutralen Anteil
! wie zuvor => ueberspringe Eintragungen in
! 'artList' und 'neutral_fract':
do j = nummer,artenMax-1
neutral_fract(j) = neutral_fract(j+1)
enddo
goto 2
endif
endif
enddo ! => next, please!
endif
art_Nr(nummer) = k
if (k.LE.4) mu_flag = .true.
artList(posL:posL+komma-pos+1) =
+ helpTxt(pos:komma-1)//', '
posL = posL + komma-pos+2 ! Position fuer naechste Art
nummer = nummer + 1 ! definieren
if (nummer.GT.artenMax) goto 3 ! nicht mehr als artenMax Arten
goto 2 ! next, please
endif
enddo
!c Art wurde nicht erkannt -> Fehlermeldung und Abbruch:
call art_Fehler(testName)
STOP
endif
2 if (komma.LT.length+1) helpTxt(komma:komma) = '#' ! , durch # ersetzen
pos = komma+1 ! und dann von vorne
enddo
3 artList(posL-2:posL-2)=' ' ! letztes Komma entfernen
c Wenn wir hier landen, wurden Teilchen in 'artList' gefunden und erkannt!
artList_defined = .true.
c falls jetzt 'log_neutralize' gesetzt ist, pruefe, ob bei wenigstens einem der
c Teilchen in 'artList' tatsaechlich Neutralisierung in der Folie verlangt ist.
c Ansonsten setze 'log_neutralize' auf .false.:
flag = .false.
do k = 1, nummer-1
if ((neutral_fract(k).LT.0. .AND. neutral_fract(k).NE.-1.) .OR.
+ neutral_fract(k).GT.100.) then
neutral_fract(k) = 0.
endif
if (neutral_fract(k).GT.0. .OR. neutral_fract(k).EQ.-1.) flag = .true.
enddo
if (.not.flag) log_neutralize = .false.
c Falls 'artList' kein Myonen-Teilchen enthaelt, braucht auch der Myonzerfall
c nicht beruecksichtigt zu werden:
if (.NOT.mu_flag) UseDecay = .false.
c Die Massen- und die Ladungsschleife einstellen:
par(1,mass) = 1. ! Masse-Schleife macht genau einen Durchgang
par(2,mass) = 1.
par(3,mass) = 1.
par(1,charge) = 1. ! Ladungsschleife macht fuer jede
par(2,charge) = nummer-1 ! Projektilart einen Durchgang
par(3,charge) = 1.
END
C===============================================================================
SUBROUTINE ART_FEHLER(artText)
c ==============================
character artText*4
write (*,*)
write (*,1) ' >>>>> Art '''//artText//''' ist unbekannt'
write (*,1) ' >>>>> Gueltig Artenbezeichnungen sind:'
write (*,1) ' >>>>> e+, e-, m+, m-, Mu, Mu-, H+, H, H-, '//
+ 'H2+, H2, H2-, alfa'
write (*,1) ' >>>>> A11+, A12+, A21+, A31+, A32+, N11+, N21+, '//
+ 'K11+, K12+, X11+, X12+'
write (*,1) ' >>>>> (das Einlesen erfolgt CASE SENSITIVE!)'
write (*,*)
1 format(T10,A)
END
c===============================================================================

663
mutrack/src/SUB_ELOSS.FOR Normal file
View File

@ -0,0 +1,663 @@
c===============================================================================
OPTIONS /EXTEND_SOURCE
SUBROUTINE CALC_ELOSS_ICRU(E0,q,m,Thickness,Everlust)
c =====================================================
c Einheiten:
c ----------
c Energie: [E0] = keV
c Ladung: [q] = e
c Masse: [m] = keV/c**2, wird auf m(Proton) umgerechnet
c Foliendicke [Thickness] = ug/cm**2 ! => 'masse'
c Energieverlust [Everlust] = keV
IMPLICIT NONE
real E0,EVerlust ! Startenergie und Energieverlust
real E,q,m,masse,Thickness ! Energie,Masse,Ladung,Foliendicke
real x ! aktuelle Position in der Folie
real dx ! Vorgabe fuer Dickenschritt
COMMON /ELoss_Ex/ E,x
COMMON /ELoss_masse / masse
integer steps ! Nummer des aktuellen Integrationsschrittes
integer maxSteps /2000/ ! maximal tolerierte Anzahl an Schritten
c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
c Ueberpruefen ob (q.EQ.+1), sonst macht diese Energieverlustberechnung keinen
c Sinn:
if (q.NE.1) then
write(*,*)
write(*,*) 'SUBROUTINE CALC_ELOSS_ICRU: Teilchenladung q = ',q
write(*,*)
write(*,*) 'Berechnung des Energieverlustes aus Protonendaten nur'
write(*,*) 'fuer Teilchen mit Ladungszahl q = +1 implementiert'
write(*,*)
write(*,*) '-> STOP'
write(*,*)
STOP
endif
c Startwerte setzen:
masse = m / 938272.3 ! Umrechnen in Protonenmassen
E = E0 ! aktuelle Energie auf Startenergie setzen
x = 0. ! Wir beginnen auf der Folienforderseite
dx = .05 ! Dring beim ersten Versuch 0.05 Mikrogramm/cm**2 in
! die Folie ein
steps = 0. ! Zaehler fuer Anzahl der Integrationsschritte resetten
c...............................................................................
c hierher wird zurueckgesprungen, solange Folienende noch nicht erreicht ist.
10 if (x+dx.GT.Thickness) dx = Thickness-x ! Schritt erreicht Folienende
Steps = Steps + 1
call INTEGRATION_ELOSS(dx)
if (x.EQ.Thickness) then
EVerlust = E0 - E
c write(*,*) 'Ein, ELoss = ',E0,EVerlust
c write(*,'(A,i4,A)') ' calculation of ''ELOSS'' needed ',steps,' steps'
RETURN
elseif (x.GT.Thickness+1.E-5) then
EVerlust = E0 - E
write(*,*)
write(*,*) 'SUBROUTINE CALC_ELOSS_ICRU: x > Foliendicke'
write(*,*)
write(*,*) 'x = ',x
write(*,*) 'Thickness = ',Thickness
write(*,*) 'x-Thickness = ',x-Thickness
write(*,*) 'E0 = ',E0
write(*,*) 'E = ',E
write(*,*) 'EVerlust = ',EVerlust
write(*,*) 'maxSteps = ',maxSteps
write(*,*) 'steps = ',steps
write(*,*)
write(*,*) '-> STOP'
write(*,*)
STOP
elseif (Steps.GT.MaxSteps) then
write(*,*)
write(*,*) 'SUBROUTINE CALC_ELOSS_ICRU:'
write(*,*)
write(*,*) 'Berechnung des Energieverlustes nicht innerhalb der erlaubten'
write(*,*) 'Maximalzahl an Schritten vollendet:'
write(*,*)
write(*,*) 'steps = ',steps
write(*,*) 'maxSteps = ',maxSteps
write(*,*) 'x = ',x
write(*,*) 'Thickness = ',Thickness
write(*,*) 'Thickness-x = ',Thickness-x
write(*,*)
write(*,*) '-> STOP'
write(*,*)
STOP
else
goto 10
endif
END
c===============================================================================
OPTIONS /EXTEND_SOURCE
SUBROUTINE INTEGRATION_ELOSS(dx)
c ================================
IMPLICIT NONE
SAVE
c Diese Subroutine berechnet zu einem vorgegebenen Dickenschritt dx den
c Energieverlust zweimal: einmal direkt mit dx und einmal ueber zwei
c aufeinanderfolgende Schritte mit dx/2. (die beiden dx/2-Schritte werden
c zuerst ausgefuehrt).
c
c Aus der Differenz der beiden Resultate wird eine Abschaetzung fuer den Fehler
c des dx-Schrittes gewonnen, die dazu verwendet wird zu entscheiden, ob der
c Integrationsschritt mit einem verkuerzten Dickenintervall wiederholt werden
c muss, oder ob das Dickenintervall fuer den folgenden ausgedehnt werden kann.
c
c Die beiden Einzelergebnisse aus dem dx- und den beiden dx/2-Schritten, die
c jeweils ueber Runge-Kutta-Rechnung vierter Ordnung erhalten werden, werden
c zum Schluss noch zusammengenommen, um ein Resultat mit Genauigkeit fuenfter
c Ordnung in dx zu erhalten.
c
c Der ganze Ablauf entspricht den Ausfuehrungen in Kapitel 15.2 der NUMERICAL
c RECIPIES: 'Adaptive Stepsize Control for Runge-Kutta'.
c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
real E ! aktuelle Energie bei Aufruf und
! Verlassen der Routine
real x ! aktuelle Position in der Folie
COMMON /ELoss_Ex/ E,x
logical log_relativ /.false./ ! relative Fehlerbetrachtung?
real eps /1e-8/ ! verlangte Genauigkeit des einzelnen
! Integrationsschrittes
real dxsmall /.001/ ! minimale Dickenaenderung
integer n_dxSmall ! wie oft wurde dxSmall unterschritten
integer maxBelowDxSmall / 50 / ! max. tolerierte Anzahl an Unterschr.
real dx ! Dickenschritt
real dx_half ! halber Dickenschritt
real dE_dx_0,dE_dx_1 ! Stoppingpower
real E1,DE1,DE2 ! fuer Energieintegration
real EDifferenz ! fuer Fehlerbetrachtung
real Error ! fuer Fehlerbetrachtung
real errCon, safety ! fuer Schrittweitensteuerung
real pShrink, pGrow ! fuer Schrittweitensteuerung
PARAMETER (errCon = 6.e-4, safety = .9) ! vgl. Referenz
PARAMETER (pShrink = -.25, pGrow = -.2)
! errCon = (4./safety)**(1/pGrow)
logical flag_dxSmall ! wenn bei dx < dxsmall der Fehler
! immer noch zu gross ist.
c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
flag_dxSmall = .false. ! flag resetten
c Lese stopping power bei aktueller Energie. Speichere sie in dE_dx_0, damit sie
c wiederverwendet werden kann, falls die Berechnung mit kuerzerem Dickenschritt
c wiederholt werden muss.
call stoppingPower(E,dE_dx_0)
c...............................................................................
10 continue ! hier gehts wieder von vorne los, falls Dickenschritt dx
! abgeaendert werden muss.
dx_half = dx / 2.
c mache ersten dx/2 - Schritt:
call RK4_ELOSS(dx_half,E,dE_dx_0,DE1)
c Lese stopping power bei Energie E1=E+DE1 und mache zweiten dx/2 - Schritt:
E1 = E+DE1
call stoppingPower(E1,dE_dx_1)
call RK4_ELOSS(dx_half,E1,dE_dx_1,DE2)
c Summiere Energieverluste der beiden dx/2 -Schritte und speichere in DE1:
DE1 = DE1 + DE2
c mache dx - Schritt:
call RK4_ELOSS(dx,E,dE_dx_0,DE2)
c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
c Fehlerbetrachtung und Berechnung des endgueltigen Ergebnisses:
C Fehlerbetrachtung: der groesste (absolute bzw. relative) Fehler soll kleiner
C als eps sein:
Error = 0.
EDifferenz = DE1-DE2
if (log_relativ) then
if (DE1.NE.0.) then
Error = Abs( EDifferenz/DE1 )
elseif (DE2.NE.0.) then
Error = Abs( EDifferenz/DE2 )
endif
else
Error = Abs( EDifferenz )
endif
c - Skaliere Fehler auf Epsilon:
Error = Error / eps
c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
c Die Groesse des reskalierten 'Error' bestimmt, ob der Integrationsschritt
c mit kleinerem Dickenintervall wiederholt werden muss, bzw. um welchen
c Faktor das Dickenintervall fuer den naechsten Schritt vergroessert werden
c kann:
c Liegt der Fehler ausserhalb des Toleranzbereiches und ist dx bereits jetzt
c kleiner als dxsmall, so mache keinen neuen Versuch sondern akzeptiere als Not-
c loesung den bestehenden Naeherungswert. Setze dx in diesem Fall als Default
c fuer den kommenden Integrationsschritt auf dxsmall. Setze aber auch das flag
c 'flag_dxsmall', damit gezaehlt werden kann, wie oft dieses Prozedur angewendet
c werden muss. Ist dies zu oft der Fall, so brich die Berechnung ganz ab.
c (2. Teil erfolgt weiter unten)
if (Error.GT.1.) then
if (dx.LT.dxsmall) then ! Fehler immer noch zu gross, obwohl
flag_dxsmall = .true. ! dxsmall schon unterschritten ist
else
!c Bestimme kuerzeren Dickenschritt fuer neuen Versuch (vgl. Referenz):
dx = safety * dx * (Error**pShrink)
goto 10
endif
endif
c Nimm die Ergebnisse aus dem dx-Schritt und den beiden dx/2-Schritten und
c berechne damit den Energieverlust mit Genauigkeit fuenfter Ordnung in dx:
E = E + DE1 + EDifferenz / 15.
c alten Dickenschritt addieren, neuen so gross wie sinnvoller weise moeglich
c machen:
x = x + dx
if (flag_dxSmall) then
if (n_dxsmall.LT.maxBelowdxSmall) then
dx = dxSmall ! fuer naechsten RK-Schritt
n_dxsmall = n_dxsmall + 1
else
write(*,*) 'n_dxSmall ueberschritten! -> STOP'
STOP
endif
else
if (Error.GT.errCon) then
dx = safety * dx * (Error**pGrow) ! vgl. Referenz
else
dx = 4. * dx ! <- Vergroesserung des Dickenschritts max. um
endif ! Faktor 4!
endif
END
c===============================================================================
OPTIONS /EXTEND_SOURCE
SUBROUTINE RK4_ELOSS(dx_,EIn,dE_dx_0,DE)
c ========================================
IMPLICIT NONE
SAVE
c Diese Subroutine berechnet bei vorgegebenem Dickenschritt einen einzelnen
c Runge-Kutta-Integrationsschritt 4. Ordnung.
c Die Vorgehensweise entspricht den Ausfuehrungen in Kapitel 15.1 der
c NUMERICAL RECIPIES: 'Runge-Kutta Method'. Die Formeln sind zwar teilweise
c etwas umgeschrieben, sind aber mathematisch alle aequivalent zu denen der
c Referenz.
c Zurueckgegeben wird die errechnete Energieaenderung anstatt direkt des neuen
c Wertes, da sonst Schwierigkeiten auftreten koennen, wenn in der Subroutine
c 'INTEGRATIONSSTEP_ELOSS' aus der Differenz der neuen Werte aus den beiden
c dx/2- und dem dx-Schritt der Fehler abgeschaetzt werden soll (kleine
c Differenz moeglicherweise grosser Werte).
real dE_dx_0, EIn ! Eingangsgroessen
real dx_,dx_half_ ! Dickenschritt, halber Dickenschritt
real DE ! Ergebnisspeicher
real Test_E ! Test-Energie
real dE_dx_1,dE_dx_2,dE_dx_3 ! Stoppingpower bei Test-Energien
c First step of Runge-Kutta-Method:
dx_half_ = dx_ / 2.
Test_E = EIn + dE_dx_0 * dx_half_
c Second step of Runge-Kutta-Method:
call stoppingPower(Test_E,dE_dx_1)
Test_E = EIn + dE_dx_1 * dx_half_
c Third step of Runge-Kutta-Method:
call stoppingPower(Test_E,dE_dx_2)
Test_E = EIn + dE_dx_2 * dx_
c Fourth step of Runge-Kutta-Method:
call stoppingPower(Test_E,dE_dx_3)
c calculate forward step:
DE = (dE_dx_0 + 2.*(dE_dx_1+dE_dx_2) + dE_dx_3) * dx_/6.
END
c===============================================================================
OPTIONS /EXTEND_SOURCE
SUBROUTINE stoppingPower(E_,dE_dx)
c =================================
IMPLICIT NONE
real E_,dE_dx,StoPo_
integer DatenZahl
parameter (DatenZahl=56)
real E(DatenZahl)
real StoPoGr(DatenZahl) ! fuer Graphit
real StoPoAK(DatenZahl) ! fuer amorphen Kohlenstoff
real Ep ! Energie von Protonen mit gleicher Geschwindigkeit
real masse ! Masse der Teilchen in Protonenmassen
COMMON /ELoss_masse / masse
integer i
logical graphitData
common /elossDataType/ graphitData
c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
c Zu den Einzelbeitraegen von Elektronen und Kernen vergleiche die Programme
c NUCL_AND_EL_STOP_AMORPH.FOR und NUCL_AND_EL_STOP_GRAPHIT.FOR im directory
c UD0:[SIMULA.PROGRAMS.ICRU-ELOSS] auf der SLOMU in Konstanz.
c
c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
c
c Die Daten sind aus dem ICRU Report 49 entnommen:
c
c ICRU Report 49: 'Stopping Powers and Ranges for Protons and Alpha Particles'
c Signatur PSI-Bibliothek West: 850 B 1:49
c Tabelle Seite 112: PROTONS IN CARBON (Graphite, density 1.7 g/cm^3)
c Spalte: TOTAL STOPPING POWER (= electronic plus nuclear)
DATA E / 0.,
+ 001,001.5,002,002.5,003,004,005,006,007,008,009,
+ 010,012.5,015,017.5,020,022.5,025,027.5,030,035,040,
+ 045,050,055,060,065,070,075,080,085,090,095,
+ 100,125,150,175,200,225,250,275,300,350,400,
+ 450,500,550,600,650,700,750,800,850,900,950 /
c Die hier aufgelisteten Werte sind um Faktor 10000. zu gross. -> Wird unten
c reskaliert.
c Dies sind die totalen Stoppingpowerdaten fuer Graphit!
c Diese wurden bis Version 1.5.6 von Mutrack ausschliesslich verwendet.
DATA StoPoGr / 0.,
+ 1677,1963,2214,2443,2652,2958,3241,3500,3738,3946,4132,
+ 4303,4678,4991,5264,5510,5731,5927,6101,6259,6551,6823,
+ 7067,7274,7441,7574,7677,7755,7810,7845,7861,7860,7846,
+ 7819,7548,7153,6721,6297,5908,5561,5254,4982,4543,4196,
+ 3906,3654,3433,3240,3073,2925,2793,2675,2568,2470,2380 /
c Dies sind die totalen Stoppingpowerdaten fuer amorphen Kohlenstoff!
DATA StoPoAK / 0.,
+ 1635,1906,2140,2351,2544,2826,3086,3323,3541,3730,3899,
+ 4055,4393,4675,4919,5140,5338,5512,5666,5806,6066,6307,
+ 6523,6706,6854,6970,7061,7129,7178,7208,7221,7222,7209,
+ 7185,6955,6619,6254,5897,5566,5265,4996,4755,4362,4048,
+ 3782,3549,3343,3162,3004,2864,2739,2626,2524,2429,2343 /
c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
if (E_.LT.0) then
write(*,*)
write(*,*) 'error in subroutine ''STOPPINGPOWER'':'
write(*,*) 'E_ = ',E_,' < 0!'
write(*,*) '-> STOP'
write(*,*)
STOP
endif
c Energie auf diejenige Energie reskalieren, die ein Proton haette, wenn es
c sich mit der gleichen Geschwindigkeit bewegen wuerde, wie das Teilchen der
c Masse 'masse', das sich mit der Energie 'E_' bewegt:
Ep = E_/masse ! masse ist in Protonenmassen angegeben
c suche zustaendige Stelle in der Tabelle:
do i = 1, DatenZahl
if (E(i).GE.Ep) goto 10
enddo
write(*,*)
write(*,*) 'error in subroutine ''STOPPINGPOWER'': Ep > Ep_max'
write(*,*) '-> STOP'
write(*,*)
STOP
10 continue
c Berechne die Stoppingpower (ueber lineare Interpolation):
if (i.lt.2) then
write(*,*) 'i = ',i
STOP
endif
if (graphitData) then
StoPo_ = StoPoGr(i-1) + (StoPoGr(i)-StoPoGr(i-1))*(Ep-E(i-1))/(E(i)-E(i-1))
else
StoPo_ = StoPoAK(i-1) + (StoPoAK(i)-StoPoAK(i-1))*(Ep-E(i-1))/(E(i)-E(i-1))
endif
dE_dx = - StoPo_ / 10000. ! negativieren und reskalieren
END
c===============================================================================
OPTIONS /EXTEND_SOURCE
SUBROUTINE E_Straggling_Yang(mean_E,m,sigmaEloss)
c =================================================
IMPLICIT NONE
c Dieses Routine berechnet die Energieverluststreuung fuer einfach geladenen
c Teilchen in der Kohlenstofffolie entsprechend den empirischen Formeln von
c Q. Yang: "Empirical formulae for energy loss straggling of ions in matter",
c Q. Yang, D.J. O'Connor, Y. Wang, NIM B61, S. 149-155 (1991)
c Eingabeparameter: Foliendicke, Teilchenart und Eingangsenergie.
c Ausgabegroesse: Energieverluststraggling
c Einheiten:
c ----------
c Energie: [E0] = keV
c Ladung: [q] = e
c Masse: [m] = keV/c**2, wird auf m(Proton) umgerechnet
c Foliendicke [Thickness] = ug/cm**2 ! => 'masse'
c Straggling: [sigmaEloss] = keV
INCLUDE 'mutrack$sourcedirectory:COM_MUTRACK.INC'
real mean_E ! mittlere Energie in Folie
real m ! Masse
real mean_Ep ! mean_E umgerechnet auf Protonenmasse
! (fuer sigmaE = 0)
real sigmaEloss ! Energieverluststreuung (Ausgabevariable)
c real sigmaInhom ! Streuung aufgrund von Dickeninhomog.
real Z2
parameter (Z2 = 6.) ! Kernladungszahl von Kohlenstoff
real factor_Thickness ! fuer Umrechnung von ug/cm**2
parameter (factor_Thickness=6.022e23/12.011e6) ! in Atome/cm**2
! 6.022e23: Avogadrokonstante
! 12.011e6: molare Masse in ug.
real eSquare ! fuer Umrechnung in SI-System
parameter (eSquare = 1.44e-10) ! keV*cm
real fourPi
parameter (fourPi = 12.56637061)
real factor_Bohr ! fuer Berechnung der Streuung nach Bohr
parameter (factor_Bohr = fourPi*Z2*eSquare*eSquare*factor_Thickness)
real OmQuad, OmQuadBohr
real OmQuad_over_OmQuadBohr
real DOmQuad_over_OmQuadBohr
real OmQuadChu_over_OmQuadBohr
real Gamma, rHelp
real A1,A2,A3,A4
parameter (A1 = -0.5127, A2 = -0.8595, A3 = 0.5626, A4 = -0.8721)
real B1,B2,B3,B4
parameter (B1 = 0.1955, B2 = 0.6941, B3 = 2.522, B4 = 1.040)
c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
c Umrechnen der Energie auf Protonenenergie in MeV:
mean_Ep = mean_E * 938272.6/m / 1000. ! mean_Ep in MeV !!!
c Berechnen der Streuung:
! Streuung nach Bohr:
OmQuadBohr = factor_Bohr * Thickness
! Streuung nach Chu:
OmQuadChu_over_OmQuadBohr = 1. / (1. + A1*mean_Ep**A2 + A3*mean_Ep**A4)
! Streuung nach Yang:
Gamma = B3 * (1. - exp(-B4*mean_Ep))
rhelp = mean_Ep - B2
DOmQuad_over_OmQuadBohr = B1*Gamma / (rHelp*rHelp + Gamma*Gamma)
! Gesamtresultat:
OmQuad_over_OmQuadBohr = OmQuadChu_over_OmQuadBohr + DOmQuad_over_OmQuadBohr
OmQuad = OmQuad_over_OmQuadBohr * OmQuadBohr
c Folieninhomogenitaeten beruecksichtigen:
c OmQuad = OmQuad + (sigmaInhom * sigmaInhom)
c Endgueltige Energiestreuung:
sigmaEloss = SQRT(OmQuad)
END
c===============================================================================
OPTIONS /EXTEND_SOURCE
SUBROUTINE E_Straggling_Lindhard(mean_E,m,sigmaEloss)
c =====================================================
IMPLICIT NONE
c Dieses Routine berechnet die Energieverluststreuung fuer einfach geladenen
c Teilchen in der Kohlenstofffolie entsprechend den Formeln von J. Lindhard
c und M. Scharff
c Eingabeparameter: Foliendicke, Teilchenart und Eingangsenergie.
c Ausgabegroessen: Energieverluststraggling
c Einheiten:
c ----------
c Energie: [E0] = keV
c Ladung: [q] = e
c Masse: [m] = keV/c**2, wird auf m(Proton) umgerechnet
c Foliendicke [Thickness] = ug/cm**2 ! => 'masse'
c Straggling: [sigmaEloss] = keV
INCLUDE 'mutrack$sourcedirectory:COM_MUTRACK.INC'
real mean_E ! mittlere Energie in Folie
real m ! Masse, Foliendicke
real sigmaEloss ! Energieverluststreuung (Ausgabevariable)
c real sigmaInhom ! Streuung aufgrund von Dickeninhomog.
real sigmaQuad
real help,L_y,y ! Fuer Berechnung der Lindhard-Scharff Korrektur
real v_over_v0_Quad
real fourPi
parameter (fourPi = 12.56637061)
real Z2
parameter (Z2 = 6.) ! Kernladungszahl von Kohlenstoff
real factor_v0Quad ! fuer Geschwindigkeitsskalierung auf v0
parameter (factor_v0Quad = 37574.632) ! (Bohrgeschwindigkeit)
! = 1/(13.6eV/me) , me in keV/c**2 eingesetzt
real factor_Thickness ! fuer Umrechnung von ug/cm**2
parameter (factor_Thickness=6.022e23/12.011e6) ! in Atome/cm**2
! 6.022e23: Avogadrokonstante
! 12.011e6: molare Masse in ug.
real eSquare ! fuer Umrechnung in SI-System
parameter (eSquare = 1.44e-10) ! keV*cm
real factor_Bohr ! fuer Berechnung der Streuung nach Bohr
parameter (factor_Bohr = fourPi*Z2*eSquare*eSquare*factor_Thickness)
c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
c Sigma nach Bohr berechnen:
sigmaQuad = factor_Bohr * Thickness
c Korrektur nach Lindhard & Scharff beruecksichtigen:
v_over_v0_Quad = mean_E/m * factor_v0Quad
y = v_over_v0_Quad / Z2
if (y.LT.3.) then
help = SQRT(y)
L_y = 1.36 * help - .016 *help*help*help
sigmaQuad = sigmaQuad * L_y / 2.
endif
c Folieninhomogenitaeten beruecksichtigen:
c sigmaQuad = sigmaQuad + (sigmaInhom * sigmaInhom)
c Endgueltige Energiestreuung berechnen:
sigmaEloss = SQRT(sigmaQuad)
END
c===============================================================================

3017
mutrack/src/SUB_INPUT.FOR Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,698 @@
c===============================================================================
OPTIONS /EXTEND_SOURCE
SUBROUTINE READ_INFO_FO
c =======================
IMPLICIT NONE
character*(*) Nr
parameter (Nr='FO')
INCLUDE 'mutrack$sourcedirectory:COM_LUNS.INC'
INCLUDE 'mutrack$sourcedirectory:COM_DIRS.INC'
INCLUDE 'mutrack$sourcedirectory:MAP_DEF_FO.INC'
c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
namelist /grid_info/
+ Dx,Dr, imax,jmax, xmax,rmax
c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
logical map_error
COMMON /map_error/ map_error
c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
c Einlesen der Mappen-Informationen:
open (lunREAD,file=mappenName//'.INFO',defaultfile=mappenDir,
+ readonly,status='old')
read (lunREAD,nml=grid_info)
close(lunREAD)
c eingelesene imax und jmax um 1 reduzieren, da in 'MUTRACK' die Feldindizes
c ab 0 laufen, bei 'RELAX3D' jedoch ab 1:
imax = imax-1
jmax = jmax-1
c die geometrischen Daten fuer Mutrack zusammenstellen:
MappenLaenge = xmax
c Uebergabebereich am MappenEnde definieren:
xStartUeber = xmax - 0.5*Dx
xEndUeber = xmax + 0.5*Dx
c checken, ob der reservierte Speicherplatz ausreicht:
if ((imax+1)*(jmax+1).NE.maxmem+1) then
write(*,*)'----------------------------------------'//
+ '----------------------------------------'
write(*,*) Nr//'-Mappe: ',mappenName
write(*,*) ' BENOETIGTER Speicher: (imax+1)*(jmax+1) = ',(imax+1)*(jmax+1)
write(*,*) ' RESERVIERTER Speicher: maxmem + 1 = ',maxmem + 1
write(*,*)
if ((imax+1)*(jmax+1).GT.maxmem+1) then
write(*,*) '=> reservierter Speicherplatz ist ungenuegend.'
write(*,*)
write(*,*) '=> ''maxmem'' in mutrack$sourcedirectory:MAP_DEF_'//Nr//'.INC angleichen,'
write(*,*) ' dann Programm mit ''LINKMUV'' am DCL-Prompt neu kompilieren'
write(*,*) ' und linken.'
write(*,*)
write(*,*) ' Mindestwert fuer ''maxmem'' ist ',(imax+1)*(jmax+1)-1
write(*,*)
map_error = .true.
endif
endif
END
c===============================================================================
OPTIONS /EXTEND_SOURCE
SUBROUTINE READ_MAP_FO
c ======================
IMPLICIT NONE
character*(*) Nr
parameter (Nr='FO')
INCLUDE 'mutrack$sourcedirectory:MAP_DEF_FO.INC'
INCLUDE 'mutrack$sourcedirectory:READ_MAP.INC'
END
c===============================================================================
OPTIONS /EXTEND_SOURCE
SUBROUTINE INTEGRATIONSSTEP_RUNGE_KUTTA_FO(dt)
c ==============================================
IMPLICIT NONE
SAVE
character*(*) Nr
parameter (Nr='Fo')
c Diese Subroutine berechnet zu einem vorgegebenen Zeitschritt dt den
c Integrationsschritt zweimal: einmal direkt mit dt und einmal ueber zwei
c aufeinanderfolgende Schritte mit dt/2. (die beiden dt/2-Schritte werden
c zuerst ausgefuehrt).
c
c Aus der Differenz der beiden Resultate wird eine Abschaetzung fuer den Fehler
c des dt-Schrittes gewonnen, die dazu verwendet wird zu entscheiden, ob der
c Integrationsschritt mit einem verkuerzten Zeitintervall wiederholt werden
c muss, oder ob das Zeitintervall fuer den folgenden ausgedehnt werden kann.
c
c Die beiden Einzelergebnisse aus dem dt- und den beiden dt/2-Schritten, die
c jeweils ueber Runge-Kutta-Rechnung vierter Ordnung erhalten werden, werden
c zum Schluss noch zusammengenommen, um ein Resultat mit Genauigkeit fuenfter
c Ordnung in dt zu erhalten.
c
c Der ganze Ablauf entspricht den Ausfuehrungen in Kapitel 15.2 der NUMERICAL
c RECIPIES: 'Adaptive Stepsize Control for Runge-Kutta' (vgl. Referenz im
c fileheader von 'MUTRACK.FOR')
INCLUDE 'mutrack$sourcedirectory:COM_MUTRACK.INC'
INCLUDE 'mutrack$sourcedirectory:MAP_DEF_FO.INC'
integer i ! Zaehlvariable
real dt,dt_half ! zeitl. Aenderung, halbe zeitl. Aenderung
real EFeld0(3),EFeld1(3) ! elektr. Felder
real x1(3),Dx1(3),Dx2(3) ! fuer Ortsintegration
real v1(3),Dv1(3),Dv2(3) ! fuer Geschw.Integration
real xDifferenz(3), vDifferenz(3)
real x_1 ! Hilfsvariable fuer testweises x(1)
real help1,help2
real maxErr_x,maxErr_v,maxErr ! fuer Fehlerbetrachtung
real errCon, safety ! fuer Schrittweitenkontrolle
real pShrink, pGrow ! fuer Schrittweitenkontrolle
PARAMETER (errCon = 6.e-4, safety = .9) ! vgl. Referenz
PARAMETER (pShrink = -.25, pGrow = -.2)
! errCon = (4./safety)**(1/pGrow)
logical flag_dtSmall ! wenn bei dt < dtsmall der Fehler
! immer noch zu gross ist.
logical found_lower ! obere und untere Grenze fuer dt um
logical found_upper ! Uebergabebereich zu treffen
real dtlower,dtupper
real help
integer returnCode_EFeld
COMMON /returnCode_EFeld/ returnCode_EFeld
! 1: TESTORT HINTER DER MAPPE
! 2: Testort neben der Mappe
! 3: TESTORT VOR DER MAPPE
c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
flag_dtSmall = .false. ! flag resetten
found_lower = .false.
found_upper = .false.
if (dt.LT.dtsmall) dt = dtsmall
c berechne EFeld am aktuellen Ort. Speichere in EFeld0, damit sie wiederverwendet
c werden kann, falls mit kuerzerem Zeitschritt wiederholt werden muss:
call EFeld_FO(x,EFeld0,*998)
c...............................................................................
10 continue ! hier gehts wieder von vorne los, falls Zeitschritt dt
! abgeaendert werden muss.
dt_half = dt / 2.
c mache ersten dt/2 - Schritt:
call SINGLESTEP_RUNGE_KUTTA_FO(dt_half,EFeld0,x,v, Dx1,Dv1 ,*999)
c berechne EFeld bei x1:
x1(1) = x(1) + Dx1(1)
x1(2) = x(2) + Dx1(2)
x1(3) = x(3) + Dx1(3)
v1(1) = v(1) + Dv1(1)
v1(2) = v(2) + Dv1(2)
v1(3) = v(3) + Dv1(3)
call EFeld_FO(x1,EFeld1,*999)
c mache zweiten dt/2 - Schritt:
call SINGLESTEP_RUNGE_KUTTA_FO(dt_half,EFeld1,x1,v1, Dx2,Dv2 ,*999)
c Summiere Ergebnisse der beiden dt/2 -Schritte und speichere in Dx1, Dv1:
Dx1(1) = Dx1(1) + Dx2(1)
Dx1(2) = Dx1(2) + Dx2(2)
Dx1(3) = Dx1(3) + Dx2(3)
Dv1(1) = Dv1(1) + Dv2(1)
Dv1(2) = Dv1(2) + Dv2(2)
Dv1(3) = Dv1(3) + Dv2(3)
c mache dt - Schritt:
call SINGLESTEP_RUNGE_KUTTA_FO(dt,EFeld0,x,v, Dx2,Dv2 ,*999)
c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
c Fehlerbetrachtung und Berechnung des endgueltigen Ergebnisses:
c Fehlerbetrachtung:
c der groesste (absolute bzw. relative) Fehler im Ort soll kleiner als eps_x
c sein, der groesste Fehler in der Geschwindigkeit kleiner als eps_v:
c -> Bestimme den jeweils groessten Fehler der drei Komponenten des Ortes und
c der Geschwindikeit (dh. die groesste Differenz der Aederungen):
maxErr_x = 0.
maxErr_v = 0.
do i = 1, 3
xDifferenz(i) = Dx1(i)-Dx2(i)
vDifferenz(i) = Dv1(i)-Dv2(i)
if (log_relativ) then
if (Dx1(i).NE.0.)
+ maxErr_x = Max( maxErr_x, Abs( xDifferenz(i)/Dx1(i) ) )
if (Dv1(i).NE.0.)
+ maxErr_v = Max( maxErr_v, Abs( vDifferenz(i)/Dv1(i) ) )
else
maxErr_x = Max( maxErr_x, Abs( xDifferenz(i) ) )
maxErr_v = Max( maxErr_v, Abs( vDifferenz(i) ) )
endif
enddo
c - Skaliere den jeweils groessten relativen Fehler auf das jeweilige Epsilon:
maxErr_x = maxErr_x / eps_x
maxErr_v = maxErr_v / eps_v
c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
c der groessere der beiden reskalierten Fehler bestimmt, ob der Integrations-
c schritt mit kleinerem Zeitintervall wiederholt werden muss, bzw. um welchen
c Faktor das Zeitintervall fuer den naechsten Schritt vergroessert werden kann:
c Liegt der Fehler ausserhalb des Toleranzbereiches und ist dt bereits jetzt
c kleiner als dtsmall, so mache keinen neuen Versuch sondern akzeptiere als Not-
c loesung den bestehenden Naeherungswert. Setze dt in diesem Fall als Default
c fuer den kommenden Integrationsschritt auf dtsmall. Setze aber auch das flag
c 'flag_dtsmall', damit gezaehlt werden kann, wie oft dieses Prozedur fuer ein
c bestimmtes Teilchen angewendet werden muss. Ist dies zu oft der Fall, so brich
c diese Trajektorienberechnung ganz ab (-> destiny = code_dtsmall).
c (2. Teil erfolgt weiter unten)
c
c Es kam vor, dass ohne Ueberschreitung der Fehlertoleranz ein 'dtupper'
c und ein 'dtlower' gefunden wurde, beim Ertasten des Uebergabebereiches
c die Fehlergrenze bei mittleren dt-Werten dann aber ueberschritten wurde,
c wodurch dt immer wieder verkuerzt wurde, ohne dass der Uebergabebereich
c erreicht werden konnte. Letztlich bildete das ganze eine unendliche Schleife.
c Daher werden jetzt jedesmal, wenn die Fehlergrenze ueberschritten wird
c 'found_upper' und 'found_lower' resettet.
maxErr = Max(maxErr_x,maxErr_v)
if (maxErr.GT.1.) then
found_upper = .false.
found_lower = .false.
if (dt.LT.dtsmall) then ! Fehler immer noch zu gross, obwohl
flag_dtsmall = .true. ! dtsmall schon unterschritten ist
else
!c Bestimme kuerzeren Zeitschritt fuer neuen Versuch (vgl. Referenz):
dt = safety * dt * (maxErr**pShrink)
goto 10
endif
endif
c Falls x(1) (== x_1) jetzt bereits jenseits des Uebergangsbereiches am Ende
c der Potentialmappe liegen sollte, behalte dieses Faktum im Gedaechtnis
c und verkuerze den aktuell verwendeten Zeitschritt so lange um Faktor 0.5, bis
c x(1) innerhalb oder vor dem Uebergabebereich liegt. Liegt es davor, suche
c einen mittleren Zeitschritt, bei dem es im Uebergangsbereich liegt. Schliesse
c dann die Integration in dieser Mappe ab.
c (Der Uebergabebereich geht von einer halben x-Gitterkonstanten vor xmax bis
c eine halbe x-Gitterkonstante hinter xmax. In diesem Bereich wird ein konstantes
c EFeld zurueckgegeben):
x_1 = x(1) + Dx1(1) + xDifferenz(1) / 15.
if (x_1.GT.xStartUeber) then
if (x_1.LT.xEndUeber) then
reachedEndOfMap = .true.
else
dtupper = dt
found_upper = .true.
if (.NOT.found_lower) then
dt = min(0.5*dt,(xStartUeber-x(1))/(x_1-x(1))*dt)
else
dt = (dtlower+dtupper)/2.
endif
goto 10 ! neue Berechnung
endif
elseif (found_upper) then
found_lower = .true.
dtlower = dt
dt = (dtlower+dtupper)/2.
goto 10 ! neue Berechnung
endif
c Nimm die Ergebnisse aus dem dt-Schritt und den beiden dt/2-Schritten und
c berechne damit den neuen Ort und die neue Geschwindigkeit mit Genauigkeit
c fuenfter Ordnung in dt:
x(1) = x_1
x(2) = x(2) + Dx1(2) + xDifferenz(2) / 15.
x(3) = x(3) + Dx1(3) + xDifferenz(3) / 15.
v(1) = v(1) + Dv1(1) + vDifferenz(1) / 15.
v(2) = v(2) + Dv1(2) + vDifferenz(2) / 15.
v(3) = v(3) + Dv1(3) + vDifferenz(3) / 15.
c alten Zeitschritt addieren:
t = t + dt
c falls Uebergabebereich erreicht wurde, berechne naeherungsweisen Schnittpunkt der
c Trajektorie mit x=xmax (exaktes Mappenende) unter Verwendung der im Uebergabebereich
c zurueckgegebenen Beschleunigung:
if (reachedEndOfMap) then
call EFeld_FO(x,EFeld0,*999)
help = v(1)*v(1) - 2.*EFeld0(1)*Beschl_Faktor*(x(1)-xmax)
if (help.LT.0.) then ! Teilchen wird noch vor Folie reflektiert werden
reachedEndOfMap = .false.
goto 3454
else
if (EFeld0(1)*Beschl_Faktor.NE.0) then
help = (sqrt(help) - v(1))/(EFeld0(1)*Beschl_Faktor) ! dt -> help
else
help = (xmax-x(1))/v(1)
endif
endif
t = t + help ! auch diesen Zeitschritt addieren
d dt = dt + help ! nur fuer dtmin_Fo,dtmax_Fo
help1 = Beschl_Faktor *help
help2 = help1*help/2.
x(1) = x(1) + v(1)*help + EFeld0(1)*help2 ! == Folie, wenn richtig
x(2) = x(2) + v(2)*help + EFeld0(2)*help2
x(3) = x(3) + v(3)*help + EFeld0(3)*help2
v(1) = v(1) + EFeld0(1)*help1
v(2) = v(2) + EFeld0(2)*help1
v(3) = v(3) + EFeld0(3)*help1
RETURN
endif
c neuen Zeitschritt so gross wie sinnvoller weise moeglich machen:
3454 if (flag_dtSmall) then
if (n_dtsmall.LT.maxBelowDtSmall) then
dt = dtSmall ! fuer naechsten RK-Schritt
n_dtsmall = n_dtsmall + 1
else
destiny = code_dtsmall ! gib Teilchen verloren
RETURN
endif
else
if (maxErr.GT.errCon) then
dt = safety * dt * (maxErr**pGrow) ! vgl. Referenz
else
dt = 4. * dt ! <- Vergroesserung des Zeitschritts max. um
endif ! Faktor 4!
! pruefen, ob Maximallaenge fuer ersten Testschritt nicht ueberschritten ist:
d if (log_confine) dt = min(dt,dl_max/sqrt(v(1)*v(1)+v(2)*v(2)+v(3)*v(3)))
endif
RETURN
c hier folgt der Code fuer 'returnCode_EFeld.NE.0':
998 continue
if (returnCode_EFeld.EQ.1) then
write(*,*) Nr//'-Mappe:'
write(*,*)' aktueller Teilchenort (nicht Testort!) hinter Potentialmappe!'
write(*,*)' -> STOP'
write(*,*)
STOP
! alternativ koennte man hier vielleicht auch nach x=xmax zurueckrechnen
endif
999 continue
if (returnCode_EFeld.EQ.1) then ! Testort hinter der Mappe
dt = 0.5*dt
found_lower = .false.
found_upper = .false.
goto 10
endif
if (returnCode_EFeld.EQ.3) then ! Testort vor der Mappe
if (v(1).LE.0) then ! reflektiert -> kann vorkommen
destiny = code_reflektiert
RETURN
else ! in Vorwaertsbewegung -> darf nicht vorkommen!!
write(*,*)
write(*,*) Nr//'-Mappe: ',mappenName
write(*,*)' Test-x liegt vor der Mappe! x,y,z = ',x
write(*,*)' Teilchen-Nr = ',Start_Nr(1)
write(*,*)' -> STOP'
write(*,*)
STOP
endif
elseif (returnCode_EFeld.NE.0) then
write(*,*)
write(*,*) 'SINGLESTEP_RUNGE_KUTTA_'//Nr//': '
write(*,*) 'unallowed value of ''returnCode_EFeld'': ',returnCode_Efeld
write(*,*) '-> STOP'
write(*,*)
STOP
endif
END
c===============================================================================
OPTIONS /EXTEND_SOURCE
SUBROUTINE SINGLESTEP_RUNGE_KUTTA_FO(dt,E0,x0,v0, Dx,Dv, *)
c ===========================================================
IMPLICIT NONE
c Diese Subroutine berechnet bei vorgegebenem Zeitschritt einen einzelnen
c Runge-Kutta-Integrationsschritt (4. Ordnung).
c Die Vorgehensweise entspricht den Ausfuehrungen in Kapitel 15.1 der
c NUMERICAL RECIPIES: 'Runge-Kutta Method'. Die Formeln sind zwar teilweise
c etwas umgeschrieben, sind aber mathematisch alle aequivalent zu denen der
c Referenz.
c Zurueckgegeben werden die errechneten Orts- und Geschwindigkeitsaenderungen
c anstatt direkt der neuen Werte, da sonst vor allem bei den Ortskoordinaten
c Schwierigkeiten auftreten koennen, wenn in der Subroutine 'INTEGRATIONSSTEP_
c RUNGE_KUTTA' aus der Differenz der neuen Werte aus den beiden dt/2- und dem
c dt-Schritt der Fehler abgeschaetzt werden soll (kleine Differenz moeglicher-
c weise grosser Werte).
real Beschl_Faktor
COMMON /Beschl_Faktor_Fo/ Beschl_Faktor
real E0(3), x0(3), v0(3) ! Eingangsgroessen
real E1(3), E2(3), E3(3) ! E-Felder an Testorten
real v1(3), v2(3), v3(3) ! Geschwindigkeiten an Testorten
real dt,dt_half,dt_sixth ! zeitl. Aenderung, dt/2, dt/6
real help, help_half, help_sixth ! Hilfsvariable, help/2, help/6
real xTest(3) ! Test-Orte
real Dx(3), Dv(3) ! Ergebnisspeicher
integer i ! Zaehlvariable
c = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
dt_half = dt / 2.
dt_sixth = dt / 6.
help = Beschl_Faktor * dt
help_half = help / 2.
help_sixth = help / 6.
do i = 1, 3
xTest(i) = x0(i) + v0(i) * dt_half
v1(i) = v0(i) + E0(i) * help_half
enddo
call EFeld_FO(xTest,E1,*999)
do i = 1, 3
xTest(i) = x0(i) + v1(i) * dt_half
v2(i) = v0(i) + E1(i) * help_half
enddo
call EFeld_FO(xTest,E2,*999)
do i = 1, 3
xTest(i) = x0(i) + v2(i) * dt
v3(i) = v0(i) + E2(i) * help
enddo
call EFeld_FO(xTest,E3,*999)
do i = 1, 3
Dx(i) = (v0(i) + 2.*(v1(i)+v2(i)) + v3(i)) * dt_sixth
Dv(i) = (E0(i) + 2.*(E1(i)+E2(i)) + E3(i)) * help_sixth
enddo
RETURN
999 RETURN 1
END
c===============================================================================
OPTIONS /EXTEND_SOURCE
SUBROUTINE EFeld_FO(x,E,*)
c ==========================
IMPLICIT NONE
INCLUDE 'mutrack$sourcedirectory:MAP_DEF_FO.INC'
real real_i,real_j ! x,r im Mappensystem in Gittereinheiten
integer stuetzstelle_i(2) ! naechste Stuetzstellen in x- und
integer stuetzstelle_j(2) ! r-Richtung
real Abstand_i,Abstand_i_Betrag ! Entfernung zur naechsten Stuetzstelle
real Abstand_j,Abstand_j_Betrag ! (in Gittereinheiten!)
integer i,j, n, ihelp
real radius ! Betrag des Radiusvektors in y-z-Ebene
real x(3),E(3) ! Ort und Feldstaerke
real E_(2) ! Hilfsspeicher fuer Feldberechnung
real Erad ! radiale Feldstaerke
c Falls Testort ausserhalb der Mappe liegt oder Anode getroffen hat:
integer returnCode_EFeld
COMMON /returnCode_EFeld/ returnCode_EFeld
! 1: TESTORT HINTER DER MAPPE
! 2: Testort neben der Mappe
! 3: TESTORT VOR DER MAPPE
c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
c Rechne in Gittereinheiten um:
radius = sqrt(x(2)*x(2)+x(3)*x(3))
real_i = (x(1) - xEnterMap) / Dx
real_j = radius / Dr ! 'Mutrack' statt
c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
c Mache die Tests und berechne die Feldstaerke:
c Teste, ob Raumpunkt innerhalb der Potentialmappe liegt:
if (real_j.GT.jmax) then ! => radial ausserhalb der Mappe
E(1) = 0.
E(2) = 0.
E(3) = 0.
RETURN
elseif (real_i.GT.real(imax)) then ! => hinter Potentialmappe, also
! hinter TriggerFolie
if (real_i.GT.real(imax)+.5) then
returnCode_EFeld = 1
RETURN 1
else
real_i = imax
endif
elseif (real_i.LT.0.) then ! => vor Beginn der Potentialmappe
E(1) = 0.
E(2) = 0.
E(3) = 0.
RETURN
c else
c returnCode_EFeld = 0
endif
c Bestimme naechstgelegene Stuetzstellen und die Komponenten des Abstands-
c Gittervektors zur allernaechsten Stuetzstelle sowie deren Betraege:
stuetzstelle_i(1) = nint(real_i)
Abstand_i = real_i - stuetzstelle_i(1) ! Abstand zur naeheren Stuetzstelle
Abstand_i_Betrag = abs(Abstand_i)
if (Abstand_i.gt.0.) then
stuetzstelle_i(2) = stuetzstelle_i(1) + 1
elseif (Abstand_i.lt.0.) then
stuetzstelle_i(2) = stuetzstelle_i(1) - 1
else
stuetzstelle_i(2) = stuetzstelle_i(1)
endif
stuetzstelle_j(1) = nint(real_j)
Abstand_j = real_j - stuetzstelle_j(1)
Abstand_j_Betrag = abs(Abstand_j)
if (Abstand_j.gt.0.) then
stuetzstelle_j(2) = stuetzstelle_j(1) + 1
elseif (Abstand_j.lt.0.) then
stuetzstelle_j(2) = stuetzstelle_j(1) - 1
else
stuetzstelle_j(2) = stuetzstelle_j(1)
endif
c...............................................................................
c Berechnen des elektrischen Feldes:
c ----------------------------------
c
c Potentialverlauf ist symmetrisch zu j=0 (Linsenachse):
c
c map(i,-j) == map(i,j).
c
c Entlang j=0 ist also Erad=0 und damit E(2)=0 und E(3)=0.
c...............................................................................
c Berechne die x-Komponente der Feldstaerke:
c Um die Feldstaerke zu bekommen, interpoliere jeweils linear zwischen den
c Werten auf den beiden naechstgelegenen j-Ketten:
i = stuetzstelle_i(1)
do n = 1, 2
j = stuetzstelle_j(n)
ihelp = j*(imax+1) + i
if (i.EQ.imax) then
E_(n) = map(ihelp-1) - map(ihelp)
elseif (i.GT.0) then
E_(n) = (-0.5+Abstand_i)*(map(ihelp)-map(ihelp-1))
+ + ( 0.5+Abstand_i)*(map(ihelp)-map(ihelp+1))
else
E_(n) = map(ihelp) - map(ihelp+1)
endif
enddo
E(1) = E_(1) + Abstand_j_Betrag*(E_(2)-E_(1))
E(1) = E(1) / Dx ! Reskalierung entsprechend x-Gitterkonstanten
c Berechne die radiale Komponente der Feldstaerke:
if (real_j.LT.1e-10) then
E(2) = 0.
E(3) = 0.
RETURN
endif
j = stuetzstelle_j(1)
do n = 1, 2
i = stuetzstelle_i(n)
ihelp = j*(imax+1) + i
if (j.EQ.jmax) then
E_(n) = map(ihelp-(imax+1)) - map(ihelp)
elseif (j.GT.0) then
E_(n) = (-0.5+Abstand_j)*(map(ihelp)-map(ihelp-(imax+1)))
+ + ( 0.5+Abstand_j)*(map(ihelp)-map(ihelp+(imax+1)))
else ! j=0 -> map(i,j-1) = map(i,j+1) == map(i,1)
E_(n) = 2.0*Abstand_j*(map(ihelp)-map(ihelp+(imax+1)))
endif
enddo
Erad = E_(1) + Abstand_i_Betrag*(E_(2)-E_(1))
Erad = Erad / Dr ! Reskalierung entsprechend r-Gitterkonstanten
c Berechne E(2) und E(3) aus Erad:
E(2) = Erad * x(2) / radius
E(3) = Erad * x(3) / radius
END
c===============================================================================

View File

@ -0,0 +1,629 @@
c===============================================================================
OPTIONS /EXTEND_SOURCE
SUBROUTINE READ_INFOS
c =====================
INCLUDE 'mutrack$sourcedirectory:COM_MUTRACK.INC'
logical map_error /.false./
COMMON /map_error/ map_error
c if (.NOT.Use_MUTRACK .OR. write_geo) then
CALL READ_INFO_L1
if (.NOT.idealMirror) then
call read_INFO_SP_1
call read_INFO_SP_2
call read_INFO_SP_3
endif
if (lense2) CALL READ_INFO_L2andFo
if (TriggerInBeam) CALL READ_INFO_FO
c endif
if (.NOT.upTOTDFoilOnly) then
CALL READ_INFO_L3
CALL READ_INFO_M2
endif
if (map_error) then
write(*,*)'----------------------------------------'//
+ '----------------------------------------'
call exit
endif
END
c===============================================================================
OPTIONS /EXTEND_SOURCE
SUBROUTINE READ_INFO_L1
c =======================
IMPLICIT NONE
character*(*) Nr
parameter (Nr='L1')
INCLUDE 'mutrack$sourcedirectory:COM_LUNS.INC'
INCLUDE 'mutrack$sourcedirectory:COM_DIRS.INC'
INCLUDE 'mutrack$sourcedirectory:MAP_DEF_L1.INC'
c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
namelist /geometry/
+ DistanceCyl,iRadiusCyl,
+ LengthOuterCyl,oRadiusOuterCyl,
+ LengthInnerCyl,oRadiusInnerCyl,
+ RadiusVacTube
namelist /grid_info/
+ Dx,Dr, imax,jmax, xmax,rmax
c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
logical map_error
COMMON /map_error/ map_error
c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
c Einlesen der Mappen-Informationen:
open (lunREAD,file=mappenName//'.INFO',defaultfile=mappenDir,
+ readonly,status='old')
read (lunREAD,nml=grid_info)
rewind (lunREAD)
read (lunREAD,nml=geometry)
close (lunREAD)
c Pruefen, ob die eingelesene Mappe den Anforderungen genuegt:
if (iRadiusCyl.NE.rmax) then
write(*,*)' L1-Mappe: rmax der Mappe stimmt nicht mit Innenradius der Zylinder ueberein'
write(*,*)' -> STOP'
STOP
endif
c eingelesene imax und jmax um 1 reduzieren, da in 'MUTRACK' die Feldindizes
c ab 0 laufen, bei 'RELAX3D' jedoch ab 1:
imax = imax-1
jmax = jmax-1
c die geometrischen Daten fuer Mutrack zusammenstellen:
xEnterMap = xCenterOfLense - xmax
xLeaveMap = xCenterOfLense + xmax
c checken, ob der reservierte Speicherplatz ausreicht:
if ((imax+1)*(jmax+1).NE.maxmem+1) then
write(*,*)'----------------------------------------'//
+ '----------------------------------------'
write(*,*) Nr//'-Mappe: ',mappenName
write(*,*) ' BENOETIGTER Speicher: (imax+1)*(jmax+1) = ',(imax+1)*(jmax+1)
write(*,*) ' RESERVIERTER Speicher: maxmem + 1 = ',maxmem + 1
write(*,*)
if ((imax+1)*(jmax+1).GT.maxmem+1) then
write(*,*) '=> reservierter Speicherplatz ist ungenuegend.'
write(*,*)
write(*,*) '=> ''maxmem'' in mutrack$sourcedirectory:MAP_DEF_'//Nr//'.INC angleichen,'
write(*,*) ' dann Programm mit ''LINKMUV'' am DCL-Prompt neu kompilieren'
write(*,*) ' und linken.'
write(*,*)
write(*,*) ' Mindestwert fuer ''maxmem'' ist ',(imax+1)*(jmax+1)-1
write(*,*)
map_error = .true.
endif
endif
END
c===============================================================================
OPTIONS /EXTEND_SOURCE
SUBROUTINE READ_MAP_L1
c ======================
IMPLICIT NONE
character*(*) Nr
parameter (Nr='L1')
INCLUDE 'mutrack$sourcedirectory:MAP_DEF_L1.INC'
INCLUDE 'mutrack$sourcedirectory:READ_MAP.INC'
END
c===============================================================================
OPTIONS /EXTEND_SOURCE
SUBROUTINE INTEGRATIONSSTEP_RUNGE_KUTTA_L1(dt)
c ==============================================
IMPLICIT NONE
SAVE
character*(*) Nr
parameter (Nr='L1')
c Diese Subroutine berechnet zu einem vorgegebenen Zeitschritt dt den
c Integrationsschritt zweimal: einmal direkt mit dt und einmal ueber zwei
c aufeinanderfolgende Schritte mit dt/2. (die beiden dt/2-Schritte werden
c zuerst ausgefuehrt).
c
c Aus der Differenz der beiden Resultate wird eine Abschaetzung fuer den Fehler
c des dt-Schrittes gewonnen, die dazu verwendet wird zu entscheiden, ob der
c Integrationsschritt mit einem verkuerzten Zeitintervall wiederholt werden
c muss, oder ob das Zeitintervall fuer den folgenden ausgedehnt werden kann.
c
c Die beiden Einzelergebnisse aus dem dt- und den beiden dt/2-Schritten, die
c jeweils ueber Runge-Kutta-Rechnung vierter Ordnung erhalten werden, werden
c zum Schluss noch zusammengenommen, um ein Resultat mit Genauigkeit fuenfter
c Ordnung in dt zu erhalten.
c
c Der ganze Ablauf entspricht den Ausfuehrungen in Kapitel 15.2 der NUMERICAL
c RECIPIES: 'Adaptive Stepsize Control for Runge-Kutta' (vgl. Referenz im
c fileheader von 'MUTRACK.FOR')
INCLUDE 'mutrack$sourcedirectory:COM_MUTRACK.INC'
INCLUDE 'mutrack$sourcedirectory:MAP_DEF_L1.INC'
integer i ! Zaehlvariable
real dt,dt_half ! zeitl. Aenderung, halbe zeitl. Aenderung
real EFeld0(3), EFeld1(3) ! elektr. Felder
real x1(3),Dx1(3),Dx2(3) ! fuer Ortsintegration
real v1(3),Dv1(3),Dv2(3) ! fuer Geschw.Integration
real xDifferenz(3), vDifferenz(3)
real maxErr_x,maxErr_v,maxErr ! fuer Fehlerbetrachtung
real errCon, safety ! fuer Schrittweitenkontrolle
real pShrink, pGrow ! fuer Schrittweitenkontrolle
PARAMETER (errCon = 6.e-4, safety = .9) ! vgl. Referenz
PARAMETER (pShrink = -.25, pGrow = -.2)
! errCon = (4./safety)**(1/pGrow)
logical flag_dtSmall ! wenn bei dt < dtsmall der Fehler
! immer noch zu gross ist.
integer returnCode_EFeld
COMMON /returnCode_EFeld/ returnCode_EFeld
! 1: Testort hinter der Mappe
! 2: TESTORT NEBEN DER MAPPE
! 3: Testort vor der Mappe
c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
flag_dtSmall = .false. ! flag resetten
if (dt.LT.dtsmall) dt = dtsmall
c berechne EFeld am aktuellen Ort. Speichere in EFeld0, damit sie wiederverwendet
c werden kann, falls mit kuerzerem Zeitschritt wiederholt werden muss:
call EFeld_L1(x,EFeld0,*999)
c...............................................................................
10 continue ! hier gehts wieder von vorne los, falls Zeitschritt dt
! abgeaendert werden muss.
dt_half = dt / 2.
c mache ersten dt/2 - Schritt:
call SINGLESTEP_RUNGE_KUTTA_L1(dt_half,EFeld0,x,v, Dx1,Dv1 ,*999)
c berechne EFeld bei x1:
x1(1) = x(1) + Dx1(1)
x1(2) = x(2) + Dx1(2)
x1(3) = x(3) + Dx1(3)
v1(1) = v(1) + Dv1(1)
v1(2) = v(2) + Dv1(2)
v1(3) = v(3) + Dv1(3)
call EFeld_L1(x1,EFeld1,*999)
c mache zweiten dt/2 - Schritt:
call SINGLESTEP_RUNGE_KUTTA_L1(dt_half,EFeld1,x1,v1, Dx2,Dv2 ,*999)
c Summiere Ergebnisse der beiden dt/2 -Schritte und speichere in Dx1, Dv1:
Dx1(1) = Dx1(1) + Dx2(1)
Dx1(2) = Dx1(2) + Dx2(2)
Dx1(3) = Dx1(3) + Dx2(3)
Dv1(1) = Dv1(1) + Dv2(1)
Dv1(2) = Dv1(2) + Dv2(2)
Dv1(3) = Dv1(3) + Dv2(3)
c mache dt - Schritt:
call SINGLESTEP_RUNGE_KUTTA_L1(dt,EFeld0,x,v, Dx2,Dv2 ,*999)
c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
c Fehlerbetrachtung und Berechnung des endgueltigen Ergebnisses:
c Fehlerbetrachtung:
c der groesste (absolute bzw. relative) Fehler im Ort soll kleiner als eps_x
c sein, der groesste Fehler in der Geschwindigkeit kleiner als eps_v:
c -> Bestimme den jeweils groessten Fehler der drei Komponenten des Ortes und
c der Geschwindikeit (dh. die groesste Differenz der Aederungen):
maxErr_x = 0.
maxErr_v = 0.
do i = 1, 3
xDifferenz(i) = Dx1(i)-Dx2(i)
vDifferenz(i) = Dv1(i)-Dv2(i)
if (log_relativ) then
if (Dx1(i).NE.0.)
+ maxErr_x = Max( maxErr_x, Abs( xDifferenz(i)/Dx1(i) ) )
if (Dv1(i).NE.0.)
+ maxErr_v = Max( maxErr_v, Abs( vDifferenz(i)/Dv1(i) ) )
else
maxErr_x = Max( maxErr_x, Abs( xDifferenz(i) ) )
maxErr_v = Max( maxErr_v, Abs( vDifferenz(i) ) )
endif
enddo
c - Skaliere den jeweils groessten relativen Fehler auf das jeweilige Epsilon:
maxErr_x = maxErr_x / eps_x
maxErr_v = maxErr_v / eps_v
c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
c der groessere der beiden reskalierten Fehler bestimmt, ob der Integrations-
c schritt mit kleinerem Zeitintervall wiederholt werden muss, bzw. um welchen
c Faktor das Zeitintervall fuer den naechsten Schritt vergroessert werden kann:
c Liegt der Fehler ausserhalb des Toleranzbereiches und ist dt bereits jetzt
c kleiner als dtsmall, so mache keinen neuen Versuch sondern akzeptiere als Not-
c loesung den bestehenden Naeherungswert. Setze dt in diesem Fall als Default
c fuer den kommenden Integrationsschritt auf dtsmall. Setze aber auch das flag
c 'flag_dtsmall', damit gezaehlt werden kann, wie oft dieses Prozedur fuer ein
c bestimmtes Teilchen angewendet werden muss. Ist dies zu oft der Fall, so brich
c diese Trajektorienberechnung ganz ab (-> destiny = code_dtsmall).
c (2. Teil erfolgt weiter unten)
maxErr = Max(maxErr_x,maxErr_v)
if (maxErr.GT.1.) then
if (dt.LT.dtsmall) then ! Fehler immer noch zu gross, obwohl
flag_dtsmall = .true. ! dtsmall schon unterschritten ist
else
!c Bestimme kuerzeren Zeitschritt fuer neuen Versuch (vgl. Referenz):
dt = safety * dt * (maxErr**pShrink)
goto 10
endif
endif
c Nimm die Ergebnisse aus dem dt-Schritt und den beiden dt/2-Schritten und
c berechne damit den neuen Ort und die neue Geschwindigkeit mit Genauigkeit
c fuenfter Ordnung in dt:
x(1) = x(1) + Dx1(1) + xDifferenz(1) / 15.
x(2) = x(2) + Dx1(2) + xDifferenz(2) / 15.
x(3) = x(3) + Dx1(3) + xDifferenz(3) / 15.
v(1) = v(1) + Dv1(1) + vDifferenz(1) / 15.
v(2) = v(2) + Dv1(2) + vDifferenz(2) / 15.
v(3) = v(3) + Dv1(3) + vDifferenz(3) / 15.
c alten Zeitschritt addieren, neuen so gross wie sinnvoller weise moeglich
c machen:
t = t + dt
if (flag_dtSmall) then
if (n_dtsmall.LT.maxBelowDtSmall) then
dt = dtSmall ! fuer naechsten RK-Schritt
n_dtsmall = n_dtsmall + 1
else
destiny = code_dtsmall ! gib Teilchen verloren
RETURN
endif
else
if (maxErr.GT.errCon) then
dt = safety * dt * (maxErr**pGrow) ! vgl. Referenz
else
dt = 4. * dt ! <- Vergroesserung des Zeitschritts max. um
endif ! Faktor 4!
! pruefen, ob Maximallaenge fuer ersten Testschritt nicht ueberschritten ist:
d if (log_confine) dt = min(dt,dl_max/sqrt(v(1)*v(1)+v(2)*v(2)+v(3)*v(3)))
endif
RETURN
c hier folgt der Code fuer 'returnCode_EFeld.NE.0':
999 continue
if (returnCode_EFeld.EQ.2) then
destiny = code_wand
RETURN
elseif (returnCode_EFeld.NE.0) then
write(*,*)
write(*,*) 'SINGLESTEP_RUNGE_KUTTA_'//Nr//': '
write(*,*) 'unallowed value of ''returnCode_EFeld'': ',returnCode_Efeld
write(*,*) '-> STOP'
write(*,*)
STOP
endif
END
c===============================================================================
OPTIONS /EXTEND_SOURCE
SUBROUTINE SINGLESTEP_RUNGE_KUTTA_L1(dt,E0,x0,v0, Dx,Dv, *)
c ===========================================================
IMPLICIT NONE
c Diese Subroutine berechnet bei vorgegebenem Zeitschritt einen einzelnen
c Runge-Kutta-Integrationsschritt (4. Ordnung).
c Die Vorgehensweise entspricht den Ausfuehrungen in Kapitel 15.1 der
c NUMERICAL RECIPIES: 'Runge-Kutta Method'. Die Formeln sind zwar teilweise
c etwas umgeschrieben, sind aber mathematisch alle aequivalent zu denen der
c Referenz.
c Zurueckgegeben werden die errechneten Orts- und Geschwindigkeitsaenderungen
c anstatt direkt der neuen Werte, da sonst vor allem bei den Ortskoordinaten
c Schwierigkeiten auftreten koennen, wenn in der Subroutine 'INTEGRATIONSSTEP_
c RUNGE_KUTTA' aus der Differenz der neuen Werte aus den beiden dt/2- und dem
c dt-Schritt der Fehler abgeschaetzt werden soll (kleine Differenz moeglicher-
c weise grosser Werte).
real Beschl_Faktor
COMMON /Beschl_Faktor_L1/ Beschl_Faktor
real E0(3), x0(3), v0(3) ! Eingangsgroessen
real E1(3), E2(3), E3(3) ! E-Felder an Testorten
real v1(3), v2(3), v3(3) ! Geschwindigkeiten an Testorten
real dt,dt_half,dt_sixth ! zeitl. Aenderung, dt/2, dt/6
real help, help_half, help_sixth ! Hilfsvariable, help/2, help/6
real xTest(3) ! Test-Orte
real Dx(3), Dv(3) ! Ergebnisspeicher
integer i ! Zaehlvariable
c = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
dt_half = dt / 2.
dt_sixth = dt / 6.
help = Beschl_Faktor * dt
help_half = help / 2.
help_sixth = help / 6.
do i = 1, 3
xTest(i) = x0(i) + v0(i) * dt_half
v1(i) = v0(i) + E0(i) * help_half
enddo
call EFeld_L1(xTest,E1,*999)
do i = 1, 3
xTest(i) = x0(i) + v1(i) * dt_half
v2(i) = v0(i) + E1(i) * help_half
enddo
call EFeld_L1(xTest,E2,*999)
do i = 1, 3
xTest(i) = x0(i) + v2(i) * dt
v3(i) = v0(i) + E2(i) * help
enddo
call EFeld_L1(xTest,E3,*999)
do i = 1, 3
Dx(i) = (v0(i) + 2.*(v1(i)+v2(i)) + v3(i)) * dt_sixth
Dv(i) = (E0(i) + 2.*(E1(i)+E2(i)) + E3(i)) * help_sixth
enddo
RETURN
999 RETURN 1
END
c===============================================================================
OPTIONS /EXTEND_SOURCE
SUBROUTINE EFeld_L1(x,E,*)
c ==========================
IMPLICIT NONE
INCLUDE 'mutrack$sourcedirectory:MAP_DEF_L1.INC'
real real_i,real_j ! x,r im Mappensystem in Gittereinheiten
integer stuetzstelle_i(2) ! naechste Stuetzstellen in x- und
integer stuetzstelle_j(2) ! r-Richtung
real Abstand_i,Abstand_i_Betrag ! Entfernung zur naechsten Stuetzstelle
real Abstand_j,Abstand_j_Betrag ! (in Gittereinheiten!)
integer i,j, n, ihelp
real radius ! Betrag des Radiusvektors in y-z-Ebene
real x(3),E(3) ! Ort und Feldstaerke
real E_(2) ! Hilfsspeicher fuer Feldberechnung
real Erad ! radiale Feldstaerke
c Falls Testort ausserhalb der Mappe liegt oder Anode getroffen hat:
integer returnCode_EFeld
COMMON /returnCode_EFeld/ returnCode_EFeld
! 1: Testort hinter der Mappe
! 2: TESTORT NEBEN DER MAPPE
! 3: Testort vor der Mappe
c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
c Rechne in Gittereinheiten um:
radius = sqrt(x(2)*x(2)+x(3)*x(3))
real_i = (xmax - abs(x(1)-xCenterOfLense)) / Dx
real_j = radius / Dr
c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
c Mache die Tests und berechne die Feldstaerke:
c Teste, ob Raumpunkt innerhalb der Potentialmappe liegt:
if (real_j.GT.jmax) then
returnCode_EFeld = 2
RETURN 1
elseif (real_i.LT.0.) then
E(1) = 0.
E(2) = 0.
E(3) = 0.
RETURN
c else
c returnCode_EFeld = 0
endif
c Bestimme naechstgelegene Stuetzstellen und die Komponenten des Abstands-
c Gittervektors zur allernaechsten Stuetzstelle sowie deren Betraege:
stuetzstelle_i(1) = nint(real_i)
Abstand_i = real_i - stuetzstelle_i(1) ! Abstand zur naeheren Stuetzstelle
Abstand_i_Betrag = abs(Abstand_i)
if (Abstand_i.gt.0.) then
stuetzstelle_i(2) = stuetzstelle_i(1) + 1
elseif (Abstand_i.lt.0.) then
stuetzstelle_i(2) = stuetzstelle_i(1) - 1
else
stuetzstelle_i(2) = stuetzstelle_i(1)
endif
stuetzstelle_j(1) = nint(real_j)
Abstand_j = real_j - stuetzstelle_j(1)
Abstand_j_Betrag = abs(Abstand_j)
if (Abstand_j.gt.0.) then
stuetzstelle_j(2) = stuetzstelle_j(1) + 1
elseif (Abstand_j.lt.0.) then
stuetzstelle_j(2) = stuetzstelle_j(1) - 1
else
stuetzstelle_j(2) = stuetzstelle_j(1)
endif
c...............................................................................
c Berechnen des elektrischen Feldes:
c ----------------------------------
c
c Potentialverlauf ist symmetrisch zu real_i = imax (Mittelebene des inneren
c Zylinders) und zu j=0 (Linsenachse):
c
c map(imax+i,-j) == map(imax-1,j),
c map(i,-j) == map(i,j).
c
c Entlang j=0 ist also Erad=0 und damit E(2)=0 und E(3)=0, bei i=imax ist E(1)=0
c...............................................................................
c Berechne die x-Komponente der Feldstaerke:
c Um die Feldstaerke zu bekommen, interpoliere jeweils linear zwischen den
c Werten auf den beiden naechstgelegenen j-Ketten:
i = stuetzstelle_i(1)
do n = 1, 2
j = stuetzstelle_j(n)
ihelp = j*(imax+1) + i
if (i.EQ.imax) then
E_(n) = 2. * Abstand_i *(map(ihelp)-map(ihelp-1)) ! i=imax -> map(imax+1,j) = map(imax-1,j)
elseif (i.GT.0) then
E_(n) = (-0.5+Abstand_i)*(map(ihelp)-map(ihelp-1))
+ + ( 0.5+Abstand_i)*(map(ihelp)-map(ihelp+1))
else
E_(n) = map(ihelp) - map(ihelp+1)
endif
enddo
E(1) = E_(1) + Abstand_j_Betrag*(E_(2)-E_(1))
E(1) = E(1) / Dx ! Reskalierung entsprechend x-Gitterkonstanten
if (x(1).GT.xCenterOfLense) E(1) = - E(1)
c Berechne die radiale Komponente der Feldstaerke:
if (real_j.LT.1e-10) then
E(2) = 0.
E(3) = 0.
RETURN
endif
j = stuetzstelle_j(1)
do n = 1, 2
i = stuetzstelle_i(n)
ihelp = j*(imax+1) + i
if (j.EQ.jmax) then
E_(n) = map(ihelp-(imax+1)) - map(ihelp)
elseif (j.GT.0) then
E_(n) = (-0.5+Abstand_j)*(map(ihelp)-map(ihelp-(imax+1)))
+ + ( 0.5+Abstand_j)*(map(ihelp)-map(ihelp+(imax+1)))
else ! j=0 -> map(i,j-1) = map(i,j+1) == map(i,1)
E_(n) = 2.0*Abstand_j*(map(ihelp)-map(ihelp+(imax+1)))
endif
enddo
Erad = E_(1) + Abstand_i_Betrag*(E_(2)-E_(1))
Erad = Erad / Dr ! Reskalierung entsprechend r-Gitterkonstanten
c Berechne E(2) und E(3) aus Erad:
E(2) = Erad * x(2) / radius
E(3) = Erad * x(3) / radius
cd write(18,*)'x,E = ',x,E
END
c===============================================================================

View File

@ -0,0 +1,802 @@
c===============================================================================
OPTIONS /EXTEND_SOURCE
SUBROUTINE READ_INFO_L2andFo
c ============================
IMPLICIT NONE
character*(*) Nr
parameter (Nr='L2andFo')
INCLUDE 'mutrack$sourcedirectory:COM_LUNS.INC'
INCLUDE 'mutrack$sourcedirectory:COM_DIRS.INC'
INCLUDE 'mutrack$sourcedirectory:MAP_DEF_L2andFo.INC'
real DistanceMapToFirst ! Der Beginn der Linse relativ zum Beginn der
! Potentialmappe
c nur fuer Einlesen des INFO-files:
real DistCenterToFoil ! Abstand zwischen Linsenmitte und TD-Folie
real rFoil ! Radius der TD-Folien-Scheibe bei Relaxation
c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
namelist /geometry/
+ DistanceMapToFirst,
+ DistanceCyl,iRadiusCyl,
+ LengthOuterCyl,oRadiusOuterCyl,
+ LengthInnerCyl,oRadiusInnerCyl,
+ RadiusVacTube,DistCenterToFoil,rFoil
namelist /grid_info/
+ Dx,Dr, imax,jmax, xmax,rmax
c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
logical map_error
COMMON /map_error/ map_error
c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
c Einlesen der Mappen-Informationen:
open (lunTMP,file=mappenName//'.INFO',defaultfile=mappenDir,
+ readonly,status='old')
read (lunTMP,nml=grid_info)
rewind (lunTMP)
read (lunTMP,nml=geometry)
close (lunTMP)
c eingelesene imax und jmax um 1 reduzieren, da in 'MUTRACK' die Feldindizes
c ab 0 laufen, bei 'RELAX3D' jedoch ab 1:
imax = imax-1
jmax = jmax-1
c die geometrischen Daten fuer Mutrack zusammenstellen (Kammer-System):
xEnterMap = xCenterOfLense - (0.5*LengthInnerCyl + DistanceCyl +
+ LengthOuterCyl + DistanceMapToFirst)
xLeaveMap = xEnterMap + xmax
xEndLense = xCenterOfLense + (0.5*LengthInnerCyl + DistanceCyl +
+ LengthOuterCyl)
c Uebergabebereich am MappenEnde definieren (MappenSystem!):
xStartUeber = xMax - 0.5*Dx
xEndUeber = xMax + 0.5*Dx
c checken, ob der reservierte Speicherplatz ausreicht:
if ((imax+1)*(jmax+1).NE.maxmem+1) then
write(*,*)'----------------------------------------'//
+ '----------------------------------------'
write(*,*) Nr//'-Mappe: ',mappenName
write(*,*) ' BENOETIGTER Speicher: (imax+1)*(jmax+1) = ',(imax+1)*(jmax+1)
write(*,*) ' RESERVIERTER Speicher: maxmem + 1 = ',maxmem + 1
write(*,*)
if ((imax+1)*(jmax+1).GT.maxmem+1) then
write(*,*) '=> reservierter Speicherplatz ist ungenuegend.'
write(*,*)
write(*,*) '=> ''maxmem'' in mutrack$sourcedirectory:MAP_DEF_'//Nr//'.INC angleichen,'
write(*,*) ' dann Programm mit ''LINKMUV'' am DCL-Prompt neu kompilieren'
write(*,*) ' und linken.'
write(*,*)
write(*,*) ' Mindestwert fuer ''maxmem'' ist ',(imax+1)*(jmax+1)-1
write(*,*)
map_error = .true.
endif
endif
END
c===============================================================================
OPTIONS /EXTEND_SOURCE
SUBROUTINE ADD_MAP_L2andFo
c ==========================
IMPLICIT NONE
character*(*) Nr
parameter (Nr='L2andFo')
INCLUDE 'mutrack$sourcedirectory:MAP_DEF_L2andFo.INC'
INCLUDE 'mutrack$sourcedirectory:COM_DIRS.INC'
INCLUDE 'mutrack$sourcedirectory:COM_LUNS.INC'
real U_L2
COMMON /U_L2/ U_L2
INCLUDE 'mutrack$sourcedirectory:COM_TD_EXT.INC' ! um U_F zu haben
integer i,j, ihelp, iostat
integer iReadMax
parameter (iReadMax=1000)
real read_memory(0:iReadMax)
COMMON /read_memory/ read_memory ! COMMON nur, damit nicht jede
! Mappe extra Speicher belegt.
c Pruefe, ob genug Speicherplatz zur Verfuegung steht:
if (imax.GT.iReadMax) then
write(*,*)
write(*,*) 'parameter ''iReadMax'' in Subroutine ADD_MAP_'//Nr//' is too small'
write(*,*) ' iMax, iReadMax = ',iMax, iReadMax
write(*,*)
write(*,*) '=> please adjust!'
write(*,*)
call exit
endif
c Einlesen der 'L2Fo_L2'-Potentialmappe:
open (lunTMP,file=mappenName//'_L2.MAPPE',
+ defaultfile=mappenDir,status='old',
+ form='unformatted',recl=imax+1,readonly)
c + form='unformatted',recl=imax,readonly)
do j = 0, jmax
ihelp = j*(imax+1)
read(lunTMP,iostat=iostat) (map(ihelp+i),i=0,imax)
if (iostat.NE.0) then
write(*,*)
write(*,999) i,j,iostat
write(*,*)' Potentialmappe: ',mappenName
write(*,*)' Directory : ',mappenDir
write(*,*)
CALL EXIT
endif
enddo
close(lunTMP)
999 format(7x'error reading grid point (i,j) = ('i4','i4')'/7x'iostat = 'i4)
c Angleichen der Potentialmappe an U_L2:
ihelp = 0
do j=0, jmax
do i=0, imax
map(ihelp) = U_L2*abs(map(ihelp))
ihelp = ihelp + 1
enddo
enddo
c Einlesen der 'L2Fo_Fo'-Potentialmappe und Angleichen an U_F:
open (lunTMP,file=mappenName//'_Fo.MAPPE',
+ defaultfile=mappenDir,status='old',
+ form='unformatted',recl=imax+1,readonly)
c + form='unformatted',recl=imax,readonly)
ihelp = 0
do j = 0, jmax
read(lunTMP,iostat=iostat) (read_memory(i),i=0,imax)
if (iostat.NE.0) then
write(*,*)
write(*,999) i,j,iostat
write(*,*)' Potentialmappe: ',mappenName
write(*,*)' Directory : ',mappenDir
write(*,*)
CALL EXIT
endif
do i=0, imax
map(ihelp) = map(ihelp) + U_F*abs(read_memory(i))
ihelp = ihelp + 1
enddo
enddo
close(lunTMP)
END
c===============================================================================
OPTIONS /EXTEND_SOURCE
SUBROUTINE INTEGRATIONSSTEP_RUNGE_KUTTA_L2(dt)
c ==============================================
IMPLICIT NONE
SAVE
character*(*) Nr
parameter (Nr='L2andFo')
c Diese Subroutine berechnet zu einem vorgegebenen Zeitschritt dt den
c Integrationsschritt zweimal: einmal direkt mit dt und einmal ueber zwei
c aufeinanderfolgende Schritte mit dt/2. (die beiden dt/2-Schritte werden
c zuerst ausgefuehrt).
c
c Aus der Differenz der beiden Resultate wird eine Abschaetzung fuer den Fehler
c des dt-Schrittes gewonnen, die dazu verwendet wird zu entscheiden, ob der
c Integrationsschritt mit einem verkuerzten Zeitintervall wiederholt werden
c muss, oder ob das Zeitintervall fuer den folgenden ausgedehnt werden kann.
c
c Die beiden Einzelergebnisse aus dem dt- und den beiden dt/2-Schritten, die
c jeweils ueber Runge-Kutta-Rechnung vierter Ordnung erhalten werden, werden
c zum Schluss noch zusammengenommen, um ein Resultat mit Genauigkeit fuenfter
c Ordnung in dt zu erhalten.
c
c Der ganze Ablauf entspricht den Ausfuehrungen in Kapitel 15.2 der NUMERICAL
c RECIPIES: 'Adaptive Stepsize Control for Runge-Kutta' (vgl. Referenz im
c fileheader von 'MUTRACK.FOR')
INCLUDE 'mutrack$sourcedirectory:COM_MUTRACK.INC'
INCLUDE 'mutrack$sourcedirectory:MAP_DEF_L2andFo.INC'
integer i ! Zaehlvariable
real dt,dt_half ! zeitl. Aenderung, halbe zeitl. Aenderung
real EFeld0(3), EFeld1(3) ! elektr. Felder
real x1(3),Dx1(3),Dx2(3) ! fuer Ortsintegration
real v1(3),Dv1(3),Dv2(3) ! fuer Geschw.Integration
real xDifferenz(3), vDifferenz(3)
real x_1 ! Hilfsvariable fuer testweises x(1)
real help1,help2
real maxErr_x,maxErr_v,maxErr ! fuer Fehlerbetrachtung
real errCon, safety ! fuer Schrittweitenkontrolle
real pShrink, pGrow ! fuer Schrittweitenkontrolle
PARAMETER (errCon = 6.e-4, safety = .9) ! vgl. Referenz
PARAMETER (pShrink = -.25, pGrow = -.2)
! errCon = (4./safety)**(1/pGrow)
logical flag_dtSmall ! wenn bei dt < dtsmall der Fehler
! immer noch zu gross ist.
logical found_lower ! obere und untere Grenze fuer dt um
logical found_upper ! Uebergabebereich zu treffen
real dtlower,dtupper
real help
integer returnCode_EFeld
COMMON /returnCode_EFeld/ returnCode_EFeld
! 1: TESTORT HINTER DER MAPPE
! 2: TESTORT NEBEN DER MAPPE
! 3: TESTORT VOR DER MAPPE
c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
flag_dtSmall = .false. ! flag resetten
found_lower = .false.
found_upper = .false.
if (dt.LT.dtsmall) dt = dtsmall
c berechne EFeld am aktuellen Ort. Speichere in EFeld0, damit sie wiederverwendet
c werden kann, falls mit kuerzerem Zeitschritt wiederholt werden muss:
call EFeld_L2andFo(x,EFeld0,*998)
c...............................................................................
10 continue ! hier gehts wieder von vorne los, falls Zeitschritt dt
! abgeaendert werden muss.
dt_half = dt / 2.
c mache ersten dt/2 - Schritt:
call SINGLESTEP_RUNGE_KUTTA_L2andFo(dt_half,EFeld0,x,v, Dx1,Dv1 ,*999)
c berechne EFeld bei x1:
x1(1) = x(1) + Dx1(1)
x1(2) = x(2) + Dx1(2)
x1(3) = x(3) + Dx1(3)
v1(1) = v(1) + Dv1(1)
v1(2) = v(2) + Dv1(2)
v1(3) = v(3) + Dv1(3)
call EFeld_L2andFo(x1,EFeld1,*999)
c mache zweiten dt/2 - Schritt:
call SINGLESTEP_RUNGE_KUTTA_L2andFo(dt_half,EFeld1,x1,v1, Dx2,Dv2 ,*999)
c Summiere Ergebnisse der beiden dt/2 -Schritte und speichere in Dx1, Dv1:
Dx1(1) = Dx1(1) + Dx2(1)
Dx1(2) = Dx1(2) + Dx2(2)
Dx1(3) = Dx1(3) + Dx2(3)
Dv1(1) = Dv1(1) + Dv2(1)
Dv1(2) = Dv1(2) + Dv2(2)
Dv1(3) = Dv1(3) + Dv2(3)
c mache dt - Schritt:
call SINGLESTEP_RUNGE_KUTTA_L2andFo(dt,EFeld0,x,v, Dx2,Dv2 ,*999)
c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
c Fehlerbetrachtung und Berechnung des endgueltigen Ergebnisses:
c Fehlerbetrachtung:
c der groesste (absolute bzw. relative) Fehler im Ort soll kleiner als eps_x
c sein, der groesste Fehler in der Geschwindigkeit kleiner als eps_v:
c -> Bestimme den jeweils groessten Fehler der drei Komponenten des Ortes und
c der Geschwindikeit (dh. die groesste Differenz der Aederungen):
maxErr_x = 0.
maxErr_v = 0.
do i = 1, 3
xDifferenz(i) = Dx1(i)-Dx2(i)
vDifferenz(i) = Dv1(i)-Dv2(i)
if (log_relativ) then
if (Dx1(i).NE.0.)
+ maxErr_x = Max( maxErr_x, Abs( xDifferenz(i)/Dx1(i) ) )
if (Dv1(i).NE.0.)
+ maxErr_v = Max( maxErr_v, Abs( vDifferenz(i)/Dv1(i) ) )
else
maxErr_x = Max( maxErr_x, Abs( xDifferenz(i) ) )
maxErr_v = Max( maxErr_v, Abs( vDifferenz(i) ) )
endif
enddo
c - Skaliere den jeweils groessten relativen Fehler auf das jeweilige Epsilon:
maxErr_x = maxErr_x / eps_x
maxErr_v = maxErr_v / eps_v
c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
c der groessere der beiden reskalierten Fehler bestimmt, ob der Integrations-
c schritt mit kleinerem Zeitintervall wiederholt werden muss, bzw. um welchen
c Faktor das Zeitintervall fuer den naechsten Schritt vergroessert werden kann:
c Liegt der Fehler ausserhalb des Toleranzbereiches und ist dt bereits jetzt
c kleiner als dtsmall, so mache keinen neuen Versuch sondern akzeptiere als Not-
c loesung den bestehenden Naeherungswert. Setze dt in diesem Fall als Default
c fuer den kommenden Integrationsschritt auf dtsmall. Setze aber auch das flag
c 'flag_dtsmall', damit gezaehlt werden kann, wie oft dieses Prozedur fuer ein
c bestimmtes Teilchen angewendet werden muss. Ist dies zu oft der Fall, so brich
c diese Trajektorienberechnung ganz ab (-> destiny = code_dtsmall).
c (2. Teil erfolgt weiter unten)
c
c Es kam vor, dass ohne Ueberschreitung der Fehlertoleranz ein 'dtupper'
c und ein 'dtlower' gefunden wurde, beim Ertasten des Uebergabebereiches
c die Fehlergrenze bei mittleren dt-Werten dann aber ueberschritten wurde,
c wodurch dt immer wieder verkuerzt wurde, ohne dass der Uebergabebereich
c erreicht werden konnte. Letztlich bildete das ganze eine unendliche Schleife.
c Daher werden jetzt jedesmal, wenn die Fehlergrenze ueberschritten wird
c 'found_upper' und 'found_lower' resettet.
maxErr = Max(maxErr_x,maxErr_v)
if (maxErr.GT.1.) then
found_upper = .false.
found_lower = .false.
if (dt.LT.dtsmall) then ! Fehler immer noch zu gross, obwohl
flag_dtsmall = .true. ! dtsmall schon unterschritten ist
else
!c Bestimme kuerzeren Zeitschritt fuer neuen Versuch (vgl. Referenz):
dt = safety * dt * (maxErr**pShrink)
goto 10
endif
endif
c Falls x(1) (== x_1) jetzt bereits jenseits des Uebergangsbereiches am Ende
c der Potentialmappe liegen sollte, behalte dieses Faktum im Gedaechtnis
c und verkuerze den aktuell verwendeten Zeitschritt so lange um Faktor 0.5, bis
c x(1) innerhalb oder vor dem Uebergabebereich liegt. Liegt es davor, suche
c einen mittleren Zeitschritt, bei dem es im Uebergangsbereich liegt. Schliesse
c dann die Integration in dieser Mappe ab.
c (Der Uebergabebereich geht von einer halben x-Gitterkonstanten vor xmax bis
c eine halbe x-Gitterkonstante hinter xmax. In diesem Bereich wird ein konstantes
c EFeld zurueckgegeben):
x_1 = x(1) + Dx1(1) + xDifferenz(1) / 15.
if (x_1.GT.xStartUeber) then
if (x_1.LT.xEndUeber) then
reachedEndOfMap = .true.
else
dtupper = dt
found_upper = .true.
if (.NOT.found_lower) then
dt = min(0.5*dt,(xStartUeber-x(1))/(x_1-x(1))*dt)
else
dt = (dtlower+dtupper)/2.
endif
goto 10 ! neue Berechnung
endif
elseif (found_upper) then
found_lower = .true.
dtlower = dt
dt = (dtlower+dtupper)/2.
goto 10 ! neue Berechnung
endif
c Nimm die Ergebnisse aus dem dt-Schritt und den beiden dt/2-Schritten und
c berechne damit den neuen Ort und die neue Geschwindigkeit mit Genauigkeit
c fuenfter Ordnung in dt:
x(1) = x_1
x(2) = x(2) + Dx1(2) + xDifferenz(2) / 15.
x(3) = x(3) + Dx1(3) + xDifferenz(3) / 15.
v(1) = v(1) + Dv1(1) + vDifferenz(1) / 15.
v(2) = v(2) + Dv1(2) + vDifferenz(2) / 15.
v(3) = v(3) + Dv1(3) + vDifferenz(3) / 15.
c alten Zeitschritt addieren:
t = t + dt
c falls Uebergabebereich erreicht wurde, berechne naeherungsweisen Schnittpunkt der
c Trajektorie mit x=xmax (exaktes Mappenende) unter Verwendung der im Uebergabebereich
c zurueckgegebenen Beschleunigung:
if (reachedEndOfMap) then
call EFeld_L2andFO(x,EFeld0,*999)
help = v(1)*v(1) - 2.*EFeld0(1)*Beschl_Faktor*(x(1)-xmax)
if (help.LT.0.) then ! Teilchen wird noch vor Folie reflektiert werden
reachedEndOfMap = .false.
goto 3454
else
if (EFeld0(1)*Beschl_Faktor.NE.0) then
help = (sqrt(help) - v(1))/(EFeld0(1)*Beschl_Faktor) ! dt -> help
else
help = (xmax-x(1))/v(1)
endif
endif
t = t + help ! auch diesen Zeitschritt addieren
d dt = dt + help ! nur fuer dtmin_L2andFO,dtmax_L2andFO
help1 = Beschl_Faktor *help
help2 = help1*help/2.
c x(1) = x(1) + v(1)*help + EFeld0(1)*help2 ! == Folie, wenn richtig
x(1) = xmax
x(2) = x(2) + v(2)*help + EFeld0(2)*help2
x(3) = x(3) + v(3)*help + EFeld0(3)*help2
v(1) = v(1) + EFeld0(1)*help1
v(2) = v(2) + EFeld0(2)*help1
v(3) = v(3) + EFeld0(3)*help1
RETURN
endif
c neuen Zeitschritt so gross wie sinnvoller weise moeglich machen:
3454 if (flag_dtSmall) then
if (n_dtsmall.LT.maxBelowDtSmall) then
dt = dtSmall ! fuer naechsten RK-Schritt
n_dtsmall = n_dtsmall + 1
else
destiny = code_dtsmall ! gib Teilchen verloren
RETURN
endif
else
if (maxErr.GT.errCon) then
dt = safety * dt * (maxErr**pGrow) ! vgl. Referenz
else
dt = 4. * dt ! <- Vergroesserung des Zeitschritts max. um
endif ! Faktor 4!
! pruefen, ob Maximallaenge fuer ersten Testschritt nicht ueberschritten ist:
d if (log_confine) dt = min(dt,dl_max/sqrt(v(1)*v(1)+v(2)*v(2)+v(3)*v(3)))
endif
RETURN
c hier folgt der Code fuer 'returnCode_EFeld.NE.0':
998 continue
if (returnCode_EFeld.EQ.1) then
write(*,*) Nr//'-Mappe:'
write(*,*)' aktueller Teilchenort (nicht Testort!) hinter Potentialmappe!'
write(*,*)' -> STOP'
write(*,*)
CALL EXIT
! alternativ koennte man hier vielleicht auch nach x=xmax zurueckrechnen
endif
999 continue
if (returnCode_EFeld.EQ.1) then ! Testort hinter der Mappe
dt = 0.5*dt
found_lower = .false.
found_upper = .false.
goto 10
elseif (returnCode_EFeld.EQ.2) then
!destiny = code_wand ! wird im Hauptprogramm zugewiesen!
RETURN
elseif (returnCode_EFeld.EQ.3) then ! Testort vor der Mappe
if (v(1).LE.0) then ! reflektiert -> kann vorkommen
destiny = code_reflektiert
RETURN
else ! in Vorwaertsbewegung -> darf nicht vorkommen!!
write(*,*)
write(*,*) Nr//'-Mappe: ',mappenName
write(*,*)' Test-x liegt vor der Mappe! x,y,z = ',x
write(*,*)' Teilchen-Nr = ',Start_Nr(1)
write(*,*)' -> STOP'
write(*,*)
CALL EXIT
endif
elseif (returnCode_EFeld.NE.0) then
write(*,*)
write(*,*) 'SINGLESTEP_RUNGE_KUTTA_'//Nr//': '
write(*,*) 'unallowed value of ''returnCode_EFeld'': ',returnCode_Efeld
write(*,*) '-> STOP'
write(*,*)
CALL EXIT
endif
END
c===============================================================================
OPTIONS /EXTEND_SOURCE
SUBROUTINE SINGLESTEP_RUNGE_KUTTA_L2andFo(dt,E0,x0,v0, Dx,Dv, *)
c ================================================================
IMPLICIT NONE
c Diese Subroutine berechnet bei vorgegebenem Zeitschritt einen einzelnen
c Runge-Kutta-Integrationsschritt (4. Ordnung).
c Die Vorgehensweise entspricht den Ausfuehrungen in Kapitel 15.1 der
c NUMERICAL RECIPIES: 'Runge-Kutta Method'. Die Formeln sind zwar teilweise
c etwas umgeschrieben, sind aber mathematisch alle aequivalent zu denen der
c Referenz.
c Zurueckgegeben werden die errechneten Orts- und Geschwindigkeitsaenderungen
c anstatt direkt der neuen Werte, da sonst vor allem bei den Ortskoordinaten
c Schwierigkeiten auftreten koennen, wenn in der Subroutine 'INTEGRATIONSSTEP_
c RUNGE_KUTTA' aus der Differenz der neuen Werte aus den beiden dt/2- und dem
c dt-Schritt der Fehler abgeschaetzt werden soll (kleine Differenz moeglicher-
c weise grosser Werte).
real Beschl_Faktor
COMMON /Beschl_Faktor/ Beschl_Faktor
real E0(3), x0(3), v0(3) ! Eingangsgroessen
real E1(3), E2(3), E3(3) ! E-Felder an Testorten
real v1(3), v2(3), v3(3) ! Geschwindigkeiten an Testorten
real dt,dt_half,dt_sixth ! zeitl. Aenderung, dt/2, dt/6
real help, help_half, help_sixth ! Hilfsvariable, help/2, help/6
real xTest(3) ! Test-Orte
real Dx(3), Dv(3) ! Ergebnisspeicher
integer i ! Zaehlvariable
c = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
dt_half = dt / 2.
dt_sixth = dt / 6.
help = Beschl_Faktor * dt
help_half = help / 2.
help_sixth = help / 6.
do i = 1, 3
xTest(i) = x0(i) + v0(i) * dt_half
v1(i) = v0(i) + E0(i) * help_half
enddo
call EFeld_L2andFo(xTest,E1,*999)
do i = 1, 3
xTest(i) = x0(i) + v1(i) * dt_half
v2(i) = v0(i) + E1(i) * help_half
enddo
call EFeld_L2andFo(xTest,E2,*999)
do i = 1, 3
xTest(i) = x0(i) + v2(i) * dt
v3(i) = v0(i) + E2(i) * help
enddo
call EFeld_L2andFo(xTest,E3,*999)
do i = 1, 3
Dx(i) = (v0(i) + 2.*(v1(i)+v2(i)) + v3(i)) * dt_sixth
Dv(i) = (E0(i) + 2.*(E1(i)+E2(i)) + E3(i)) * help_sixth
enddo
RETURN
999 RETURN 1
END
c===============================================================================
OPTIONS /EXTEND_SOURCE
SUBROUTINE EFeld_L2andFo(x,E,*)
c ===============================
IMPLICIT NONE
INCLUDE 'mutrack$sourcedirectory:MAP_DEF_L2andFo.INC'
real real_i,real_j ! x,r im Mappensystem in Gittereinheiten
integer stuetzstelle_i(2) ! naechste Stuetzstellen in x- und
integer stuetzstelle_j(2) ! r-Richtung
real Abstand_i,Abstand_i_Betrag ! Entfernung zur naechsten Stuetzstelle
real Abstand_j,Abstand_j_Betrag ! (in Gittereinheiten!)
integer i,j, n, ihelp
real radius ! Betrag des Radiusvektors in y-z-Ebene
real x(3),E(3) ! Ort und Feldstaerke
real E_(2) ! Hilfsspeicher fuer Feldberechnung
real Erad ! radiale Feldstaerke
c Falls Testort ausserhalb der Mappe liegt oder Anode getroffen hat:
integer returnCode_EFeld
COMMON /returnCode_EFeld/ returnCode_EFeld
! 1: TESTORT HINTER DER MAPPE
! 2: TESTORT NEBEN DER MAPPE
! 3: TESTORT VOR DER MAPPE
c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
c Rechne in Gittereinheiten um:
radius = sqrt(x(2)*x(2)+x(3)*x(3))
real_i = x(1) / Dx ! bereits im Hauptprogr.: x(1) -> x(1)-xEnterMap
real_j = radius / Dr
c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
c Mache die Tests und berechne die Feldstaerke:
c Teste, ob Raumpunkt innerhalb der Potentialmappe liegt:
if (real_i.GT.real(imax)) then ! => hinter Potentialmappe, also
! hinter TriggerFolie
if (real_i.GT.real(imax)+.5) then
returnCode_EFeld = 1
RETURN 1
else
real_i = imax
endif
elseif (real_j.GT.jmax) then ! => radial ausserhalb der Mappe
returnCode_EFeld = 2
RETURN 1
elseif (real_i.LT.0.) then ! => vor Beginn der Potentialmappe
E(1) = 0.
E(2) = 0.
E(3) = 0.
RETURN
endif
c Bestimme naechstgelegene Stuetzstellen und die Komponenten des Abstands-
c Gittervektors zur allernaechsten Stuetzstelle sowie deren Betraege:
stuetzstelle_i(1) = nint(real_i)
Abstand_i = real_i - stuetzstelle_i(1) ! Abstand zur naeheren Stuetzstelle
Abstand_i_Betrag = abs(Abstand_i)
if (Abstand_i.gt.0.) then
stuetzstelle_i(2) = stuetzstelle_i(1) + 1
elseif (Abstand_i.lt.0.) then
stuetzstelle_i(2) = stuetzstelle_i(1) - 1
else
stuetzstelle_i(2) = stuetzstelle_i(1)
endif
stuetzstelle_j(1) = nint(real_j)
Abstand_j = real_j - stuetzstelle_j(1)
Abstand_j_Betrag = abs(Abstand_j)
if (Abstand_j.gt.0.) then
stuetzstelle_j(2) = stuetzstelle_j(1) + 1
elseif (Abstand_j.lt.0.) then
stuetzstelle_j(2) = stuetzstelle_j(1) - 1
else
stuetzstelle_j(2) = stuetzstelle_j(1)
endif
c...............................................................................
c Berechnen des elektrischen Feldes:
c ----------------------------------
c
c Potentialverlauf ist symmetrisch zu j=0 (Linsenachse):
c
c map(i,-j) == map(i,j).
c
c Entlang j=0 ist also Erad=0 und damit E(2)=0 und E(3)=0.
c...............................................................................
c Berechne die x-Komponente der Feldstaerke:
c Um die Feldstaerke zu bekommen, interpoliere jeweils linear zwischen den
c Werten auf den beiden naechstgelegenen j-Ketten:
i = stuetzstelle_i(1)
do n = 1, 2
j = stuetzstelle_j(n)
ihelp = j*(imax+1) + i
if (i.EQ.imax) then
E_(n) = map(ihelp-1) - map(ihelp)
elseif (i.GT.0) then
E_(n) = (-0.5+Abstand_i)*(map(ihelp)-map(ihelp-1))
+ + ( 0.5+Abstand_i)*(map(ihelp)-map(ihelp+1))
else
E_(n) = map(ihelp) - map(ihelp+1)
endif
enddo
E(1) = E_(1) + Abstand_j_Betrag*(E_(2)-E_(1))
E(1) = E(1) / Dx ! Reskalierung entsprechend x-Gitterkonstanten
c Berechne die radiale Komponente der Feldstaerke:
if (real_j.LT.1e-10) then
E(2) = 0.
E(3) = 0.
RETURN
endif
j = stuetzstelle_j(1)
do n = 1, 2
i = stuetzstelle_i(n)
ihelp = j*(imax+1) + i
if (j.EQ.jmax) then
E_(n) = map(ihelp-(imax+1)) - map(ihelp)
elseif (j.GT.0) then
E_(n) = (-0.5+Abstand_j)*(map(ihelp)-map(ihelp-(imax+1)))
+ + ( 0.5+Abstand_j)*(map(ihelp)-map(ihelp+(imax+1)))
else ! j=0 -> map(i,j-1) = map(i,j+1) == map(i,1)
E_(n) = 2.0*Abstand_j*(map(ihelp)-map(ihelp+(imax+1)))
endif
enddo
Erad = E_(1) + Abstand_i_Betrag*(E_(2)-E_(1))
Erad = Erad / Dr ! Reskalierung entsprechend r-Gitterkonstanten
c Berechne E(2) und E(3) aus Erad:
E(2) = Erad * x(2) / radius
E(3) = Erad * x(3) / radius
END
c===============================================================================

View File

@ -0,0 +1,709 @@
c===============================================================================
OPTIONS /EXTEND_SOURCE
SUBROUTINE READ_INFO_L3
c =======================
IMPLICIT NONE
character*(*) Nr
parameter (Nr='L3')
INCLUDE 'mutrack$sourcedirectory:COM_LUNS.INC'
INCLUDE 'mutrack$sourcedirectory:COM_DIRS.INC'
INCLUDE 'mutrack$sourcedirectory:MAP_DEF_L3.INC'
c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
namelist /geometry/
+ DistanceCyl,iRadiusCyl,
+ LengthOuterCyl,oRadiusOuterCyl,
+ LengthInnerCyl,oRadiusInnerCyl,
+ RadiusVacTube
namelist /grid_info/
+ Dx,Dr, imax,jmax, xmax,rmax
c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
logical map_error
COMMON /map_error/ map_error
c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
c Einlesen der Mappen-Informationen:
open (lunREAD,file=mappenName//'.INFO',defaultfile=mappenDir,
+ readonly,status='old')
read (lunREAD,nml=grid_info)
rewind (lunREAD)
read (lunREAD,nml=geometry)
close (lunREAD)
c Pruefen, ob die eingelesene Mappe den Anforderungen genuegt:
if (iRadiusCyl.NE.rmax) then
write(*,*)' L3-Mappe: rmax der Mappe stimmt nicht mit Innenradius der Zylinder ueberein'
write(*,*)' -> STOP'
STOP
endif
c eingelesene imax und jmax um 1 reduzieren, da in 'MUTRACK' die Feldindizes
c ab 0 laufen, bei 'RELAX3D' jedoch ab 1:
imax = imax-1
jmax = jmax-1
c die geometrischen Daten fuer Mutrack zusammenstellen:
xEnterMap = xCenterOfLense - xmax
xLeaveMap = xCenterOfLense + xmax
c checken, ob der reservierte Speicherplatz ausreicht:
if ((imax+1)*(jmax+1).NE.maxmem+1) then
write(*,*)'----------------------------------------'//
+ '----------------------------------------'
write(*,*) Nr//'-Mappe: ',mappenName
write(*,*) ' BENOETIGTER Speicher: (imax+1)*(jmax+1) = ',(imax+1)*(jmax+1)
write(*,*) ' RESERVIERTER Speicher: maxmem + 1 = ',maxmem + 1
write(*,*)
if ((imax+1)*(jmax+1).GT.maxmem+1) then
write(*,*) '=> reservierter Speicherplatz ist ungenuegend.'
write(*,*)
write(*,*) '=> ''maxmem'' in mutrack$sourcedirectory:MAP_DEF_'//Nr//'.INC angleichen,'
write(*,*) ' dann Programm mit ''LINKMUV'' am DCL-Prompt neu kompilieren'
write(*,*) ' und linken.'
write(*,*)
write(*,*) ' Mindestwert fuer ''maxmem'' ist ',(imax+1)*(jmax+1)-1
write(*,*)
map_error = .true.
endif
endif
END
c===============================================================================
OPTIONS /EXTEND_SOURCE
SUBROUTINE READ_MAP_L3
c ======================
IMPLICIT NONE
character*(*) Nr
parameter (Nr='L3')
INCLUDE 'mutrack$sourcedirectory:MAP_DEF_L3.INC'
INCLUDE 'mutrack$sourcedirectory:READ_MAP.INC'
END
c===============================================================================
OPTIONS /EXTEND_SOURCE
SUBROUTINE INTEGRATIONSSTEP_RUNGE_KUTTA_L3(dt)
c ==============================================
IMPLICIT NONE
SAVE
character*(*) Nr
parameter (Nr='L3')
c Diese Subroutine berechnet zu einem vorgegebenen Zeitschritt dt den
c Integrationsschritt zweimal: einmal direkt mit dt und einmal ueber zwei
c aufeinanderfolgende Schritte mit dt/2. (die beiden dt/2-Schritte werden
c zuerst ausgefuehrt).
c
c Aus der Differenz der beiden Resultate wird eine Abschaetzung fuer den Fehler
c des dt-Schrittes gewonnen, die dazu verwendet wird zu entscheiden, ob der
c Integrationsschritt mit einem verkuerzten Zeitintervall wiederholt werden
c muss, oder ob das Zeitintervall fuer den folgenden ausgedehnt werden kann.
c
c Die beiden Einzelergebnisse aus dem dt- und den beiden dt/2-Schritten, die
c jeweils ueber Runge-Kutta-Rechnung vierter Ordnung erhalten werden, werden
c zum Schluss noch zusammengenommen, um ein Resultat mit Genauigkeit fuenfter
c Ordnung in dt zu erhalten.
c
c Der ganze Ablauf entspricht den Ausfuehrungen in Kapitel 15.2 der NUMERICAL
c RECIPIES: 'Adaptive Stepsize Control for Runge-Kutta' (vgl. Referenz im
c fileheader von 'MUTRACK.FOR')
INCLUDE 'mutrack$sourcedirectory:COM_MUTRACK.INC'
INCLUDE 'mutrack$sourcedirectory:MAP_DEF_L3.INC'
integer i ! Zaehlvariable
real dt,dt_half ! zeitl. Aenderung, halbe zeitl. Aenderung
real EFeld0(3), EFeld1(3) ! elektr. Felder
real x1(3),Dx1(3),Dx2(3) ! fuer Ortsintegration
real v1(3),Dv1(3),Dv2(3) ! fuer Geschw.Integration
real xDifferenz(3), vDifferenz(3)
real maxErr_x,maxErr_v,maxErr ! fuer Fehlerbetrachtung
real errCon, safety ! fuer Schrittweitenkontrolle
real pShrink, pGrow ! fuer Schrittweitenkontrolle
PARAMETER (errCon = 6.e-4, safety = .9) ! vgl. Referenz
PARAMETER (pShrink = -.25, pGrow = -.2)
! errCon = (4./safety)**(1/pGrow)
logical flag_dtSmall ! wenn bei dt < dtsmall der Fehler
! immer noch zu gross ist.
integer returnCode_EFeld
COMMON /returnCode_EFeld/ returnCode_EFeld
! 1: Testort hinter der Mappe
! 2: TESTORT NEBEN DER MAPPE
! 3: Testort vor der Mappe
c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
flag_dtSmall = .false. ! flag resetten
if (dt.LT.dtsmall) dt = dtsmall
c berechne EFeld am aktuellen Ort. Speichere in EFeld0, damit sie wiederverwendet
c werden kann, falls mit kuerzerem Zeitschritt wiederholt werden muss:
call EFeld_L3(x,EFeld0,*999)
c...............................................................................
10 continue ! hier gehts wieder von vorne los, falls Zeitschritt dt
! abgeaendert werden muss.
dt_half = dt / 2.
c mache ersten dt/2 - Schritt:
call SINGLESTEP_RUNGE_KUTTA_L3(dt_half,EFeld0,x,v, Dx1,Dv1 ,*999)
c berechne EFeld bei x1:
x1(1) = x(1) + Dx1(1)
x1(2) = x(2) + Dx1(2)
x1(3) = x(3) + Dx1(3)
v1(1) = v(1) + Dv1(1)
v1(2) = v(2) + Dv1(2)
v1(3) = v(3) + Dv1(3)
call EFeld_L3(x1,EFeld1,*999)
c mache zweiten dt/2 - Schritt:
call SINGLESTEP_RUNGE_KUTTA_L3(dt_half,EFeld1,x1,v1, Dx2,Dv2 ,*999)
c Summiere Ergebnisse der beiden dt/2 -Schritte und speichere in Dx1, Dv1:
Dx1(1) = Dx1(1) + Dx2(1)
Dx1(2) = Dx1(2) + Dx2(2)
Dx1(3) = Dx1(3) + Dx2(3)
Dv1(1) = Dv1(1) + Dv2(1)
Dv1(2) = Dv1(2) + Dv2(2)
Dv1(3) = Dv1(3) + Dv2(3)
c mache dt - Schritt:
call SINGLESTEP_RUNGE_KUTTA_L3(dt,EFeld0,x,v, Dx2,Dv2 ,*999)
c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
c Fehlerbetrachtung und Berechnung des endgueltigen Ergebnisses:
c Fehlerbetrachtung:
c der groesste (absolute bzw. relative) Fehler im Ort soll kleiner als eps_x
c sein, der groesste Fehler in der Geschwindigkeit kleiner als eps_v:
c -> Bestimme den jeweils groessten Fehler der drei Komponenten des Ortes und
c der Geschwindikeit (dh. die groesste Differenz der Aederungen):
maxErr_x = 0.
maxErr_v = 0.
do i = 1, 3
xDifferenz(i) = Dx1(i)-Dx2(i)
vDifferenz(i) = Dv1(i)-Dv2(i)
if (log_relativ) then
if (Dx1(i).NE.0.)
+ maxErr_x = Max( maxErr_x, Abs( xDifferenz(i)/Dx1(i) ) )
if (Dv1(i).NE.0.)
+ maxErr_v = Max( maxErr_v, Abs( vDifferenz(i)/Dv1(i) ) )
else
maxErr_x = Max( maxErr_x, Abs( xDifferenz(i) ) )
maxErr_v = Max( maxErr_v, Abs( vDifferenz(i) ) )
endif
enddo
c - Skaliere den jeweils groessten relativen Fehler auf das jeweilige Epsilon:
maxErr_x = maxErr_x / eps_x
maxErr_v = maxErr_v / eps_v
c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
c der groessere der beiden reskalierten Fehler bestimmt, ob der Integrations-
c schritt mit kleinerem Zeitintervall wiederholt werden muss, bzw. um welchen
c Faktor das Zeitintervall fuer den naechsten Schritt vergroessert werden kann:
c Liegt der Fehler ausserhalb des Toleranzbereiches und ist dt bereits jetzt
c kleiner als dtsmall, so mache keinen neuen Versuch sondern akzeptiere als Not-
c loesung den bestehenden Naeherungswert. Setze dt in diesem Fall als Default
c fuer den kommenden Integrationsschritt auf dtsmall. Setze aber auch das flag
c 'flag_dtsmall', damit gezaehlt werden kann, wie oft dieses Prozedur fuer ein
c bestimmtes Teilchen angewendet werden muss. Ist dies zu oft der Fall, so brich
c diese Trajektorienberechnung ganz ab (-> destiny = code_dtsmall).
c (2. Teil erfolgt weiter unten)
maxErr = Max(maxErr_x,maxErr_v)
if (maxErr.GT.1.) then
if (dt.LT.dtsmall) then ! Fehler immer noch zu gross, obwohl
flag_dtsmall = .true. ! dtsmall schon unterschritten ist
else
!c Bestimme kuerzeren Zeitschritt fuer neuen Versuch (vgl. Referenz):
dt = safety * dt * (maxErr**pShrink)
goto 10
endif
endif
c Nimm die Ergebnisse aus dem dt-Schritt und den beiden dt/2-Schritten und
c berechne damit den neuen Ort und die neue Geschwindigkeit mit Genauigkeit
c fuenfter Ordnung in dt:
x(1) = x(1) + Dx1(1) + xDifferenz(1) / 15.
x(2) = x(2) + Dx1(2) + xDifferenz(2) / 15.
x(3) = x(3) + Dx1(3) + xDifferenz(3) / 15.
v(1) = v(1) + Dv1(1) + vDifferenz(1) / 15.
v(2) = v(2) + Dv1(2) + vDifferenz(2) / 15.
v(3) = v(3) + Dv1(3) + vDifferenz(3) / 15.
c alten Zeitschritt addieren, neuen so gross wie sinnvoller weise moeglich
c machen:
t = t + dt
if (flag_dtSmall) then
if (n_dtsmall.LT.maxBelowDtSmall) then
dt = dtSmall ! fuer naechsten RK-Schritt
n_dtsmall = n_dtsmall + 1
else
destiny = code_dtsmall ! gib Teilchen verloren
RETURN
endif
else
if (maxErr.GT.errCon) then
dt = safety * dt * (maxErr**pGrow) ! vgl. Referenz
else
dt = 4. * dt ! <- Vergroesserung des Zeitschritts max. um
endif ! Faktor 4!
! pruefen, ob Maximallaenge fuer ersten Testschritt nicht ueberschritten ist:
d if (log_confine) dt = min(dt,dl_max/sqrt(v(1)*v(1)+v(2)*v(2)+v(3)*v(3)))
endif
RETURN
c hier folgt der Code fuer 'returnCode_EFeld.NE.0':
999 continue
if (returnCode_EFeld.EQ.2) then
destiny = code_wand
RETURN
elseif (returnCode_EFeld.NE.0) then
write(*,*)
write(*,*) 'SINGLESTEP_RUNGE_KUTTA_'//Nr//': '
write(*,*) 'unallowed value of ''returnCode_EFeld'': ',returnCode_Efeld
write(*,*) '-> STOP'
write(*,*)
STOP
endif
END
c===============================================================================
OPTIONS /EXTEND_SOURCE
SUBROUTINE SINGLESTEP_RUNGE_KUTTA_L3(dt,E0,x0,v0, Dx,Dv, *)
c ===========================================================
IMPLICIT NONE
c Diese Subroutine berechnet bei vorgegebenem Zeitschritt einen einzelnen
c Runge-Kutta-Integrationsschritt (4. Ordnung).
c Die Vorgehensweise entspricht den Ausfuehrungen in Kapitel 15.1 der
c NUMERICAL RECIPIES: 'Runge-Kutta Method'. Die Formeln sind zwar teilweise
c etwas umgeschrieben, sind aber mathematisch alle aequivalent zu denen der
c Referenz.
c Zurueckgegeben werden die errechneten Orts- und Geschwindigkeitsaenderungen
c anstatt direkt der neuen Werte, da sonst vor allem bei den Ortskoordinaten
c Schwierigkeiten auftreten koennen, wenn in der Subroutine 'INTEGRATIONSSTEP_
c RUNGE_KUTTA' aus der Differenz der neuen Werte aus den beiden dt/2- und dem
c dt-Schritt der Fehler abgeschaetzt werden soll (kleine Differenz moeglicher-
c weise grosser Werte).
real Beschl_Faktor
COMMON /Beschl_Faktor_L3/ Beschl_Faktor
real E0(3), x0(3), v0(3) ! Eingangsgroessen
real E1(3), E2(3), E3(3) ! E-Felder an Testorten
real v1(3), v2(3), v3(3) ! Geschwindigkeiten an Testorten
real dt,dt_half,dt_sixth ! zeitl. Aenderung, dt/2, dt/6
real help, help_half, help_sixth ! Hilfsvariable, help/2, help/6
real xTest(3) ! Test-Orte
real Dx(3), Dv(3) ! Ergebnisspeicher
integer i ! Zaehlvariable
c = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
dt_half = dt / 2.
dt_sixth = dt / 6.
help = Beschl_Faktor * dt
help_half = help / 2.
help_sixth = help / 6.
do i = 1, 3
xTest(i) = x0(i) + v0(i) * dt_half
v1(i) = v0(i) + E0(i) * help_half
enddo
call EFeld_L3(xTest,E1,*999)
do i = 1, 3
xTest(i) = x0(i) + v1(i) * dt_half
v2(i) = v0(i) + E1(i) * help_half
enddo
call EFeld_L3(xTest,E2,*999)
do i = 1, 3
xTest(i) = x0(i) + v2(i) * dt
v3(i) = v0(i) + E2(i) * help
enddo
call EFeld_L3(xTest,E3,*999)
do i = 1, 3
Dx(i) = (v0(i) + 2.*(v1(i)+v2(i)) + v3(i)) * dt_sixth
Dv(i) = (E0(i) + 2.*(E1(i)+E2(i)) + E3(i)) * help_sixth
enddo
RETURN
999 RETURN 1
END
cc was hier kommt ist die etwas ausfuehrlichere Version:
cc First step of Runge-Kutta-Method: dx1, dv1
c dx1(1) = vIn(1) * dt_
c dx1(2) = vIn(2) * dt_
c dx1(3) = vIn(3) * dt_
c dv1(1) = a0(1) * dt_
c dv1(2) = a0(2) * dt_
c dv1(3) = a0(3) * dt_
cc Second step of Runge-Kutta-Method: dx2, dv2
c xTest(1) = xIn(1) + dx1(1) / 2.
c xTest(2) = xIn(2) + dx1(2) / 2.
c xTest(3) = xIn(3) + dx1(3) / 2.
c vTest(1) = vIn(1) + dv1(1) / 2.
c vTest(2) = vIn(2) + dv1(2) / 2.
c vTest(3) = vIn(3) + dv1(3) / 2.
c call EFeld_L3(xTest,ETest)
c if (returnCode_EFeld.NE.0) RETURN
c dx2(1) = vTest(1) * dt_
c dx2(2) = vTest(2) * dt_
c dx2(3) = vTest(3) * dt_
c dv2(1) = Beschl_Faktor * ETest(1) * dt_
c dv2(2) = Beschl_Faktor * ETest(2) * dt_
c dv2(3) = Beschl_Faktor * ETest(3) * dt_
cc Third step of Runge-Kutta-Method: dx3, dv3
c xTest(1) = xIn(1) + dx2(1) / 2.
c xTest(2) = xIn(2) + dx2(2) / 2.
c xTest(3) = xIn(3) + dx2(3) / 2.
c vTest(1) = vIn(1) + dv2(1) / 2.
c vTest(2) = vIn(2) + dv2(2) / 2.
c vTest(3) = vIn(3) + dv2(3) / 2.
c call EFeld_L3(xTest,ETest)
c if (returnCode_EFeld.NE.0) RETURN
c dx3(1) = vTest(1) * dt_
c dx3(2) = vTest(2) * dt_
c dx3(3) = vTest(3) * dt_
c dv3(1) = Beschl_Faktor * ETest(1) * dt_
c dv3(2) = Beschl_Faktor * ETest(2) * dt_
c dv3(3) = Beschl_Faktor * ETest(3) * dt_
cc Fourth step of Runge-Kutta-Method: dx4, dv4
c xTest(1) = xIn(1) + dx3(1)
c xTest(2) = xIn(2) + dx3(2)
c xTest(3) = xIn(3) + dx3(3)
c vTest(1) = vIn(1) + dv2(1)
c vTest(2) = vIn(2) + dv2(2)
c vTest(3) = vIn(3) + dv2(3)
c call EFeld_L3(xTest,ETest)
c if (returnCode_EFeld.NE.0) RETURN
c dx4(1) = vTest(1) * dt_
c dx4(2) = vTest(2) * dt_
c dx4(3) = vTest(3) * dt_
c dv4(1) = Beschl_Faktor * ETest(1) * dt_
c dv4(2) = Beschl_Faktor * ETest(2) * dt_
c dv4(3) = Beschl_Faktor * ETest(3) * dt_
cc calculate forward step:
c Dx(1) = (dx1(1)+2.*dx2(1)+2.*dx3(1)+dx4(1)) / 6.
c Dx(2) = (dx1(2)+2.*dx2(2)+2.*dx3(2)+dx4(2)) / 6.
c Dx(3) = (dx1(3)+2.*dx2(3)+2.*dx3(3)+dx4(3)) / 6.
c Dv(1) = (dv1(1)+2.*dv2(1)+2.*dv3(1)+dv4(1)) / 6.
c Dv(2) = (dv1(2)+2.*dv2(2)+2.*dv3(2)+dv4(2)) / 6.
c Dv(3) = (dv1(3)+2.*dv2(3)+2.*dv3(3)+dv4(3)) / 6.
cc was jetzt kommt ist die falsche alte Version!!!!!
cc First step of Runge-Kutta-Method: dx1, dv1
c dv1(1) = a0(1) * dt_
c dv1(2) = a0(2) * dt_
c dv1(3) = a0(3) * dt_
c dx1(1) = vIn(1) * dt_
c dx1(2) = vIn(2) * dt_
c dx1(3) = vIn(3) * dt_
cc Second step of Runge-Kutta-Method: dx2, dv2
c xTest(1)= xIn(1) + dx1(1) / 2.
c xTest(2)= xIn(2) + dx1(2) / 2.
c xTest(3)= xIn(3) + dx1(3) / 2.
c call EFeld_L3(xTest,ETest)
c if (returnCode_EFeld.NE.0) RETURN
c dv2(1)= Beschl_Faktor * ETest(1) * dt_
c dv2(2)= Beschl_Faktor * ETest(2) * dt_
c dv2(3)= Beschl_Faktor * ETest(3) * dt_
c dx2(1) = dx1(1) + dt_ * dv1(1) / 2.
c dx2(2) = dx1(2) + dt_ * dv1(2) / 2.
c dx2(3) = dx1(3) + dt_ * dv1(3) / 2.
cc Third step of Runge-Kutta-Method: dx3, dv3
c xTest(1)= xIn(1) + dx2(1) / 2.
c xTest(2)= xIn(2) + dx2(2) / 2.
c xTest(3)= xIn(3) + dx2(3) / 2.
c call EFeld_L3(xTest,ETest)
c if (returnCode_EFeld.NE.0) RETURN
c dv3(1)= Beschl_Faktor * ETest(1) * dt_
c dv3(2)= Beschl_Faktor * ETest(2) * dt_
c dv3(3)= Beschl_Faktor * ETest(3) * dt_
c dx3(1) = dx1(1) + dt_ * dv2(1) / 2.
c dx3(2) = dx1(2) + dt_ * dv2(2) / 2.
c dx3(3) = dx1(3) + dt_ * dv2(3) / 2.
cc Fourth step of Runge-Kutta-Method: dx4, dv4
c xTest(1)= xIn(1) + dx3(1)
c xTest(2)= xIn(2) + dx3(2)
c xTest(3)= xIn(3) + dx3(3)
c call EFeld_L3(xTest,ETest)
c if (returnCode_EFeld.NE.0) RETURN
c dv4(1)= Beschl_Faktor * ETest(1) * dt_
c dv4(2)= Beschl_Faktor * ETest(2) * dt_
c dv4(3)= Beschl_Faktor * ETest(3) * dt_
c dx4(1) = dx1(1) + dt_ * dv3(1)
c dx4(2) = dx1(2) + dt_ * dv3(2)
c dx4(3) = dx1(3) + dt_ * dv3(3)
cc calculate forward step:
c Dx(1) = (dx1(1)+2.*dx2(1)+2.*dx3(1)+dx4(1)) / 6.
c Dx(2) = (dx1(2)+2.*dx2(2)+2.*dx3(2)+dx4(2)) / 6.
c Dx(3) = (dx1(3)+2.*dx2(3)+2.*dx3(3)+dx4(3)) / 6.
c Dv(1) = (dv1(1)+2.*dv2(1)+2.*dv3(1)+dv4(1)) / 6.
c Dv(2) = (dv1(2)+2.*dv2(2)+2.*dv3(2)+dv4(2)) / 6.
c Dv(3) = (dv1(3)+2.*dv2(3)+2.*dv3(3)+dv4(3)) / 6.
c===============================================================================
OPTIONS /EXTEND_SOURCE
SUBROUTINE EFeld_L3(x,E,*)
c ==========================
IMPLICIT NONE
INCLUDE 'mutrack$sourcedirectory:MAP_DEF_L3.INC'
real real_i,real_j ! x,r im Mappensystem in Gittereinheiten
integer stuetzstelle_i(2) ! naechste Stuetzstellen in x- und
integer stuetzstelle_j(2) ! r-Richtung
real Abstand_i,Abstand_i_Betrag ! Entfernung zur naechsten Stuetzstelle
real Abstand_j,Abstand_j_Betrag ! (in Gittereinheiten!)
integer i,j, n, ihelp
real radius ! Betrag des Radiusvektors in y-z-Ebene
real x(3),E(3) ! Ort und Feldstaerke
real E_(2) ! Hilfsspeicher fuer Feldberechnung
real Erad ! radiale Feldstaerke
c Falls Testort ausserhalb der Mappe liegt oder Anode getroffen hat:
integer returnCode_EFeld
COMMON /returnCode_EFeld/ returnCode_EFeld
! 1: Testort hinter der Mappe
! 2: TESTORT NEBEN DER MAPPE
! 3: Testort vor der Mappe
c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
c Rechne in Gittereinheiten um:
radius = sqrt(x(2)*x(2)+x(3)*x(3))
real_i = (xmax - abs(x(1)-xCenterOfLense)) / Dx
real_j = radius / Dr
c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
c Mache die Tests und berechne die Feldstaerke:
c Teste, ob Raumpunkt innerhalb der Potentialmappe liegt:
if (real_j.GT.jmax) then
returnCode_EFeld = 2
RETURN 1
elseif (real_i.LT.0.) then
E(1) = 0.
E(2) = 0.
E(3) = 0.
RETURN
c else
c returnCode_EFeld = 0
endif
c Bestimme naechstgelegene Stuetzstellen und die Komponenten des Abstands-
c Gittervektors zur allernaechsten Stuetzstelle sowie deren Betraege:
stuetzstelle_i(1) = nint(real_i)
Abstand_i = real_i - stuetzstelle_i(1) ! Abstand zur naeheren Stuetzstelle
Abstand_i_Betrag = abs(Abstand_i)
if (Abstand_i.gt.0.) then
stuetzstelle_i(2) = stuetzstelle_i(1) + 1
elseif (Abstand_i.lt.0.) then
stuetzstelle_i(2) = stuetzstelle_i(1) - 1
else
stuetzstelle_i(2) = stuetzstelle_i(1)
endif
stuetzstelle_j(1) = nint(real_j)
Abstand_j = real_j - stuetzstelle_j(1)
Abstand_j_Betrag = abs(Abstand_j)
if (Abstand_j.gt.0.) then
stuetzstelle_j(2) = stuetzstelle_j(1) + 1
elseif (Abstand_j.lt.0.) then
stuetzstelle_j(2) = stuetzstelle_j(1) - 1
else
stuetzstelle_j(2) = stuetzstelle_j(1)
endif
c...............................................................................
c Berechnen des elektrischen Feldes:
c ----------------------------------
c
c Potentialverlauf ist symmetrisch zu real_i = imax (Mittelebene des inneren
c Zylinders) und zu j=0 (Linsenachse):
c
c map(imax+i,-j) == map(imax-1,j),
c map(i,-j) == map(i,j).
c
c Entlang j=0 ist also Erad=0 und damit E(2)=0 und E(3)=0, bei i=imax ist E(1)=0
c...............................................................................
c Berechne die x-Komponente der Feldstaerke:
c Um die Feldstaerke zu bekommen, interpoliere jeweils linear zwischen den
c Werten auf den beiden naechstgelegenen j-Ketten:
i = stuetzstelle_i(1)
do n = 1, 2
j = stuetzstelle_j(n)
ihelp = j*(imax+1) + i
if (i.EQ.imax) then
E_(n) = 2. * Abstand_i *(map(ihelp)-map(ihelp-1)) ! i=imax -> map(imax+1,j) = map(imax-1,j)
elseif (i.GT.0) then
E_(n) = (-0.5+Abstand_i)*(map(ihelp)-map(ihelp-1))
+ + ( 0.5+Abstand_i)*(map(ihelp)-map(ihelp+1))
else
E_(n) = map(ihelp) - map(ihelp+1)
endif
enddo
E(1) = E_(1) + Abstand_j_Betrag*(E_(2)-E_(1))
E(1) = E(1) / Dx ! Reskalierung entsprechend x-Gitterkonstanten
if (x(1).GT.xCenterOfLense) E(1) = - E(1)
c Berechne die radiale Komponente der Feldstaerke:
if (real_j.LT.1e-10) then
E(2) = 0.
E(3) = 0.
RETURN
endif
j = stuetzstelle_j(1)
do n = 1, 2
i = stuetzstelle_i(n)
ihelp = j*(imax+1) + i
if (j.EQ.jmax) then
E_(n) = map(ihelp-(imax+1)) - map(ihelp)
elseif (j.GT.0) then
E_(n) = (-0.5+Abstand_j)*(map(ihelp)-map(ihelp-(imax+1)))
+ + ( 0.5+Abstand_j)*(map(ihelp)-map(ihelp+(imax+1)))
else ! j=0 -> map(i,j-1) = map(i,j+1) == map(i,1)
E_(n) = 2.0*Abstand_j*(map(ihelp)-map(ihelp+(imax+1)))
endif
enddo
Erad = E_(1) + Abstand_i_Betrag*(E_(2)-E_(1))
Erad = Erad / Dr ! Reskalierung entsprechend r-Gitterkonstanten
c Berechne E(2) und E(3) aus Erad:
E(2) = Erad * x(2) / radius
E(3) = Erad * x(3) / radius
cd write(18,*)'x,E = ',x,E
END
c===============================================================================

View File

@ -0,0 +1,721 @@
c===============================================================================
OPTIONS /EXTEND_SOURCE
SUBROUTINE READ_INFO_M2
c =======================
IMPLICIT NONE
character*(*) Nr
parameter (Nr='M2')
INCLUDE 'mutrack$sourcedirectory:COM_LUNS.INC'
INCLUDE 'mutrack$sourcedirectory:COM_DIRS.INC'
INCLUDE 'mutrack$sourcedirectory:MAP_DEF_M2.INC'
c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
namelist /grid_info/
+ Dx,Dr, imax,jmax, xmax,rmax
namelist /geometry/
+ xMCPfront,diamMCP,thickMCP,xFlansch,rTube
real xMCPfront,diamMCP,thickMCP,xFlansch,rTube
c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
logical map_error
COMMON /map_error/ map_error
c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
c Einlesen der Mappen-Informationen:
open (lunREAD,file=mappenName//'.INFO',defaultfile=mappenDir,
+ readonly,status='old')
read (lunREAD,nml=grid_info)
rewind(lunREAD)
read (lunREAD,nml=geometry)
close (lunREAD)
radius_MCP2 = diamMCP / 2.
c Pruefen, ob die eingelesene Mappe den Anforderungen genuegt:
if (xMCPfront.NE.xmax) then
write(*,*)' M2-Mappe: Mappenende stimmt nicht mit MCP2-Vorderseite ueberein'
write(*,*)' -> STOP'
STOP
endif
c eingelesene imax und jmax um 1 reduzieren, da in 'MUTRACK' die Feldindizes
c ab 0 laufen, bei 'RELAX3D' jedoch ab 1:
imax = imax-1
jmax = jmax-1
c die geometrischen Daten fuer Mutrack zusammenstellen:
xEnterMap = xMCP2-xmax
c Uebergabebereich am MappenEnde definieren:
xStartUeber = xMCP2 - 0.5*Dx
xEndUeber = xMCP2 + 0.5*Dx
c checken, ob der reservierte Speicherplatz ausreicht:
if ((imax+1)*(jmax+1).NE.maxmem+1) then
write(*,*)'----------------------------------------'//
+ '----------------------------------------'
write(*,*) Nr//'-Mappe: ',mappenName
write(*,*) ' BENOETIGTER Speicher: (imax+1)*(jmax+1) = ',(imax+1)*(jmax+1)
write(*,*) ' RESERVIERTER Speicher: maxmem + 1 = ',maxmem + 1
write(*,*)
if ((imax+1)*(jmax+1).GT.maxmem+1) then
write(*,*) '=> reservierter Speicherplatz ist ungenuegend.'
write(*,*)
write(*,*) '=> ''maxmem'' in mutrack$sourcedirectory:MAP_DEF_'//Nr//'.INC angleichen,'
write(*,*) ' dann Programm mit ''LINKMUV'' am DCL-Prompt neu kompilieren'
write(*,*) ' und linken.'
write(*,*)
write(*,*) ' Mindestwert fuer ''maxmem'' ist ',(imax+1)*(jmax+1)-1
write(*,*)
map_error = .true.
endif
endif
END
c===============================================================================
OPTIONS /EXTEND_SOURCE
SUBROUTINE READ_MAP_M2
c ======================
IMPLICIT NONE
character*(*) Nr
parameter (Nr='M2')
INCLUDE 'mutrack$sourcedirectory:MAP_DEF_M2.INC'
INCLUDE 'mutrack$sourcedirectory:READ_MAP.INC'
END
c===============================================================================
OPTIONS /EXTEND_SOURCE
SUBROUTINE INTEGRATIONSSTEP_RUNGE_KUTTA_M2(dt)
c ==============================================
IMPLICIT NONE
SAVE
character*(*) Nr
parameter (Nr='M2')
c Diese Subroutine berechnet zu einem vorgegebenen Zeitschritt dt den
c Integrationsschritt zweimal: einmal direkt mit dt und einmal ueber zwei
c aufeinanderfolgende Schritte mit dt/2. (die beiden dt/2-Schritte werden
c zuerst ausgefuehrt).
c
c Aus der Differenz der beiden Resultate wird eine Abschaetzung fuer den Fehler
c des dt-Schrittes gewonnen, die dazu verwendet wird zu entscheiden, ob der
c Integrationsschritt mit einem verkuerzten Zeitintervall wiederholt werden
c muss, oder ob das Zeitintervall fuer den folgenden ausgedehnt werden kann.
c
c Die beiden Einzelergebnisse aus dem dt- und den beiden dt/2-Schritten, die
c jeweils ueber Runge-Kutta-Rechnung vierter Ordnung erhalten werden, werden
c zum Schluss noch zusammengenommen, um ein Resultat mit Genauigkeit fuenfter
c Ordnung in dt zu erhalten.
c
c Der ganze Ablauf entspricht den Ausfuehrungen in Kapitel 15.2 der NUMERICAL
c RECIPIES: 'Adaptive Stepsize Control for Runge-Kutta' (vgl. Referenz im
c fileheader von 'MUTRACK.FOR')
INCLUDE 'mutrack$sourcedirectory:COM_MUTRACK.INC'
INCLUDE 'mutrack$sourcedirectory:MAP_DEF_M2.INC'
integer i ! Zaehlvariable
real dt,dt_half ! zeitl. Aenderung, halbe zeitl. Aenderung
real EFeld0(3), EFeld1(3) ! elektr. Felder
real x1(3),Dx1(3),Dx2(3) ! fuer Ortsintegration
real v1(3),Dv1(3),Dv2(3) ! fuer Geschw.Integration
real xDifferenz(3), vDifferenz(3)
real x_1 ! Hilfsvariable fuer testweises x(1)
real help,help1,help2
real maxErr_x,maxErr_v,maxErr ! fuer Fehlerbetrachtung
real errCon, safety ! fuer Schrittweitenkontrolle
real pShrink, pGrow ! fuer Schrittweitenkontrolle
PARAMETER (errCon = 6.e-4, safety = .9) ! vgl. Referenz
PARAMETER (pShrink = -.25, pGrow = -.2)
! errCon = (4./safety)**(1/pGrow)
logical flag_dtSmall ! wenn bei dt < dtsmall der Fehler
! immer noch zu gross ist.
logical found_lower ! obere und untere Grenze fuer dt um
logical found_upper ! Uebergabebereich zu treffen
real dtlower,dtupper
integer returnCode_EFeld
COMMON /returnCode_EFeld/ returnCode_EFeld
! 1: TESTORT HINTER DER MAPPE
! 2: TESTORT NEBEN DER MAPPE
! 3: TESTORT VOR DER MAPPE
c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
flag_dtSmall = .false. ! flag resetten
found_lower = .false.
found_upper = .false.
if (dt.LT.dtsmall) dt = dtsmall
c berechne EFeld am aktuellen Ort. Speichere in EFeld0, damit sie wiederverwendet
c werden kann, falls mit kuerzerem Zeitschritt wiederholt werden muss:
call EFeld_M2(x,EFeld0,*998)
c...............................................................................
10 continue ! hier gehts wieder von vorne los, falls Zeitschritt dt
! abgeaendert werden muss.
dt_half = dt / 2.
c mache ersten dt/2 - Schritt:
call SINGLESTEP_RUNGE_KUTTA_M2(dt_half,EFeld0,x,v, Dx1,Dv1 ,*999)
c berechne EFeld bei x1:
x1(1) = x(1) + Dx1(1)
x1(2) = x(2) + Dx1(2)
x1(3) = x(3) + Dx1(3)
v1(1) = v(1) + Dv1(1)
v1(2) = v(2) + Dv1(2)
v1(3) = v(3) + Dv1(3)
call EFeld_M2(x1,EFeld1,*999)
c mache zweiten dt/2 - Schritt:
call SINGLESTEP_RUNGE_KUTTA_M2(dt_half,EFeld1,x1,v1, Dx2,Dv2 ,*999)
c Summiere Ergebnisse der beiden dt/2 -Schritte und speichere in Dx1, Dv1:
Dx1(1) = Dx1(1) + Dx2(1)
Dx1(2) = Dx1(2) + Dx2(2)
Dx1(3) = Dx1(3) + Dx2(3)
Dv1(1) = Dv1(1) + Dv2(1)
Dv1(2) = Dv1(2) + Dv2(2)
Dv1(3) = Dv1(3) + Dv2(3)
c mache dt - Schritt:
call SINGLESTEP_RUNGE_KUTTA_M2(dt,EFeld0,x,v, Dx2,Dv2 ,*999)
c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
c Fehlerbetrachtung und Berechnung des endgueltigen Ergebnisses:
c Fehlerbetrachtung:
c der groesste (absolute bzw. relative) Fehler im Ort soll kleiner als eps_x
c sein, der groesste Fehler in der Geschwindigkeit kleiner als eps_v:
c -> Bestimme den jeweils groessten Fehler der drei Komponenten des Ortes und
c der Geschwindikeit (dh. die groesste Differenz der Aederungen):
maxErr_x = 0.
maxErr_v = 0.
do i = 1, 3
xDifferenz(i) = Dx1(i)-Dx2(i)
vDifferenz(i) = Dv1(i)-Dv2(i)
if (log_relativ) then
if (Dx1(i).NE.0.)
+ maxErr_x = Max( maxErr_x, Abs( xDifferenz(i)/Dx1(i) ) )
if (Dv1(i).NE.0.)
+ maxErr_v = Max( maxErr_v, Abs( vDifferenz(i)/Dv1(i) ) )
else
maxErr_x = Max( maxErr_x, Abs( xDifferenz(i) ) )
maxErr_v = Max( maxErr_v, Abs( vDifferenz(i) ) )
endif
enddo
c - Skaliere den jeweils groessten relativen Fehler auf das jeweilige Epsilon:
maxErr_x = maxErr_x / eps_x
maxErr_v = maxErr_v / eps_v
c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
c der groessere der beiden reskalierten Fehler bestimmt, ob der Integrations-
c schritt mit kleinerem Zeitintervall wiederholt werden muss, bzw. um welchen
c Faktor das Zeitintervall fuer den naechsten Schritt vergroessert werden kann:
c Liegt der Fehler ausserhalb des Toleranzbereiches und ist dt bereits jetzt
c kleiner als dtsmall, so mache keinen neuen Versuch sondern akzeptiere als Not-
c loesung den bestehenden Naeherungswert. Setze dt in diesem Fall als Default
c fuer den kommenden Integrationsschritt auf dtsmall. Setze aber auch das flag
c 'flag_dtsmall', damit gezaehlt werden kann, wie oft dieses Prozedur fuer ein
c bestimmtes Teilchen angewendet werden muss. Ist dies zu oft der Fall, so brich
c diese Trajektorienberechnung ganz ab (-> destiny = code_dtsmall).
c (2. Teil erfolgt weiter unten)
c
c Es kam vor, dass ohne Ueberschreitung der Fehlertoleranz ein 'dtupper'
c und ein 'dtlower' gefunden wurde, beim Ertasten des Uebergabebereiches
c die Fehlergrenze bei mittleren dt-Werten dann aber ueberschritten wurde,
c wodurch dt immer wieder verkuerzt wurde, ohne dass der Uebergabebereich
c erreicht werden konnte. Letztlich bildete das ganze eine unendliche Schleife.
c Daher werden jetzt jedesmal, wenn die Fehlergrenze ueberschritten wird
c 'found_upper' und 'found_lower' resettet.
maxErr = Max(maxErr_x,maxErr_v)
if (maxErr.GT.1.) then
found_upper = .false.
found_lower = .false.
if (dt.LT.dtsmall) then ! Fehler immer noch zu gross, obwohl
flag_dtsmall = .true. ! dtsmall schon unterschritten ist
else
!c Bestimme kuerzeren Zeitschritt fuer neuen Versuch (vgl. Referenz):
dt = safety * dt * (maxErr**pShrink)
goto 10
endif
endif
c Falls x(1) (== x_1) jetzt bereits jenseits des Uebergangsbereiches am Ende
c der Potentialmappe liegen sollte, behalte dieses Faktum im Gedaechtnis
c und verkuerze den aktuell verwendeten Zeitschritt so lange um Faktor 0.5, bis
c x(1) innerhalb oder vor dem Uebergabebereich liegt. Liegt es davor, suche
c einen mittleren Zeitschritt, bei dem es im Uebergangsbereich liegt. Schliesse
c dann die Integration in dieser Mappe ab.
c (Der Uebergabebereich geht von einer halben x-Gitterkonstanten vor xmax bis
c eine halbe x-Gitterkonstante hinter xmax. In diesem Bereich wird ein konstantes
c EFeld zurueckgegeben):
x_1 = x(1) + Dx1(1) + xDifferenz(1) / 15.
if (x_1.GT.xStartUeber) then
if (x_1.LT.xEndUeber) then
reachedEndOfMap = .true.
else
dtupper = dt
found_upper = .true.
if (.NOT.found_lower) then
dt = min(0.5*dt,(xStartUeber-x(1))/(x_1-x(1))*dt)
else
dt = (dtlower+dtupper)/2.
endif
goto 10 ! neue Berechnung
endif
elseif (found_upper) then
found_lower = .true.
dtlower = dt
dt = (dtlower+dtupper)/2.
goto 10 ! neue Berechnung
endif
c Nimm die Ergebnisse aus dem dt-Schritt und den beiden dt/2-Schritten und
c berechne damit den neuen Ort und die neue Geschwindigkeit mit Genauigkeit
c fuenfter Ordnung in dt:
x(1) = x_1
x(2) = x(2) + Dx1(2) + xDifferenz(2) / 15.
x(3) = x(3) + Dx1(3) + xDifferenz(3) / 15.
v(1) = v(1) + Dv1(1) + vDifferenz(1) / 15.
v(2) = v(2) + Dv1(2) + vDifferenz(2) / 15.
v(3) = v(3) + Dv1(3) + vDifferenz(3) / 15.
c alten Zeitschritt addieren:
t = t + dt
c falls Uebergabebereich erreicht wurde, berechne naeherungsweisen Schnittpunkt der
c Trajektorie mit x=xmax (exaktes Mappenende) unter Verwendung der im Uebergabebereich
c zurueckgegebenen Beschleunigung:
if (reachedEndOfMap) then
call EFeld_M2(x,EFeld0,*999)
help = v(1)*v(1) - 2.*EFeld0(1)*Beschl_Faktor*(x(1)-xMCP2)
if (help.LT.0.) then ! Teilchen wird noch vor MCP2 reflektiert werden
reachedEndOfMap = .false.
goto 3454
else
if (EFeld0(1)*Beschl_Faktor.NE.0) then
help = (sqrt(help) - v(1))/(EFeld0(1)*Beschl_Faktor) ! dt -> help
else
help = (xMCP2-x(1))/v(1)
endif
endif
t = t + help ! auch diesen Zeitschritt addieren
d dt = dt + help ! nur fuer dtmin_M2,dtmax_M2
help1 = Beschl_Faktor *help
help2 = help1*help/2.
x(1) = x(1) + v(1)*help + EFeld0(1)*help2 ! == xMCP2, wenn richtig
x(2) = x(2) + v(2)*help + EFeld0(2)*help2
x(3) = x(3) + v(3)*help + EFeld0(3)*help2
v(1) = v(1) + EFeld0(1)*help1
v(2) = v(2) + EFeld0(2)*help1
v(3) = v(3) + EFeld0(3)*help1
RETURN
endif
c neuen Zeitschritt so gross wie sinnvoller weise moeglich machen:
3454 if (flag_dtSmall) then
if (n_dtsmall.LT.maxBelowDtSmall) then
dt = dtSmall ! fuer naechsten RK-Schritt
n_dtsmall = n_dtsmall + 1
else
destiny = code_dtsmall ! gib Teilchen verloren
RETURN
endif
else
if (maxErr.GT.errCon) then
dt = safety * dt * (maxErr**pGrow) ! vgl. Referenz
else
dt = 4. * dt ! <- Vergroesserung des Zeitschritts max. um
endif ! Faktor 4!
! pruefen, ob Maximallaenge fuer ersten Testschritt nicht ueberschritten ist:
d if (log_confine) dt = min(dt,dl_max/sqrt(v(1)*v(1)+v(2)*v(2)+v(3)*v(3)))
endif
RETURN
c hier folgt der Code fuer 'returnCode_EFeld.NE.0':
998 continue
if (returnCode_EFeld.EQ.1) then
write(*,*) Nr//'-Mappe:'
write(*,*)' aktueller Teilchenort (nicht Testort!) hinter Potentialmappe!'
write(*,*)' -> STOP'
write(*,*)
STOP
! alternativ koennte man hier vielleicht auch nach x=xmax zurueckrechnen
endif
999 continue
if (returnCode_EFeld.EQ.1) then ! Testort hinter der Mappe
dt = 0.5*dt
found_lower = .false.
found_upper = .false.
goto 10
elseif (returnCode_EFeld.EQ.2) then ! Testort neben der Mappe
destiny = code_wand
elseif (returnCode_EFeld.EQ.3) then ! Testort vor der Mappe
if (v(1).LE.0) then ! reflektiert -> kann vorkommen
destiny = code_reflektiert
else ! in Vorwaertsbewegung -> darf nicht vorkommen!!
write(*,*)
write(*,*) Nr//'-Mappe: ',mappenName
write(*,*)
write(*,*)' Test-x liegt vor der Mappe!'
write(*,*)' x,y,z = ',x
write(*,*)' Teilchen-Nr = ',Start_Nr(1)
write(*,*)' xEnterMap_M2 = ',xEnterMap
write(*,*)' xEnterMap_M2 - x(1) = ',xEnterMap - x(1)
write(*,*)
write(*,*)' -> STOP'
write(*,*)
STOP
endif
elseif (returnCode_EFeld.NE.0) then
write(*,*)
write(*,*) 'SINGLESTEP_RUNGE_KUTTA_'//Nr//': '
write(*,*) 'unallowed value of ''returnCode_EFeld'': ',returnCode_Efeld
write(*,*) '-> STOP'
write(*,*)
STOP
endif
END
c===============================================================================
OPTIONS /EXTEND_SOURCE
SUBROUTINE SINGLESTEP_RUNGE_KUTTA_M2(dt,E0,x0,v0, Dx,Dv, *)
c ===========================================================
IMPLICIT NONE
c Diese Subroutine berechnet bei vorgegebenem Zeitschritt einen einzelnen
c Runge-Kutta-Integrationsschritt (4. Ordnung).
c Die Vorgehensweise entspricht den Ausfuehrungen in Kapitel 15.1 der
c NUMERICAL RECIPIES: 'Runge-Kutta Method'.
c Zurueckgegeben werden die errechneten Orts- und Geschwindigkeitsaenderungen
c anstatt direkt der neuen Werte, da sonst vor allem bei den Ortskoordinaten
c Schwierigkeiten auftreten koennen, wenn in der Subroutine 'INTEGRATIONSSTEP_
c RUNGE_KUTTA' aus der Differenz der neuen Werte aus den beiden dt/2- und dem
c dt-Schritt der Fehler abgeschaetzt werden soll (kleine Differenz moeglicher-
c weise grosser Werte).
real Beschl_Faktor
COMMON /Beschl_Faktor_M2/ Beschl_Faktor
real E0(3), x0(3), v0(3) ! Eingangsgroessen
real E1(3), E2(3), E3(3) ! E-Felder an Testorten
real v1(3), v2(3), v3(3) ! Geschwindigkeiten an Testorten
real dt,dt_half,dt_sixth ! zeitl. Aenderung, dt/2, dt/6
real help, help_half, help_sixth ! Hilfsvariable, help/2, help/6
real xTest(3) ! Test-Orte
real Dx(3), Dv(3) ! Ergebnisspeicher
integer i ! Zaehlvariable
c = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
dt_half = dt / 2.
dt_sixth = dt / 6.
help = Beschl_Faktor * dt
help_half = help / 2.
help_sixth = help / 6.
do i = 1, 3
xTest(i) = x0(i) + v0(i) * dt_half
v1(i) = v0(i) + E0(i) * help_half
enddo
call EFeld_M2(xTest,E1,*999)
do i = 1, 3
xTest(i) = x0(i) + v1(i) * dt_half
v2(i) = v0(i) + E1(i) * help_half
enddo
call EFeld_M2(xTest,E2,*999)
do i = 1, 3
xTest(i) = x0(i) + v2(i) * dt
v3(i) = v0(i) + E2(i) * help
enddo
call EFeld_M2(xTest,E3,*999)
do i = 1, 3
Dx(i) = (v0(i) + 2.*(v1(i)+v2(i)) + v3(i)) * dt_sixth
Dv(i) = (E0(i) + 2.*(E1(i)+E2(i)) + E3(i)) * help_sixth
enddo
RETURN
999 RETURN 1
END
c===============================================================================
OPTIONS /EXTEND_SOURCE
SUBROUTINE EFeld_M2(x,E,*)
c ==========================
IMPLICIT NONE
INCLUDE 'mutrack$sourcedirectory:MAP_DEF_M2.INC'
real real_i,real_j ! x,r im Mappensystem in Gittereinheiten
integer stuetzstelle_i(2) ! naechste Stuetzstellen in x- und
integer stuetzstelle_j(2) ! r-Richtung
real Abstand_i,Abstand_i_Betrag ! Entfernung zur naechsten Stuetzstelle
real Abstand_j,Abstand_j_Betrag ! (in Gittereinheiten!)
integer i,j, n, ihelp
real radius ! Betrag des Radiusvektors in y-z-Ebene
real x(3),E(3) ! Ort und Feldstaerke
real E_(2) ! Hilfsspeicher fuer Feldberechnung
real Erad ! radiale Feldstaerke
c Falls Testort ausserhalb der Mappe liegt oder Anode getroffen hat:
integer returnCode_EFeld
COMMON /returnCode_EFeld/ returnCode_EFeld
! 1: TESTORT HINTER DER MAPPE
! 2: TESTORT NEBEN DER MAPPE
! 3: TESTORT VOR DER MAPPE
c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
c Rechne in Gittereinheiten um:
radius = sqrt(x(2)*x(2)+x(3)*x(3))
real_i = (x(1) - xEnterMap) / Dx
real_j = radius / Dr
c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
c Mache die Tests und berechne die Feldstaerke:
c Teste, ob Raumpunkt innerhalb der Potentialmappe liegt:
if (real_j.GT.jmax) then
returnCode_EFeld = 2
RETURN 1
elseif (real_i.GT.real(imax)) then
if (real_i.GT.real(imax)+.5) then
returnCode_EFeld = 1
RETURN 1
else
real_i = imax
endif
elseif (real_i.LT.0.) then
returnCode_EFeld = 3
E(1) = 0.
E(2) = 0.
E(3) = 0.
RETURN 1
c else
c returnCode_EFeld = 0
endif
c Bestimme naechstgelegene Stuetzstellen und die Komponenten des Abstands-
c Gittervektors zur allernaechsten Stuetzstelle sowie deren Betraege:
stuetzstelle_i(1) = nint(real_i)
Abstand_i = real_i - stuetzstelle_i(1) ! Abstand zur naeheren Stuetzstelle
Abstand_i_Betrag = abs(Abstand_i)
if (Abstand_i.gt.0.) then
stuetzstelle_i(2) = stuetzstelle_i(1) + 1
elseif (Abstand_i.lt.0.) then
stuetzstelle_i(2) = stuetzstelle_i(1) - 1
else
stuetzstelle_i(2) = stuetzstelle_i(1)
endif
stuetzstelle_j(1) = nint(real_j)
Abstand_j = real_j - stuetzstelle_j(1)
Abstand_j_Betrag = abs(Abstand_j)
if (Abstand_j.gt.0.) then
stuetzstelle_j(2) = stuetzstelle_j(1) + 1
elseif (Abstand_j.lt.0.) then
stuetzstelle_j(2) = stuetzstelle_j(1) - 1
else
stuetzstelle_j(2) = stuetzstelle_j(1)
endif
c...............................................................................
c Berechnen des elektrischen Feldes:
c ----------------------------------
c
c Potentialverlauf ist symmetrisch zu j=0 (Linsenachse):
c
c map(i,-j) == map(i,j).
c
c Entlang j=0 ist also Erad=0 und damit E(2)=0 und E(3)=0.
c...............................................................................
c Berechne die x-Komponente der Feldstaerke:
c Um die Feldstaerke zu bekommen, interpoliere jeweils linear zwischen den
c Werten auf den beiden naechstgelegenen j-Ketten:
i = stuetzstelle_i(1)
do n = 1, 2
j = stuetzstelle_j(n)
ihelp = j*(imax+1) + i
if (i.EQ.imax) then
E_(n) = map(ihelp-1) - map(ihelp)
elseif (i.GT.0) then
E_(n) = (-0.5+Abstand_i)*(map(ihelp)-map(ihelp-1))
+ + ( 0.5+Abstand_i)*(map(ihelp)-map(ihelp+1))
else
E_(n) = map(ihelp) - map(ihelp+1)
endif
enddo
E(1) = E_(1) + Abstand_j_Betrag*(E_(2)-E_(1))
E(1) = E(1) / Dx ! Reskalierung entsprechend x-Gitterkonstanten
c Berechne die radiale Komponente der Feldstaerke:
if (real_j.LT.1e-10) then
E(2) = 0.
E(3) = 0.
RETURN
endif
j = stuetzstelle_j(1)
do n = 1, 2
i = stuetzstelle_i(n)
ihelp = j*(imax+1) + i
if (j.EQ.jmax) then
E_(n) = map(ihelp-(imax+1)) - map(ihelp)
elseif (j.GT.0) then
E_(n) = (-0.5+Abstand_j)*(map(ihelp)-map(ihelp-(imax+1)))
+ + ( 0.5+Abstand_j)*(map(ihelp)-map(ihelp+(imax+1)))
else ! j=0 -> map(i,j-1) = map(i,j+1) == map(i,1)
E_(n) = 2.0*Abstand_j*(map(ihelp)-map(ihelp+(imax+1)))
endif
enddo
Erad = E_(1) + Abstand_i_Betrag*(E_(2)-E_(1))
Erad = Erad / Dr ! Reskalierung entsprechend r-Gitterkonstanten
c Berechne E(2) und E(3) aus Erad:
E(2) = Erad * x(2) / radius
E(3) = Erad * x(3) / radius
END
c===============================================================================

File diff suppressed because it is too large Load Diff

2874
mutrack/src/SUB_OUTPUT.FOR Normal file

File diff suppressed because it is too large Load Diff

1842
mutrack/src/SUB_PICTURE.FOR Normal file

File diff suppressed because it is too large Load Diff

928
mutrack/src/SUB_TRIGGER.FOR Normal file
View File

@ -0,0 +1,928 @@
c******************************************************************************
c* ... SUB_TRIGGER.FOR *
c* *
c* Die Routinen dieser Datei dienen der Berechnung und der Ausgabe *
c* von Flugbahnen geladener Teilchen innerhalb des NEMU - Triggerdetektors. *
c* *
c* Die Daten fuer die DetektorGEOmetrie (dx1 bis dx11, bzw. dy1 bis dy15) *
c* werden beim Compilieren aus 'GEO_TRIGGER.INC' eingelesen. *
c* *
c* F -> FOLIE *
c* V -> Gitter VORNE *
c* H -> Gitter HINTEN *
c* G -> Gitter GROUND (geerdetes Gitter nach HINTEN) *
c* 3 -> MCP3 (front) *
c* *
c******************************************************************************
OPTIONS /EXTEND_SOURCE
SUBROUTINE READ_TRIGGER_GEO
c ===========================
implicit none
INCLUDE 'mutrack$sourcedirectory:GEO_TRIGGER.INC'
INCLUDE 'mutrack$sourcedirectory:COM_LUNS.INC'
integer iostat
c namelist:
namelist /trigger_grids/
+ dist_Wires_V1,dist_Wires_V2,dist_Wires_V3,
+ dist_Wires_H1,dist_Wires_H2,dist_Wires_G,
+ dWires_V1,dWires_V2,dWires_V3,dWires_H1,dWires_H2,dWires_G
read(lunREAD,nml=trigger_grids,iostat=iostat) ! wurde in SUB_INPUT geoeffnet
! iostat notwendig, da bei aelteren Files keine namelist 'trigger_grids'
! vorhanden ist. Dort: Defaultwerte.
WireRadiusQuad_V1 = dwires_V1*dWires_V1/4.
WireRadiusQuad_V2 = dwires_V2*dWires_V2/4.
WireRadiusQuad_V3 = dwires_V3*dWires_V3/4.
WireRadiusQuad_H1 = dwires_H1*dWires_H1/4.
WireRadiusQuad_H2 = dwires_H2*dWires_H2/4.
WireRadiusQuad_G = dwires_G *dWires_G /4.
END
c===============================================================================
OPTIONS /EXTEND_SOURCE
SUBROUTINE TRIGGER(m_,q_,t_,x_,v_,DEBUG_,GRAPHICS_,n_return_)
c =============================================================
c Deklarationen:
implicit none
real m_,q_,t_,x_(3),v_(3) ! die Aufruf-Parameter
real E, vSquare ! EnergieFkt und Geschw.Quadrat
real dt,delta_x,delta_y,delta_xs,delta_xp,v_s,v_p,a
real sqrt_2,c
real barriere_FV,barriere_VH,barriere_HG,barriere_V3
integer n_return_
integer vorne_hinten !
integer vorne_hinten_refl ! die Label
integer vorne_mcp3 ! fuer GOTO-Anweisungen
integer vorne_mcp3_refl !
logical log_p4 ! notiert, ob Pfosten P4 getroffen wird.
logical DEBUG_,GRAPHICS_
c Die Trigger-Geometrie
INCLUDE 'mutrack$sourcedirectory:GEO_TRIGGER.INC'
c Variablen fuer Test ob Draht getroffen wurde:
integer DrahtNr
real help,DistToWire(2)
logical WireHit
logical TestOnWireHit
COMMON /TestOnWireHit/ TestOnWireHit
integer seed
COMMON /seed/ seed
c Konstanten-Definitionen:
parameter (sqrt_2=1.414213562, c=299.7925) ! c in [mm/ns]
c Common-Bloecke:
INCLUDE 'mutrack$sourcedirectory:COM_TD_INT.INC'
INCLUDE 'mutrack$sourcedirectory:COM_TD_EXT.INC'
c Funktionen-Deklarationen:
E(vSquare) = m/2.*vSquare/c**2. ! E in [keV]; vSquare==v**2.
c hier werden die Labels getauft:
assign 100 to vorne_hinten
assign 200 to vorne_hinten_refl
assign 300 to vorne_mcp3
assign 400 to vorne_mcp3_refl
c Uebertragen der Aufruf-Parameter auf die lokalen Variablen:
m = m_
q = q_
t = t_
x = 0.
y = x_(2)
z = x_(3)
v_x = v_(1)
v_y = v_(2)
v_z = v_(3)
DEBUG = DEBUG_
GRAPHICS = GRAPHICS_
n_return = 0 ! n_return > 100 <-> Fehlermeldungen
c sonstige Start-Werte:
E0 = E(v_x**2+v_y**2.+v_z**2.)
barriere_FV = q * (U_V - U_F)
barriere_VH = q * (U_H - U_V)
barriere_HG = q * (0. - U_H)
barriere_V3 = q * (U_MCP3 - U_V)
log_refl_VH = .false. ! das Teilchen ist noch
log_refl_V3 = .false. ! nirgends reflektiert worden
log_p4 = .false. ! und hat Pfosten 4 nicht beruehrt
c...............................................................................
c hier startet das Teilchen:
c --------------------------
dt = 0
call TestAndOut('F ',*800)
if (v_x.LT.0.) then ! Start in neg. x-Richtung
n_return = 103
if (DEBUG) call outText(n_return)
GOTO 800
endif
C zwischen 'FOLIE' und 'VORNE': -----------------------------
if (E(v_x**2.).LT.barriere_FV) then ! Potentialbarriere F-V zu gross
n_return = 104
if (DEBUG) call outText(n_return)
GOTO 800
endif
if (barriere_FV.EQ.0.) then ! keine Spannung zwischen F und V
if (v_x.EQ.0.) then ! U=0 und v_x=0 =>
n_return = 105 ! Teilchen bleibt stehen
if (DEBUG) call outText(n_return)
GOTO 800
endif
dt = dx1/v_x ! v_x > 0
else
a = -barriere_FV/(m*dx1) * c**2. ! <- a = F/m = q/m*(U_F-U_V)/dx1
! = -barriere_FV/(m*dx1)
dt = (sqrt(v_x**2.+2.*a*dx1)-v_x)/a ! <- ergibt sich aus x=v*t+1/2*a*t**2
! mit richtiger V.Z.-Wahl ('+')
v_x = v_x + a*dt
endif
x = dx1
y = y + v_y*dt
z = z + v_z*dt
t = t + dt
c haben wir vielleicht einen Pfosten getroffen? Wenn nein, gib die Trajektorien-Daten aus
if (y.GT.dy3) then ! (Bahn FV1)
call pfosten(1,*800)
elseif (y.GT.dy5) then ! (Bahn FV2)
call pfosten(3,*800)
elseif (y.LT.-dy4) then ! (Bahn FV5)
call pfosten(2,*800)
elseif (y.LT.-dy6) then ! (Bahn FV4)
call pfosten(4,*800)
else ! (Bahn FV3)
call TestAndOut('V1 ',*800)
! Treffen wir einen Gitterstab von V1?
if (testOnWireHit) then
DrahtNr = nInt(y/dist_Wires_V1)
distToWire(1) = 0.
distToWire(2) = y - DrahtNr*dist_Wires_V1
call Test_WireHit(distToWire,WireRadiusQuad_V1,v_x,v_y,WireHit)
if (WireHit) then
n_return = -5
goto 800
endif
endif
endif
c innerhalb von 'VORNE':
c ----------------------
if (y+dy6.LT.-dx7*v_y/v_x) log_p4=.true.! Teilchen trifft auf Pfosten 4
if (v_y.LE.-v_x) goto 20 ! Flugbahn ist parallel zu Ebene V2
! bzw. Schnitt bei dt < 0
c Schnittpunkt der Bahn (y'=y+delta_x*v_y/v_x) mit Ebene V2 (y'=dx2-delta_x):
if (v_x.EQ.0.) then
if (v_y.LT.0.) then
dt = (-dy4-y)/v_y
x = dx1
y = -dy4
z = z + v_z*dt
t = t + dt
call pfosten(2,*800)
endif
delta_x = 0
else
delta_x = (dx2-y)/(1+v_y/v_x)
endif
if (delta_x.GT.dx2+dy8) goto 20 ! Bahn schneidet erst Ebene V3
if (v_x.NE.0.) then
dt = delta_x/v_x
else
dt = (dx2-delta_x-y)/v_y
endif
x = x + delta_x
y = dx2 - delta_x
z = z + v_z*dt
t = t + dt
if (log_p4) call pfosten(4,*800) ! (Bahn VV8)
if (y.GT.dy5) then ! (Bahn VV1)
call pfosten(3,*800)
elseif (y.GE.-dy11) then ! (Bahn VV2)
call TestAndOut('V2 ',*800)
! Treffen wir einen Gitterstab von V2?
if (testOnWireHit) then
DrahtNr = nInt(y/(.5*sqrt_2*dist_Wires_V2))
distToWire(2) = y - DrahtNr*.5*sqrt_2*dist_Wires_V2
distToWire(1) = -distToWire(2)
call Test_WireHit(distToWire,WireRadiusQuad_V2,v_x,v_y,WireHit)
if (WireHit) then
n_return = -5
goto 800
endif
endif
goto vorne_hinten
else
call pfosten(5,*800) ! (Bahn VV3)
endif
c Schnittpunkt der Bahn (y'=y+delta_x*v_y/v_x) mit Ebene V3 (y'=-dy8):
20 delta_y = -dy8-y
dt = delta_y/v_y
x = x + v_x*dt
y = -dy8
z = z + v_z*dt
t = t + dt
if (log_p4) call pfosten(4,*800) ! (Bahn VV8)
if (x.GT.dx1+dx2+dy11) then ! (Bahn VV3)
call pfosten(5,*800)
elseif (x.GT.dx1+dx2+dy8-dx10) then ! (Bahn VV4)
call pfosten(13,*800)
elseif (x.GE.dx1+dx8) then ! (Bahn VV5)
call TestAndOut('V3 ',*800)
! Treffen wir einen Gitterstab von V3?
if (testOnWireHit) then
help = x-dx1-dx8
DrahtNr = nInt(help/dist_Wires_V3)
distToWire(1) = help - DrahtNr*dist_Wires_V3
distToWire(2) = 0.
call Test_WireHit(distToWire,WireRadiusQuad_V3,v_x,v_y,WireHit)
if (WireHit) then
n_return = -5
goto 800
endif
endif
goto vorne_mcp3
else ! (Bahn VV6)
call pfosten(12,*800)
endif
c zwischen 'VORNE' und 'HINTEN': vorne_hinten
c -------------------------------------------
100 v_s = (v_x + v_y)/sqrt_2 ! v_s: v senkrecht zur Spiegelebene
v_p = (v_x - v_y)/sqrt_2 ! v_p: v parallel zur Spiegelebene
if (barriere_VH.EQ.0.) then ! keine Spannung zwischen V und H
dt = dx3/sqrt_2 / v_s ! v_s > 0, sonst waere V3 gar nicht
x = x + v_x*dt ! erreicht worden
y = y + v_y*dt
else
a = -barriere_VH * sqrt_2/(m*dx3) * c**2.
if (E(v_s**2.).LT.barriere_VH) goto vorne_hinten_refl
dt = (sqrt(v_s**2.+sqrt_2*a*dx3)-v_s)/a ! aus x=v*t+a/2*t**2
delta_xs = dx3/sqrt_2 ! = Versetzung senkrecht zur Spiegelebene
delta_xp = v_p*dt ! = Versetzung parallel zur Spiegelebene
v_s = v_s + a*dt
x = x + (delta_xs + delta_xp)/sqrt_2
y = y + (delta_xs - delta_xp)/sqrt_2
v_x = (v_s + v_p)/sqrt_2
v_y = (v_s - v_p)/sqrt_2
endif
z = z + v_z*dt
t = t + dt
if (y.GT.dy7) then ! (Bahn VH1)
call pfosten(6,*800)
elseif (y.GE.-dy13) then ! (Bahn VH2)
call TestAndOut('H1 ',*800)
! Treffen wir einen Gitterstab von H1?
if (testOnWireHit) then
DrahtNr = nInt(y/(.5*sqrt_2*dist_Wires_H1))
distToWire(2) = y - DrahtNr*.5*sqrt_2*dist_Wires_H1
distToWire(1) = -distToWire(2)
call Test_WireHit(distToWire,WireRadiusQuad_H1,v_x,v_y,WireHit)
if (WireHit) then
n_return = -5
goto 800
endif
endif
else ! (Bahn VH3)
call pfosten(9,*800)
endif
c innerhalb von 'HINTEN':
c -----------------------
if (v_y.LE.0.) goto 30 ! Flugbahn parallel zu (y'=dy9)
! bzw. Schnitt bei dt < 0
c Schnittpunkt mit (y'=dy9):
delta_x = (dy9-y)*v_x/v_y ! v_y <> 0.
if (x+delta_x.GT.d_Folie_Hinten2) goto 30
dt = (dy9-y)/v_y
x = x + delta_x
y = dy9
z = z + v_z*dt
t = t + dt
if (x.LT.d_Folie_Hinten2-dx4-dy7) then ! (Bahn HH1)
call pfosten(6,*800)
elseif (x.LT.d_Folie_Hinten2 -dx6) then ! (Bahn HH2)
call pfosten(7,*800)
else ! (Bahn HH3)
call pfosten(8,*800)
endif
c Schnittpunkt mit Ebene H2 (x'=d_Folie_Hinten2):
30 delta_x = d_Folie_Hinten2 - x
dt = delta_x/v_x ! v_x > 0.
x = d_Folie_Hinten2
y = y + v_y*dt
z = z + v_z*dt
t = t + dt
if (y.GT.dy12) then ! (Bahn HH3)
call pfosten(8,*800)
elseif (y.GT.dy14) then ! (Bahn HH4)
call pfosten(10,*800)
elseif (y.LT.-dy13) then ! (Bahn HH7)
call pfosten(9,*800)
elseif (y.LT.-dy15) then ! (Bahn HH6)
call pfosten(11,*800)
else ! (Bahn HH5)
call TestAndOut('H2 ',*800)
! Treffen wir einen Gitterstab von H2?
if (testOnWireHit) then
DrahtNr = nInt(y/dist_Wires_H2)
distToWire(1) = 0.
distToWire(2) = y - DrahtNr*dist_Wires_H2
call Test_WireHit(distToWire,WireRadiusQuad_H2,v_x,v_y,WireHit)
if (WireHit) then
n_return = -5
goto 800
endif
endif
endif
c zwischen 'HINTEN' und 'GROUND':
c -------------------------------
if (E(v_x**2.).LT.barriere_HG) then ! Potentialbarriere H-G zu gross
n_return = 106
if (DEBUG) call outText(n_return)
GOTO 800
endif
if (barriere_HG.EQ.0.) then ! keine Spannung zwischen H und G
dt = dx5/v_x ! v_x > 0.
else
a = -barriere_HG/(m*dx5) * c**2.
dt = (sqrt(v_x**2.+2.*a*dx5)-v_x)/a
v_x = v_x + a*dt
endif
x = d_Folie_Hinten2 + dx5
y = y + v_y*dt
z = z + v_z*dt
t = t + dt
if (y.GT.dy14) then ! (Bahn HG1)
call pfosten(10,*800)
elseif (y.GE.-dy15) then ! (Bahn HG2)
if (z.GT.dz1) then
call pfosten(12,*800)
elseif (z.LT.-dz2) then
call pfosten(13,*800)
else
call TestAndOut('G ',*800)
! Treffen wir einen Gitterstab von G?
if (testOnWireHit) then
DrahtNr = nInt(y/dist_Wires_G)
distToWire(1) = 0.
distToWire(2) = y - DrahtNr*dist_Wires_G
call Test_WireHit(distToWire,WireRadiusQuad_G,v_x,v_y,WireHit)
if (WireHit) then
n_return = -5
goto 800
endif
endif
n_return = 0 ! Teilchen verlaesst TD durch G
endif
GOTO 800
else ! (Bahn HG3)
call pfosten(11,*800)
endif
c REFLEKTION zwischen 'VORNE' und 'HINTEN': vorne_hinten_refl
c -----------------------------------------------------------
200 if (log_refl_V3) then ! schon an MCP3, jetzt an
n_return = 107 ! HINTEN reflektiert
if (DEBUG) call outText(n_return)
GOTO 800
endif
log_refl_VH = .true. ! die Reflektion notieren
dt = -2.*v_s/a ! folgt aus v'=-v und v'=v+a*t
x = x + v_p * dt / sqrt_2 ! senkrecht zur Spiegelflaeche
y = y - v_p * dt / sqrt_2 ! findet keine Versetzung statt
z = z + v_z*dt
t = t + dt
v_x = (-v_s + v_p)/sqrt_2 ! v_s geht bei der Spiegelung
v_y = (-v_s - v_p)/sqrt_2 ! in -(v_s) ueber
if (y.GT.dy5) then ! (Bahn VHr1)
call pfosten(3,*800)
elseif (y.GE.-dy11) then ! (Bahn VHr2)
call TestAndOut('V2 ',*800)
! Treffen wir einen Gitterstab von V2?
if (testOnWireHit) then
DrahtNr = nInt(y/(.5*sqrt_2*dist_Wires_V2))
distToWire(2) = y - DrahtNr*.5*sqrt_2*dist_Wires_V2
distToWire(1) = -distToWire(2)
call Test_WireHit(distToWire,WireRadiusQuad_V2,v_x,v_y,WireHit)
if (WireHit) then
n_return = -5
goto 800
endif
endif
else ! (Bahn VHr3)
call pfosten(5,*800)
endif
c innerhalb von 'VORNE' (nach Reflektion an 'HINTEN'):
c ----------------------------------------------------
if (v_x.GE.0.) goto 40 ! Flugbahn parallel zu V1
! bzw. Schnitt bei dt < 0
c Schnittpunkt mit V1-Ebene (x'=dx1):
delta_y = (dx1-x)*v_y/v_x
if (y+delta_y.LT.-dy8) goto 40
dt = (dx1-x)/v_x
x = dx1
y = y + delta_y
z = z + v_z*dt
t = t + dt
if (y.GT.dy5) then ! (Bahn VVr1)
call pfosten(3,*800)
elseif (y.GT.dy3) then ! (Bahn VVr2)
call pfosten(1,*800)
elseif (y.LT.-dy6) then ! (Bahn VVr5)
call pfosten(4,*800)
elseif (y.LT.-dy4) then ! (Bahn VVr4)
call pfosten(2,*800)
else ! (Bahn VVr3)
n_return = 108 ! Teilchen zurueck auf V1
if (DEBUG) call outText(n_return)
RETURN
endif
c Schnittpunkt mit V3-Ebene (y'=-dy8):
40 delta_y = -dy8-y
dt = delta_y/v_y ! v_y < 0.
x = x + v_x*dt
y = -dy8
z = z + v_z*dt
t = t + dt
if (x.LT.dx1+dx7) then ! (Bahn VVr5)
call pfosten(4,*800)
elseif (x.LT.dx1+dx8) then ! (Bahn VVr4)
call pfosten(14,*800)
elseif (x.GT.dx1+dx2+dy11) then ! (Bahn VVr9)
call pfosten(5,*800)
elseif (x.GT.dx1+dx2+dy8-dx10) then ! (Bahn VVr8)
call pfosten(15,*800)
else ! (Bahn VVr7)
call TestAndOut('V3 ',*800)
! Treffen wir einen Gitterstab von V3?
if (testOnWireHit) then
help = x-dx1-dx8
DrahtNr = nInt(help/dist_Wires_V3)
distToWire(1) = help - DrahtNr*dist_Wires_V3
distToWire(2) = 0.
call Test_WireHit(distToWire,WireRadiusQuad_V3,v_x,v_y,WireHit)
if (WireHit) then
n_return = -5
goto 800
endif
endif
endif
c zwischen 'VORNE' und 'MCP3': vorne_mcp3
c ----------------------------------------
300 a = +barriere_V3/(m*dy10) * c**2.
if (E(v_y**2.).LT.barriere_V3) goto vorne_mcp3_refl
if (a.EQ.0.) then
dt = -dy10/v_y ! v_y < 0.
else
dt = (-sqrt(v_y**2.-2.*a*dy10)-v_y)/a ! aus dy=v*dt+a/2*dt**2 mit
v_y = v_y + a * dt ! richtiger V.Z.-Wahl ('-')
endif
x = x + v_x*dt
y = -dy8-dy10
z = z + v_z*dt
t = t + dt
if (x.LT.dx1+dx8) then ! (Bahn V31)
call pfosten(14,*800)
elseif (x.LT.dx1+dx9) then ! (Bahn V32)
call pfosten(16,*800)
elseif (x.GT.dx1+dx2+dy8-dx10) then ! (Bahn V35)
call pfosten(15,*800)
elseif (x.GT.dx1+dx2+dy8-dx11) then ! (Bahn V34)
call pfosten(17,*800)
else ! (Bahn V33)
if (((x - xCenter_MCP3)**2.+z**2).GT.radiusQuad_MCP3) then
if (z.GE.0 .AND. x.GE. xCenter_MCP3) then
call pfosten(19,*800)
elseif (z.GE.0 .AND. x.LT. xCenter_MCP3) then
call pfosten(18,*800)
elseif (z.LT.0 .AND. x.LT. xCenter_MCP3) then
call pfosten(20,*800)
else
call pfosten(21,*800)
endif
else
call TestAndOut('M3 ',*800)
if (testOnWireHit .AND. ran(seed).GT.efficiencyM3) then
n_return = -9 ! Teilchen NICHT in MCP3
else ! nachgewiesen
n_return = -10 ! Teilchen in MCP3
endif ! nachgewiesen
endif
GOTO 800
endif
c REFLEKTION zwischen 'VORNE' und 'MCP3': vorne_mcp3_refl
c --------------------------------------------------------
400 if (log_refl_VH) then ! schon an HINTEN, jetzt an
n_return = 109 ! MCP3 reflektiert
if (DEBUG) call outText(n_return)
GOTO 800
endif
log_refl_V3 = .true. ! die Reflektion notieren
if (v_x.LE.0.) then ! Reflektion an MCP3 mit
n_return = 110 ! negativem v_x
if (DEBUG) call outText(n_return)
GOTO 800
endif
dt = -2.*v_y/a
x = x + v_x*dt ! y'=y
z = z + v_z*dt
t = t + dt
if (x.GT.dx1+dx2+dy8-dx10) then ! (Bahn V3r1)
call pfosten(15,*800)
elseif (x.GT.dx1+dx2+dy11) then ! (Bahn V3r2)
call pfosten(5,*800)
else ! (Bahn V3r3)
v_y = -v_y ! v_x'=v_x
call TestAndOut('V3 ',*800)
! Treffen wir einen Gitterstab von V3?
if (testOnWireHit) then
help = x-dx1-dx8
DrahtNr = nInt(help/dist_Wires_V3)
distToWire(1) = help - DrahtNr*dist_Wires_V3
distToWire(2) = 0.
call Test_WireHit(distToWire,WireRadiusQuad_V3,v_x,v_y,WireHit)
if (WireHit) then
n_return = -5
goto 800
endif
endif
endif
c innerhalb von 'VORNE' (nach Reflektion an 'MCP3'):
c ---------------------------------------------------
c Schnittpunkt mit Ebene V2 (y'=dx2-(x'-dx1)):
delta_x = (dx1+dx2-y+x*v_y/v_x)/(1+v_y/v_x)-x ! v_x,v_y > 0.
dt = delta_x/v_x
x = x + delta_x
y = y + v_y*dt
z = z + v_z*dt
t = t + dt
if (y.GT.dy5) then ! (Bahn VVrr1)
call pfosten(3,*800)
elseif (y.GE.-dy11) then ! (Bahn VVrr2)
call TestAndOut('V2 ',*800)
! Treffen wir einen Gitterstab von V2?
if (testOnWireHit) then
DrahtNr = nInt(y/(.5*sqrt_2*dist_Wires_V2))
distToWire(2) = y - DrahtNr*.5*sqrt_2*dist_Wires_V2
distToWire(1) = -distToWire(2)
call Test_WireHit(distToWire,WireRadiusQuad_V2,v_x,v_y,WireHit)
if (WireHit) then
n_return = -5
goto 800
endif
endif
goto vorne_hinten
else ! (Bahn VVrr3)
call pfosten(5,*800)
endif
c...............................................................................
800 continue
c Die Trajektorienberechnung innerhalb des TDs ist beendeet -> bringe die
c Aufruf-Variablen auf den aktuellen Stand und gehe zurueck ins Hauptprogramm.
t_ = t
x_(1) = x
x_(2) = y
x_(3) = z
v_(1) = v_x
v_(2) = v_y
n_return_ = n_return
RETURN
END
c===============================================================================
OPTIONS /EXTEND_SOURCE
SUBROUTINE PFOSTEN(p,*)
c =======================
implicit none
integer p
character pfo*3 /'P '/
INCLUDE 'mutrack$sourcedirectory:COM_TD_INT.INC'
write(pfo(2:3),'(I2)') p
call TestAndOut(pfo)
if (log_refl_V3) then
n_return = p+50
elseif (log_refl_VH) then
n_return = p+25
else
n_return = p
endif
RETURN 1
END
c===============================================================================
OPTIONS /EXTEND_SOURCE
SUBROUTINE TestAndOut(text,*)
c =============================
implicit none
INCLUDE 'mutrack$sourcedirectory:COM_TD_INT.INC'
INCLUDE 'mutrack$sourcedirectory:COM_TD_EXT.INC'
INCLUDE 'mutrack$sourcedirectory:COM_WINKEL.INC'
INCLUDE 'mutrack$sourcedirectory:COM_KAMMER.INC'
INCLUDE 'mutrack$sourcedirectory:GEO_TRIGGER.INC'
INCLUDE 'mutrack$sourcedirectory:COM_OUTPUT.INC'
c Variablen fuer die Graphikausgabe:
real xKoord(1000) ! Koordinatenfelder fuer die
real yKoord(1000) ! Graphikausgabe
real zKoord(1000) !
cMBc real tKoord(1000) !
integer nKoord ! Anzahl der Koordinaten
cMBc COMMON /GRAPHIX/ xKoord,yKoord,zKoord,nKoord,tKoord ! fuer Graphikaufruf
COMMON /GRAPHIX/ xKoord,yKoord,zKoord,nKoord ! fuer Graphikaufruf
real Ekin, help1, help2, help3, help4, c
character text*3
parameter (c=299.7925) ! <- c in [mm/ns]!
c Ausgabe der DEBUG-Informationen:
if (DEBUG) then
Ekin = m/2.*(v_x**2.+v_y**2.+v_z**2.) / c**2.
if (alfaTD.NE.0) then
help1 = (x-d_Folie_Achse)*Cos_alfaTD - y*Sin_alfaTD + xTD
help2 = (x-d_Folie_Achse)*Sin_alfaTD + y*Cos_alfaTD
help3 = v_x*Cos_alfaTD - v_y*Sin_alfaTD + xTD
help4 = v_x*Sin_alfaTD + v_y*Cos_alfaTD
write(lun(1),1)text,help1,help2,z,help3,help4,v_z,Ekin
else
write(lun(1),1)text,t,x-d_Folie_Achse+xTD,y,z,
+ v_x,v_y,v_z,Ekin
endif
endif
1 format(5X,A4,3X,F6.1,2X,F7.2,X,F6.2,X,F6.2,2X,F6.2,X,
+ F6.2,X,F6.2,2X,G13.6)
c Speichern der Koordinaten fuer GRAPHICS:
if (Graphics) then
nKoord = nKoord + 1
if (alfaTD.NE.0) then
xKoord(nKoord) = (x-d_Folie_Achse)*Cos_alfaTD -
+ y*Sin_alfaTD + xTD
yKoord(nKoord) = (x-d_Folie_Achse)*Sin_alfaTD +
+ y*Cos_alfaTD
else
xKoord(nKoord) = x-d_Folie_Achse + xTD
yKoord(nKoord) = y
endif
zKoord(nKoord) = z
cMBc tKoord(nKoord) = t
if (nKoord.EQ.1000) then
call plot_vertikal
xKoord(1) = xKoord( 999) ! die letzten beiden uebernehme
yKoord(1) = yKoord( 999) ! damit gegebenenfalls der Rich
zKoord(1) = zKoord( 999) ! pfeil gezeichnet werden kann.
cMBc tKoord(1) = tKoord( 999)
xKoord(2) = xKoord(1000)
yKoord(2) = yKoord(1000)
zKoord(2) = zKoord(1000)
cMBc tKoord(2) = tKoord(1000)
nKoord = 2
endif
endif
c Testen, ob Teilchen stehen bleibt:
if (v_x.EQ.0. .AND.v_y.EQ.0.) then
if (text(1:1).NE.'F') then
n_return = 111
if (DEBUG) call outText(n_return)
RETURN 1
endif
endif
END
c===============================================================================
OPTIONS /EXTEND_SOURCE
SUBROUTINE outText(n)
c =====================
implicit none
integer n
character text*70
INCLUDE 'mutrack$sourcedirectory:COM_OUTPUT.INC'
c -10: Teilchen in MCP3 nachgewiesen
c - 9: Teilchen nicht in MCP3 nachgewiesen
c - 5: Teilchen traf auf Gitterstab
c 0: TD durch G verlassen
c 1-25: Nummer der direkt getroffenen Pfosten
c 26-50: Nummer der nach Refl. an Hinten getroffenen Pfosten + 15
c 51-75: Nummer der nach Refl. an MCP3 getroffenen Pfosten + 30
c 12: oberhalb von G
c 13: unterhalb von G
c 18: rechts oben von MCP3 (in Flugrichtung)
c 19: links oben von MCP3 (in Flugrichtung)
c 20: rechts unten von MCP3 (in Flugrichtung)
c 21: links unten von MCP3 (in Flugrichtung)
if (n.EQ.101) then
text='Startposition auf Folientraeger'
elseif (n.EQ.103) then
text='Start in negative x-Richtung'
elseif (n.EQ.104) then
text='Teilchen zwischen FOLIE und VORNE reflektiert'
elseif (n.EQ.105) then
text='v_x=0 und U(FOLIE,VORNE)=0 -> Teilchen steht'
elseif (n.EQ.106) then
text='Teilchen zwischen HINTEN und GROUND reflektiert'
elseif (n.EQ.107) then
text='Reflektion bei MCP3 und bei HINTEN'
elseif (n.EQ.108) then
text='Teilchen zurueck auf Gitter V1'
elseif (n.EQ.109) then
text='Reflektion bei HINTEN und bei MCP3'
elseif (n.EQ.110) then
text='Teilchen zwischen VORNE und MCP3 reflektiert '//
+ 'mit v_x <=0'
elseif (n.EQ.111) then
text='Teilchen bleibt stehen'
endif
write(lun(1),*) ' >>> ',text
END
c===============================================================================