/* Example programs from the book Scientific and Engineering Programming in C++: An Introduction with Advanced Techniques and Examples, Addison-Wesley, 1994. (c) COPYRIGHT INTERNATIONAL BUSINESS MACHINES CORPORATION 1994. ALL RIGHTS RESERVED. See README file for further details. */ #include #include #include "SciEng/Boolean.h" #include "examples/ch6/Point.h" #include "examples/ch6/SimpleArray.h" // Redefine EXIT_SUCCESS and EXIT_FAILURE. When this program works it should return // EXIT_FAILURE, but run-test in the Makefile tests for EXIT_SUCCESS. #undef EXIT_SUCCESS #undef EXIT_FAILURE #define EXIT_SUCCESS 1 #define EXIT_FAILURE 0 typedef Point Node; class Element { public: int operator[](int i) const; int numNodes() const; friend istream& operator>>(istream&, Element&); private: SimpleArray node_numbers; }; int Element::operator[](int i) const { return node_numbers[i]; } int Element::numNodes() const { return node_numbers.numElts(); } istream& operator>>(istream& instream, Element& e) { int n; instream >> n; e.node_numbers.setSize(n); for (int i = 0; i < n; i++) instream >> e.node_numbers[i]; return instream; } class Mesh { public: Boolean checkElementAngles(Number angle_threshold) const; Number maxAngle(const Element& e) const; int numNodes() const; int numElements() const; friend istream& operator>>(istream&, Mesh&); private: SimpleArray node_table; SimpleArray element_table; }; int Mesh::numNodes() const { return node_table.numElts(); } int Mesh::numElements() const { return element_table.numElts(); } Boolean Mesh::checkElementAngles(Number angle_threshold) const { Boolean anglesOK = Boolean::true; for (int eltNum = 0; eltNum < numElements(); eltNum++) { const Element& e = element_table[eltNum]; // e is an alias for element # eltNum if (maxAngle(e) > angle_threshold) { cout << "Element [ "; for (int i = 0; i < e.numNodes(); i++) cout << node_table[e[i]] << " "; cout << "] has a large angle." << endl; anglesOK = Boolean::false; } } return anglesOK; } Number Mesh::maxAngle(const Element& e) const { Number maxang = 0.0; int numNodes = e.numNodes(); for (int i = 0; i < numNodes; i++) { int ccwNodeNum = (i + 1) % numNodes; int cwNodeNum = (i + numNodes - 1) % numNodes; Number angle = node_table[e[i]].angle(node_table[e[cwNodeNum]], node_table[e[ccwNodeNum]]); if ( angle > maxang ) maxang = angle; } return maxang; } istream& operator>>(istream& instream, Mesh& m) { int nNodes; int nElements; instream >> nNodes >> nElements; m.node_table.setSize(nNodes); m.element_table.setSize(nElements); for (int nodeNum = 0; nodeNum < nNodes; nodeNum++) { instream >> m.node_table[nodeNum]; } for (int elementNum = 0; elementNum < nElements; elementNum++) { instream >> m.element_table[elementNum]; } return instream; } int main() { Mesh m; cin >> m; Number angle_threshold; cin >> angle_threshold; Boolean anglesOK = m.checkElementAngles(angle_threshold); return anglesOK ? EXIT_SUCCESS : EXIT_FAILURE; }