1/* Copyright (c) 2012 Massachusetts Institute of Technology 2 * 3 * Permission is hereby granted, free of charge, to any person obtaining a copy 4 * of this software and associated documentation files (the "Software"), to deal 5 * in the Software without restriction, including without limitation the rights 6 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 * copies of the Software, and to permit persons to whom the Software is 8 * furnished to do so, subject to the following conditions: 9 * 10 * The above copyright notice and this permission notice shall be included in 11 * all copies or substantial portions of the Software. 12 * 13 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 * THE SOFTWARE. 20 */ 21 22#include "model/OpticalModel.h" 23 24#include "model/PortInfo.h" 25#include "model/EventInfo.h" 26#include "model/optical_graph/OpticalWaveguide.h" 27#include "model/optical_graph/OpticalNode.h" 28#include "model/optical_graph/OpticalLaser.h" 29#include "model/optical_graph/OpticalModulator.h" 30#include "model/optical_graph/OpticalFilter.h" 31#include "model/optical_graph/OpticalDetector.h" 32#include "model/optical_graph/OpticalWavelength.h" 33 34namespace DSENT 35{ 36 OpticalModel::OpticalModel(const String& instance_name_, const TechModel* tech_model_) 37 : ElectricalModel(instance_name_, tech_model_) 38 { 39 m_optical_input_ports_ = new Map<PortInfo*>; 40 m_optical_output_ports_ = new Map<PortInfo*>; 41 42 m_waveguides_ = new Map<OpticalWaveguide*>; 43 m_lasers_ = new Map<OpticalLaser*>; 44 m_modulators_ = new Map<OpticalModulator*>; 45 m_filters_ = new Map<OpticalFilter*>; 46 m_detectors_ = new Map<OpticalDetector*>; 47 } 48 49 OpticalModel::~OpticalModel() 50 { 51 delete m_optical_input_ports_; 52 delete m_optical_output_ports_; 53 deletePtrMap<OpticalWaveguide>(m_waveguides_); 54 deletePtrMap<OpticalLaser>(m_lasers_); 55 deletePtrMap<OpticalModulator>(m_modulators_); 56 deletePtrMap<OpticalFilter>(m_filters_); 57 deletePtrMap<OpticalDetector>(m_detectors_); 58 m_optical_input_ports_ = NULL; 59 m_optical_output_ports_ = NULL; 60 m_waveguides_ = NULL; 61 m_lasers_ = NULL; 62 m_modulators_ = NULL; 63 m_filters_ = NULL; 64 m_detectors_ = NULL; 65 } 66 67 // Connect an optical port (input or output) to some OpticalWaveguide 68 void OpticalModel::opticalPortConnect(OpticalModel* connect_model_, const String& port_name_, const String& waveguide_name_) 69 { 70 // Check that the connecting waveguide exists 71 ASSERT(m_waveguides_->keyExist(waveguide_name_), "[Error] " + getInstanceName() + 72 " -> Waveguide '" + waveguide_name_ + "' does not exist!"); 73 74 // Check whether the port name is an input or output, assertion error if neither 75 bool is_input = connect_model_->getOpticalInputs()->keyExist(port_name_); 76 bool is_output = connect_model_->getOpticalOutputs()->keyExist(port_name_); 77 ASSERT(is_input || is_output, "[Error] " + getInstanceName() + " -> Model '" + connect_model_->getInstanceName() + 78 "' does not have a port named '" + port_name_ + "'!"); 79 80 // Get the two waveguides 81 OpticalWaveguide* port_waveguide = connect_model_->getWaveguide(port_name_); 82 OpticalWaveguide* connect_waveguide = getWaveguide(waveguide_name_); 83 84 // Check that the two waveguides expect the same wavelengths 85 ASSERT((port_waveguide->getWavelengths().first == connect_waveguide->getWavelengths().first) && 86 (port_waveguide->getWavelengths().second == connect_waveguide->getWavelengths().second), 87 "[Error] " + getInstanceName() + " -> Optical port expects different wavelengths for Model '" + 88 connect_model_->getInstanceName() + "." + port_name_ + "' and waveguide '" + waveguide_name_ + "'!"); 89 90 if(is_input) 91 { 92 connect_waveguide->addDownstreamNode(port_waveguide); 93 } 94 else if(is_output) 95 { 96 port_waveguide->addDownstreamNode(connect_waveguide); 97 } 98 } 99 100 //Get Waveguides 101 const Map<OpticalWaveguide*>* OpticalModel::getWaveguides() const 102 { 103 return m_waveguides_; 104 } 105 106 OpticalWaveguide* OpticalModel::getWaveguide(const String& name_) 107 { 108 return m_waveguides_->get(name_); 109 } 110 111 //Get Lasers 112 const Map<OpticalLaser*>* OpticalModel::getLasers() const 113 { 114 return m_lasers_; 115 } 116 117 OpticalLaser* OpticalModel::getLaser(const String& name_) 118 { 119 return m_lasers_->get(name_); 120 } 121 122 //Get Modulators 123 const Map<OpticalModulator*>* OpticalModel::getModulators() const 124 { 125 return m_modulators_; 126 } 127 128 OpticalModulator* OpticalModel::getModulator(const String& name_) 129 { 130 return m_modulators_->get(name_); 131 } 132 133 //Get Filters 134 const Map<OpticalFilter*>* OpticalModel::getFilters() const 135 { 136 return m_filters_; 137 } 138 139 OpticalFilter* OpticalModel::getFilter(const String& name_) 140 { 141 return m_filters_->get(name_); 142 } 143 144 //Get Detectors 145 const Map<OpticalDetector*>* OpticalModel::getDetectors() const 146 { 147 return m_detectors_; 148 } 149 150 OpticalDetector* OpticalModel::getDetector(const String& name_) 151 { 152 return m_detectors_->get(name_); 153 } 154 155 //Get Inputs 156 const Map<PortInfo*>* OpticalModel::getOpticalInputs() const 157 { 158 return m_optical_input_ports_; 159 } 160 161 PortInfo* OpticalModel::getOpticalInputPort(const String& name_) 162 { 163 ASSERT(m_optical_input_ports_->keyExist(name_), "[Error] " + getInstanceName() + 164 " -> Input port (" + name_ + ") does not exist"); 165 166 return m_optical_input_ports_->get(name_); 167 } 168 169 const PortInfo* OpticalModel::getOpticalInputPort(const String& name_) const 170 { 171 ASSERT(m_optical_input_ports_->keyExist(name_), "[Error] " + getInstanceName() + 172 " -> Input port (" + name_ + ") does not exist"); 173 174 return m_optical_input_ports_->get(name_); 175 } 176 177 //Get Outputs 178 const Map<PortInfo*>* OpticalModel::getOpticalOutputs() const 179 { 180 return m_optical_output_ports_; 181 } 182 183 PortInfo* OpticalModel::getOpticalOutputPort(const String& name_) 184 { 185 ASSERT(m_optical_output_ports_->keyExist(name_), "[Error] " + getInstanceName() + 186 " -> Input port (" + name_ + ") does not exist"); 187 188 return m_optical_output_ports_->get(name_); 189 } 190 191 const PortInfo* OpticalModel::getOpticalOutputPort(const String& name_) const 192 { 193 ASSERT(m_optical_output_ports_->keyExist(name_), "[Error] " + getInstanceName() + 194 " -> Input port (" + name_ + ") does not exist"); 195 196 return m_optical_output_ports_->get(name_); 197 } 198 199 //------------------------------------------------------------------------- 200 // Optical Connectivity Creation Functions 201 //------------------------------------------------------------------------- 202 void OpticalModel::createOpticalInputPort(const String& name_, const WavelengthGroup& wavelength_group_) 203 { 204 // Create the new waveguides 205 // This should already check that it has not been previously declared 206 createWaveguide(name_, wavelength_group_); 207 // Add the waveguide name to list of input ports 208 m_optical_input_ports_->set(name_, new PortInfo(name_, wavelength_group_)); 209 return; 210 } 211 212 void OpticalModel::createOpticalOutputPort(const String& name_, const WavelengthGroup& wavelength_group_) 213 { 214 // Create the new waveguides (including its waveguide reference) 215 // This should already check that it has not been previously declared 216 createWaveguide(name_, wavelength_group_); 217 // Add the waveguide name to list of output ports 218 m_optical_output_ports_->set(name_, new PortInfo(name_, wavelength_group_)); 219 return; 220 } 221 222 // Waveguide creation 223 void OpticalModel::createWaveguide(const String& name_, const WavelengthGroup& wavelengths_) 224 { 225 // Check that the waveguide hasn't been previously declared 226 ASSERT( !m_waveguides_->keyExist(name_), "[Error] " + getInstanceName() + 227 " -> Redeclaration of waveguide " + name_); 228 m_waveguides_->set(name_, new OpticalWaveguide(name_, this, wavelengths_)); 229 return; 230 } 231 232 // Laser creation 233 void OpticalModel::createLaser(const String& name_, const WavelengthGroup& wavelengths_) 234 { 235 // Check that the laser hasn't been previously declared 236 ASSERT( !m_lasers_->keyExist(name_), "[Error] " + getInstanceName() + 237 " -> Redeclaration of laser " + name_); 238 m_lasers_->set(name_, new OpticalLaser(name_, this, wavelengths_)); 239 return; 240 } 241 242 // Modulator creation 243 void OpticalModel::createModulator(const String& name_, const WavelengthGroup& wavelengths_, bool opt_loss_, OpticalTransmitter* transmitter_) 244 { 245 // Check that the modulator hasn't been previously declared 246 ASSERT( !m_modulators_->keyExist(name_), "[Error] " + getInstanceName() + 247 " -> Redeclaration of modulator " + name_); 248 m_modulators_->set(name_, new OpticalModulator(name_, this, wavelengths_, opt_loss_, transmitter_)); 249 return; 250 } 251 252 // Modulator Multiplier creation 253 void OpticalModel::createFilter(const String& name_, const WavelengthGroup& wavelengths_, bool drop_all_, const WavelengthGroup& drop_wavelengths_) 254 { 255 // Check that the filter hasn't been previously declared 256 ASSERT( !m_filters_->keyExist(name_), "[Error] " + getInstanceName() + 257 " -> Redeclaration of filter " + name_); 258 m_filters_->set(name_, new OpticalFilter(name_, this, wavelengths_, drop_all_, drop_wavelengths_)); 259 return; 260 } 261 262 // Detector creation 263 void OpticalModel::createDetector(const String& name_, const WavelengthGroup& wavelengths_, OpticalReceiver* receiver_) 264 { 265 // Check that the detector hasn't been previously declared 266 ASSERT( !m_detectors_->keyExist(name_), "[Error] " + getInstanceName() + 267 " -> Redeclaration of detector " + name_); 268 m_detectors_->set(name_, new OpticalDetector(name_, this, wavelengths_, receiver_)); 269 return; 270 } 271 272 //------------------------------------------------------------------------- 273 274 // Assign a waveguide to be downstream from another waveguide 275 // assign downtream_waveguide_name_ = upstream_waveguide_name_ 276 void OpticalModel::opticalAssign(const String& downstream_waveguide_name_, const String& upstream_waveguide_name_) 277 { 278 ASSERT(getWaveguides()->keyExist(downstream_waveguide_name_), "[Error] " + getInstanceName() + " -> Waveguide '" + 279 downstream_waveguide_name_ + "' does not exist!"); 280 281 ASSERT(getWaveguides()->keyExist(upstream_waveguide_name_), "[Error] " + getInstanceName() + " -> Waveguide '" + 282 upstream_waveguide_name_ + "' does not exist!"); 283 284 // Get the two waveguides 285 OpticalWaveguide* upstream_waveguide = getWaveguide(upstream_waveguide_name_); 286 OpticalWaveguide* downstream_waveguide = getWaveguide(downstream_waveguide_name_); 287 288 // Check that the two waveguides expect the same wavelengths 289 ASSERT((upstream_waveguide->getWavelengths().first == downstream_waveguide->getWavelengths().first) && 290 (upstream_waveguide->getWavelengths().second == downstream_waveguide->getWavelengths().second), 291 "[Error] " + getInstanceName() + " -> Assignment expects different wavelengths for waveguide '" + 292 upstream_waveguide_name_ + "' and waveguide '" + downstream_waveguide_name_ + "'!"); 293 294 // Connect the downstream waveguide and the upstream waveguide 295 upstream_waveguide->addDownstreamNode(downstream_waveguide); 296 return; 297 } 298} // namespace DSENT 299