From 93dcb7878cc955f33307de27045a6e45e06d8bdb Mon Sep 17 00:00:00 2001 From: shoaibmahmod7 <64025778+shoaibmahmod7@users.noreply.github.com> Date: Sun, 27 Feb 2022 14:46:36 +0300 Subject: [PATCH 1/5] Squashed commit of the following: commit b673e8286317a8d95b6cc17c56da6d1fda5acef4 Author: Maged Eltorkoman Date: Fri Feb 25 11:10:39 2022 +0200 Feat: save and load for alpha and conditions commit 8d61187f698518d61a792680cf0f406f59f63607 Author: Maged Eltorkoman Date: Fri Feb 25 09:04:23 2022 +0200 Bug: Make logger hidden in ci_matrix commit 8433efcaa766eb25783e23aab53e7186812fad59 Author: Maged Eltorkoman Date: Wed Feb 23 21:39:43 2022 +0200 Tried SCIP solver in splitting benchmark_splitting commit 65f66df4d854b626a11093b4e84660f7d12e1f8e Merge: 900f087 2cbb1de Author: Maged Turkoman <64289883+MagedMohamedTurk@users.noreply.github.com> Date: Tue Feb 15 10:29:54 2022 +0200 Merge pull request #1 from MagedMohamedTurk/test-binder-env Update environment.yml commit 2cbb1de7075509578a7580539f5cdd8d9fc5879e Author: Maged Turkoman <64289883+MagedMohamedTurk@users.noreply.github.com> Date: Tue Feb 15 10:20:46 2022 +0200 added plotting packages commit 493b8359b7ae999b57aa796cec1cc692cfaaaf3d Author: Maged Turkoman <64289883+MagedMohamedTurk@users.noreply.github.com> Date: Tue Feb 15 10:09:21 2022 +0200 Update environment.yml commit 900f0871d9591d57ad9eb8d6591b09275e9706a9 Author: Maged Turkoman <64289883+MagedMohamedTurk@users.noreply.github.com> Date: Tue Feb 15 10:03:53 2022 +0200 Docs: update readme with mybinder link --- README.md | 6 +++- environment.yml | 5 +++ pyproject.toml | 5 +++ setup.py | 2 +- src/hsbalance/CI_matrix.py | 56 ++++++++++++++++------------- src/hsbalance/model.py | 2 ++ src/hsbalance/my_alpha.npy | Bin 200 -> 0 bytes test/benchmark_splitting_solver.md | 6 ++-- test/test_ALPHA.py | 12 +++++++ test/test_model.py | 22 ++++++++++-- 10 files changed, 85 insertions(+), 31 deletions(-) delete mode 100644 src/hsbalance/my_alpha.npy diff --git a/README.md b/README.md index ecd1941..ce11d68 100644 --- a/README.md +++ b/README.md @@ -10,10 +10,14 @@ The purpose of this project is to solve the problem of turbomachinery [rotor bal ![pic](https://img.shields.io/badge/Python-14354C?&logo=python&logoColor=white) ![pic](https://img.shields.io/badge/-Jupyter-white?logo=Jupyter) [![Generic badge](https://img.shields.io/badge/Build-Dev-red.svg)]() -[![Generic badge](https://img.shields.io/badge/Test-Passing-Green.svg)]() +[![Generic badge](https://img.shields.io/badge/Test-Passing-Green.svg)]() +[![Binder](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/MagedMohamedTurk/Turbomachinery-Rotors-Balancing/HEAD?labpath=examples%2F) HSBALANCE package is a python tool-kit that enables field engineer to do rotor balancing job on large number of measuring and balancing planes. It facilitates testing various scenarios through applying different optimization methods and applying different constraints. The package takes advantage of object oriented programming which makes it easier to build, extend and maintain. The package also make it possible to easily use the code in a notebook which is a great advantage to work freely, try different method of optimization and splitting for your case, get to compare results and RMS errors and even plot charts and diagrams. +## Binder +Use [mybinder link](https://mybinder.org/v2/gh/MagedMohamedTurk/Turbomachinery-Rotors-Balancing/HEAD?labpath=examples%2F) to quickly navigate through examples with no installation required. +## Installation To quickly use the package: 1. Optional create an isolated environment for python 3.8. (for Anaconda users `e.g. $ conda create -n myenv python=3.8`) 2. `$ pip install hsbalance` diff --git a/environment.yml b/environment.yml index be937a6..50c8c5b 100644 --- a/environment.yml +++ b/environment.yml @@ -4,3 +4,8 @@ channels: - defaults dependencies: - python=3.8 + - pip + - pip: + - hsbalance + - matplotlib + - ipympl diff --git a/pyproject.toml b/pyproject.toml index 374b58c..28e2cdb 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,3 +4,8 @@ requires = [ "wheel" ] build-backend = "setuptools.build_meta" +[tool.pytest.ini_options] +log_cli=true +log_level='NOTSET' +log_cli_format = "%(asctime)s [%(levelname)8s] %(message)s (%(filename)s:%(lineno)s)" +log_cli_date_format = "%Y-%m-%d %H:%M:%S" diff --git a/setup.py b/setup.py index e9b4979..f768b61 100644 --- a/setup.py +++ b/setup.py @@ -5,7 +5,7 @@ setuptools.setup( name="hsbalance", - version="0.5.3", + version="0.5.4", author="Maged M.Eltorkoman", author_email="newmaged@gmail.com", description="Python tools for Practical Modeling and Solving High Speed Rotor Unbalance Problem", diff --git a/src/hsbalance/CI_matrix.py b/src/hsbalance/CI_matrix.py index e980ade..de99e2c 100644 --- a/src/hsbalance/CI_matrix.py +++ b/src/hsbalance/CI_matrix.py @@ -3,13 +3,14 @@ import numpy as np import hsbalance.tools as tools import pandas as pd +import pickle -logger = logging.getLogger(__name__) -logger.propagate = False -logger.setLevel(logging.DEBUG) -console_handle = logging.StreamHandler() -console_handle.setLevel(logging.INFO) -logger.addHandler(console_handle) +_logger = logging.getLogger(__name__) +_logger.propagate = False +_logger.setLevel(logging.DEBUG) +_console_handle = logging.StreamHandler() +_console_handle.setLevel(logging.INFO) +_logger.addHandler(_console_handle) pd.set_option('display.max_columns', 1000) # Set maximum number of columns to 1000 class Alpha(): @@ -106,23 +107,23 @@ def check(self, ill_condition_remove=False): _check_sym = np.allclose(self.value, self.value.T, 0.1, 1e-06) if not _check_sym: warnings.warn('\nWarning: Influence Matrix is asymmetrical!') - logger.info('\nInfluence Matrix is asymmetrical, check your data.') + _logger.info('\nInfluence Matrix is asymmetrical, check your data.') else: - logger.info('\nInfluence Matrix is symmetric --> OK') + _logger.info('\nInfluence Matrix is symmetric --> OK') else: - logger.info('\nNot a square matrix --> no exact solution.') + _logger.info('\nNot a square matrix --> no exact solution.') # Checking ILL-CONDITIONED planes ill_plane = tools.ill_condition(self.value) if ill_plane: - logger.info(f'\nIll-conditioned found in plane # {ill_plane}') + _logger.info(f'\nIll-conditioned found in plane # {ill_plane}') if ill_condition_remove: - logger.warn(f'\nRemoving Ill-conditioned plane # {ill_plane}') - logger.info(f'\nIC matrix before removing\n{tools.convert_cart_math(self.value)}\n') + _logger.warn(f'\nRemoving Ill-conditioned plane # {ill_plane}') + _logger.info(f'\nIC matrix before removing\n{tools.convert_cart_math(self.value)}\n') self.value = np.delete(self.value,[ill_plane], axis=1) - logger.info(f'\nIC matrix after removing\n{tools.convert_cart_math(self.value)}\n') + _logger.info(f'\nIC matrix after removing\n{tools.convert_cart_math(self.value)}\n') else: - logger.info('\nNo ill conditioned planes --> ok') + _logger.info('\nNo ill conditioned planes --> ok') def _info(self): ''' @@ -256,17 +257,24 @@ def __repr__(self): return ''.join(formatter.info()) -def test_save(): - alpha = Alpha(name='Model_IC') - alpha.add(np.random.rand(3, 3)) - alpha.save('my_alpha') - + def save(self, file:str): + ''' + Method to save condition instance. + ''' + if isinstance(file, str): + self.file = file + with open(self.file, 'wb') as f: + pickle.dump(self, f) -if __name__ == '__main__': - test_save() - my_alpha = Alpha() - my_alpha.load('my_alpha') - print(my_alpha) + def load(self, file:str): + ''' + Method to load condition instance. + ''' + if isinstance(file, str): + self.file = file + with open(self.file, 'rb') as f: + _loaded_instance = pickle.load(f) + self.add(_loaded_instance.alpha, _loaded_instance.A) diff --git a/src/hsbalance/model.py b/src/hsbalance/model.py index 23bd4c6..0f68fce 100644 --- a/src/hsbalance/model.py +++ b/src/hsbalance/model.py @@ -8,6 +8,7 @@ class _Model: """Abstract class for models""" + # TODO init model by only name to be able to load from previous saved instance def __init__(self, A:'initial_vibration'=None, alpha: 'instance of Alpha class'=None, conditions: 'list of condition instances'=None, name:'string'=''): @@ -291,6 +292,7 @@ def info(self): return ''.join(formatter.info()) + class LeastSquares(_Model): """subclass of Model solving the model using Least squares method, The objective function diff --git a/src/hsbalance/my_alpha.npy b/src/hsbalance/my_alpha.npy deleted file mode 100644 index fa3fece4ed5435b64f953917e2454774803c9a74..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 200 zcmbR27wQ`j$;eQ~P_3SlTAW;@Zl$1ZlV+i=qoAIaUsO_*m=~X4l#&V(cT3DEP6dh= zXCxM+0{I%oIts>`ItsN4WCO0HO#6x$Za%V~62YJ(T6N1_!R_p+3-^xLOI(~)b(r^} vy@`JMJL#pj>>Z{au33Hjj{QgRirhb5Z|xt%unF)M-?k5sf81;IaE(0x>v}!i diff --git a/test/benchmark_splitting_solver.md b/test/benchmark_splitting_solver.md index 99fa98a..a040852 100644 --- a/test/benchmark_splitting_solver.md +++ b/test/benchmark_splitting_solver.md @@ -32,8 +32,10 @@ This size is convenient for practical rotor balancing (i.e. number of angles ava |-|-|-| |xpress|56.5 ms ± 4.21 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)|array([2.10034846])| |mip_cvxpy[2](#2)| 154 ms ± 1.01 ms per loop (mean ± std. dev. of 3 runs, 1 loop each)|array([2.10034846])| -|ECOS_BB[3](#3)| 1.62 s ± 6.36 ms per loop (mean ± std. dev. of 3 runs, 1 loop each)|array([2.10034846])| +|ECOS_BB[3](#3)| 1.62 s ± 6.36 ms per loop (mean ± std. dev. of 3 runs, 1 loop each)|array([2.10034846])| +|SCIP[4](#4)| 242 ms ± 19.8 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)|array([2.10034846])| [1] Huang, Bin, et al. "Constrained balancing of two industrial rotor systems: Least squares and min-max approaches." Shock and Vibration 16.1 (2009): 1-12. [2] solving with objective function minimize L1 norm -[3] solving with objective function minimize L1 norm +[3] solving with objective function minimize L1 norm +[4] solving with SCIP interface with Python [PySCIPOpt](https://github.com/scipopt/PySCIPOpt). The solver is free, capable of solving MISOCP(Mixed Integer Second Order Cone Programming) and accurate but it is way too slow and not easy to install. diff --git a/test/test_ALPHA.py b/test/test_ALPHA.py index d0432c7..9d0669f 100644 --- a/test/test_ALPHA.py +++ b/test/test_ALPHA.py @@ -5,6 +5,10 @@ import test_tools import warnings import hsbalance as hs +import tempfile +import logging +logger = logging.getLogger(__name__) +temp_file = tempfile.NamedTemporaryFile() '''This module is for testing ALPHA class''' # Reading the test cases from config.yaml file @@ -150,3 +154,11 @@ def test_info(): condition1 = hs.Condition(name='Speed 2500') condition1.add(alpha2, A=np.random.rand(m,1)) print(alpha1, alpha2, condition1) + +def test_alpha_save_load(test_alpha): + np.random.seed(42) + test_alpha.add(np.random.rand(6,4)) + test_alpha.save(temp_file.name) + loaded_alpha = hs.Alpha() + loaded_alpha.load(temp_file.name) + np.testing.assert_allclose(loaded_alpha.value, test_alpha.value) diff --git a/test/test_model.py b/test/test_model.py index ceca181..5e5d82e 100644 --- a/test/test_model.py +++ b/test/test_model.py @@ -1,13 +1,14 @@ import time -from scipy.interpolate import make_interp_spline -import matplotlib.pyplot as plt -import scipy.optimize as opt import numpy as np import sys import yaml import pytest import test_tools import hsbalance as hs +import tempfile +import logging +logger = logging.getLogger(__name__) +temp_file = tempfile.NamedTemporaryFile() def test_model_with_no_argument(): with pytest.raises(TypeError) as e_info: @@ -195,8 +196,23 @@ def test_info_model(): split2.update(confirm=True) print(model.info()) +# Testing save and load conditions + +def test_Condition_save_load(test_A, test_alpha): + condition = hs.Condition() + condition.add(test_alpha, test_A) + condition.save(temp_file.name) + loaded_condition = hs.Condition() + loaded_condition.load(temp_file.name) + np.testing.assert_allclose(loaded_condition.alpha.value, test_alpha.value) + np.testing.assert_allclose(loaded_condition.A, test_A) + if __name__ == '__main__': + from scipy.interpolate import make_interp_spline + import matplotlib.pyplot as plt + import scipy.optimize as opt + def test_performance(n): alpha = hs.Alpha() real = np.random.uniform(0, 10, [n, n]) From e1ab78b103899c25b4f03ed7ca96225c9b491cec Mon Sep 17 00:00:00 2001 From: "Eng \\ Soaaib Mahmod" <64025778+shoaibmahmod7@users.noreply.github.com> Date: Mon, 28 Feb 2022 22:33:56 +0300 Subject: [PATCH 2/5] OFP-1 --- examples/Balancing-All.ipynb | 1478 ++++++++++++++++++++++++++++++++++ examples/splitting-WLS.ipynb | 1289 +++++++++++++++++++++++++++++ 2 files changed, 2767 insertions(+) create mode 100644 examples/Balancing-All.ipynb create mode 100644 examples/splitting-WLS.ipynb diff --git a/examples/Balancing-All.ipynb b/examples/Balancing-All.ipynb new file mode 100644 index 0000000..f8e29e5 --- /dev/null +++ b/examples/Balancing-All.ipynb @@ -0,0 +1,1478 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 65, + "id": "c7266ecd", + "metadata": { + "jupyter": { + "source_hidden": true + }, + "tags": [] + }, + "outputs": [], + "source": [ + "# Importing modules\n", + "try:\n", + " import hsbalance as hs;\n", + "except ImportError:\n", + " !pip install hsbalance\n", + " import hsbalance as hs;\n", + "try:\n", + " import matplotlib\n", + "except ImportError:\n", + " !pip install matplotlib\n", + " import matplotlib\n", + "try:\n", + " import ipympl\n", + "except ImportError:\n", + " !pip install ipympl\n", + " import ipympl" + ] + }, + { + "cell_type": "code", + "execution_count": 66, + "id": "f622ade9", + "metadata": { + "jupyter": { + "source_hidden": true + }, + "tags": [] + }, + "outputs": [], + "source": [ + "import numpy as np\n", + "import matplotlib.pyplot as plt\n", + "%matplotlib widget" + ] + }, + { + "cell_type": "markdown", + "id": "ce6e51fc", + "metadata": { + "tags": [] + }, + "source": [ + "\n", + "# # Creating Model\n" + ] + }, + { + "cell_type": "markdown", + "id": "9aa04d4f", + "metadata": { + "tags": [] + }, + "source": [ + "1. Enter the initial vibration column vector `A`:\n", + "- each row represents the vibration at certain measuring plane.\n", + "- vibration is to be represented in the form ('amplitude' @ 'phase(degrees)')\n" + ] + }, + { + "cell_type": "code", + "execution_count": 67, + "id": "84e04880-b802-43cd-a56a-991ea94d89df", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "A_math = [['42@68'], ['41@221'],['27@153'],['26@325']] \n", + "\n", + "B_math = [['53@54','30@75'],['37.5@220','57@230'],['33@144','22@160'],['28@315','35@324'] ]\n", + "\n", + "U_math =['80@90','108@293']" + ] + }, + { + "cell_type": "markdown", + "id": "90c543d6", + "metadata": { + "tags": [] + }, + "source": [ + "4. Transform matrices to cartesian (complex number) form:" + ] + }, + { + "cell_type": "code", + "execution_count": 68, + "id": "ced90208", + "metadata": { + "jupyter": { + "source_hidden": true + }, + "tags": [] + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "A=\n", + "[[ 15.73347692+38.94172189j]\n", + " [-30.94309279-26.89842019j]\n", + " [-24.05717615+12.25774349j]\n", + " [ 21.29795315-14.91298735j]]\n", + "\n", + "B=\n", + "[[ 31.15261837+42.8779007j 7.76457135+28.97777479j]\n", + " [-28.72666662-24.10453536j -36.63889375-43.66453326j]\n", + " [-26.69756081+19.39691333j -20.67323766 +7.52444315j]\n", + " [ 19.79898987-19.79898987j 28.3155948 -20.57248383j]]\n", + "\n", + "U = [4.89858720e-15+80.j 4.21989619e+01-99.41452417j]\n" + ] + } + ], + "source": [ + "A = hs.convert_matrix_to_cart(A_math)\n", + "B = hs.convert_matrix_to_cart(B_math)\n", + "U = hs.convert_matrix_to_cart(U_math)\n", + "print('A=\\n{}\\n\\nB=\\n{}\\n\\nU = {}'.format(A, B, U))" + ] + }, + { + "cell_type": "markdown", + "id": "0c2e6a2c", + "metadata": {}, + "source": [ + "Transform back to mathematical expression form" + ] + }, + { + "cell_type": "code", + "execution_count": 69, + "id": "738fa68d-f4e1-4358-8ef0-19308db812a3", + "metadata": { + "jupyter": { + "source_hidden": true + }, + "tags": [] + }, + "outputs": [ + { + "data": { + "text/plain": [ + "array([['0.199 @ 284.3', '0.118 @ 298.3'],\n", + " ['0.045 @ 321.6', '0.164 @ 318.2'],\n", + " ['0.095 @ 20.3', '0.054 @ 12.6'],\n", + " ['0.064 @ 162.9', '0.083 @ 28.1']], dtype='\n", + "
\n", + " Figure\n", + "
\n", + " \n", + " \n", + " " + ], + "text/plain": [ + "Canvas(toolbar=Toolbar(toolitems=[('Home', 'Reset original view', 'home', 'home'), ('Back', 'Back to previous …" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "plot_models(models)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.7" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/examples/splitting-WLS.ipynb b/examples/splitting-WLS.ipynb new file mode 100644 index 0000000..60d2c03 --- /dev/null +++ b/examples/splitting-WLS.ipynb @@ -0,0 +1,1289 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "id": "0a4a46ad", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Using the Community license in this session. If you have a full Xpress license, first set the XPAUTH_PATH environment variable to the full path to your license file, xpauth.xpr, and then restart Python. If you want to use the FICO Community license and no longer want to see this message, set the XPAUTH_PATH environment variable to: C:\\Users\\shoai\\anaconda3\\envs\\myenv\\Lib\\site-packages\\xpress\\license\\community-xpauth.xpr\n", + "NB: setting XPAUTH_PATH will also affect any other Xpress products installed on your system.\n" + ] + } + ], + "source": [ + "# Importing modules\n", + "try:\n", + " import hsbalance as hs;\n", + "except ImportError:\n", + " !pip install hsbalance\n", + " import hsbalance as hs;" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "f622ade9", + "metadata": { + "scrolled": true + }, + "outputs": [], + "source": [ + "import numpy as np" + ] + }, + { + "cell_type": "markdown", + "id": "a602bc7e", + "metadata": {}, + "source": [ + "# Huang test_case" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "f8088da8", + "metadata": { + "scrolled": true + }, + "outputs": [], + "source": [ + "ALPHA_math=[['0.199 @ 284.3', '0.118 @ 298.3'],\n", + " ['0.045 @ 321.6', '0.164 @ 318.2'],\n", + " ['0.095 @ 20.3', '0.054 @ 12.6'],\n", + " ['0.064 @ 162.9', '0.083 @ 28.1']]\n", + "\n", + "A_math=[['42@68'], ['41@221'],['27@153'],['26@325']] " + ] + }, + { + "cell_type": "markdown", + "id": "c7144ede", + "metadata": {}, + "source": [ + "Convert to complex numbers (cartesian) form" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "7933f461", + "metadata": { + "scrolled": true + }, + "outputs": [], + "source": [ + "A = hs.convert_matrix_to_cart(A_math)\n", + "ALPHA = hs.convert_matrix_to_cart(ALPHA_math)\n", + "# A, ALPHA" + ] + }, + { + "cell_type": "markdown", + "id": "9524b2c9", + "metadata": {}, + "source": [ + "Adding ALPHA" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "eb13e858", + "metadata": { + "scrolled": true + }, + "outputs": [], + "source": [ + "alpha = hs.Alpha()\n", + "alpha.add(direct_matrix=ALPHA)" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "a41c59f0", + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\n", + "Not a square matrix --> no exact solution.\n", + "\n", + "No ill conditioned planes --> ok\n" + ] + } + ], + "source": [ + "alpha.check()" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "4fa0b512", + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "++++++++++++++++++++++++++++++++++++++++\n", + "Influence Coefficient Matrix\n", + "++++++++++++++++++++++++++++++++++++++++\n", + "\n", + "++++++++++++++++++++++++++++++++++++++++\n", + "Coefficient Values\n", + "==============================\n", + " Plane 1 Plane 2\n", + "Sensor 1 0.199 @ 284.3 0.118 @ 298.3\n", + "Sensor 2 0.045 @ 321.6 0.164 @ 318.2\n", + "Sensor 3 0.095 @ 20.3 0.054 @ 12.6\n", + "Sensor 4 0.064 @ 162.9 0.083 @ 28.1\n", + "==============================\n", + "End of Coefficient Values\n", + "++++++++++++++++++++++++++++++++++++++++\n", + "\n", + " \n" + ] + } + ], + "source": [ + "print(alpha)" + ] + }, + { + "cell_type": "markdown", + "id": "4c81228e", + "metadata": {}, + "source": [ + "## Solving with Least squares:" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "6b55e039", + "metadata": { + "scrolled": true + }, + "outputs": [], + "source": [ + " # Instantiate least square model" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "id": "2ec2321b", + "metadata": { + "scrolled": true + }, + "outputs": [], + "source": [ + "model_LeastSquares = hs.LeastSquares(A, alpha)" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "id": "25d4e6ab", + "metadata": { + "scrolled": true + }, + "outputs": [], + "source": [ + "W_LeastSquares = model_LeastSquares.solve() #solve" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "id": "918ed0cd", + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "array([['319.223 @ 314.6'],\n", + " ['227.495 @ 103.7']], dtype='\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
0270315
weights_available
50.00.00.0
100.00.00.0
205.05.05.0
\n", + "" + ], + "text/plain": [ + " 0 270 315\n", + "weights_available \n", + "5 0.0 0.0 0.0\n", + "10 0.0 0.0 0.0\n", + "20 5.0 5.0 5.0" + ] + }, + "execution_count": 18, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "split_BZA.results()" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "id": "bff59a8b", + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "array([77.82988302])" + ] + }, + "execution_count": 19, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "split_BZA.error()" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "id": "32a45124", + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "array('241.421 @ 315.0', dtype='\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
67.5112.5
weights_available
104.00.0
200.09.0
\n", + "" + ], + "text/plain": [ + " 67.5 112.5\n", + "weights_available \n", + "10 4.0 0.0\n", + "20 0.0 9.0" + ] + }, + "execution_count": 33, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "split_BZC.results()" + ] + }, + { + "cell_type": "code", + "execution_count": 34, + "id": "20a4b752", + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "array([17.80399053])" + ] + }, + "execution_count": 34, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "split_BZC.error()" + ] + }, + { + "cell_type": "code", + "execution_count": 35, + "id": "e4afe820", + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "array('210.196 @ 104.8', dtype=',\n", + " ]" + ] + }, + "execution_count": 43, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "model_LeastSquares.split_instance # We can see the splitting instances that override the optimum solution" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.7" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} From 1825e7ffdfb7770b46ca4217f3690c1677693067 Mon Sep 17 00:00:00 2001 From: "Eng \\ Soaaib Mahmod" <64025778+shoaibmahmod7@users.noreply.github.com> Date: Mon, 28 Feb 2022 23:09:30 +0300 Subject: [PATCH 3/5] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index ce11d68..6a5ebcf 100644 --- a/README.md +++ b/README.md @@ -11,12 +11,12 @@ The purpose of this project is to solve the problem of turbomachinery [rotor bal ![pic](https://img.shields.io/badge/-Jupyter-white?logo=Jupyter) [![Generic badge](https://img.shields.io/badge/Build-Dev-red.svg)]() [![Generic badge](https://img.shields.io/badge/Test-Passing-Green.svg)]() -[![Binder](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/MagedMohamedTurk/Turbomachinery-Rotors-Balancing/HEAD?labpath=examples%2F) +[![Binder](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/shoaibmahmod7/Turbomachinery-Rotors-Balancing/HEAD?labpath=examples) HSBALANCE package is a python tool-kit that enables field engineer to do rotor balancing job on large number of measuring and balancing planes. It facilitates testing various scenarios through applying different optimization methods and applying different constraints. The package takes advantage of object oriented programming which makes it easier to build, extend and maintain. The package also make it possible to easily use the code in a notebook which is a great advantage to work freely, try different method of optimization and splitting for your case, get to compare results and RMS errors and even plot charts and diagrams. ## Binder -Use [mybinder link](https://mybinder.org/v2/gh/MagedMohamedTurk/Turbomachinery-Rotors-Balancing/HEAD?labpath=examples%2F) to quickly navigate through examples with no installation required. +Use [mybinder link](https://mybinder.org/v2/gh/shoaibmahmod7/Turbomachinery-Rotors-Balancing/HEAD?labpath=examples) to quickly navigate through examples with no installation required. ## Installation To quickly use the package: 1. Optional create an isolated environment for python 3.8. (for Anaconda users `e.g. $ conda create -n myenv python=3.8`) From 8bb4c1ec97c4646bcd69ed3398aafc7f985bc96d Mon Sep 17 00:00:00 2001 From: "Eng \\ Soaaib Mahmod" <64025778+shoaibmahmod7@users.noreply.github.com> Date: Sat, 9 Apr 2022 23:01:02 +0300 Subject: [PATCH 4/5] Update CI_matrix.py Self=(B-A) @ inv(U) --- src/hsbalance/CI_matrix.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/hsbalance/CI_matrix.py b/src/hsbalance/CI_matrix.py index de99e2c..0f54fe8 100644 --- a/src/hsbalance/CI_matrix.py +++ b/src/hsbalance/CI_matrix.py @@ -69,7 +69,7 @@ def add(self, direct_matrix:'np.array'=None, A:'initial_vibration numpy.array'=N # Test dimensions if A.shape[1] > 1: raise tools.CustomError('`A` should be column vector') - elif U.ndim > 1: + elif U.ndim < 1: raise tools.CustomError('`U` should be row vector') elif B.shape[0] != A.shape[0] or B.shape[1] != U.shape[0]: raise tools.CustomError('`B` dimensions should match `A`and `U`') @@ -78,7 +78,7 @@ def add(self, direct_matrix:'np.array'=None, A:'initial_vibration numpy.array'=N self.B = B self.U = U if not keep_trial: - self.value = (self.B - self.A) / self.U + self.value = (self.B - self.A) @ np.linalg.inv(self.U) else: _A_keep_trial = np.delete((np.insert(self.B, [0], self.A, axis=1)), -1, axis=1) @@ -148,6 +148,7 @@ def _info(self): index=_index, columns=_columns)) if self.U is not None: _index = (f'Plane {n+1}' for n in range(self.U.shape[0])) + _columns = (f'Plane {n+1}' for n in range(self.U.shape[1]) yield ('Trial Masses', pd.DataFrame(tools.convert_cart_math(self.U), index=_index, columns=['Mass'])) From fe4b1f970a1911a2062d807e9ba8f8dbc53bb4f7 Mon Sep 17 00:00:00 2001 From: "Eng \\ Soaaib Mahmod" <64025778+shoaibmahmod7@users.noreply.github.com> Date: Thu, 21 Sep 2023 20:03:31 +0300 Subject: [PATCH 5/5] Create python-package-conda.yml --- .github/workflows/python-package-conda.yml | 34 ++++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 .github/workflows/python-package-conda.yml diff --git a/.github/workflows/python-package-conda.yml b/.github/workflows/python-package-conda.yml new file mode 100644 index 0000000..384f9b7 --- /dev/null +++ b/.github/workflows/python-package-conda.yml @@ -0,0 +1,34 @@ +name: Python Package using Conda + +on: [push] + +jobs: + build-linux: + runs-on: ubuntu-latest + strategy: + max-parallel: 5 + + steps: + - uses: actions/checkout@v3 + - name: Set up Python 3.10 + uses: actions/setup-python@v3 + with: + python-version: '3.10' + - name: Add conda to system path + run: | + # $CONDA is an environment variable pointing to the root of the miniconda directory + echo $CONDA/bin >> $GITHUB_PATH + - name: Install dependencies + run: | + conda env update --file environment.yml --name base + - name: Lint with flake8 + run: | + conda install flake8 + # stop the build if there are Python syntax errors or undefined names + flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics + # exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide + flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics + - name: Test with pytest + run: | + conda install pytest + pytest