00001 //###################################################################\\ 00002 // \\ 00003 // Optical Communication Systems Simulator \\ 00004 // \\ 00005 // Copyright (2000): \\ 00006 // Optical Fiber Communications Laboratory (OFCL) \\ 00007 // Computer Science & Electrical Engineering Department (CSEE) \\ 00008 // University of Maryland Baltimore County (UMBC) \\ 00009 // \\ 00010 //###################################################################\\ 00011 00012 00013 //###################################################################\\ 00014 // \\ 00015 // The applications in this file were written by John Zweck \\ 00016 // and are not to be modified by anyone else for now. \\ 00017 // \\ 00018 //###################################################################\\ 00019 00020 #include <iostream.h> 00021 #include <complex.h> 00022 00023 #include "ocs.hh" 00024 #include "StartupPape.hh" 00025 00026 #include <time.h> 00027 #include <sys/time.h> 00028 #include <sys/times.h> 00029 00030 00031 extern ofstream LogFile; 00032 00033 void AJ(StartupZweck * Startup); 00034 00035 00036 // ## Application Wrapper 00037 00038 /*********************************************************************\ 00039 / #Function added by John Zweck \ 00040 / Documention: Pape D. Thiam \ 00041 / \ 00042 / Function : MyApplication \ 00043 / usage : This function is passed by default the two parameters \ 00044 / that the main function received from the keyboard. An \ 00045 / object of type "StartupZweck" is instantiated. A data \ 00046 / member of the class object is expected to hold the \ 00047 / value '1'. If it actually holds the value '1', the \ 00048 / function "AJ" is called and the instantiated object is \ 00049 / passed to it by reference, conversly, an error message \ 00050 / is thrown to the screen if the data member does not \ 00051 / hold the value '1'. \ 00052 / \ 00053 / input(s) : The data is read from a file \ 00054 / output(s): The data is written to a file as well. \ 00055 \*********************************************************************/ 00056 00057 // The main function takes data from the keyboard and make it available to the 00058 // user by passing it to this function. 00059 void MyApplication(int argc, char *argv[]) 00060 { 00061 // An object of type "StartupZweck" is instantiated and a string is 00062 // passed to the constructor to initiate a data member 00063 StartupZweck Startup("Startup.in"); 00064 00065 // The object accesses a private data member via its accessor 00066 // Note that the object "Startup" can not access the private data members 00067 // of the class "StartupZweck" unless it is a friend of the class or through 00068 // private inheritance. 00069 switch(Startup.GetSimType()) 00070 { 00071 // If the content of the switch statement returns a 1, the function AJ 00072 // is called and the object "Startup" is passed by reference. If "case 1" 00073 // is not executed, the default case gets executed, an error message 00074 // is thrown directly to the screen, and the program is exited. 00075 case 1: 00076 AJ(&Startup); 00077 break; 00078 00079 default: 00080 cerr << "MyApplication: Invalid choice of application in SimType" 00081 << endl; 00082 exit(1); 00083 00084 } // end switch 00085 00086 } // end MyAppn 00087 00088 00089 /*********************************************************************\ 00090 / #Function added by John Zweck \ 00091 / Documention: Pape D. Thiam \ 00092 / \ 00093 / Function : AJ \ 00094 / usage : \ 00095 / \ 00096 / \ 00097 / \ 00098 / \ 00099 / \ 00100 / \ 00101 / \ 00102 / \ 00103 / \ 00104 / input(s) : \ 00105 / output(s): \ 00106 \*********************************************************************/ 00107 void AJ(StartupZweck * Startup) 00108 { 00109 // StartTime and EndTime are instantiated as objects of the class time_t 00110 // which is defined in the C++ standard template library 00111 time_t StartTime,EndTime; 00112 00113 struct tms my_tms; 00114 00115 // Since NULL is passed to time, the value of the current time is not stored 00116 // but it is still returned by the function. Note that the reference time is 00117 // a default time stored in the compiler. The actual value stored is 00118 // actually the elapsed time since the default time stored in the compiler. 00119 // Note that time_t is generally defined as long and it is calculated in 00120 // seconds. 00121 StartTime = time(NULL); 00122 00123 // When ctime is called, the returned string has the following format 00124 // Www Mmm dd hh:mm:ss yyy 00125 // Where Www is the weekday, Mmm the month in letters, dd the day of the 00126 // month, hh:mm:ss is the time and yyy is the current year 00127 cout << "Start Time: " << ctime(&StartTime) << endl; 00128 00129 // This function call separates the data current data in the file from the 00130 // new data with a line of pound signs. 00131 LogFileSeparator(); 00132 00133 // Data is written into the file. Note that the buffer is flushed before and 00134 // data is written to the file. 00135 LogFile << endl << "AJ" << endl; 00136 00137 // Starup is a class object of type "StartupZweck". "GetInputFilesDir()" 00138 // and "GetJobPrefix()" are two member functions (accessors). They both 00139 // return strings. 00140 string InDir = Startup->GetInputFilesDir(); 00141 string Job = Startup->GetJobPrefix(); 00142 00143 // Class objects of type RanNumGen are being instantiated and the 00144 // constructor is being passed a string. Note that InDir is a string and a 00145 // string is appended to it. 00146 RanNumGen RNGSignal(InDir + "RanNumGenSig.in"); 00147 RanNumGen RNGAmps(InDir + "RanNumGenAmps.in"); 00148 RanNumGen RNGFibers(InDir + "RanNumGenFibers.in"); 00149 00150 // ## Initiating the optical pulses 00151 00152 // A class object of type "OptSignal" is instantiated as a pointer. 00153 OptSignal * Signal; 00154 00155 // A block of memory is being allocated for Signal to point to. 00156 Signal = new OptSignal("Signal.in", &RNGSignal); 00157 00158 // A class object of type "OptDataWriter" is instantiated and the 00159 // constructor is passed a set of data. 00160 OptDataWriter DataWriter(InDir + "DataWriter.in", InDir,Job,Signal); 00161 00162 DataWriter.WriteInitialData(); 00163 00164 // ## Declare and initialize the fibers 00165 // Note that "OptFiberLocalError" is a class and the different parameters it 00166 // receives are geared towards its default constructor. 00167 OptFiberLocalError PreDCF(InDir + "PreDCF.in",Signal,&RNGFibers,Job); 00168 OptFiberLocalError PostDCF(InDir + "PostDCF.in",Signal,&RNGFibers,Job); 00169 OptFiberLocalError SMF(InDir + "SMF.in",Signal, &RNGFibers,Job); 00170 OptFiberLocalError DCF(InDir + "DCF.in",Signal, &RNGFibers,Job); 00171 00172 // Four fibers are being used 00173 int NumFibers = 4; 00174 00175 OptFiberLocalError * FiberPtr[NumFibers]; 00176 00177 FiberPtr[0] = &PreDCF; 00178 FiberPtr[1] = &PostDCF; 00179 FiberPtr[2] = &SMF; 00180 FiberPtr[3] = &DCF; 00181 00182 // The Amplifiers are declared and initialized. Note that "OptAmplifier" is 00183 // a class and the differed parameters it receives are geared towards its 00184 // default constructor. 00185 OptAmplifier Amp(InDir + "Amp.in",Signal,&RNGAmps); 00186 OptAmplifier Amp2(InDir + "Amp2.in",Signal,&RNGAmps); 00187 OptAmplifier PAmp(InDir + "PAmp.in",Signal,&RNGAmps); 00188 00189 // Three amplifiers are being used 00190 int NumAmps = 3; 00191 00192 // A new array of amplifiers is declared as a pointer. And the cells of the 00193 // array point to the three amplifiers previously defined. 00194 OptAmplifier * AmpPtr[NumAmps]; 00195 00196 AmpPtr[0] = &Amp; 00197 AmpPtr[1] = &Amp2; 00198 AmpPtr[2] = &PAmp; 00199 00200 // The value stored in the private data member "DebugLevelAmps" is retrieved 00201 // If true is returned, the retrieved value is stored in all the three 00202 // amplifier objects, i.e. the private data member "DebugLevel" of each of 00203 // the amplifier objects will be assigned the retrieved value. 00204 if(Startup->GetDebugLevelAmps()) 00205 { 00206 for(int i = 0; i < NumAmps; i++) 00207 AmpPtr[i]->SetDebugLevel(Startup->GetDebugLevelAmps()); 00208 } 00209 00210 // The type of amplifier is being setup. 00211 for(int i = 0; i < NumAmps; i++) 00212 AmpPtr[i]->SetTypeAmplifier(typeAmplifier(Startup->GetTypeAmp())); 00213 00214 // The value stored in the private data member "AmpsNoiseOffFlag" 00215 // is retrieved If true is returned,the noise of every amplifier is turned 00216 // off. 00217 if(Startup->GetAmpsNoiseOffFlag()) 00218 { 00219 for(int i = 0; i < NumAmps; i++) 00220 AmpPtr[i]->SetTypeAmplifierNoise(NOISE_OFF); 00221 } 00222 00223 // The private data member "SndOrDispFiber" of the fibers is initialized to 00224 // zero if true is returned. 00225 if(Startup->GetBeta3ZeroFlag()) 00226 { 00227 for(int i = 0; i < NumFibers; i++) 00228 FiberPtr[i]->SetSndOrDispFiber(0); 00229 } 00230 00231 // The private data member "GammaFiber" of the fibers are initialized to 00232 // zero if true is returned. 00233 if(Startup->GetNonLinearityZeroFlag()) 00234 { 00235 for(int i = 0; i < NumFibers; i++) 00236 FiberPtr[i]->SetGammaFiber(0); 00237 } 00238 00239 // The private data member "Attenuation" of the fibers are initialized to 00240 // zero if true is returned. 00241 if(Startup->GetFiberLossZeroFlag()) 00242 for(int ii = 0; ii < NumFibers; ii++) 00243 FiberPtr[ii]->SetAttenuation(0); 00244 00245 // The private data member "RelativeErrorGoal" of the fibers are initialized 00246 // to the value stored in "RelativeErrorGoal". 00247 for(int ii = 0; ii < NumFibers; ii++) 00248 FiberPtr[ii]->SetRelativeErrorGoal(Startup->GetRelativeErrorGoal()); 00249 00250 // The private data member "OutputStepSizesFlag" of the fibers are 00251 // initialized to the value stored in "OutputStepSizesFlag". 00252 for(int ii = 0; ii < NumFibers; ii++) 00253 { 00254 FiberPtr[ii]->SetOutputStepSizesFlag(Startup->GetOutputStepSizesFlag()); 00255 } 00256 00257 00258 // #### Propagate signal through fiber #### 00259 00260 double PropagatedLength = 0; 00261 int ZStepNum = 0; 00262 00263 // The signal is propagated trhough the "PreDCF" fiber and the "PAmp" 00264 // amplifier amplifies it. 00265 PreDCF.Propagate(&PropagatedLength, &ZStepNum); 00266 PAmp.AmplifyOptSignal(); 00267 00268 int kk = 0; 00269 00270 // ask questions about this and explain later 00271 DataWriter.WriteEndMap(0,kk,PropagatedLength); 00272 00273 for(kk = 0; kk < Startup->GetQtMapSpans(); kk++) 00274 { 00275 // The signal is propagated trhough the "SMF" fiber and the "Amp" 00276 // amplifier amplifies it. 00277 SMF.Propagate(&PropagatedLength,&ZStepNum); 00278 DataWriter.WriteWithinMap(0,kk,PropagatedLength); 00279 Amp.AmplifyOptSignal(); 00280 00281 // ask questions about this and explain later 00282 DataWriter.WriteWithinMap(0,kk,PropagatedLength); 00283 00284 // The signal is propagated trhough the "DCF" fiber and the "Amp2" 00285 // amplifier amplifies it. 00286 DCF.Propagate(&PropagatedLength,&ZStepNum); 00287 DataWriter.WriteWithinMap(0,kk,PropagatedLength); 00288 Amp2.AmplifyOptSignal(); 00289 00290 // ask questions about this and explain later 00291 DataWriter.WriteEndMap(0,kk,PropagatedLength); 00292 00293 if(kk % 10 == 0 && kk != 0) 00294 cout << "Completed " << kk << " periods of dispersion map " << endl; 00295 00296 }// ## end for kk-loop 00297 00298 // The signal is propagated trhough the "PostDCF" fiber and the "PAmp" 00299 // amplifier amplifies it. 00300 PostDCF.Propagate(&PropagatedLength,&ZStepNum); 00301 PAmp.AmplifyOptSignal(); 00302 00303 // ####################### End of Propagation ########################### 00304 00305 DataWriter.WriteEndTransmission(0,kk,PropagatedLength); 00306 00307 // ask questions about this and explain later 00308 cout <<"Total PropagatedLength [km] = "<<PropagatedLength*1e-3<< endl; 00309 cout <<"Number Steps in Z taken by solver = " << ZStepNum << endl; 00310 00311 // Since NULL is passed to time, the value of the current time is not stored 00312 // but it is still returned by the function. Note that the reference time is 00313 // a default time stored in the compiler. The actual value stored is 00314 // actually the elapsed time since the default time stored in the compiler. 00315 // Note that time_t is generally defined as long and it is calculated in 00316 // seconds. This is the end of the propagation. 00317 EndTime = time(NULL); 00318 00319 // The propagation time is determined and stored in TotalTime 00320 double TotalTime = double(EndTime - StartTime); 00321 00322 // ask questions about this and explain later 00323 times(&my_tms); 00324 00325 // ask questions about this and explain later 00326 double CPUtime = (double(my_tms.tms_utime))/(double(sysconf(_SC_CLK_TCK))); 00327 00328 // Since "TotalTime" & "CPU Time" are in seconds, they are converted to hours 00329 // The percentage of the CPU Time is also calculated 00330 cout << "Total Run Time [hrs] = " << TotalTime/3600.0 << endl 00331 << "Total CPU Time [hrs] = " << CPUtime/3600.0 << " = " 00332 << 100.0*CPUtime/TotalTime << "%" << endl; 00333 00334 // When ctime is called, the returned string has the following format 00335 // Www Mmm dd hh:mm:ss yyy 00336 // Where Www is the weekday, Mmm the month in letters, dd the day of the 00337 // month, hh:mm:ss is the time and yyy is the current year 00338 cout << "End Time: " << ctime(&EndTime) << endl; 00339 00340 cout << "THE END" << endl; 00341 00342 // "THE END" is written to the file. 00343 LogFile << "THE END" << endl; 00344 00345 00346 } // ## end AJ 00347 00348 // #####################################################################