#include #include #include #include #include "components.h" /* Lab 4 - TDDE18 - Simulator lab - Main file Usage: $ ./a.out [ITERATIONS] [NB_OUTPUT] [TIME_STEP] [BATTERY_VOLTAGE] If you are using our build script (available on our private Github), you can do: $ ./build_and_run.sh -v [ITERATIONS] [NB_OUTPUT] [TIME_STEP] [BATTERY_VOLTAGE] to run the binary in valgrind. Note: Compilation warning dues to unused parameter is normal (seen with lab assistant). New circuits can be created in the /// Simulations setup /// section (line 90) by following existing functions patterns. Add also a line at the end of the program to execute simulation. */ using namespace std; ///////////////////////// /// Utility functions /// ///////////////////////// /// Function that print output's header void print_header(vector circuit) { for (Component* element : circuit) { cout << setw(15) << element->get_name(); } cout << endl; for (long unsigned int i = 0; i < circuit.size(); ++i) { cout << setw(8) << "Volt" << setw(7) << "Curr"; } cout << endl; } /// Function that print circuit status at a given step void print_status(vector circuit) { for (Component* element : circuit) { cout << fixed << setprecision(2) << setw(8) << element->voltage() << setw(7) << element->current(); } cout << endl; } /// Simulates the circuit's charges motion void simulate(vector circuit, int const iterations, int const nb_output, double const dt) { int output_step = iterations / nb_output; print_header(circuit); for (int step = 1; step <= iterations; ++step){ // Simulate each component for (Component* element : circuit) { element->simulate(dt); } // Print info every output_step if (step % output_step == 0){ print_status(circuit); } } cout << endl; } /// Delete components to avoid memory leaks void clean(vector circuit) { for (Component* element : circuit) { delete element; } } void invalid_arguments() { cout << "Invalid arguments, usage: " << endl; cout << "./bin [ITERATIONS] [NB_OUTPUT] [TIME_STEP] [BATTERY_VOLTAGE]" << endl; cout << "Example: ./bin 200000 10 0.01 24" << endl; } ///////////////////////// /// Simulations setup /// ///////////////////////// // A very basic simulation, to test resistance simulation. void simulation0(int iterations, int nb_output, double dt, double battery_voltage) { Link P, N, r12; vector circuit; circuit.push_back(new Battery("Bat", P, N, battery_voltage)); circuit.push_back(new Resistor("R1", P, r12, 6.0)); circuit.push_back(new Resistor("R2", r12, N, 8.0)); simulate(circuit, iterations, nb_output, dt); clean(circuit); } // Corresponds to the first (top) circuit in the lab PDF (figure 1). void simulation1(int iterations, int nb_output, double dt, double battery_voltage) { Link P, N, r124, r23; vector circuit; circuit.push_back(new Battery("Bat", P, N, battery_voltage)); circuit.push_back(new Resistor("R1", P, r124, 6.0)); circuit.push_back(new Resistor("R2", r124, r23, 4.0)); circuit.push_back(new Resistor("R3", r23, N, 8.0)); circuit.push_back(new Resistor("R4", r124, N, 12.0)); simulate(circuit, iterations, nb_output, dt); clean(circuit); } // Corresponds to the second (middle) circuit in the lab PDF (figure 1). void simulation2(int iterations, int nb_output, double dt, double battery_voltage) { Link P, N, L, R; vector circuit; circuit.push_back(new Battery("Bat", P, N, battery_voltage)); circuit.push_back(new Resistor("R1", P, L, 150.0)); circuit.push_back(new Resistor("R2", P, R, 50.0)); circuit.push_back(new Resistor("R3", R, L, 100.0)); circuit.push_back(new Resistor("R4", L, N, 300.0)); circuit.push_back(new Resistor("R5", R, N, 250.0)); simulate(circuit, iterations, nb_output, dt); clean(circuit); } // Corresponds to the third (bottom) circuit in the lab PDF (figure 1). void simulation3(int iterations, int nb_output, double dt, double battery_voltage) { Link P, N, L, R; vector circuit; circuit.push_back(new Battery("Bat", P, N, battery_voltage)); circuit.push_back(new Resistor("R1", P, L, 150.0)); circuit.push_back(new Resistor("R2", P, R, 50.0)); circuit.push_back(new Capacitor("C3", R, L, 1.0)); circuit.push_back(new Resistor("R4", L, N, 300.0)); circuit.push_back(new Capacitor("C5", R, N, 0.75)); simulate(circuit, iterations, nb_output, dt); clean(circuit); } ///////////////////////////////////// /// Main function & args. parsing /// ///////////////////////////////////// int main(int argc, char* argv[]){ int iterations{}; int nb_output{}; double dt{}; double battery_voltage{}; // Arguments parsing if (argc == 5) { try { vector args {argv, argv + argc}; iterations = std::stoi(args[1]); nb_output = std::stoi(args[2]); dt = std::stod(args[3]); battery_voltage = std::stod(args[4]); if (iterations <= 0) { throw std::logic_error{"Negative iterations"}; } else if (nb_output > iterations) { throw std::logic_error{"Too many output for given iterations"}; } else if (dt <= 0) { throw std::logic_error{"Time step must be strictly positive"}; } } catch (std::exception& e) { cerr << "ERROR (" << e.what() << ")." << endl; invalid_arguments(); return 1; } } else { cerr << "ERROR (no enough arguments)." << endl; invalid_arguments(); return 1; } // Running simulations simulation0(iterations, nb_output, dt, battery_voltage); simulation1(iterations, nb_output, dt, battery_voltage); simulation2(iterations, nb_output, dt, battery_voltage); simulation3(iterations, nb_output, dt, battery_voltage); return 0; }