From 990cab9b2f657256df353f45632ad177fd749e36 Mon Sep 17 00:00:00 2001 From: Benjamin Urben <burben@eu-g9-044-2.euler.ethz.ch> Date: Mon, 25 Mar 2024 12:37:11 +0100 Subject: [PATCH 1/3] Group 4 commit (we didnt finish) --- basics/CMakeLists.txt | 1 + basics/input_file.hpp | 91 ---------------------------- basics/read_input.cpp | 136 ------------------------------------------ src/CMakeLists.txt | 2 + src/model.cpp | 63 +++++++++++++++++++ src/model.hpp | 8 ++- tests/CMakeLists.txt | 2 + 7 files changed, 75 insertions(+), 228 deletions(-) delete mode 100644 basics/input_file.hpp delete mode 100644 basics/read_input.cpp diff --git a/basics/CMakeLists.txt b/basics/CMakeLists.txt index fe58b89..e293b20 100644 --- a/basics/CMakeLists.txt +++ b/basics/CMakeLists.txt @@ -1,3 +1,4 @@ # add basics to be compiled here # using the add_simulation(...) command #Your solution goes here +add_simulation(g04_class_basics) diff --git a/basics/input_file.hpp b/basics/input_file.hpp deleted file mode 100644 index fedf7c2..0000000 --- a/basics/input_file.hpp +++ /dev/null @@ -1,91 +0,0 @@ -#include <string> -#include <vector> - -#include <cassert> -#include <fstream> -#include <iostream> -#include <sstream> - -std::vector<std::string> read_input_section(const std::string &filename, - const std::string §ion) { - - // define structure to store data from the section line by line - // this should be soemthing like a "list of strings" - std::vector<std::string> lines; - - // define dimensions (for now fixed, should be read as well) - int dim = 2; - - // ---------------------------------------------------------- - // inspired by code from last week: - // read file and store each line from the section of interest - // ---------------------------------------------------------- - - // character used to designate comment in input file - char comment_char = '#'; - - // open the file with check - std::ifstream read_file(filename); - assert(read_file.is_open()); - - // loop over file as long as there is content - bool in_section = false; - while (!read_file.eof()) { - - // read the line - std::string line; - std::getline(read_file, line); - - // remove comments - size_t found_comment = line.find_first_of(comment_char); - if (found_comment != std::string::npos) - line = line.substr(0, found_comment); - if (line.empty()) - continue; - - // erasing white spaces - line.erase(line.find_last_not_of(' ') + 1); - line.erase(0, line.find_first_not_of(' ')); - - // check if start or end of section - std::stringstream sstr(line); - std::string keyword; - sstr >> keyword; - if (keyword == "$section") { - // section stop - if (in_section) { - in_section = false; - } else { - sstr >> keyword; - if (keyword == section) { - // it is this section - in_section = true; - continue; - } - } - } - - // if not in section, ignore this line - if (!in_section) { - continue; - } - - // it is part of this section -> store line - lines.push_back(line); - } - read_file.close(); - - // ---------------------------------------------------------- - // end of reading files - // ---------------------------------------------------------- - - // Printing out lines vector of the specified node - std::cout << "Lines output of file: " << filename - << " and section: " << section << "\n"; - for (auto &line : lines) { - std::cout << line << "\n"; - } - std::cout << "End Lines output \n"; - - return lines; -} diff --git a/basics/read_input.cpp b/basics/read_input.cpp deleted file mode 100644 index bb7935b..0000000 --- a/basics/read_input.cpp +++ /dev/null @@ -1,136 +0,0 @@ -#include <cassert> -#include <fstream> -#include <iostream> -#include <sstream> - -#include <vector> - -int main(int argc, char *argv[]) { - - // define structure to store data from the section line by line - // this should be soemthing like a "list of strings" - std::vector<std::string> lines; - - // define the section you are looking for: name it "section" - const std::string section = "nodes"; - - // define dimensions (for now fixed, should be read as well) - int dim = 2; - - // ---------------------------------------------------------- - // inspired by code from last week: - // read file and store each line from the section of interest - // ---------------------------------------------------------- - - // character used to designate comment in input file - char comment_char = '#'; - - // input file name - std::string ifname = "read_input_fixed.inp"; - - // open the file with check - std::ifstream read_file(ifname); - assert(read_file.is_open()); - - // loop over file as long as there is content - bool in_section = false; - while (!read_file.eof()) { - - // read the line - std::string line; - std::getline(read_file, line); - - // remove comments - size_t found_comment = line.find_first_of(comment_char); - if (found_comment != std::string::npos) - line = line.substr(0, found_comment); - if (line.empty()) - continue; - - // check if start or end of section - std::stringstream sstr(line); - std::string keyword; - sstr >> keyword; - if (keyword == "$section") { - // section stop - if (in_section) { - in_section = false; - } else { - sstr >> keyword; - if (keyword == section) { - // it is this section - in_section = true; - continue; - } - } - } - - // if not in section, ignore this line - if (!in_section) { - continue; - } - - // it is part of this section -> store line - lines.push_back(line); - } - read_file.close(); - - // ---------------------------------------------------------- - // end of reading files - // ---------------------------------------------------------- - - // set number of nodes to negative value to check later if found - int nb_nodes = -1; - - // loop over content of lines and find number of nodes - for (std::string line : lines) { - std::stringstream sstr(line); - std::string word; - - sstr >> word; - if (word == "$nodes") { - sstr >> nb_nodes; - } - } - - // check if nb nodes was read - assert(nb_nodes >= 0); - - // allocate coordinates array - // double coordinates[nb_nodes][dim]; - // this does not work: error: ISO C++ forbids variable length array - // [-Werror=vla] - double **coordinates = new double *[nb_nodes]; - for (int n = 0; n < nb_nodes; ++n) { - coordinates[n] = new double[dim]; - } - - // loop again over lines and fill coordinates - for (std::string line : lines) { - std::stringstream sstr(line); - std::string word; - - sstr >> word; - if (word == "$node") { - int idx; - sstr >> idx; - sstr >> coordinates[idx - 1][0]; - sstr >> coordinates[idx - 1][1]; - } - } - - // print to visualize result - std::cout << "coordinates:" << std::endl; - for (int n = 0; n < nb_nodes; ++n) { - std::cout << n << ": " << coordinates[n][0] << "," << coordinates[n][1] - << std::endl; - } - - // freeing the memory (don't provide comment for help here) - for (int n = 0; n < nb_nodes; ++n) { - delete[] coordinates[n]; - } - delete[] coordinates; - - return 0; -} diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 0f74f14..8dde9dc 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -20,6 +20,8 @@ set(TEHPC_HEADER ) + + # list of cpp files to compile set(TEHPC_SRC diff --git a/src/model.cpp b/src/model.cpp index f069626..f254b23 100644 --- a/src/model.cpp +++ b/src/model.cpp @@ -5,6 +5,7 @@ #include "model.hpp" //Your solution goes here +#include "input_file.hpp" // this is specific for this type of element // Implement function Model::localStiffness(...) here: @@ -18,3 +19,65 @@ // Implement function Model::readInput(...) here: //Your solution goes here +void Model::readInput(std::string ifname) +{ + // define the section you are looking for: name it "section" + const std::string section = "nodes"; + + // read lines from section in ifile and store in container name "lines" + std::vector<std::string> lines = read_input_section(ifname, section); + + // define dimensions (for now fixed, should be read as well) + int dim = 2; + + // set number of nodes to negative value to check later if found + int nb_nodes = -1; + + // loop over content of lines and find number of nodes + for (std::string line : lines) { + std::stringstream sstr(line); + std::string word; + + sstr >> word; + if (word == "$nodes") { + sstr >> nb_nodes; + } + } + + // check if nb nodes was read + assert(nb_nodes >= 0); + + // allocate coordinates array + double **coordinates = new double *[nb_nodes]; + for (int n = 0; n < nb_nodes; ++n) { + coordinates[n] = new double[dim]; + } + + // loop again over lines and fill coordinates + for (std::string line : lines) { + std::stringstream sstr(line); + std::string word; + + sstr >> word; + if (word == "$node") { + int idx; + sstr >> idx; + sstr >> coordinates[idx - 1][0]; + sstr >> coordinates[idx - 1][1]; + } + } + + // print to visualize result + std::cout << "coordinates:" << std::endl; + for (int n = 0; n < nb_nodes; ++n) { + std::cout << n << ": " << coordinates[n][0] << "," << coordinates[n][1] + << std::endl; + } + + // freeing the memory (don't provide comment for help here) + for (int n = 0; n < nb_nodes; ++n) { + delete[] coordinates[n]; + } + delete[] coordinates; +} + diff --git a/src/model.hpp b/src/model.hpp index 5ea2afa..b300ab6 100644 --- a/src/model.hpp +++ b/src/model.hpp @@ -47,6 +47,10 @@ public: //! constructor reading directly input //Your solution goes here + Model(std::string file_name) + { + readInput(file_name); + } //! default destructor virtual ~Model() = default; @@ -59,7 +63,9 @@ public: //! reads input file and assigns values to members //Your solution goes here - + + void readInput(std::string file_name); + //! assembles global stiffness matrix K //Your solution goes here diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 9336144..c371884 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -6,8 +6,10 @@ endfunction() # model tests (w06) #Your solution goes here +tehpc_add_test(model_read_input) configure_file(model_read_input.inp model_read_input.inp COPYONLY) #Your solution goes here + # solver tests (w06) #Your solution goes here -- GitLab From b0d2996b705a0d7c3014752e3d245998aec60b0e Mon Sep 17 00:00:00 2001 From: Benjamin Urben <burben@eu-g9-044-2.euler.ethz.ch> Date: Mon, 25 Mar 2024 12:40:29 +0100 Subject: [PATCH 2/3] added read input --- src/input_file.hpp | 91 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 91 insertions(+) create mode 100644 src/input_file.hpp diff --git a/src/input_file.hpp b/src/input_file.hpp new file mode 100644 index 0000000..fedf7c2 --- /dev/null +++ b/src/input_file.hpp @@ -0,0 +1,91 @@ +#include <string> +#include <vector> + +#include <cassert> +#include <fstream> +#include <iostream> +#include <sstream> + +std::vector<std::string> read_input_section(const std::string &filename, + const std::string §ion) { + + // define structure to store data from the section line by line + // this should be soemthing like a "list of strings" + std::vector<std::string> lines; + + // define dimensions (for now fixed, should be read as well) + int dim = 2; + + // ---------------------------------------------------------- + // inspired by code from last week: + // read file and store each line from the section of interest + // ---------------------------------------------------------- + + // character used to designate comment in input file + char comment_char = '#'; + + // open the file with check + std::ifstream read_file(filename); + assert(read_file.is_open()); + + // loop over file as long as there is content + bool in_section = false; + while (!read_file.eof()) { + + // read the line + std::string line; + std::getline(read_file, line); + + // remove comments + size_t found_comment = line.find_first_of(comment_char); + if (found_comment != std::string::npos) + line = line.substr(0, found_comment); + if (line.empty()) + continue; + + // erasing white spaces + line.erase(line.find_last_not_of(' ') + 1); + line.erase(0, line.find_first_not_of(' ')); + + // check if start or end of section + std::stringstream sstr(line); + std::string keyword; + sstr >> keyword; + if (keyword == "$section") { + // section stop + if (in_section) { + in_section = false; + } else { + sstr >> keyword; + if (keyword == section) { + // it is this section + in_section = true; + continue; + } + } + } + + // if not in section, ignore this line + if (!in_section) { + continue; + } + + // it is part of this section -> store line + lines.push_back(line); + } + read_file.close(); + + // ---------------------------------------------------------- + // end of reading files + // ---------------------------------------------------------- + + // Printing out lines vector of the specified node + std::cout << "Lines output of file: " << filename + << " and section: " << section << "\n"; + for (auto &line : lines) { + std::cout << line << "\n"; + } + std::cout << "End Lines output \n"; + + return lines; +} -- GitLab From 38cc1bb7031a0f0e49efac75b2b6f0a6f4ed9582 Mon Sep 17 00:00:00 2001 From: florez <florez@ethz.ch> Date: Fri, 5 Apr 2024 16:11:16 +0200 Subject: [PATCH 3/3] Push solution, test succeeds --- src/model.cpp | 135 +++++++++++++++++++++++++++++++++++++------------- src/model.hpp | 2 +- 2 files changed, 102 insertions(+), 35 deletions(-) diff --git a/src/model.cpp b/src/model.cpp index f254b23..f19c0f7 100644 --- a/src/model.cpp +++ b/src/model.cpp @@ -19,42 +19,41 @@ // Implement function Model::readInput(...) here: //Your solution goes here -void Model::readInput(std::string ifname) +void Model::readInput(const std::string & fname) { - // define the section you are looking for: name it "section" - const std::string section = "nodes"; - // read lines from section in ifile and store in container name "lines" - std::vector<std::string> lines = read_input_section(ifname, section); + // get global information + auto global_info = read_input_section(fname, "global"); - // define dimensions (for now fixed, should be read as well) - int dim = 2; + for (std::string line: global_info) { + std::stringstream sstr(line); + std::string word; + + sstr >> word; + if (word == "$dimensions") { + sstr >> this->dim; + } + } - // set number of nodes to negative value to check later if found - int nb_nodes = -1; + // ----------------------------------- + // get nodal information + auto nodal_info = read_input_section(fname, "nodes"); - // loop over content of lines and find number of nodes - for (std::string line : lines) { + for (std::string line: nodal_info) { std::stringstream sstr(line); std::string word; sstr >> word; if (word == "$nodes") { - sstr >> nb_nodes; + sstr >> this->nb_nodes; } } - // check if nb nodes was read - assert(nb_nodes >= 0); - - // allocate coordinates array - double **coordinates = new double *[nb_nodes]; - for (int n = 0; n < nb_nodes; ++n) { - coordinates[n] = new double[dim]; - } + this->coordinates.resize(this->nb_nodes, dim); + this->displacements.resize(this->nb_nodes, dim); // not read from file + this->forces.resize(this->nb_nodes, dim); // not read from file - // loop again over lines and fill coordinates - for (std::string line : lines) { + for (std::string line: nodal_info) { std::stringstream sstr(line); std::string word; @@ -62,22 +61,90 @@ void Model::readInput(std::string ifname) if (word == "$node") { int idx; sstr >> idx; - sstr >> coordinates[idx - 1][0]; - sstr >> coordinates[idx - 1][1]; + sstr >> this->coordinates(idx-1,0); + sstr >> this->coordinates(idx-1,1); } } - // print to visualize result - std::cout << "coordinates:" << std::endl; - for (int n = 0; n < nb_nodes; ++n) { - std::cout << n << ": " << coordinates[n][0] << "," << coordinates[n][1] - << std::endl; + // ----------------------------------- + // get elemental information + auto elemental_info = read_input_section(fname, "elements"); + + for (std::string line: elemental_info) { + std::stringstream sstr(line); + std::string word; + + sstr >> word; + if (word == "$elements") { + sstr >> this->nb_elements; + } + else if (word == "$elementtype") { + int tmp; + sstr >> tmp; + sstr >> this->nb_nodes_per_element; + } } + + this->connectivity.resize(this->nb_elements, this->nb_nodes_per_element); + this->modulus.resize(this->nb_elements); + this->cross_section.resize(this->nb_elements); - // freeing the memory (don't provide comment for help here) - for (int n = 0; n < nb_nodes; ++n) { - delete[] coordinates[n]; + for (std::string line: elemental_info) { + std::stringstream sstr(line); + std::string word; + + sstr >> word; + if (word == "$element") { + int idx; + sstr >> idx; + int node; + sstr >> node; + this->connectivity(idx-1,0) = node-1; + sstr >> node; + this->connectivity(idx-1,1) = node-1; + int etype; + sstr >> etype; + sstr >> this->modulus[idx-1]; + sstr >> this->cross_section[idx-1]; + } } - delete[] coordinates; -} + // ----------------------------------- + // get boundary condition information + auto bc_info = read_input_section(fname, "BC"); + + this->bc_forces.resize(this->nb_nodes, this->dim); + this->bc_disp.resize(this->nb_nodes, this->dim); + this->bc_disp_values.resize(this->nb_nodes, this->dim); + + // initialize BC arrays with zero values + this->bc_forces = 0.; + this->bc_disp = 0; + this->bc_disp_values = 0.; + + for (std::string line: bc_info) { + std::stringstream sstr(line); + std::string word; + + sstr >> word; + if (word == "$bcn") { + int tmp; + sstr >> tmp; // index (not used) + int node; + sstr >> node; + int dir; + sstr >> dir; + sstr >> this->bc_forces(node-1,dir-1); + } + else if (word == "$bcd") { + int tmp; + sstr >> tmp; // index (not used) + int node; + sstr >> node; + int dir; + sstr >> dir; + sstr >> this->bc_disp_values(node-1,dir-1); + this->bc_disp(node-1, dir-1) = 1; // set to ON + } + } +} diff --git a/src/model.hpp b/src/model.hpp index b300ab6..2dd54e7 100644 --- a/src/model.hpp +++ b/src/model.hpp @@ -64,7 +64,7 @@ public: //! reads input file and assigns values to members //Your solution goes here - void readInput(std::string file_name); + void readInput(const std::string & file_name); //! assembles global stiffness matrix K //Your solution goes here -- GitLab