diff --git a/.vscode/settings.json b/.vscode/settings.json index cc134d0ef702c058524988399a29a66bbe4794c1..ea261910acfff66be95c82ae8f2774a2a524009d 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,5 +1,53 @@ { "files.associations": { - "cstdlib": "c" + "cstdlib": "c", + "array": "cpp", + "atomic": "cpp", + "bit": "cpp", + "*.tcc": "cpp", + "cctype": "cpp", + "clocale": "cpp", + "cmath": "cpp", + "compare": "cpp", + "complex": "cpp", + "concepts": "cpp", + "cstdarg": "cpp", + "cstddef": "cpp", + "cstdint": "cpp", + "cstdio": "cpp", + "ctime": "cpp", + "cwchar": "cpp", + "cwctype": "cpp", + "deque": "cpp", + "unordered_map": "cpp", + "vector": "cpp", + "exception": "cpp", + "algorithm": "cpp", + "functional": "cpp", + "iterator": "cpp", + "memory": "cpp", + "memory_resource": "cpp", + "numeric": "cpp", + "optional": "cpp", + "random": "cpp", + "string": "cpp", + "string_view": "cpp", + "system_error": "cpp", + "tuple": "cpp", + "type_traits": "cpp", + "utility": "cpp", + "fstream": "cpp", + "initializer_list": "cpp", + "iosfwd": "cpp", + "iostream": "cpp", + "istream": "cpp", + "limits": "cpp", + "new": "cpp", + "ostream": "cpp", + "ranges": "cpp", + "sstream": "cpp", + "stdexcept": "cpp", + "streambuf": "cpp", + "typeinfo": "cpp" } } \ No newline at end of file diff --git a/finegrain/LICENSE b/finegrain/LICENSE new file mode 100644 index 0000000000000000000000000000000000000000..aefe5f34183901be1731db190622afe025449374 --- /dev/null +++ b/finegrain/LICENSE @@ -0,0 +1,23 @@ +MIT License + +Copyright (c) 2019-2021, University of Southampton and Contributors. +All rights reserved. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice (including the +next paragraph) shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/finegrain/find_max.cpp b/finegrain/find_max.cpp index 4e0c882d7acce8cf5c5e697bf2dae2ba96a36c0e..23a48a18bf5ad122f3e2e95e737adfbc9883287a 100644 --- a/finegrain/find_max.cpp +++ b/finegrain/find_max.cpp @@ -1,33 +1,39 @@ +/* + * Copyright (c) 2019-2021, University of Southampton and Contributors. + * All rights reserved. + * + * SPDX-License-Identifier: MIT + */ + + /* Adapted from msp_hiber.c */ +#include "msp_hiber.h" -#include "msp_hiber.h" +double msp_hiber(double cap, double cell_area) { + double v; // Vc + double g; // irradiance + double c = cap; // Capacitance -double msp_hiber(double cap, double cell_area) -{ - double v; // Vc - double g; // irradiance - double c = cap; // Capacitance - - double t; // simulation time - double t_temp; // next timing of ir change + double t; // simulation time + double t_temp; // next timing of ir change // double tHR; // time overheads of hibernate/restore operations double time_on; - double time_step; // simulation time step - double time_MO; // time in MIDDLE or OVER - double time_int; // each interruption period + double time_step; // simulation time step + double time_MO; // time in MIDDLE or OVER + double time_int; // each interruption period // power/current flow, comment either p or i - // double p_in; // power input + // double p_in; // power input // double p_out; // power output // double p_leak; // 6.48 * c * 0.01, 6.48 = 0.5 * 3.6 * 3.6 double i_in; // current input double i_out; // current output double i_leak; - double forward_progress; // a measurement of forward progress - + double forward_progress; // a measurement of forward progress + int op; // operating point - int state_saved = 0; // is a state saved? + int state_saved = 0; // is a state saved? // int i; // c is calculated in i loop // int c_min; // int c_max; @@ -42,31 +48,31 @@ double msp_hiber(double cap, double cell_area) clock_t end; // ------ File Control variables ------ - char line[MAX_CHARACTER_PER_LINE]; - char* delete_ptr; - char delims[] = ","; - FILE* fp_i = NULL; - FILE* fp_o = NULL; - // FILE* fp_v = NULL; - // FILE* fp_ph = NULL; // file for recording sys Perf and Hibernation per min - FILE* fp_interrupt_periods = NULL; // file for recording interruption periods - - if ((fp_i = fopen("2018denver.txt", "r")) == NULL){ + char line[MAX_CHARACTER_PER_LINE]; + char* delete_ptr; + char delims[] = ","; + FILE* fp_i = NULL; + FILE* fp_o = NULL; + // FILE* fp_v = NULL; + // FILE* fp_ph = NULL; // file for recording sys Perf and Hibernation per min + FILE* fp_interrupt_periods = NULL; // file for recording interruption periods + + if ((fp_i = fopen("2018denver.txt", "r")) == NULL) { printf("Failed to read file.\n"); return 1; } - if ((fp_o = fopen("output.csv","a")) == NULL){ + if ((fp_o = fopen("output.csv", "a")) == NULL) { printf("Failed to write file.\n"); return 1; } - if ((fp_interrupt_periods = fopen("interruption.csv","w")) == NULL){ // not used for now + if ((fp_interrupt_periods = fopen("interruption.csv", "w")) == NULL){ // not used for now printf("Failed to write file.\n"); return 1; } op = 0; state_saved = 0; - v = 0.0; // initial Vc + v = 0.0; // initial Vc t = 0.0; t_temp = 0.0; // comment either p or i @@ -76,13 +82,13 @@ double msp_hiber(double cap, double cell_area) i_out = 0.0; // i_leak = 0.01 * c * 10.0; // rated voltage: 10.0V // if (i_leak < 4e-6) i_leak = 4e-6; - i_leak = capCurrentLeak(c, (V_R + V_S) / 2) ; + i_leak = capCurrentLeak(c, (V_R + V_S) / 2); time_step = adaptiveTimeStep(c, i_leak, cell_area); - + // init measurements time_on = 0.0; time_MO = 0.0; - time_int = 0.0; + time_int = 0.0; forward_progress = 0.0; n_hiber = 0; // n_hiber_last = 0; @@ -91,24 +97,24 @@ double msp_hiber(double cap, double cell_area) rewind(fp_i); begin = clock(); - + // read data while (fgets(line, MAX_CHARACTER_PER_LINE, fp_i)) { - t_temp += 60.0; // defined by the time resolution of data + t_temp += 60.0; // defined by the time resolution of data delete_ptr = strtok(line, delims); delete_ptr = strtok(NULL, delims); - g = atof(strtok(NULL, delims)); // read irradiance + g = atof(strtok(NULL, delims)); // read irradiance // g = 1000.0; // define a constant irradiance - if (g < 0.0) g = 0.0; // filter negative data + if (g < 0.0) g = 0.0; // filter negative data // here, the data is solar irradiance, this should be converted by PV model - + while (t < t_temp) { i_in = pvCellCurrent(g, v, cell_area); /* ------ Hibernus Model (On/Off) ------ */ /* Could make this part to a function later */ - if (op == 0){ + if (op == 0) { // when off, restore if (v >= V_R) { op = 1; @@ -119,14 +125,13 @@ double msp_hiber(double cap, double cell_area) time_int += T_RESTORE; } // else {} // no overhead - + fprintf(fp_interrupt_periods, "%lf \n", time_int); time_int = 0.0; - // forward_progress -= perf[op] / APP_CYCLE * T_RESTORE; // 1.35ms time overheads + // forward_progress -= perf[op] / APP_CYCLE * T_RESTORE; // 1.35ms time overheads continue; } - } - else { + } else { // when on, hibernate if (v <= V_S) { op = 0; @@ -141,52 +146,52 @@ double msp_hiber(double cap, double cell_area) time_on += time_step; } - if (v > V_OFF) { if (op == 0) { i_out = I_SLEEP; time_int += time_step; - } - else { + } else { i_out = I_EXE; forward_progress += time_step; } - } - else { + } else { state_saved = 0; i_out = 0.0; time_int += time_step; - } + } v = capacitor(c, v, time_step, i_in, i_out, i_leak, 'i'); if (i_in > i_leak) time_MO += time_step; t += time_step; - } // t reaches t_temp - } // End of loop for reading all data + } // t reaches t_temp + } // End of loop for reading all data forward_progress = forward_progress / t; /* Output */ // fprintf(fp_o, "%lf, %lf, %d, ", I_SC / nParal, I_M / nParal, nParal); - fprintf(fp_o, "%e, %lf, %lld, %.3lf, %.3lf, %.3lf, %.3lf\n", c, forward_progress, n_hiber, n_hiber / t, n_hiber / time_MO, time_on / t, time_MO / t); + fprintf(fp_o, "%e, %lf, %lld, %.3lf, %.3lf, %.3lf, %.3lf\n", + c, forward_progress, n_hiber, + n_hiber / t, n_hiber / time_MO, + time_on / t, time_MO / t); // printf("%lf, %lf, %d, ", I_SC / nParal, I_M / nParal, nParal); printf("%e, %lf, %lld\n", c, forward_progress, n_hiber); end = clock(); double time_spent = (double) (end - begin) / CLOCKS_PER_SEC; - printf ("msp_hiber() time spent: %lf, simulated with time step: %lf\n", time_spent, time_step); + printf("msp_hiber() time spent: %lf, simulated with time step: %lf\n", + time_spent, time_step); fclose(fp_i); fclose(fp_o); // fclose(fp_v); // fclose(fp_ph); - fclose(fp_interrupt_periods); - - return forward_progress; + fclose(fp_interrupt_periods); + + return forward_progress; } -double adaptiveTimeStep(double cap, double ileak, double cell_area) -{ +double adaptiveTimeStep(double cap, double ileak, double cell_area) { double timestep; double tcharge; double tdischarge; @@ -194,49 +199,37 @@ double adaptiveTimeStep(double cap, double ileak, double cell_area) tcharge = cap * (V_R - V_S) / (I_MPP_MM2 * cell_area - ileak); tdischarge = cap * (V_R - V_S) / (I_EXE + ileak); - if (tcharge <= tdischarge) timestep = tcharge; - else timestep = tdischarge; + if (tcharge <= tdischarge) + timestep = tcharge; + else + timestep = tdischarge; timestep /= 10.0; return timestep; } -// double pvCellCurrent(double g, double v, double voc, double vm, double isc, double im, int number_series, int number_parallel){ -// double Voc = voc * number_series; // V -// double Isc = isc * number_parallel; // A -// double Vm = vm * number_series; // Vmpp -// double Im = im * number_parallel; // Impp -// double Gpu; // Gpu = G / 1000 -// double i; - -// Gpu = g / G_REF; - -// if (v > Voc) i = 0; -// else i = Gpu * Isc * (1 - exp(log(1 - Im / Isc) * (v - Voc) / (Vm - Voc))); - -// return i; -// } -double pvCellCurrent(double g, double v, double cell_area) -{ - if (v < 0){ +double pvCellCurrent(double g, double v, double cell_area) { + if (v < 0) { printf("PV cell voltage < 0! Abnormal. \n"); return EXIT_FAILURE; } - double Voc = V_OC_CELL * N_S; // V - double Isc = I_SC_MM2 * cell_area; // - double Vmpp = V_MPP_CELL * N_S; // Vmpp - double Impp = I_MPP_MM2 * cell_area; // Impp - double Gpu; // percentage irradiance - double i; + double Voc = V_OC_CELL * N_S; // V + double Isc = I_SC_MM2 * cell_area; + double Vmpp = V_MPP_CELL * N_S; // Vmpp + double Impp = I_MPP_MM2 * cell_area; // Impp + double Gpu; // percentage irradiance + double i; if (g < 0) g = 0; Gpu = g / G_REF; - if (v > Voc) i = 0; - else i = Gpu * Isc * (1 - exp(log(1 - Impp / Isc) * (v - Voc) / (Vmpp - Voc))); + if (v > Voc) + i = 0; + else + i = Gpu * Isc * (1 - exp(log(1 - Impp / Isc) * + (v - Voc) / (Vmpp - Voc))); return i; } -double capCurrentLeak(double cap, double v) -{ +double capCurrentLeak(double cap, double v) { double i_leak; // Aluminium @@ -245,30 +238,31 @@ double capCurrentLeak(double cap, double v) // Tantalum AVX TAJ double v_ratio = v / V_RATED_CAP; - double i_leak_ratio = I_LEAK_RATIO_START * pow(1 / I_LEAK_RATIO_START, v_ratio); + double i_leak_ratio = I_LEAK_RATIO_START * + pow(1 / I_LEAK_RATIO_START, v_ratio); i_leak = K_CAP_LEAK * cap * V_RATED_CAP * i_leak_ratio; - return i_leak; } -double capacitor(double capacitance, double voltage, double time, double inFlow, double outFlow, double leakFlow, char mode) -{ +double capacitor(double capacitance, double voltage, double time, + double inFlow, double outFlow, double leakFlow, char mode) { switch (mode) { - case 'p': // use power flow - if (2 / capacitance * (inFlow - outFlow - leakFlow) * time + voltage * voltage < 0.0) + case 'p': // use power flow + if (2 / capacitance * (inFlow - outFlow - leakFlow) * time + voltage * voltage < 0.0) voltage = 0.0; - else voltage = sqrt(2 / capacitance * (inFlow - outFlow - leakFlow) * time + voltage * voltage); + else + voltage = sqrt(2 / capacitance * (inFlow - outFlow - leakFlow) * time + voltage * voltage); return voltage; break; - case 'i': // use current flow + case 'i': // use current flow voltage = (inFlow - outFlow - leakFlow) * time / capacitance + voltage; if (voltage < 0.0) voltage = 0.0; return voltage; break; - + default: printf("Error: please select an operating mode for PV modules using 'p' or 'i'.\n"); exit(1); @@ -287,39 +281,35 @@ double capacitor(double capacitance, double voltage, double time, double inFlow, #include <fstream> #include <string> -void swap(double& a, double& b) -{ +void swap(double& a, double& b) { double tmp = a; a = b; b = tmp; } -void swap_cnt(int& a, int& b) -{ +void swap_cnt(int& a, int& b) { int tmp = a; a = b; b = tmp; } -void quickSort(std::vector<double>& nums, int l, int r, std::vector<int>& cnt) -{ - if(l >= r) return; - int i = l; // cursor for final pivot location - for(int j = l; j <= r - 1; j++){ // nums[r] is chosen as the pivot - if(nums[j] <= nums[r]){ +void quickSort(std::vector<double>& nums, int l, int r, std::vector<int>& cnt) { + if (l >= r) return; + int i = l; // cursor for final pivot location + for (int j = l; j <= r - 1; j++) { // nums[r] is chosen as the pivot + if (nums[j] <= nums[r]) { swap(nums[i], nums[j]); swap_cnt(cnt[i], cnt[j]); - i++; // smaller or equal elements go to the left of i + i++; // smaller or equal elements go to the left of i } } - swap(nums[i], nums[r]); // after swap, the pivot is nums[i] + swap(nums[i], nums[r]); // after swap, the pivot is nums[i] swap_cnt(cnt[i], cnt[r]); quickSort(nums, l, i - 1, cnt); quickSort(nums, i + 1, r, cnt); } -double quicksort_adapted() -{ +double quicksort_adapted() { std::ifstream inFile; inFile.open("interruption.csv"); // inFile.open("test.csv"); @@ -344,8 +334,7 @@ double quicksort_adapted() if (!inFile.is_open()) { std::cout << "Unable to open inFile.\n"; return 1; - } - else { + } else { while (getline(inFile, line)) { // outFile << line << std::endl; temp = std::stod(line, NULL); @@ -354,8 +343,7 @@ double quicksort_adapted() if (it == value.end()) { value.push_back(temp); count.push_back(1); - } - else { + } else { count[std::distance(value.begin(), it)]++; } line_cnt++; @@ -385,7 +373,7 @@ double quicksort_adapted() } outFile2 << i << ", " << value[cnt_index - 1] << std::endl; - if (i == 90) return_value = value[cnt_index - 1]; // take the 90th percentile + if (i == 90) return_value = value[cnt_index - 1]; // take the 90th percentile } end = clock(); @@ -406,18 +394,15 @@ double quicksort_adapted() #define K2 200.0 #define K3 0.5 -double cost_function(double fwpg, double volume, double interruption) -{ - return static_cast<double> (fwpg / K1 - pow(volume / K2, 2) - pow(interruption / K3, 2)); +double cost_function(double fwpg, double volume, double interruption) { + return static_cast<double> (fwpg / K1 - pow(volume / K2, 2) - pow(interruption / K3, 2)); } -double cap_volume(double cap) -{ +double cap_volume(double cap) { return (double) 2.172 * pow(cap * 1e6, 0.685); } -double routine(double cap, double cell_area) -{ +double routine(double cap, double cell_area) { std::cout << "\nStart simulating with " << cap << " uF...\n"; std::cout << "msp_hiber() starts...\n"; @@ -434,11 +419,11 @@ double routine(double cap, double cell_area) // double cost = cost_function(fwpg, vol, interrupt); double cost = fwpg; - std::cout << "fwpg state: cap = " + std::cout << "fwpg state: cap = " << cap << " fwpg = " - << cost << " \n"; + << cost << " \n"; - // std::cout << "Tradeoff state: " + // std::cout << "Tradeoff state: " // << cap << " " // << cost << " " // << fwpg << " " @@ -456,11 +441,10 @@ double routine(double cap, double cell_area) return cost; } -#define F 0.38196601125010515179541316563436 // 1 - 0.618... +#define F 0.38196601125010515179541316563436 // 1 - 0.618... -int main () -{ - double cell_area = 20; // by default +int main() { + double cell_area = 20; // by default printf("Please enter the cell area you want to test in mm^2 (Total PV panel area = %d * cell_area): ", N_S); scanf("%lf", &cell_area); std::cout << "cell_area: " << cell_area << " panel area: " << cell_area * N_S << std::endl; @@ -488,7 +472,7 @@ int main () std::cout << "Simulating capM1: " << capM1 << "uF...\n"; costM1 = routine(capM1, cell_area); - capM2 = capR - F * (capR - capL); + capM2 = capR - F * (capR - capL); std::cout << "Simulating capM2: " << capM2 << "uF...\n"; costM2 = routine(capM2, cell_area); std::cout << "Tested Capacitance (uF): " << capL << " " << capM1 << " " << capM2 << " " << capR << std::endl; @@ -496,17 +480,16 @@ int main () if (costM1 < costM2) { costL = costM1; capL = capM1; - } - else { // costM1 >= costM2 + } else { // costM1 >= costM2 costR = costM2; capR = capM2; } } - + while (capR - capL > 1e-6) { cnt++; std::cout << "================ Round " << cnt << " ================\n"; - + if (costM1 < costM2) { capM1 = capM2; costM1 = costM2; @@ -514,8 +497,7 @@ int main () capM2 = capR - F * (capR - capL); std::cout << "Simulating capM2: " << capM2 << "uF...\n"; costM2 = routine(capM2, cell_area); - } - else { // costM1 >= costM2 + } else { // costM1 >= costM2 capM2 = capM1; costM2 = costM1; @@ -526,41 +508,34 @@ int main () std::cout << "Tested Capacitance (uF): " << capL << " " << capM1 << " " << capM2 << " " << capR << std::endl; std::cout << "Cost: " << costL << " " << costM1 << " " << costM2 << " " << costR << std::endl; - + if (costM1 < costM2) { costL = costM1; capL = capM1; - } - else { // costM1 >= costM2 + } else { // costM1 >= costM2 costR = costM2; capR = capM2; } } if (costL > costR) { - if (costM1 > costL) { // costM2 == costR + if (costM1 > costL) { // costM2 == costR std::cout << "Best cap is: " << capM1 << " uF.\n"; - } - else if (costM2 > costL) { // costM1 == costL + } else if (costM2 > costL) { // costM1 == costL std::cout << "Best cap is: " << capM2 << " uF.\n"; - } - else { + } else { std::cout << "Best cap is: " << capL << " uF.\n"; } - - } - else { - if (costM2 > costR) { // costM1 = costL + } else { + if (costM2 > costR) { // costM1 = costL std::cout << "Best cap is: " << capM2 << " uF.\n"; - } - else if (costM1 > costR) { // costM2 = costR + } else if (costM1 > costR) { // costM2 = costR std::cout << "Best cap is: " << capM1 << " uF.\n"; - } - else { + } else { std::cout << "Best cap is: " << capR << " uF.\n"; } } return 0; -} \ No newline at end of file +} diff --git a/finegrain/msp_hiber.c b/finegrain/msp_hiber.c index 3da08378939efde35dfdc8f9ab8ff147881c26fd..0b7c470f3e372bcb890e0b75f937d6cb3c0e384e 100644 --- a/finegrain/msp_hiber.c +++ b/finegrain/msp_hiber.c @@ -1,45 +1,49 @@ /* + * Copyright (c) 2019-2021, University of Southampton and Contributors. + * All rights reserved. + * + * SPDX-License-Identifier: MIT + */ -*/ #include "msp_hiber.h" /* ------------------ Main ------------------ */ -int main (int argv, char** argc){ - double v; // Vc - double g; // irradiance - double c; // Capacitance - - double t; // simulation time - double t_temp; // next timing of ir change +int main(int argv, char** argc) { + double v; // Vc + double g; // irradiance + double c; // Capacitance + + double t; // simulation time + double t_temp; // next timing of ir change // double tHR; // time overheads of hibernate/restore operations double time_on; - double time_step; // simulation time step - double time_MO; // time in MIDDLE or OVER - double time_int; // each interruption period + double time_step; // simulation time step + double time_MO; // time in MIDDLE or OVER + double time_int; // each interruption period // power/current flow, comment either p or i - // double p_in; // power input + // double p_in; // power input // double p_out; // power output - // double p_leak; // 6.48 * c * 0.01, 6.48 = 0.5 * 3.6 * 3.6 + // double p_leak; // 6.48 * c * 0.01, 6.48 = 0.5 * 3.6 * 3.6 double i_in; // current input double i_out; // current output double i_leak; - double forward_progress; // a measurement of forward progress - + double forward_progress; // a measurement of forward progress + int op; // operating point - int state_saved = 0; // is a state saved? + int state_saved = 0; // is a state saved? // int nParal; // number of parallel cells, indicating size of PV module // nParal = nParallel; - int single_multiple = -1; // 0 single, 1 multiple, -1 N/A (default) - int i; // c is calculated in i loop + int single_multiple = -1; // 0 single, 1 multiple, -1 N/A (default) + int i; // c is calculated in i loop int c_min; int c_max; int c_step; // ------ Measurement variables ------ - long long int n_hiber; + long long int n_hiber; // int n_hiber_last; int thrp; int thrp_last; @@ -47,24 +51,24 @@ int main (int argv, char** argc){ clock_t end; // ------ File Control variables ------ - char line[MAX_CHARACTER_PER_LINE]; - char *delete; - char delims[] = ","; - FILE* fp_i = NULL; - FILE* fp_o = NULL; - // FILE* fp_v = NULL; - // FILE* fp_ph = NULL; // file for recording sys Perf and Hibernation per min - FILE* fp_interrupt_periods = NULL; // file for recording interruption periods - - if (argv != 3){ + char line[MAX_CHARACTER_PER_LINE]; + char *delete; + char delims[] = ","; + FILE* fp_i = NULL; + FILE* fp_o = NULL; + // FILE* fp_v = NULL; + // FILE* fp_ph = NULL; // recording sys Perf and Hibernation per min + FILE* fp_interrupt_periods = NULL; // recording interruption periods + + if (argv != 3) { printf("Invalid number of variables (data filename s/m).\n"); return 1; } - if ((fp_i = fopen(argc[1], "r")) == NULL){ + if ((fp_i = fopen(argc[1], "r")) == NULL) { printf("Failed to read file.\n"); return 1; } - if ((fp_o = fopen("CvsPerf_daymsp.csv","w")) == NULL){ + if ((fp_o = fopen("CvsPerf_daymsp.csv", "w")) == NULL) { printf("Failed to write file.\n"); return 1; } @@ -72,61 +76,59 @@ int main (int argv, char** argc){ // printf("Failed to write file.\n"); // return 1; // } - // if ((fp_ph = fopen("msp_PerfHiber_1m.csv","w")) == NULL){ // not used for now + // if ((fp_ph = fopen("msp_PerfHiber_1m.csv","w")) == NULL) { // not used for now // printf("Failed to write file.\n"); // return 1; // } - if ((fp_interrupt_periods = fopen("interruption.csv","w")) == NULL){ // not used for now + if ((fp_interrupt_periods = fopen("interruption.csv", "w")) == NULL) { // not used for now printf("Failed to write file.\n"); return 1; } - if (strcmp(argc[2], "s") == 0){ + if (strcmp(argc[2], "s") == 0) { single_multiple = 0; printf("Please enter the capcitance (uF): \n"); scanf("%d", &c_min); c_max = c_min; c_step = 1; - } - else if (strcmp(argc[2], "m") == 0){ + } else if (strcmp(argc[2], "m") == 0) { single_multiple = 1; printf("Please enter c_min c_max c_step: \n"); scanf("%d %d %d", &c_min, &c_max, &c_step); - } - else{ + } else { printf("Invalid input, should be s/m (single/multiple)\n"); return 1; } - double cell_area = 20; // 20 mm2 by default + double cell_area = 20; // 20 mm2 by default printf("Please enter the cell area you want to test in mm^2 (Total PV panel area = %d * cell_area): ", N_S); scanf("%lf", &cell_area); - - for (i = c_min; i <= c_max; i += c_step){ - // for (nParal = 90; nParal >= 50; nParal -= 10){ + + for (i = c_min; i <= c_max; i += c_step) { + // for (nParal = 90; nParal >= 50; nParal -= 10) { // double cell_area = 20; // ------ Initialization of simulation ------ - c = i / 1000000.0; // c = i uF + c = i / 1000000.0; // c = i uF // c = 6.2e-6; op = 0; state_saved = 0; - v = 0.0; // initial Vc - t = 0.0; - t_temp = 0.0; + v = 0.0; // initial Vc + t = 0.0; + t_temp = 0.0; // comment either p or i - // p_in = 0.0; - // p_out = 0.0; + // p_in = 0.0; + // p_out = 0.0; i_in = 0.0; i_out = 0.0; // i_leak = 0.01 * c * 10.0; // rated voltage: 10.0V // if (i_leak < 4e-6) i_leak = 4e-6; - i_leak = capCurrentLeak(c, (V_R + V_S) / 2) ; + i_leak = capCurrentLeak(c, (V_R + V_S) / 2); time_step = adaptiveTimeStep(c, i_leak, cell_area); - + // init measurements time_on = 0.0; time_MO = 0.0; - time_int = 0.0; + time_int = 0.0; forward_progress = 0.0; n_hiber = 0; // n_hiber_last = 0; @@ -135,27 +137,25 @@ int main (int argv, char** argc){ rewind(fp_i); begin = clock(); - - // read data - while (fgets(line, MAX_CHARACTER_PER_LINE, fp_i)){ - t_temp += 60.0; // defined by the time resolution of data + // read data + while (fgets(line, MAX_CHARACTER_PER_LINE, fp_i)) { + t_temp += 60.0; // defined by the time resolution of data delete = strtok(line, delims); delete = strtok(NULL, delims); - g = atof(strtok(NULL, delims)); // read irradiance - // g = 1000.0; // define a constant irradiance - if (g < 0.0) g = 0.0; // filter negative data - // here, the data is solar irradiance, this should be converted by PV model - - while (t < t_temp){ - + g = atof(strtok(NULL, delims)); // read irradiance + // g = 1000.0; // define a constant irradiance + if (g < 0.0) g = 0.0; // filter negative data + // here, the data is solar irradiance + // this should be converted to current by PV model + while (t < t_temp) { i_in = pvCellCurrent(g, v, cell_area); /* ------ Hibernus Model (On/Off) ------ */ /* Could make this part to a function later */ - if (op == 0){ + if (op == 0) { // when off, restore - if (v >= V_R){ + if (v >= V_R) { op = 1; if (state_saved) { v = (i_in - I_R - i_leak) * T_RESTORE / c + v; @@ -163,15 +163,13 @@ int main (int argv, char** argc){ time_MO += T_RESTORE; time_int += T_RESTORE; } - // else {} // no overhead - + // else {} // no overhead fprintf(fp_interrupt_periods, "%lf \n", time_int); time_int = 0.0; - // forward_progress -= perf[op] / APP_CYCLE * T_RESTORE; // 1.35ms time overheads + // forward_progress -= perf[op] / APP_CYCLE * T_RESTORE; // 1.35ms time overheads continue; } - } - else{ + } else { // when on, hibernate if (v <= V_S) { op = 0; @@ -186,56 +184,57 @@ int main (int argv, char** argc){ time_on += time_step; } - if (v > V_OFF) { if (op == 0) { i_out = I_SLEEP; time_int += time_step; - } - else { + } else { i_out = I_EXE; forward_progress += time_step; } - } - else { + } else { state_saved = 0; i_out = 0.0; time_int += time_step; - } + } v = capacitor(c, v, time_step, i_in, i_out, i_leak, 'i'); if (i_in > i_leak) time_MO += time_step; t += time_step; + } // t reaches t_temp + } // End of loop for reading all data + forward_progress = forward_progress / t; - - } // t reaches t_temp - } // End of loop for reading all data - forward_progress = forward_progress / t; - - /* Output */ + /* Output */ // fprintf(fp_o, "%lf, %lf, %d, ", I_SC / nParal, I_M / nParal, nParal); - fprintf(fp_o, "%d, %lf, %lld, %.3lf, %.3lf, %.3lf, %.3lf\n", i, forward_progress, n_hiber, n_hiber / t, n_hiber / time_MO, time_on / t, time_MO / t); + fprintf(fp_o, "%d, %lf, %lld, %.3lf, %.3lf, %.3lf, %.3lf\n", + i, forward_progress, n_hiber, + n_hiber / t, n_hiber / time_MO, + time_on / t, time_MO / t); // printf("%lf, %lf, %d, ", I_SC / nParal, I_M / nParal, nParal); - printf("%d, %lf, %lld, %.3lf, %.3lf, %.3lf, %.3lf\n", i, forward_progress, n_hiber, n_hiber / t, n_hiber / time_MO, time_on / t, time_MO / t); + printf("%d, %lf, %lld, %.3lf, %.3lf, %.3lf, %.3lf\n", + i, forward_progress, n_hiber, + n_hiber / t, n_hiber / time_MO, + time_on / t, time_MO / t); end = clock(); double time_spent = (double) (end - begin) / CLOCKS_PER_SEC; - printf ("%lf, %lf\n", time_spent, time_step); + printf("%lf, %lf\n", time_spent, time_step); - // } // End of loop for scale nParal - } // End of loop for c, capacitance + // } // End of loop for scale nParal + } // End of loop for c, capacitance fclose(fp_i); fclose(fp_o); // fclose(fp_v); // fclose(fp_ph); - fclose(fp_interrupt_periods); - - return 0; + fclose(fp_interrupt_periods); + + return 0; } -double adaptiveTimeStep(double cap, double ileak, double cell_area){ +double adaptiveTimeStep(double cap, double ileak, double cell_area) { double timestep; double tcharge; double tdischarge; @@ -243,49 +242,57 @@ double adaptiveTimeStep(double cap, double ileak, double cell_area){ tcharge = cap * (V_R - V_S) / (I_MPP_MM2 * cell_area - ileak); tdischarge = cap * (V_R - V_S) / (I_EXE + ileak); - if (tcharge <= tdischarge) timestep = tcharge; - else timestep = tdischarge; + if (tcharge <= tdischarge) + timestep = tcharge; + else + timestep = tdischarge; timestep /= 10.0; return timestep; } -// double pvCellCurrent(double g, double v, double voc, double vm, double isc, double im, int number_series, int number_parallel){ -// double Voc = voc * number_series; // V -// double Isc = isc * number_parallel; // A -// double Vm = vm * number_series; // Vmpp -// double Im = im * number_parallel; // Impp -// double Gpu; // Gpu = G / 1000 -// double i; +// double pvCellCurrent(double g, double v, double voc, double vm, +// double isc, double im, int number_series, int number_parallel) { +// double Voc = voc * number_series; // V +// double Isc = isc * number_parallel; // A +// double Vm = vm * number_series; // Vmpp +// double Im = im * number_parallel; // Impp +// double Gpu; // Gpu = G / 1000 +// double i; // Gpu = g / G_REF; -// if (v > Voc) i = 0; -// else i = Gpu * Isc * (1 - exp(log(1 - Im / Isc) * (v - Voc) / (Vm - Voc))); +// if (v > Voc) +// i = 0; +// else +// i = Gpu * Isc * (1 - exp(log(1 - Im / Isc) +// * (v - Voc) / (Vm - Voc))); // return i; // } -double pvCellCurrent(double g, double v, double cell_area) -{ - if (v < 0){ + +double pvCellCurrent(double g, double v, double cell_area) { + if (v < 0) { printf("PV cell voltage < 0! Abnormal. \n"); return EXIT_FAILURE; } - double Voc = V_OC_CELL * N_S; // V - double Isc = I_SC_MM2 * cell_area; // - double Vmpp = V_MPP_CELL * N_S; // Vmpp - double Impp = I_MPP_MM2 * cell_area; // Impp - double Gpu; // percentage irradiance - double i; + double Voc = V_OC_CELL * N_S; // V + double Isc = I_SC_MM2 * cell_area; + double Vmpp = V_MPP_CELL * N_S; // Vmpp + double Impp = I_MPP_MM2 * cell_area; // Impp + double Gpu; // percentage irradiance + double i; if (g < 0) g = 0; Gpu = g / G_REF; - if (v > Voc) i = 0; - else i = Gpu * Isc * (1 - exp(log(1 - Impp / Isc) * (v - Voc) / (Vmpp - Voc))); + if (v > Voc) + i = 0; + else + i = Gpu * Isc * (1 - exp(log(1 - Impp / Isc) + * (v - Voc) / (Vmpp - Voc))); return i; } -double capCurrentLeak(double cap, double v) -{ +double capCurrentLeak(double cap, double v) { double i_leak; // Aluminium @@ -294,32 +301,36 @@ double capCurrentLeak(double cap, double v) // Tantalum AVX TAJ double v_ratio = v / V_RATED_CAP; - double i_leak_ratio = I_LEAK_RATIO_START * pow(1 / I_LEAK_RATIO_START, v_ratio); + double i_leak_ratio = I_LEAK_RATIO_START * + pow(1 / I_LEAK_RATIO_START, v_ratio); i_leak = K_CAP_LEAK * cap * V_RATED_CAP * i_leak_ratio; - return i_leak; } -double capacitor(double capacitance, double voltage, double time, double inFlow, double outFlow, double leakFlow, char mode){ - switch (mode){ - case 'p': // use power flow - if (2 / capacitance * (inFlow - outFlow - leakFlow) * time + voltage * voltage < 0.0) +double capacitor(double capacitance, double voltage, double time, + double inFlow, double outFlow, double leakFlow, char mode) { + switch (mode) { + case 'p': // use power flow + if (2 / capacitance * (inFlow - outFlow - leakFlow) + * time + voltage * voltage < 0.0) voltage = 0.0; - else voltage = sqrt(2 / capacitance * (inFlow - outFlow - leakFlow) * time + voltage * voltage); + else + voltage = sqrt(2 / capacitance * (inFlow - outFlow - leakFlow) + * time + voltage * voltage); return voltage; break; - case 'i': // use current flow - voltage = (inFlow - outFlow - leakFlow) * time / capacitance + voltage; + case 'i': // use current flow + voltage = (inFlow - outFlow - leakFlow) * + time / capacitance + voltage; if (voltage < 0.0) voltage = 0.0; return voltage; break; - default: printf("Error: please select an operating mode for PV modules using 'p' or 'i'.\n"); exit(1); break; } -} \ No newline at end of file +} diff --git a/finegrain/msp_hiber.h b/finegrain/msp_hiber.h index 542a93a43b182b7ac9ab1961990c0788af80c0e1..54a676805123d58c582740a5e9709243d9739c2c 100644 --- a/finegrain/msp_hiber.h +++ b/finegrain/msp_hiber.h @@ -1,3 +1,11 @@ +/* + * Copyright (c) 2019-2021, University of Southampton and Contributors. + * All rights reserved. + * + * SPDX-License-Identifier: MIT + */ + + #ifndef _MSP_HIBER_H #define _MSP_HIBER_H @@ -36,39 +44,39 @@ double minCapRisk(double supply_current); // Reference: Panasonic Amorton Amorphous Silicon Solar Cells // Open-circuit voltage -#define V_OC_CELL 0.89 // 0.89 V per cell +#define V_OC_CELL 0.89 // 0.89 V per cell // Short-circuit current -#define I_SC_MM2 0.148e-3 // A/mm^2, (14.8 mA/cm^2) per cell -// Maximum power point voltage -#define V_MPP_CELL 0.65 // 0.65 V per cell +#define I_SC_MM2 0.148e-3 // A/mm^2, (14.8 mA/cm^2) per cell +// Maximum power point voltage +#define V_MPP_CELL 0.65 // 0.65 V per cell // Maximum power point current -#define I_MPP_MM2 0.121e-3 // A/mm^2, (12.1 mA/cm^2) per cell +#define I_MPP_MM2 0.121e-3 // A/mm^2, (12.1 mA/cm^2) per cell // Reference irradiance for the measurements above #define G_REF 1000.0 // No. of cells in series, to scale voltage -#define N_S 4 // to get a 3.56V Voc to match MCU max operating voltage 3.6V -// Default area per cell, to scale current -#define DEFAULT_CELL_AREA 10.0 // mm^2 default area of a cell +#define N_S 4 // to get a 3.56V Voc to match MCU max operating voltage 3.6V +// Default area per cell, to scale current +#define DEFAULT_CELL_AREA 10.0 // mm^2 default area of a cell // Not use no. of cell in parallel due to poor granularity -// #define N_P 1 // reserved +// #define N_P 1 // reserved // --------------------------------------- // Capacitor model parameters // Reference: AVX TAJ series, and "Low Leakage Current Aspect of Designing with // Tantalum and Niobium Oxide Capacitors" -#define V_RATED_CAP 10.0 // 10V rated voltage -#define K_CAP_LEAK 0.01 // for AVX TAJ tantalum, 0.01 +#define V_RATED_CAP 10.0 // 10V rated voltage +#define K_CAP_LEAK 0.01 // for AVX TAJ tantalum, 0.01 #define I_LEAK_RATIO_START 0.05 // --------------------------------------- // Load model parameters, after 17 Oct 2019 // Experimentally measured data -// Experiment setup: +// Experiment setup: // Master Clock frequency 8 MHz -// 1.2V Vref module, +// 1.2V Vref module, // Internal comparator (w/ 3Mohms voltage divider), // Workload Dijkstra, // RAM usage 1696B. @@ -77,43 +85,43 @@ double minCapRisk(double supply_current); #define I_OFF 0.0 // Sleep current draw -#define I_SLEEP 26e-6 // A, 26uA @ 2.1 ~ 2.4V, measured 6 Dec 2019 -// #define I_SLEEP 10e-6 // A, 10uA demo +#define I_SLEEP 26e-6 // A, 26uA @ 2.1 ~ 2.4V, measured 6 Dec 2019 +// #define I_SLEEP 10e-6 // A, 10uA demo // #define I_SLEEP 400e-6 // A, 400uA ADC voltage polling // Execute current draw -#define I_EXE 887e-6 // A, 887uA @ 2.1 ~ 2.4V, measured 6 Dec 2019 +#define I_EXE 887e-6 // A, 887uA @ 2.1 ~ 2.4V, measured 6 Dec 2019 // Current mean 0.8957mA min 0.8330mA max 0.9260mA, Voltage 3.2882V // #define I_EXE 1e-3 // A, 1mA demo // #define I_EXE 870e-6 // A, 870uA counting down (w/ ADC) // Restore current draw -#define I_R 971e-6 // A, 971uA @ 2.4V, measured 6 Dec 2019 +#define I_R 971e-6 // A, 971uA @ 2.4V, measured 6 Dec 2019 // #define I_R 1e-3 // A, same as I_EXE -// Save (hibernate) current draw -#define I_S 811e-6 // A, 811uA @ 2.1V, measured 6 Dec 2019 +// Save (hibernate) current draw +#define I_S 811e-6 // A, 811uA @ 2.1V, measured 6 Dec 2019 // #define I_S 1e-3 // A, same as I_EXE -#define V_OFF 1.8 // V, ref: msp430fr6989 datasheet, Table 5-2 +#define V_OFF 1.8 // V, ref: msp430fr6989 datasheet, Table 5-2 // Restore threshold -#define V_R 2.4 // V, Comparator E, measured roughly +#define V_R 2.4 // V, Comparator E, measured roughly // #define V_R 2.3 // V, hibernus // Save threshold -#define V_S 2.1 // V, Comparator E, measured roughly +#define V_S 2.1 // V, Comparator E, measured roughly // #define V_S 2.2 // V, hibernate threshold // Restore/Save time overheads // #define T_RS_SCALE #ifdef T_RS_SCALE // if time overheads linearly scaled by RAM usage - #define T_RESTORE_MAX 2.298e-3 // second, full RAM 2048B - #define T_SAVE_MAX 2.274e-3 // second, full RAM 2048B - #define T_RESTORE_MIN 0.232e-3 // second, least RAM 160B stack - #define T_SAVE_MIN 0.208e-3 // second, least RAM 160B stack - #define RAM_USAGE_TUNE 1.0 // 0 ~ 1, scaling factor + #define T_RESTORE_MAX 2.298e-3 // second, full RAM 2048B + #define T_SAVE_MAX 2.274e-3 // second, full RAM 2048B + #define T_RESTORE_MIN 0.232e-3 // second, least RAM 160B stack + #define T_SAVE_MIN 0.208e-3 // second, least RAM 160B stack + #define RAM_USAGE_TUNE 1.0 // 0 ~ 1, scaling factor #define T_RESTORE (T_RESTORE_MIN + \ (T_RESTORE_MAX - \ T_RESTORE_MIN) * \ @@ -125,28 +133,28 @@ double minCapRisk(double supply_current); // if given with a certain value #define T_RESTORE 1.903e-3 #define T_SAVE 1.880e-3 -#endif // T_RS_SCALE +#endif // T_RS_SCALE -// use clock frequency in the metric if needed -#define PERF_ACTIVE 8.0 // MHz -#define PERF_INACTIVE 0.0 // MHz +// use clock frequency in the metric if needed +#define PERF_ACTIVE 8.0 // MHz +#define PERF_INACTIVE 0.0 // MHz -#define HIBERNUS +#define HIBERNUS // if HIBERNUS, only restore after brownout, no restore after sleep // if not HIBERNUS, restore after brownout and sleep // --------------------------------------- // Old Parameters (obsolete) -// const double power[3] = {0.0, 1.10e-6, 2.79e-3}; // W, msp430fr6989, Hibernus++ -// const double perf [3] = {0.0, 0.0, 8.0}; // MHz +// const double power[3] = {0.0, 1.10e-6, 2.79e-3}; // W, msp430fr6989, Hibernus++ +// const double perf [3] = {0.0, 0.0, 8.0}; // MHz // const double time_step = 0.005; -// const double V_OFF = 2.0; -// const double E_HIBERNATE = 2.99e-6; // Graceful; -// const double E_RESTORE = 3.56e-6; // unit J -// const double T_HIBERNATE = 1.40e-3; // unit second +// const double V_OFF = 2.0; +// const double E_HIBERNATE = 2.99e-6; // Graceful; +// const double E_RESTORE = 3.56e-6; // unit J +// const double T_HIBERNATE = 1.40e-3; // unit second // const double T_RESTORE = 1.35e-3; -// const double APP_CYCLE = 0.1; // 0.1 million cycles to complete one FFT iteration, refer to slaa698b +// const double APP_CYCLE = 0.1; // 0.1 million cycles to complete one FFT iteration, refer to slaa698b // const double V_OC = 1.80; // const double I_SC = 0.275 / 3000.0; // const double V_M = 1.50; // given from datasheet @@ -157,4 +165,4 @@ double minCapRisk(double supply_current); /* --------- Model Configurations End ------- */ -#endif // !_MSP_HIBER_H +#endif // !_MSP_HIBER_H diff --git a/finegrain/quicksort_time.cpp b/finegrain/quicksort_time.cpp index f734c19724ad2359fd29b919a297897267fc98e7..a01559589fa4d5c7665e21178dc8d4116629bfa3 100644 --- a/finegrain/quicksort_time.cpp +++ b/finegrain/quicksort_time.cpp @@ -1,3 +1,11 @@ +/* + * Copyright (c) 2019-2021, University of Southampton and Contributors. + * All rights reserved. + * + * SPDX-License-Identifier: MIT + */ + + #include <iostream> #include <vector> #include <ctime> @@ -5,30 +13,27 @@ #include <string> // #include <stdlib.h> -void swap(double& a, double& b) -{ +void swap(double& a, double& b) { double tmp = a; a = b; b = tmp; } -void quickSort(std::vector<double>& nums, int l, int r) -{ - if(l >= r) return; - int i = l; // cursor for final pivot location - for(int j = l; j <= r - 1; j++){ // nums[r] is chosen as the pivot - if(nums[j] <= nums[r]){ +void quickSort(std::vector<double>& nums, int l, int r) { + if (l >= r) return; + int i = l; // cursor for final pivot location + for (int j = l; j <= r - 1; j++) { // nums[r] is chosen as the pivot + if (nums[j] <= nums[r]) { swap(nums[i], nums[j]); - i++; // smaller or equal elements go to the left of i + i++; // smaller or equal elements go to the left of i } } - swap(nums[i], nums[r]); // after swap, the pivot is nums[i] + swap(nums[i], nums[r]); // after swap, the pivot is nums[i] quickSort(nums, l, i - 1); quickSort(nums, i + 1, r); } -int main() -{ +int main() { std::ifstream inFile; inFile.open("interruption.csv"); std::ofstream outFile; @@ -40,8 +45,7 @@ int main() if (!inFile.is_open()) { std::cout << "Unable to open inFile.\n"; return 0; - } - else { + } else { while (getline(inFile, line)) { // outFile << line << std::endl; temp.push_back(std::stod(line, NULL)); diff --git a/finegrain/quicksort_time_adapted.cpp b/finegrain/quicksort_time_adapted.cpp index 8ab963bbbd0cd62d7e8bff70dd123f8d44cf1eea..f97011a7167c0aba7a70816e3eeec51ab08b8f51 100644 --- a/finegrain/quicksort_time_adapted.cpp +++ b/finegrain/quicksort_time_adapted.cpp @@ -1,42 +1,46 @@ +/* + * Copyright (c) 2019-2021, University of Southampton and Contributors. + * All rights reserved. + * + * SPDX-License-Identifier: MIT + */ + + #include <iostream> #include <vector> #include <ctime> #include <fstream> #include <string> -void swap(double& a, double& b) -{ +void swap(double& a, double& b) { double tmp = a; a = b; b = tmp; } -void swap_cnt(int& a, int& b) -{ +void swap_cnt(int& a, int& b) { int tmp = a; a = b; b = tmp; } -void quickSort(std::vector<double>& nums, int l, int r, std::vector<int>& cnt) -{ - if(l >= r) return; - int i = l; // cursor for final pivot location - for(int j = l; j <= r - 1; j++){ // nums[r] is chosen as the pivot - if(nums[j] <= nums[r]){ +void quickSort(std::vector<double>& nums, int l, int r, std::vector<int>& cnt) { + if (l >= r) return; + int i = l; // cursor for final pivot location + for (int j = l; j <= r - 1; j++) { // nums[r] is chosen as the pivot + if (nums[j] <= nums[r]) { swap(nums[i], nums[j]); swap_cnt(cnt[i], cnt[j]); - i++; // smaller or equal elements go to the left of i + i++; // smaller or equal elements go to the left of i } } - swap(nums[i], nums[r]); // after swap, the pivot is nums[i] + swap(nums[i], nums[r]); // after swap, the pivot is nums[i] swap_cnt(cnt[i], cnt[r]); quickSort(nums, l, i - 1, cnt); quickSort(nums, i + 1, r, cnt); } -int main() -{ +int main() { std::ifstream inFile; inFile.open("interruption.csv"); // inFile.open("test.csv"); @@ -61,8 +65,7 @@ int main() if (!inFile.is_open()) { std::cout << "Unable to open inFile.\n"; return 0; - } - else { + } else { while (getline(inFile, line)) { // outFile << line << std::endl; temp = std::stod(line, NULL); @@ -71,8 +74,7 @@ int main() if (it == value.end()) { value.push_back(temp); count.push_back(1); - } - else { + } else { count[std::distance(value.begin(), it)]++; } line_cnt++; @@ -92,7 +94,7 @@ int main() // std::cout << value[i] << " " << count[i] << std::endl; outFile1 << value[i] << " " << count[i] << std::endl; } - + // for (int i = 0; i < temp.size(); i++) { // std::cout << temp[i] << '\n'; // } @@ -115,4 +117,4 @@ int main() outFile2.close(); return 0; -} \ No newline at end of file +} diff --git a/finegrain/sort_time.c b/finegrain/sort_time.c index 12f676904fab9c41a59672d7faefbad8f520e780..47c6d4b3d51ba1f2a264c94be167b03979d753e6 100644 --- a/finegrain/sort_time.c +++ b/finegrain/sort_time.c @@ -1,13 +1,20 @@ +/* + * Copyright (c) 2019-2021, University of Southampton and Contributors. + * All rights reserved. + * + * SPDX-License-Identifier: MIT + */ + + #include <stdio.h> #include <stdlib.h> #include <string.h> #include <math.h> #include <time.h> -int main (int argv, char** argc) -{ +int main(int argv, char** argc) { FILE* fp_r = NULL; - if ((fp_r = fopen("interruption.csv","r")) == NULL){ // not used for now + if ((fp_r = fopen("interruption.csv", "r")) == NULL) { printf("Failed to read file.\n"); return 1; } @@ -20,9 +27,8 @@ int main (int argv, char** argc) while (fgets(buff, 256, fp_r)) { interrupt_time = atof(buff); // printf("%lf\n", interrupt_time); - - // sorting + // sorting if (interrupt_time < 0.001) slot[0]++; else if (interrupt_time >= 0.001 && interrupt_time < 0.01) slot[1]++; else if (interrupt_time >= 0.01 && interrupt_time < 0.1) slot[2]++; @@ -30,11 +36,11 @@ int main (int argv, char** argc) else if (interrupt_time >= 1 && interrupt_time < 10) slot[4]++; else if (interrupt_time >= 10 && interrupt_time < 100) slot[5]++; else if (interrupt_time >= 100 && interrupt_time < 1000) slot[6]++; - else slot[7]++; // interrupt_time >= 1000 + else slot[7]++; // interrupt_time >= 1000 } FILE* fp_w = NULL; - if ((fp_w = fopen("sort.txt","w")) == NULL){ // not used for now + if ((fp_w = fopen("sort.txt", "w")) == NULL) { printf("Failed to write file.\n"); return 1; } @@ -46,4 +52,4 @@ int main (int argv, char** argc) fclose(fp_r); return 0; -} \ No newline at end of file +} diff --git a/finegrain/tradeoff.cpp b/finegrain/tradeoff.cpp index 19117c74e462cb4360dec37a27634a9ba4b845c7..7e8a65103ba06eea647081a719013df293d817e0 100644 --- a/finegrain/tradeoff.cpp +++ b/finegrain/tradeoff.cpp @@ -1,33 +1,39 @@ +/* + * Copyright (c) 2019-2021, University of Southampton and Contributors. + * All rights reserved. + * + * SPDX-License-Identifier: MIT + */ + + /* Adapted from msp_hiber.c */ +#include "msp_hiber.h" -#include "msp_hiber.h" - -double msp_hiber(double cap, double cell_area) -{ - double v; // Vc - double g; // irradiance - double c = cap; // Capacitance - - double t; // simulation time - double t_temp; // next timing of ir change - // double tHR; // time overheads of hibernate/restore operations +double msp_hiber(double cap, double cell_area) { + double v; // Vc + double g; // irradiance + double c = cap; // Capacitance + + double t; // simulation time + double t_temp; // next timing of ir change + // double tHR; // time overheads of hibernate/restore operations double time_on; - double time_step; // simulation time step - double time_MO; // time in MIDDLE or OVER - double time_int; // each interruption period + double time_step; // simulation time step + double time_MO; // time in MIDDLE or OVER + double time_int; // each interruption period // power/current flow, comment either p or i - // double p_in; // power input + // double p_in; // power input // double p_out; // power output // double p_leak; // 6.48 * c * 0.01, 6.48 = 0.5 * 3.6 * 3.6 double i_in; // current input double i_out; // current output double i_leak; - double forward_progress; // a measurement of forward progress - + double forward_progress; // a measurement of forward progress + int op; // operating point - int state_saved = 0; // is a state saved? + int state_saved = 0; // is a state saved? // int i; // c is calculated in i loop // int c_min; // int c_max; @@ -42,31 +48,31 @@ double msp_hiber(double cap, double cell_area) clock_t end; // ------ File Control variables ------ - char line[MAX_CHARACTER_PER_LINE]; - char* delete_ptr; - char delims[] = ","; - FILE* fp_i = NULL; - FILE* fp_o = NULL; - // FILE* fp_v = NULL; - // FILE* fp_ph = NULL; // file for recording sys Perf and Hibernation per min - FILE* fp_interrupt_periods = NULL; // file for recording interruption periods - - if ((fp_i = fopen("2018denver.txt", "r")) == NULL){ + char line[MAX_CHARACTER_PER_LINE]; + char* delete_ptr; + char delims[] = ","; + FILE* fp_i = NULL; + FILE* fp_o = NULL; + // FILE* fp_v = NULL; + // FILE* fp_ph = NULL; // recording sys Perf and Hibernation per min + FILE* fp_interrupt_periods = NULL; // recording interruption periods + + if ((fp_i = fopen("2018denver.txt", "r")) == NULL) { printf("Failed to read file.\n"); return 1; } - if ((fp_o = fopen("output.csv","a")) == NULL){ + if ((fp_o = fopen("output.csv", "a")) == NULL) { printf("Failed to write file.\n"); return 1; } - if ((fp_interrupt_periods = fopen("interruption.csv","w")) == NULL){ // not used for now + if ((fp_interrupt_periods = fopen("interruption.csv", "w")) == NULL) { printf("Failed to write file.\n"); return 1; } op = 0; state_saved = 0; - v = 0.0; // initial Vc + v = 0.0; // initial Vc t = 0.0; t_temp = 0.0; // comment either p or i @@ -76,13 +82,13 @@ double msp_hiber(double cap, double cell_area) i_out = 0.0; // i_leak = 0.01 * c * 10.0; // rated voltage: 10.0V // if (i_leak < 4e-6) i_leak = 4e-6; - i_leak = capCurrentLeak(c, (V_R + V_S) / 2) ; + i_leak = capCurrentLeak(c, (V_R + V_S) / 2); time_step = adaptiveTimeStep(c, i_leak, cell_area); - + // init measurements time_on = 0.0; time_MO = 0.0; - time_int = 0.0; + time_int = 0.0; forward_progress = 0.0; n_hiber = 0; // n_hiber_last = 0; @@ -91,24 +97,24 @@ double msp_hiber(double cap, double cell_area) rewind(fp_i); begin = clock(); - + // read data while (fgets(line, MAX_CHARACTER_PER_LINE, fp_i)) { - t_temp += 60.0; // defined by the time resolution of data + t_temp += 60.0; // defined by the time resolution of data delete_ptr = strtok(line, delims); delete_ptr = strtok(NULL, delims); - g = atof(strtok(NULL, delims)); // read irradiance - // g = 1000.0; // define a constant irradiance - if (g < 0.0) g = 0.0; // filter negative data + g = atof(strtok(NULL, delims)); // read irradiance + // g = 1000.0; // define a constant irradiance + if (g < 0.0) g = 0.0; // filter negative data // here, the data is solar irradiance, this should be converted by PV model - + while (t < t_temp) { i_in = pvCellCurrent(g, v, cell_area); /* ------ Hibernus Model (On/Off) ------ */ /* Could make this part to a function later */ - if (op == 0){ + if (op == 0) { // when off, restore if (v >= V_R) { op = 1; @@ -119,14 +125,12 @@ double msp_hiber(double cap, double cell_area) time_int += T_RESTORE; } // else {} // no overhead - fprintf(fp_interrupt_periods, "%lf \n", time_int); time_int = 0.0; - // forward_progress -= perf[op] / APP_CYCLE * T_RESTORE; // 1.35ms time overheads + // forward_progress -= perf[op] / APP_CYCLE * T_RESTORE; // 1.35ms time overheads continue; } - } - else { + } else { // when on, hibernate if (v <= V_S) { op = 0; @@ -141,52 +145,51 @@ double msp_hiber(double cap, double cell_area) time_on += time_step; } - if (v > V_OFF) { if (op == 0) { i_out = I_SLEEP; time_int += time_step; - } - else { + } else { i_out = I_EXE; forward_progress += time_step; } - } - else { + } else { state_saved = 0; i_out = 0.0; time_int += time_step; - } + } v = capacitor(c, v, time_step, i_in, i_out, i_leak, 'i'); if (i_in > i_leak) time_MO += time_step; t += time_step; - } // t reaches t_temp - } // End of loop for reading all data + } // t reaches t_temp + } // End of loop for reading all data forward_progress = forward_progress / t; /* Output */ // fprintf(fp_o, "%lf, %lf, %d, ", I_SC / nParal, I_M / nParal, nParal); - fprintf(fp_o, "%e, %lf, %lld, %.3lf, %.3lf, %.3lf, %.3lf\n", c, forward_progress, n_hiber, n_hiber / t, n_hiber / time_MO, time_on / t, time_MO / t); + fprintf(fp_o, "%e, %lf, %lld, %.3lf, %.3lf, %.3lf, %.3lf\n", + c, forward_progress, n_hiber, n_hiber / t, + n_hiber / time_MO, time_on / t, time_MO / t); // printf("%lf, %lf, %d, ", I_SC / nParal, I_M / nParal, nParal); printf("%e, %lf, %lld\n", c, forward_progress, n_hiber); end = clock(); double time_spent = (double) (end - begin) / CLOCKS_PER_SEC; - printf ("msp_hiber() time spent: %lf, simulated with time step: %lf\n", time_spent, time_step); + printf("msp_hiber() time spent: %lf, simulated with time step: %lf\n", + time_spent, time_step); fclose(fp_i); fclose(fp_o); // fclose(fp_v); // fclose(fp_ph); - fclose(fp_interrupt_periods); - - return forward_progress; + fclose(fp_interrupt_periods); + + return forward_progress; } -double adaptiveTimeStep(double cap, double ileak, double cell_area) -{ +double adaptiveTimeStep(double cap, double ileak, double cell_area) { double timestep; double tcharge; double tdischarge; @@ -194,49 +197,36 @@ double adaptiveTimeStep(double cap, double ileak, double cell_area) tcharge = cap * (V_R - V_S) / (I_MPP_MM2 * cell_area - ileak); tdischarge = cap * (V_R - V_S) / (I_EXE + ileak); - if (tcharge <= tdischarge) timestep = tcharge; - else timestep = tdischarge; + if (tcharge <= tdischarge) + timestep = tcharge; + else + timestep = tdischarge; timestep /= 10.0; return timestep; } -// double pvCellCurrent(double g, double v, double voc, double vm, double isc, double im, int number_series, int number_parallel){ -// double Voc = voc * number_series; // V -// double Isc = isc * number_parallel; // A -// double Vm = vm * number_series; // Vmpp -// double Im = im * number_parallel; // Impp -// double Gpu; // Gpu = G / 1000 -// double i; - -// Gpu = g / G_REF; - -// if (v > Voc) i = 0; -// else i = Gpu * Isc * (1 - exp(log(1 - Im / Isc) * (v - Voc) / (Vm - Voc))); - -// return i; -// } -double pvCellCurrent(double g, double v, double cell_area) -{ - if (v < 0){ +double pvCellCurrent(double g, double v, double cell_area) { + if (v < 0) { printf("PV cell voltage < 0! Abnormal. \n"); return EXIT_FAILURE; } - double Voc = V_OC_CELL * N_S; // V - double Isc = I_SC_MM2 * cell_area; // - double Vmpp = V_MPP_CELL * N_S; // Vmpp - double Impp = I_MPP_MM2 * cell_area; // Impp - double Gpu; // percentage irradiance - double i; + double Voc = V_OC_CELL * N_S; // V + double Isc = I_SC_MM2 * cell_area; + double Vmpp = V_MPP_CELL * N_S; // Vmpp + double Impp = I_MPP_MM2 * cell_area; // Impp + double Gpu; // percentage irradiance + double i; if (g < 0) g = 0; Gpu = g / G_REF; - if (v > Voc) i = 0; - else i = Gpu * Isc * (1 - exp(log(1 - Impp / Isc) * (v - Voc) / (Vmpp - Voc))); + if (v > Voc) + i = 0; + else + i = Gpu * Isc * (1 - exp(log(1 - Impp / Isc) * (v - Voc) / (Vmpp - Voc))); return i; } -double capCurrentLeak(double cap, double v) -{ +double capCurrentLeak(double cap, double v) { double i_leak; // Aluminium @@ -248,27 +238,25 @@ double capCurrentLeak(double cap, double v) double i_leak_ratio = I_LEAK_RATIO_START * pow(1 / I_LEAK_RATIO_START, v_ratio); i_leak = K_CAP_LEAK * cap * V_RATED_CAP * i_leak_ratio; - return i_leak; } -double capacitor(double capacitance, double voltage, double time, double inFlow, double outFlow, double leakFlow, char mode) -{ +double capacitor(double capacitance, double voltage, double time, + double inFlow, double outFlow, double leakFlow, char mode) { switch (mode) { - case 'p': // use power flow - if (2 / capacitance * (inFlow - outFlow - leakFlow) * time + voltage * voltage < 0.0) + case 'p': // use power flow + if (2 / capacitance * (inFlow - outFlow - leakFlow) * time + voltage * voltage < 0.0) voltage = 0.0; - else voltage = sqrt(2 / capacitance * (inFlow - outFlow - leakFlow) * time + voltage * voltage); + else + voltage = sqrt(2 / capacitance * (inFlow - outFlow - leakFlow) * time + voltage * voltage); return voltage; break; - - case 'i': // use current flow + case 'i': // use current flow voltage = (inFlow - outFlow - leakFlow) * time / capacitance + voltage; if (voltage < 0.0) voltage = 0.0; return voltage; break; - default: printf("Error: please select an operating mode for PV modules using 'p' or 'i'.\n"); exit(1); @@ -287,39 +275,35 @@ double capacitor(double capacitance, double voltage, double time, double inFlow, #include <fstream> #include <string> -void swap(double& a, double& b) -{ +void swap(double& a, double& b) { double tmp = a; a = b; b = tmp; } -void swap_cnt(int& a, int& b) -{ +void swap_cnt(int& a, int& b) { int tmp = a; a = b; b = tmp; } -void quickSort(std::vector<double>& nums, int l, int r, std::vector<int>& cnt) -{ - if(l >= r) return; - int i = l; // cursor for final pivot location - for(int j = l; j <= r - 1; j++){ // nums[r] is chosen as the pivot - if(nums[j] <= nums[r]){ +void quickSort(std::vector<double>& nums, int l, int r, std::vector<int>& cnt) { + if (l >= r) return; + int i = l; // cursor for final pivot location + for (int j = l; j <= r - 1; j++) { // nums[r] is chosen as the pivot + if (nums[j] <= nums[r]) { swap(nums[i], nums[j]); swap_cnt(cnt[i], cnt[j]); - i++; // smaller or equal elements go to the left of i + i++; // smaller or equal elements go to the left of i } } - swap(nums[i], nums[r]); // after swap, the pivot is nums[i] + swap(nums[i], nums[r]); // after swap, the pivot is nums[i] swap_cnt(cnt[i], cnt[r]); quickSort(nums, l, i - 1, cnt); quickSort(nums, i + 1, r, cnt); } -double quicksort_adapted() -{ +double quicksort_adapted() { std::ifstream inFile; inFile.open("interruption.csv"); // inFile.open("test.csv"); @@ -344,8 +328,7 @@ double quicksort_adapted() if (!inFile.is_open()) { std::cout << "Unable to open inFile.\n"; return 1; - } - else { + } else { while (getline(inFile, line)) { // outFile << line << std::endl; temp = std::stod(line, NULL); @@ -354,8 +337,7 @@ double quicksort_adapted() if (it == value.end()) { value.push_back(temp); count.push_back(1); - } - else { + } else { count[std::distance(value.begin(), it)]++; } line_cnt++; @@ -385,7 +367,7 @@ double quicksort_adapted() } outFile2 << i << ", " << value[cnt_index - 1] << std::endl; - if (i == 90) return_value = value[cnt_index - 1]; // take the 90th percentile + if (i == 90) return_value = value[cnt_index - 1]; // take the 90th percentile } end = clock(); @@ -406,18 +388,15 @@ double quicksort_adapted() #define K2 200.0 #define K3 0.5 -double cost_function(double fwpg, double volume, double interruption) -{ +double cost_function(double fwpg, double volume, double interruption) { return static_cast<double> (fwpg / K1 - pow(volume / K2, 2) - pow(interruption / K3, 2)); } -double cap_volume(double cap) -{ +double cap_volume(double cap) { return (double) 2.172 * pow(cap * 1e6, 0.685); } -double routine(double cap, double cell_area) -{ +double routine(double cap, double cell_area) { std::cout << "\nStart simulating with " << cap << " uF...\n"; std::cout << "msp_hiber() starts...\n"; @@ -433,7 +412,7 @@ double routine(double cap, double cell_area) double cost = cost_function(fwpg, vol, interrupt); - std::cout << "Tradeoff state: " + std::cout << "Tradeoff state: " << cap << " " << cost << " " << fwpg << " " @@ -451,11 +430,10 @@ double routine(double cap, double cell_area) return cost; } -#define F 0.38196601125010515179541316563436 // 1 - 0.618... +#define F 0.38196601125010515179541316563436 // 1 - 0.618... -int main () -{ - double cell_area = 20; // by default +int main () { + double cell_area = 20; // by default printf("Please enter the cell area you want to test in mm^2 (Total PV panel area = %d * cell_area): ", N_S); scanf("%lf", &cell_area); std::cout << "cell_area: " << cell_area << " panel area: " << cell_area * N_S << std::endl; @@ -483,7 +461,7 @@ int main () std::cout << "Simulating capM1: " << capM1 << "uF...\n"; costM1 = routine(capM1, cell_area); - capM2 = capR - F * (capR - capL); + capM2 = capR - F * (capR - capL); std::cout << "Simulating capM2: " << capM2 << "uF...\n"; costM2 = routine(capM2, cell_area); std::cout << "Tested Capacitance (uF): " << capL << " " << capM1 << " " << capM2 << " " << capR << std::endl; @@ -491,17 +469,15 @@ int main () if (costM1 < costM2) { costL = costM1; capL = capM1; - } - else { // costM1 >= costM2 + } else { // costM1 >= costM2 costR = costM2; capR = capM2; } } - + while (capR - capL > 1e-6) { cnt++; std::cout << "================ Round " << cnt << " ================\n"; - if (costM1 < costM2) { capM1 = capM2; costM1 = costM2; @@ -509,8 +485,7 @@ int main () capM2 = capR - F * (capR - capL); std::cout << "Simulating capM2: " << capM2 << "uF...\n"; costM2 = routine(capM2, cell_area); - } - else { // costM1 >= costM2 + } else { // costM1 >= costM2 capM2 = capM1; costM2 = costM1; @@ -521,41 +496,34 @@ int main () std::cout << "Tested Capacitance (uF): " << capL << " " << capM1 << " " << capM2 << " " << capR << std::endl; std::cout << "Cost: " << costL << " " << costM1 << " " << costM2 << " " << costR << std::endl; - + if (costM1 < costM2) { costL = costM1; capL = capM1; - } - else { // costM1 >= costM2 + } else { // costM1 >= costM2 costR = costM2; capR = capM2; } } if (costL > costR) { - if (costM1 > costL) { // costM2 == costR + if (costM1 > costL) { // costM2 == costR std::cout << "Best cap is: " << capM1 << " uF.\n"; - } - else if (costM2 > costL) { // costM1 == costL + } else if (costM2 > costL) { // costM1 == costL std::cout << "Best cap is: " << capM2 << " uF.\n"; - } - else { + } else { std::cout << "Best cap is: " << capL << " uF.\n"; } - - } - else { - if (costM2 > costR) { // costM1 = costL + } else { + if (costM2 > costR) { // costM1 = costL std::cout << "Best cap is: " << capM2 << " uF.\n"; - } - else if (costM1 > costR) { // costM2 = costR + } else if (costM1 > costR) { // costM2 = costR std::cout << "Best cap is: " << capM1 << " uF.\n"; - } - else { + } else { std::cout << "Best cap is: " << capR << " uF.\n"; } } return 0; -} \ No newline at end of file +}