110448Snilay@cs.wisc.edu/* Copyright (c) 2012 Massachusetts Institute of Technology
210448Snilay@cs.wisc.edu *
310448Snilay@cs.wisc.edu * Permission is hereby granted, free of charge, to any person obtaining a copy
410448Snilay@cs.wisc.edu * of this software and associated documentation files (the "Software"), to deal
510448Snilay@cs.wisc.edu * in the Software without restriction, including without limitation the rights
610448Snilay@cs.wisc.edu * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
710448Snilay@cs.wisc.edu * copies of the Software, and to permit persons to whom the Software is
810448Snilay@cs.wisc.edu * furnished to do so, subject to the following conditions:
910448Snilay@cs.wisc.edu *
1010448Snilay@cs.wisc.edu * The above copyright notice and this permission notice shall be included in
1110448Snilay@cs.wisc.edu * all copies or substantial portions of the Software.
1210448Snilay@cs.wisc.edu *
1310448Snilay@cs.wisc.edu * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1410448Snilay@cs.wisc.edu * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1510448Snilay@cs.wisc.edu * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
1610448Snilay@cs.wisc.edu * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
1710448Snilay@cs.wisc.edu * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
1810448Snilay@cs.wisc.edu * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
1910448Snilay@cs.wisc.edu * THE SOFTWARE.
2010448Snilay@cs.wisc.edu */
2110448Snilay@cs.wisc.edu
2210447Snilay@cs.wisc.edu#include "model/OpticalModel.h"
2310447Snilay@cs.wisc.edu
2410447Snilay@cs.wisc.edu#include "model/PortInfo.h"
2510447Snilay@cs.wisc.edu#include "model/EventInfo.h"
2610447Snilay@cs.wisc.edu#include "model/optical_graph/OpticalWaveguide.h"
2710447Snilay@cs.wisc.edu#include "model/optical_graph/OpticalNode.h"
2810447Snilay@cs.wisc.edu#include "model/optical_graph/OpticalLaser.h"
2910447Snilay@cs.wisc.edu#include "model/optical_graph/OpticalModulator.h"
3010447Snilay@cs.wisc.edu#include "model/optical_graph/OpticalFilter.h"
3110447Snilay@cs.wisc.edu#include "model/optical_graph/OpticalDetector.h"
3210447Snilay@cs.wisc.edu#include "model/optical_graph/OpticalWavelength.h"
3310447Snilay@cs.wisc.edu
3410447Snilay@cs.wisc.edunamespace DSENT
3510447Snilay@cs.wisc.edu{
3610447Snilay@cs.wisc.edu    OpticalModel::OpticalModel(const String& instance_name_, const TechModel* tech_model_)
3710447Snilay@cs.wisc.edu        : ElectricalModel(instance_name_, tech_model_)
3810447Snilay@cs.wisc.edu    {
3910447Snilay@cs.wisc.edu        m_optical_input_ports_ = new Map<PortInfo*>;
4010447Snilay@cs.wisc.edu        m_optical_output_ports_ = new Map<PortInfo*>;
4110447Snilay@cs.wisc.edu
4210447Snilay@cs.wisc.edu        m_waveguides_ = new Map<OpticalWaveguide*>;
4310447Snilay@cs.wisc.edu        m_lasers_ = new Map<OpticalLaser*>;
4410447Snilay@cs.wisc.edu        m_modulators_ = new Map<OpticalModulator*>;
4510447Snilay@cs.wisc.edu        m_filters_ = new Map<OpticalFilter*>;
4610447Snilay@cs.wisc.edu        m_detectors_ = new Map<OpticalDetector*>;
4710447Snilay@cs.wisc.edu    }
4810447Snilay@cs.wisc.edu
4910447Snilay@cs.wisc.edu    OpticalModel::~OpticalModel()
5010447Snilay@cs.wisc.edu    {
5110447Snilay@cs.wisc.edu        delete m_optical_input_ports_;
5210447Snilay@cs.wisc.edu        delete m_optical_output_ports_;
5310447Snilay@cs.wisc.edu        deletePtrMap<OpticalWaveguide>(m_waveguides_);
5410447Snilay@cs.wisc.edu        deletePtrMap<OpticalLaser>(m_lasers_);
5510447Snilay@cs.wisc.edu        deletePtrMap<OpticalModulator>(m_modulators_);
5610447Snilay@cs.wisc.edu        deletePtrMap<OpticalFilter>(m_filters_);
5710447Snilay@cs.wisc.edu        deletePtrMap<OpticalDetector>(m_detectors_);
5810447Snilay@cs.wisc.edu        m_optical_input_ports_ = NULL;
5910447Snilay@cs.wisc.edu        m_optical_output_ports_ = NULL;
6010447Snilay@cs.wisc.edu        m_waveguides_ = NULL;
6110447Snilay@cs.wisc.edu        m_lasers_ = NULL;
6210447Snilay@cs.wisc.edu        m_modulators_ = NULL;
6310447Snilay@cs.wisc.edu        m_filters_ = NULL;
6410447Snilay@cs.wisc.edu        m_detectors_ = NULL;
6510447Snilay@cs.wisc.edu    }
6610447Snilay@cs.wisc.edu
6710447Snilay@cs.wisc.edu    // Connect an optical port (input or output) to some OpticalWaveguide
6810447Snilay@cs.wisc.edu    void OpticalModel::opticalPortConnect(OpticalModel* connect_model_, const String& port_name_, const String& waveguide_name_)
6910447Snilay@cs.wisc.edu    {
7010447Snilay@cs.wisc.edu        // Check that the connecting waveguide exists
7110447Snilay@cs.wisc.edu        ASSERT(m_waveguides_->keyExist(waveguide_name_), "[Error] " + getInstanceName() +
7210447Snilay@cs.wisc.edu            " -> Waveguide '" + waveguide_name_ + "' does not exist!");
7310447Snilay@cs.wisc.edu
7410447Snilay@cs.wisc.edu        // Check whether the port name is an input or output, assertion error if neither
7510447Snilay@cs.wisc.edu        bool is_input = connect_model_->getOpticalInputs()->keyExist(port_name_);
7610447Snilay@cs.wisc.edu        bool is_output = connect_model_->getOpticalOutputs()->keyExist(port_name_);
7710447Snilay@cs.wisc.edu        ASSERT(is_input || is_output, "[Error] " + getInstanceName() + " -> Model '" + connect_model_->getInstanceName() +
7810447Snilay@cs.wisc.edu            "' does not have a port named '" + port_name_ + "'!");
7910447Snilay@cs.wisc.edu
8010447Snilay@cs.wisc.edu        // Get the two waveguides
8110447Snilay@cs.wisc.edu        OpticalWaveguide* port_waveguide = connect_model_->getWaveguide(port_name_);
8210447Snilay@cs.wisc.edu        OpticalWaveguide* connect_waveguide = getWaveguide(waveguide_name_);
8310447Snilay@cs.wisc.edu
8410447Snilay@cs.wisc.edu        // Check that the two waveguides expect the same wavelengths
8510447Snilay@cs.wisc.edu        ASSERT((port_waveguide->getWavelengths().first == connect_waveguide->getWavelengths().first) &&
8610447Snilay@cs.wisc.edu            (port_waveguide->getWavelengths().second == connect_waveguide->getWavelengths().second),
8710447Snilay@cs.wisc.edu            "[Error] " + getInstanceName() + " -> Optical port expects different wavelengths for Model '" +
8810447Snilay@cs.wisc.edu            connect_model_->getInstanceName() + "." + port_name_ + "' and waveguide '" + waveguide_name_ + "'!");
8910447Snilay@cs.wisc.edu
9010447Snilay@cs.wisc.edu        if(is_input)
9110447Snilay@cs.wisc.edu        {
9210447Snilay@cs.wisc.edu            connect_waveguide->addDownstreamNode(port_waveguide);
9310447Snilay@cs.wisc.edu        }
9410447Snilay@cs.wisc.edu        else if(is_output)
9510447Snilay@cs.wisc.edu        {
9610447Snilay@cs.wisc.edu            port_waveguide->addDownstreamNode(connect_waveguide);
9710447Snilay@cs.wisc.edu        }
9810447Snilay@cs.wisc.edu    }
9910447Snilay@cs.wisc.edu
10010447Snilay@cs.wisc.edu    //Get Waveguides
10110447Snilay@cs.wisc.edu    const Map<OpticalWaveguide*>* OpticalModel::getWaveguides() const
10210447Snilay@cs.wisc.edu    {
10310447Snilay@cs.wisc.edu        return m_waveguides_;
10410447Snilay@cs.wisc.edu    }
10510447Snilay@cs.wisc.edu
10610447Snilay@cs.wisc.edu    OpticalWaveguide* OpticalModel::getWaveguide(const String& name_)
10710447Snilay@cs.wisc.edu    {
10810447Snilay@cs.wisc.edu        return m_waveguides_->get(name_);
10910447Snilay@cs.wisc.edu    }
11010447Snilay@cs.wisc.edu
11110447Snilay@cs.wisc.edu    //Get Lasers
11210447Snilay@cs.wisc.edu    const Map<OpticalLaser*>* OpticalModel::getLasers() const
11310447Snilay@cs.wisc.edu    {
11410447Snilay@cs.wisc.edu        return m_lasers_;
11510447Snilay@cs.wisc.edu    }
11610447Snilay@cs.wisc.edu
11710447Snilay@cs.wisc.edu    OpticalLaser* OpticalModel::getLaser(const String& name_)
11810447Snilay@cs.wisc.edu    {
11910447Snilay@cs.wisc.edu        return m_lasers_->get(name_);
12010447Snilay@cs.wisc.edu    }
12110447Snilay@cs.wisc.edu
12210447Snilay@cs.wisc.edu    //Get Modulators
12310447Snilay@cs.wisc.edu    const Map<OpticalModulator*>* OpticalModel::getModulators() const
12410447Snilay@cs.wisc.edu    {
12510447Snilay@cs.wisc.edu        return m_modulators_;
12610447Snilay@cs.wisc.edu    }
12710447Snilay@cs.wisc.edu
12810447Snilay@cs.wisc.edu    OpticalModulator* OpticalModel::getModulator(const String& name_)
12910447Snilay@cs.wisc.edu    {
13010447Snilay@cs.wisc.edu        return m_modulators_->get(name_);
13110447Snilay@cs.wisc.edu    }
13210447Snilay@cs.wisc.edu
13310447Snilay@cs.wisc.edu    //Get Filters
13410447Snilay@cs.wisc.edu    const Map<OpticalFilter*>* OpticalModel::getFilters() const
13510447Snilay@cs.wisc.edu    {
13610447Snilay@cs.wisc.edu        return m_filters_;
13710447Snilay@cs.wisc.edu    }
13810447Snilay@cs.wisc.edu
13910447Snilay@cs.wisc.edu    OpticalFilter* OpticalModel::getFilter(const String& name_)
14010447Snilay@cs.wisc.edu    {
14110447Snilay@cs.wisc.edu        return m_filters_->get(name_);
14210447Snilay@cs.wisc.edu    }
14310447Snilay@cs.wisc.edu
14410447Snilay@cs.wisc.edu    //Get Detectors
14510447Snilay@cs.wisc.edu    const Map<OpticalDetector*>* OpticalModel::getDetectors() const
14610447Snilay@cs.wisc.edu    {
14710447Snilay@cs.wisc.edu        return m_detectors_;
14810447Snilay@cs.wisc.edu    }
14910447Snilay@cs.wisc.edu
15010447Snilay@cs.wisc.edu    OpticalDetector* OpticalModel::getDetector(const String& name_)
15110447Snilay@cs.wisc.edu    {
15210447Snilay@cs.wisc.edu        return m_detectors_->get(name_);
15310447Snilay@cs.wisc.edu    }
15410447Snilay@cs.wisc.edu
15510447Snilay@cs.wisc.edu    //Get Inputs
15610447Snilay@cs.wisc.edu    const Map<PortInfo*>* OpticalModel::getOpticalInputs() const
15710447Snilay@cs.wisc.edu    {
15810447Snilay@cs.wisc.edu        return m_optical_input_ports_;
15910447Snilay@cs.wisc.edu    }
16010447Snilay@cs.wisc.edu
16110447Snilay@cs.wisc.edu    PortInfo* OpticalModel::getOpticalInputPort(const String& name_)
16210447Snilay@cs.wisc.edu    {
16310447Snilay@cs.wisc.edu        ASSERT(m_optical_input_ports_->keyExist(name_), "[Error] " + getInstanceName() +
16410447Snilay@cs.wisc.edu                " -> Input port (" + name_ + ") does not exist");
16510447Snilay@cs.wisc.edu
16610447Snilay@cs.wisc.edu        return m_optical_input_ports_->get(name_);
16710447Snilay@cs.wisc.edu    }
16810447Snilay@cs.wisc.edu
16910447Snilay@cs.wisc.edu    const PortInfo* OpticalModel::getOpticalInputPort(const String& name_) const
17010447Snilay@cs.wisc.edu    {
17110447Snilay@cs.wisc.edu        ASSERT(m_optical_input_ports_->keyExist(name_), "[Error] " + getInstanceName() +
17210447Snilay@cs.wisc.edu                " -> Input port (" + name_ + ") does not exist");
17310447Snilay@cs.wisc.edu
17410447Snilay@cs.wisc.edu        return m_optical_input_ports_->get(name_);
17510447Snilay@cs.wisc.edu    }
17610447Snilay@cs.wisc.edu
17710447Snilay@cs.wisc.edu    //Get Outputs
17810447Snilay@cs.wisc.edu    const Map<PortInfo*>* OpticalModel::getOpticalOutputs() const
17910447Snilay@cs.wisc.edu    {
18010447Snilay@cs.wisc.edu        return m_optical_output_ports_;
18110447Snilay@cs.wisc.edu    }
18210447Snilay@cs.wisc.edu
18310447Snilay@cs.wisc.edu    PortInfo* OpticalModel::getOpticalOutputPort(const String& name_)
18410447Snilay@cs.wisc.edu    {
18510447Snilay@cs.wisc.edu        ASSERT(m_optical_output_ports_->keyExist(name_), "[Error] " + getInstanceName() +
18610447Snilay@cs.wisc.edu                " -> Input port (" + name_ + ") does not exist");
18710447Snilay@cs.wisc.edu
18810447Snilay@cs.wisc.edu        return m_optical_output_ports_->get(name_);
18910447Snilay@cs.wisc.edu    }
19010447Snilay@cs.wisc.edu
19110447Snilay@cs.wisc.edu    const PortInfo* OpticalModel::getOpticalOutputPort(const String& name_) const
19210447Snilay@cs.wisc.edu    {
19310447Snilay@cs.wisc.edu        ASSERT(m_optical_output_ports_->keyExist(name_), "[Error] " + getInstanceName() +
19410447Snilay@cs.wisc.edu                " -> Input port (" + name_ + ") does not exist");
19510447Snilay@cs.wisc.edu
19610447Snilay@cs.wisc.edu        return m_optical_output_ports_->get(name_);
19710447Snilay@cs.wisc.edu    }
19810447Snilay@cs.wisc.edu
19910447Snilay@cs.wisc.edu    //-------------------------------------------------------------------------
20010447Snilay@cs.wisc.edu    //  Optical Connectivity Creation Functions
20110447Snilay@cs.wisc.edu    //-------------------------------------------------------------------------
20210447Snilay@cs.wisc.edu    void OpticalModel::createOpticalInputPort(const String& name_, const WavelengthGroup& wavelength_group_)
20310447Snilay@cs.wisc.edu    {
20410447Snilay@cs.wisc.edu        // Create the new waveguides
20510447Snilay@cs.wisc.edu        // This should already check that it has not been previously declared
20610447Snilay@cs.wisc.edu        createWaveguide(name_, wavelength_group_);
20710447Snilay@cs.wisc.edu        // Add the waveguide name to list of input ports
20810447Snilay@cs.wisc.edu        m_optical_input_ports_->set(name_, new PortInfo(name_, wavelength_group_));
20910447Snilay@cs.wisc.edu        return;
21010447Snilay@cs.wisc.edu    }
21110447Snilay@cs.wisc.edu
21210447Snilay@cs.wisc.edu    void OpticalModel::createOpticalOutputPort(const String& name_, const WavelengthGroup& wavelength_group_)
21310447Snilay@cs.wisc.edu    {
21410447Snilay@cs.wisc.edu        // Create the new waveguides (including its waveguide reference)
21510447Snilay@cs.wisc.edu        // This should already check that it has not been previously declared
21610447Snilay@cs.wisc.edu        createWaveguide(name_, wavelength_group_);
21710447Snilay@cs.wisc.edu        // Add the waveguide name to list of output ports
21810447Snilay@cs.wisc.edu        m_optical_output_ports_->set(name_, new PortInfo(name_, wavelength_group_));
21910447Snilay@cs.wisc.edu        return;
22010447Snilay@cs.wisc.edu    }
22110447Snilay@cs.wisc.edu
22210447Snilay@cs.wisc.edu    // Waveguide creation
22310447Snilay@cs.wisc.edu    void OpticalModel::createWaveguide(const String& name_, const WavelengthGroup& wavelengths_)
22410447Snilay@cs.wisc.edu    {
22510447Snilay@cs.wisc.edu        // Check that the waveguide hasn't been previously declared
22610447Snilay@cs.wisc.edu        ASSERT( !m_waveguides_->keyExist(name_), "[Error] " + getInstanceName() +
22710447Snilay@cs.wisc.edu            " -> Redeclaration of waveguide " + name_);
22810447Snilay@cs.wisc.edu        m_waveguides_->set(name_, new OpticalWaveguide(name_, this, wavelengths_));
22910447Snilay@cs.wisc.edu        return;
23010447Snilay@cs.wisc.edu    }
23110447Snilay@cs.wisc.edu
23210447Snilay@cs.wisc.edu    // Laser creation
23310447Snilay@cs.wisc.edu    void OpticalModel::createLaser(const String& name_, const WavelengthGroup& wavelengths_)
23410447Snilay@cs.wisc.edu    {
23510447Snilay@cs.wisc.edu        // Check that the laser hasn't been previously declared
23610447Snilay@cs.wisc.edu        ASSERT( !m_lasers_->keyExist(name_), "[Error] " + getInstanceName() +
23710447Snilay@cs.wisc.edu            " -> Redeclaration of laser " + name_);
23810447Snilay@cs.wisc.edu        m_lasers_->set(name_, new OpticalLaser(name_, this, wavelengths_));
23910447Snilay@cs.wisc.edu        return;
24010447Snilay@cs.wisc.edu    }
24110447Snilay@cs.wisc.edu
24210447Snilay@cs.wisc.edu    // Modulator creation
24310447Snilay@cs.wisc.edu    void OpticalModel::createModulator(const String& name_, const WavelengthGroup& wavelengths_, bool opt_loss_, OpticalTransmitter* transmitter_)
24410447Snilay@cs.wisc.edu    {
24510447Snilay@cs.wisc.edu        // Check that the modulator hasn't been previously declared
24610447Snilay@cs.wisc.edu        ASSERT( !m_modulators_->keyExist(name_), "[Error] " + getInstanceName() +
24710447Snilay@cs.wisc.edu            " -> Redeclaration of modulator " + name_);
24810447Snilay@cs.wisc.edu        m_modulators_->set(name_, new OpticalModulator(name_, this, wavelengths_, opt_loss_, transmitter_));
24910447Snilay@cs.wisc.edu        return;
25010447Snilay@cs.wisc.edu    }
25110447Snilay@cs.wisc.edu
25210447Snilay@cs.wisc.edu    // Modulator Multiplier creation
25310447Snilay@cs.wisc.edu    void OpticalModel::createFilter(const String& name_, const WavelengthGroup& wavelengths_, bool drop_all_, const WavelengthGroup& drop_wavelengths_)
25410447Snilay@cs.wisc.edu    {
25510447Snilay@cs.wisc.edu        // Check that the filter hasn't been previously declared
25610447Snilay@cs.wisc.edu        ASSERT( !m_filters_->keyExist(name_), "[Error] " + getInstanceName() +
25710447Snilay@cs.wisc.edu            " -> Redeclaration of filter " + name_);
25810447Snilay@cs.wisc.edu        m_filters_->set(name_, new OpticalFilter(name_, this, wavelengths_, drop_all_, drop_wavelengths_));
25910447Snilay@cs.wisc.edu        return;
26010447Snilay@cs.wisc.edu    }
26110447Snilay@cs.wisc.edu
26210447Snilay@cs.wisc.edu    // Detector creation
26310447Snilay@cs.wisc.edu    void OpticalModel::createDetector(const String& name_, const WavelengthGroup& wavelengths_, OpticalReceiver* receiver_)
26410447Snilay@cs.wisc.edu    {
26510447Snilay@cs.wisc.edu        // Check that the detector hasn't been previously declared
26610447Snilay@cs.wisc.edu        ASSERT( !m_detectors_->keyExist(name_), "[Error] " + getInstanceName() +
26710447Snilay@cs.wisc.edu            " -> Redeclaration of detector " + name_);
26810447Snilay@cs.wisc.edu        m_detectors_->set(name_, new OpticalDetector(name_, this, wavelengths_, receiver_));
26910447Snilay@cs.wisc.edu        return;
27010447Snilay@cs.wisc.edu    }
27110447Snilay@cs.wisc.edu
27210447Snilay@cs.wisc.edu    //-------------------------------------------------------------------------
27310447Snilay@cs.wisc.edu
27410447Snilay@cs.wisc.edu    // Assign a waveguide to be downstream from another waveguide
27510447Snilay@cs.wisc.edu    // assign downtream_waveguide_name_ = upstream_waveguide_name_
27610447Snilay@cs.wisc.edu    void OpticalModel::opticalAssign(const String& downstream_waveguide_name_, const String& upstream_waveguide_name_)
27710447Snilay@cs.wisc.edu    {
27810447Snilay@cs.wisc.edu        ASSERT(getWaveguides()->keyExist(downstream_waveguide_name_), "[Error] " + getInstanceName() + " -> Waveguide '" +
27910447Snilay@cs.wisc.edu            downstream_waveguide_name_ + "' does not exist!");
28010447Snilay@cs.wisc.edu
28110447Snilay@cs.wisc.edu        ASSERT(getWaveguides()->keyExist(upstream_waveguide_name_), "[Error] " + getInstanceName() + " -> Waveguide '" +
28210447Snilay@cs.wisc.edu            upstream_waveguide_name_ + "' does not exist!");
28310447Snilay@cs.wisc.edu
28410447Snilay@cs.wisc.edu        // Get the two waveguides
28510447Snilay@cs.wisc.edu        OpticalWaveguide* upstream_waveguide = getWaveguide(upstream_waveguide_name_);
28610447Snilay@cs.wisc.edu        OpticalWaveguide* downstream_waveguide = getWaveguide(downstream_waveguide_name_);
28710447Snilay@cs.wisc.edu
28810447Snilay@cs.wisc.edu        // Check that the two waveguides expect the same wavelengths
28910447Snilay@cs.wisc.edu        ASSERT((upstream_waveguide->getWavelengths().first == downstream_waveguide->getWavelengths().first) &&
29010447Snilay@cs.wisc.edu            (upstream_waveguide->getWavelengths().second == downstream_waveguide->getWavelengths().second),
29110447Snilay@cs.wisc.edu            "[Error] " + getInstanceName() + " -> Assignment expects different wavelengths for waveguide '" +
29210447Snilay@cs.wisc.edu                upstream_waveguide_name_ + "' and waveguide '" + downstream_waveguide_name_ + "'!");
29310447Snilay@cs.wisc.edu
29410447Snilay@cs.wisc.edu        // Connect the downstream waveguide and the upstream waveguide
29510447Snilay@cs.wisc.edu        upstream_waveguide->addDownstreamNode(downstream_waveguide);
29610447Snilay@cs.wisc.edu        return;
29710447Snilay@cs.wisc.edu    }
29810447Snilay@cs.wisc.edu} // namespace DSENT
299