From ff9b8bb838ecdfbfc1dc81038fcf3b2a87636982 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Zrounba?= <6691770+clement-z@users.noreply.github.com> Date: Sat, 30 Sep 2023 23:06:01 +0200 Subject: Initial release --- src/devices/octane_matrix.cpp | 365 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 365 insertions(+) create mode 100644 src/devices/octane_matrix.cpp (limited to 'src/devices/octane_matrix.cpp') diff --git a/src/devices/octane_matrix.cpp b/src/devices/octane_matrix.cpp new file mode 100644 index 0000000..d8126f3 --- /dev/null +++ b/src/devices/octane_matrix.cpp @@ -0,0 +1,365 @@ +#include + + +#define __modname(SUFFIX, IDX) \ + ((""s + this->name() + "_" + SUFFIX + to_string(IDX)).c_str()) + +#define __outname(SUFFIX, IDX, IDY) \ + ((""s + this->name() + "_" + SUFFIX + to_string(IDX) + "_" + to_string(IDY)).c_str()) + +using std::size_t; +using std::pow; + +void OctaneMatrix::init_ports() +{ + // --------------------------------------------------------------------------// + // --------------------------------------------------------------------------// + // Initializing input ports + // --------------------------------------------------------------------------// + // --------------------------------------------------------------------------// + + p_in_r.clear(); + p_in_c.clear(); + + // cout << "Initializing input ports of " << name() << endl; + + for(size_t i = 0; i < m_rows; i++) + p_in_r.push_back(make_unique(__modname("IN_R_", i))); + + for(size_t i = 0; i < m_columns; i++) + p_in_c.push_back(make_unique(__modname("IN_C_", i))); + + // --------------------------------------------------------------------------// + // --------------------------------------------------------------------------// + // Initializing output port matrix + // --------------------------------------------------------------------------// + // --------------------------------------------------------------------------// + + p_readout.clear(); // clearing before start + + // cout << "Initializing output ports of " << name() << endl; + + vector>> temp_vector; + + for(size_t i = 0; i < m_rows; i++) + { + temp_vector.clear(); // moving to new row + for(size_t j = 0; j < m_columns; j++) + { + temp_vector.push_back(make_unique>(__outname("PD_", i, j))); + } + p_readout.push_back(std::move(temp_vector)); // adding new row + } + + // cout << "Successful port initialization of " << name() << endl; + +} + +void OctaneMatrix::init() +{ + + double crossing_loss = 0; + + // --------------------------------------------------------------------------// + // --------------------------------------------------------------------------// + // Initializing circuit elements (waveguides, DCs, octanecell) + // --------------------------------------------------------------------------// + // --------------------------------------------------------------------------// + + m_optical_connect_horizontal.clear(); + m_optical_connect_vertical.clear(); + m_segment.clear(); + m_cross.clear(); + + // cout << "Initializing submodules of " << name() << endl; + + // Optical wires + unsigned long num_of_nets_horizontal = 3*m_rows*(m_columns-1); + unsigned long num_of_nets_vertical = (m_rows-1)*m_columns; + + for(unsigned long i = 0; i < num_of_nets_horizontal; i++) + m_optical_connect_horizontal.push_back(make_unique>(__modname("wh_", i))); + for(unsigned long i = 0; i < num_of_nets_vertical; i++) + m_optical_connect_vertical.push_back(make_unique>(__modname("wv_", i))); + + // Crossings + for(unsigned long i = 0; i < m_rows; i++) + { // Last column doesn't have crossings, thus the -1 in the loop + for(unsigned long j = 0; j < (m_columns - 1); j++) + { + m_cross.push_back(make_unique(__outname("X_", i, j), crossing_loss)); + } + } + + // Octane segments + bool term_row = false; + bool term_col = false; + double coupling_through_row = 0; + double coupling_through_col = 0; + + for(unsigned long i = 0; i < m_rows; i++) + { + for(unsigned long j = 0; j < m_columns; j++) + { + if(isLastRow(i) && isLastCol(j)) + { + // Last element + term_col = true; + term_row = true; + coupling_through_row = 0; + coupling_through_col = 0; + } + else if(isLastRow(i)) + { + // Term row + term_col = false; + term_row = true; + coupling_through_row = (1.0 - 1.0/(m_columns - j)); + coupling_through_col = 0; + } + else if(isLastCol(j)) + { + // Term col + term_col = true; + term_row = false; + coupling_through_row = 0; + coupling_through_col = (1.0 - 1.0/(m_rows - i)); + } + else + { + // Inner element + term_col = false; + term_row = false; + coupling_through_row = (1.0 - 1.0/(m_columns - j)); + coupling_through_col = (1.0 - 1.0/(m_rows - i)); + } + auto temp_segment = make_unique + ( + __outname("SEG_", i, j), + term_row, term_col, + coupling_through_row, coupling_through_col, + m_meltEnergy, m_nStates, m_isCompact + ); + temp_segment->init(); // mandatory initialization + m_segment.push_back(std::move(temp_segment)); + } + } + + // cout << "Successful module initialization of " << name() << endl; + + // Modules are constructed in their vectors, time to connect ! + connect_submodules(); + +} + +void OctaneMatrix::connect_submodules() +{ + + // cout << "Connecting submodules of " << name() << endl; + + // If there is only one element in the matrix + // the pins are connected directly + if((m_rows == 1) && (m_columns == 1)) + { + // cout << name() << "contains only one element. " << endl; + + m_segment.at(0)->p_in[0]->bind(*p_in_r.at(0)); + m_segment.at(0)->p_in[1]->bind(*p_in_c.at(0)); + m_segment.at(0)->p_readout->bind(*p_readout[0][0]); + + // cout << "Successful connection of " << name() << endl; + return; + } + + // Column vector + if(m_columns == 1) + { + // cout << name() << "contains only one column. " << endl; + + for(unsigned long i = 0; i < m_rows; i++) + { + // in segment, in row is p_in[0] + m_segment.at(i)->p_in[0]->bind(*p_in_r.at(i)); + + if(isFirstRow(i)) // should connect to the port + m_segment.at(i)->p_in[1]->bind(*p_in_c.at(0)); + else // connects to intermediate net which is output of the previous block + m_segment.at(i)->p_in[1]->bind(*m_optical_connect_vertical.at(i-1)); + + if(!isLastRow(i)) // there's only one output in vector segment + m_segment.at(i)->p_out[0]->bind(*m_optical_connect_vertical.at(i)); + + m_segment.at(i)->p_readout->bind(*p_readout[i][0]); + + } + // cout << "Successful connection of " << name() << endl; + return; + } + + // Row vector + if(m_rows == 1) + { + // cout << name() << "contains only one row. " << endl; + + for(unsigned long j = 0; j < m_columns; j++) + { + if(isFirstCol(j)) + { + // in segment, in row is p_in[0] + m_segment.at(j)->p_in[0]->bind(*p_in_r.at(0)); + m_segment.at(j)->p_in[1]->bind(*m_optical_connect_horizontal.at(3*j+1)); + m_segment.at(j)->p_out[0]->bind(*m_optical_connect_horizontal.at(3*j)); + + // in1, out1 are horizontal connections + m_cross.at(j)->p_in1.bind(*m_optical_connect_horizontal.at(3*j)); + m_cross.at(j)->p_in2.bind(*p_in_c.at(j)); + m_cross.at(j)->p_out1.bind(*m_optical_connect_horizontal.at(3*j+2)); + m_cross.at(j)->p_out2.bind(*m_optical_connect_horizontal.at(3*j+1)); + } + else if(!isLastCol(j)) + { // middle element + m_segment.at(j)->p_in[0]->bind(*m_optical_connect_horizontal.at(3*j-1)); + m_segment.at(j)->p_in[1]->bind(*m_optical_connect_horizontal.at(3*j+1)); + m_segment.at(j)->p_out[0]->bind(*m_optical_connect_horizontal.at(3*j)); + + // in1, out1 are horizontal connections + m_cross.at(j)->p_in1.bind(*m_optical_connect_horizontal.at(3*j)); + m_cross.at(j)->p_in2.bind(*p_in_c.at(j)); + m_cross.at(j)->p_out1.bind(*m_optical_connect_horizontal.at(3*j+2)); + m_cross.at(j)->p_out2.bind(*m_optical_connect_horizontal.at(3*j+1)); + } + else + { // last column here + m_segment.at(j)->p_in[0]->bind(*m_optical_connect_horizontal.at(3*j-1)); + m_segment.at(j)->p_in[1]->bind(*p_in_c.at(j)); + } + m_segment.at(j)->p_readout->bind(*p_readout[0][j]); + } + // cout << "Successful connection of " << name() << endl; + return; + } + + // Getting here means it's an actual matrix with more than one element + unsigned long cur_pos; + unsigned long cur_cross; + unsigned long seg_out_h; + unsigned long seg_out_v; + for(unsigned long i = 0; i < m_rows; i++) + { + for(unsigned long j = 0; j < m_columns; j++) + { + cur_pos = m_columns*i + j; + cur_cross = (m_columns-1)*i + j; + seg_out_h = 3*(m_columns-1)*i+3*j; + seg_out_v = m_columns*i+j; + // cout << "cur_pos: " << cur_pos << endl; + // cout << "cur_cross: " << cur_cross << endl; + // cout << "out_h: " << seg_out_h << endl; + // cout << "out_v: " << seg_out_v << endl; + + if(isFirstRow(i) && isFirstCol(j)) + { + // cout << "first element" << endl; + m_segment.at(cur_pos)->p_in[0]->bind(*p_in_r.at(i)); + m_segment.at(cur_pos)->p_in[1]->bind(*m_optical_connect_horizontal.at(seg_out_h+1)); + m_segment.at(cur_pos)->p_out[0]->bind(*m_optical_connect_horizontal.at(seg_out_h)); + m_segment.at(cur_pos)->p_out[1]->bind(*m_optical_connect_vertical.at(seg_out_v)); + + m_cross.at(cur_cross)->p_in1.bind(*m_optical_connect_horizontal.at(seg_out_h)); + m_cross.at(cur_cross)->p_in2.bind(*p_in_c.at(j)); + m_cross.at(cur_cross)->p_out1.bind(*m_optical_connect_horizontal.at(seg_out_h+2)); + m_cross.at(cur_cross)->p_out2.bind(*m_optical_connect_horizontal.at(seg_out_h+1)); + } + else if(isFirstRow(i) && !isLastCol(j)) + { + // cout << "first row not last col" << endl; + m_segment.at(cur_pos)->p_in[0]->bind(*m_optical_connect_horizontal.at(seg_out_h-1)); + m_segment.at(cur_pos)->p_in[1]->bind(*m_optical_connect_horizontal.at(seg_out_h+1)); + m_segment.at(cur_pos)->p_out[0]->bind(*m_optical_connect_horizontal.at(seg_out_h)); + m_segment.at(cur_pos)->p_out[1]->bind(*m_optical_connect_vertical.at(seg_out_v)); + + m_cross.at(cur_cross)->p_in1.bind(*m_optical_connect_horizontal.at(seg_out_h)); + m_cross.at(cur_cross)->p_in2.bind(*p_in_c.at(j)); + m_cross.at(cur_cross)->p_out1.bind(*m_optical_connect_horizontal.at(seg_out_h+2)); + m_cross.at(cur_cross)->p_out2.bind(*m_optical_connect_horizontal.at(seg_out_h+1)); + } + else if(isFirstRow(i) && isLastCol(j)) + { + // cout << "first row last col" << endl; + m_segment.at(cur_pos)->p_in[0]->bind(*m_optical_connect_horizontal.at(seg_out_h-1)); + m_segment.at(cur_pos)->p_in[1]->bind(*p_in_c.at(j)); + // no row output + m_segment.at(cur_pos)->p_out[0]->bind(*m_optical_connect_vertical.at(seg_out_v)); + } + else if(!isFirstRow(i) && !isLastRow(i) && isFirstCol(j)) + { + // cout << "middle row first col" << endl; + m_segment.at(cur_pos)->p_in[0]->bind(*p_in_r.at(i)); + m_segment.at(cur_pos)->p_in[1]->bind(*m_optical_connect_horizontal.at(seg_out_h+1)); + m_segment.at(cur_pos)->p_out[0]->bind(*m_optical_connect_horizontal.at(seg_out_h)); + m_segment.at(cur_pos)->p_out[1]->bind(*m_optical_connect_vertical.at(seg_out_v)); + + m_cross.at(cur_cross)->p_in1.bind(*m_optical_connect_horizontal.at(seg_out_h)); + m_cross.at(cur_cross)->p_in2.bind(*m_optical_connect_vertical.at(seg_out_v-m_columns)); + m_cross.at(cur_cross)->p_out1.bind(*m_optical_connect_horizontal.at(seg_out_h+2)); + m_cross.at(cur_cross)->p_out2.bind(*m_optical_connect_horizontal.at(seg_out_h+1)); + } + else if(!isFirstRow(i) && !isLastRow(i) && !isLastCol(j)) + { + // cout << "middle row middle col" << endl; + m_segment.at(cur_pos)->p_in[0]->bind(*m_optical_connect_horizontal.at(seg_out_h-1)); + m_segment.at(cur_pos)->p_in[1]->bind(*m_optical_connect_horizontal.at(seg_out_h+1)); + m_segment.at(cur_pos)->p_out[0]->bind(*m_optical_connect_horizontal.at(seg_out_h)); + m_segment.at(cur_pos)->p_out[1]->bind(*m_optical_connect_vertical.at(seg_out_v)); + + m_cross.at(cur_cross)->p_in1.bind(*m_optical_connect_horizontal.at(seg_out_h)); + m_cross.at(cur_cross)->p_in2.bind(*m_optical_connect_vertical.at(seg_out_v-m_columns)); + m_cross.at(cur_cross)->p_out1.bind(*m_optical_connect_horizontal.at(seg_out_h+2)); + m_cross.at(cur_cross)->p_out2.bind(*m_optical_connect_horizontal.at(seg_out_h+1)); + } + else if(!isFirstRow(i) && !isLastRow(i) && isLastCol(j)) + { + // cout << "middle row last col" << endl; + m_segment.at(cur_pos)->p_in[0]->bind(*m_optical_connect_horizontal.at(seg_out_h-1)); + m_segment.at(cur_pos)->p_in[1]->bind(*m_optical_connect_vertical.at(seg_out_v-m_columns)); + // no row output + m_segment.at(cur_pos)->p_out[0]->bind(*m_optical_connect_vertical.at(seg_out_v)); + } + else if(isLastRow(i) && isFirstCol(j)) + { + // cout << "last row first col" << endl; + m_segment.at(cur_pos)->p_in[0]->bind(*p_in_r.at(i)); + m_segment.at(cur_pos)->p_in[1]->bind(*m_optical_connect_horizontal.at(seg_out_h+1)); + m_segment.at(cur_pos)->p_out[0]->bind(*m_optical_connect_horizontal.at(seg_out_h)); + + m_cross.at(cur_cross)->p_in1.bind(*m_optical_connect_horizontal.at(seg_out_h)); + m_cross.at(cur_cross)->p_in2.bind(*m_optical_connect_vertical.at(seg_out_v-m_columns)); + m_cross.at(cur_cross)->p_out1.bind(*m_optical_connect_horizontal.at(seg_out_h+2)); + m_cross.at(cur_cross)->p_out2.bind(*m_optical_connect_horizontal.at(seg_out_h+1)); + } + else if(isLastRow(i) && !isLastCol(j)) + { + // cout << "last row middle col" << endl; + m_segment.at(cur_pos)->p_in[0]->bind(*m_optical_connect_horizontal.at(seg_out_h-1)); + m_segment.at(cur_pos)->p_in[1]->bind(*m_optical_connect_horizontal.at(seg_out_h+1)); + m_segment.at(cur_pos)->p_out[0]->bind(*m_optical_connect_horizontal.at(seg_out_h)); + + m_cross.at(cur_cross)->p_in1.bind(*m_optical_connect_horizontal.at(seg_out_h)); + m_cross.at(cur_cross)->p_in2.bind(*m_optical_connect_vertical.at(seg_out_v-m_columns)); + m_cross.at(cur_cross)->p_out1.bind(*m_optical_connect_horizontal.at(seg_out_h+2)); + m_cross.at(cur_cross)->p_out2.bind(*m_optical_connect_horizontal.at(seg_out_h+1)); + } + else if(isLastRow(i) && isLastCol(j)) + { + // cout << "last row last col" << endl; + m_segment.at(cur_pos)->p_in[0]->bind(*m_optical_connect_horizontal.at(seg_out_h-1)); + m_segment.at(cur_pos)->p_in[1]->bind(*m_optical_connect_vertical.at(seg_out_v-m_columns)); + } + else + cout<< endl << endl << "This condition should not appear" << endl << endl; + + m_segment.at(cur_pos)->p_readout->bind(*p_readout[i][j]); + + } + } +} \ No newline at end of file -- cgit v1.2.3